Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

monoruby Progress Summary (April 2025 – April 2026)

Over the past year monoruby advanced through roughly 500 commits, expanding language coverage, hardening the JIT, and dramatically improving CRuby compatibility.


Overview

PeriodKey themes
Apr–Jun 2025Standard library expansion, Onigmo regex engine integration
Jul–Sep 2025Full keyword-argument support, Hash/Enumerable improvements, JIT refactoring
Oct–Dec 2025JIT abstract-interpretation improvements, optimizations, ruby-bench support
Jan–Feb 2026FFI/Fiddle support, continuation frames, further optimizations
Mar–Apr 2026Large-scale ruby/spec compatibility push, crash/panic elimination

Language Features

Parser

  • Splat in multiple-assignment LHS: *a = 100
  • when *ary syntax
  • %W word-array literals
  • =begin/=end block comments
  • Brace-less hash literals (foo: 1, bar: 2)
  • Squiggly heredoc <<~
  • Reserved words (self/true/false) as keyword-argument labels
  • Anonymous block forwarding: def foo(&); bar(&) end (#128)
  • def ** pattern (used by BigDecimal)
  • Fixed rescue-modifier scoping (#181)
  • Fixed do...end block incorrectly attaching to Foo::BAR instead of the outer call (#144)

Runtime / Closures

  • defined? super
  • SIGINT handled as a Ruby-level exception
  • retry statement (#109)
  • return inside eval now propagates correctly (#232)
  • yield correctly traverses Fiber boundaries (#187, #188)
  • method_missing accepts splat / hash-splat / block arguments (#143)
  • Improved backtraces

Standard Library Expansion

Regexp / MatchData

  • Onigmo regex engine (#71, May 2025) — Rust bindings for Ruby’s standard regex engine
  • Regexp class implementation
  • MatchData class ([], back-references, special variables $1$9, …)
  • Interpolated symbols and back-references in alias (#147)

Rational / Complex

  • Rational reimplemented as a native Rust type with literal support (#266, Apr 2026)
  • Full arithmetic / comparison operators and to_f/to_i/to_r (#224)
  • Complex literals are now always frozen

Array

  • flatten!, reverse_each, shuffle!, to_h, union, intersect?, product
  • | (union), & (intersection)
  • eql?, slice, bsearch, replace, fill (including crash fixes)
  • values_at (#260)
  • Array#[] and #[]= defined as inlinable methods (#269)

String

  • rindex, delete, delete_prefix, upcase!, downcase!
  • String.try_convert, String.new
  • succ!/next!, insert, byteindex, to_c, to_r
  • encode/encode! (stubs), codepoints (#260)
  • concat, prepend, reverse, chop, squeeze, partition, upto
  • String#bytesize JIT-inlined (#139)

Hash

  • replace, clone, filter!
  • assoc, rassoc, shift, key, keep_if
  • delete_if, reject!, default_proc=
  • Comparison operators <, <=, >, >= (#196)
  • Hash.[] class method (#191)
  • Customizable hash / eql? methods (#76, Sep 2025)

Enumerable / Enumerator

  • find, filter, filter_map, one?, min_by, take_while
  • each_with_object, to_a, none?
  • step, lazy, permutation, curry (#227)

IO / File / Dir

  • IO#flush, IO#closed?, IO.popen (r+/w modes)
  • IO.select, IO#fileno, IO#write (variadic), IO#syswrite, IO.sysopen (#230)
  • IO.for_fd (#260)
  • File.size, File.size? (#247)
  • File.delete, File.chmod, File.symlink, File.readlines
  • File.stat / File::Stat, File.umask, File.fnmatch, File.absolute_path, File.split
  • File.zero? (#260)
  • Dir.glob / Dir[] (#106), Dir.mkdir / Dir.rmdir / Dir.entries
  • Dir.exist? (#208), Dir.open / Dir.new, Dir instance methods (#256)
  • Kernel#open (#256)

Numeric / Math

  • Dozens of missing methods added (#189, #193, #223)
  • All standard Math module functions implemented (#192)
  • Correct / and % semantics (sign, truncation direction) (#97)
  • Integer#div, Integer#ceildiv (#267)
  • Full overhaul of the coerce protocol (#225, #226, #249, #250)

Encoding

  • Encoding.find expanded to ~70 encoding names and aliases (#246)
  • ~60 Encoding constants added (US_ASCII, ISO-8859-, Shift_JIS, EUC_JP, IBM, …) (#242)
  • Encoding.default_external / internal stubs

Module / Class / Object

  • Module#ancestors, Module#private_instance_methods
  • Module#undef_method (#73, Jun 2025)
  • Module#method_added, Kernel#__method__
  • Module#define_method (fully correct)
  • Object#singleton_methods, Object#methods
  • Module.new with block (#174)
  • Class.new with block (#163)
  • Per-class Class#allocate (#164)
  • Object#clone, initialize_copy, initialize_clone, initialize_dup (#153, #154)
  • define_singleton_method (#155)
  • BasicObject spec compliance improvements (#166, #168)
  • singleton_class fixes (#167)

Other Classes

  • Marshal support (#125, Mar 2026)
  • Thread class — minimal single-threaded implementation (#222)
  • SizedQueue, ConditionVariable (#260)
  • Method#to_proc, Method#source_location
  • Method / UnboundMethod builtin methods (#216)
  • Exception#set_backtrace (#156)
  • Range#bsearch, Range#min/max/count/minmax (endless-range support)
  • Struct subclass support
  • Kernel#autoload, Kernel#load (#105)
  • Kernel#exec (#145), Kernel#format / Kernel#sprintf (#162)
  • $0, Dir.pwd, Dir.chdir
  • Process::Status, Signal.list
  • Frozen-object support (#240) — correct freeze / frozen? behavior throughout
  • Stack-overflow detection

JIT Compiler Improvements

Architecture

  • CacheMap introduction (#75, Sep 2025) — better inline-cache management
  • StackFrame introduction — abstraction for JIT stack frames
  • Constant functions (#77, Sep 2025) — pure constant computations optimized away
  • Effect tracking (#89, Dec 2025) — side-effect information per function
  • Immediate bytecode instruction (#95, Jan 2026)
  • Continuation frames (#101, Feb 2026)
  • Fixpoint iteration for abstract interpretation (#81, Nov 2025) — more precise type inference
  • LinkMode::None / LinkMode::MaybeNone (#79, Nov 2025)
  • InlineFuncInfo::CFunc_F_F (#80, Nov 2025)
  • Codegen detached from Globals
  • RecompileReason introduced

Optimizations

  • Binary-op JIT optimization (#87, Dec 2025) — faster Float/Integer arithmetic
  • f ** 2 special-cased (Apr 2025)
  • Rest-param and keyword-rest-param JIT optimization (#96, Feb 2026)
  • Range class optimization (#98, Feb 2026)
  • Eliminated unnecessary locals write-back
  • Frozen-literal allocation avoidance (Feb 2026)
  • String#bytesize inlined (#139, Mar 2026)
  • Constant folding across method/block boundaries (#90, Dec 2025)
  • Array#[] and #[]= inlined (#269, Apr 2026)
  • inlinegen can now use class information of the first argument (Apr 2026)

Bug Fixes

  • Wrong x86-64 condition codes for NaN float comparisons (#186)
  • GC crash on JIT constant slots (#185)
  • Panic after BOP (basic-op) redefinition (#220)
  • Stale type information in JIT locals_to_S (#112)
  • Temporary-receiver-slot bug in safe navigation operator (&.)
  • Bignum JIT dispatch falling through to wrong path (#271)

External Library / Ecosystem Support

FFI / Fiddle

  • fiddle support (Feb 2026) — Ruby bindings to C libraries
  • ffi support (Feb 2026) — compatibility with the ffi gem
  • SQLite3 FFI bridge (#160, Mar 2026) — support for the sqlite3 gem
  • one shared native-call primitive set (Aug 2026) — Fiddle.___dlopen / ___call / ___read / ___write / … (src/builtins/fiddle.rs) are now the single place C is reached from. gem/ffi_c.rb calls them instead of a duplicate registration under FFI (which also gains the JIT inliners for ___read / ___write), and the sqlite3 bridge calls them directly rather than through FFI::Library, so it no longer needs the host ffi gem.

Benchmarks

  • ruby-bench support (#88, Dec 2025)
  • optcarrot kept running continuously (#115, Mar 2026)
  • rubyboy benchmark support (#111)
  • lee benchmark support (#117, #120)

Infrastructure

  • ruruby-parse vendored into the workspace (Apr 2025)
  • CLAUDE.md AI-assistant guide added (#107)
  • bin/spec — script for batch-running all 58 ruby/spec core categories
  • bin/compare command added (Mar 2026)
  • --disable-gems CLI option (Mar 2026)

ruby/spec Compatibility

A large-scale compatibility drive (mainly Feb–Apr 2026) pushed ruby/spec core pass rates substantially:

MetricBefore (≈ Feb 2026)After (Apr 2026)
F+E (Fail + Error)~14,000~10,300
Pass rate~60 %~73.6 %
Crashesmany0
cargo test568 pass / 10 fail756 pass / 0 fail

Areas fixed

  • Implicit type conversions (to_int/to_str/to_f/to_ary/to_hash) across all builtins
  • Coerce protocol for numeric binary operators
  • TypeError / ArgumentError messages matching CRuby format
  • Errno exceptionsRuntimeError → proper Errno::ENOENT / EACCES / … everywhere
  • IOError for closed-stream operations
  • Float formatting (inf, -0.0, scientific-notation thresholds)
  • Frozen-object enforcement — freeze check added in JIT fast paths
  • Method arities — 30+ builtin methods corrected (#243, #245)
  • Integer spec — 10+ sub-categories fixed (#263, #265, #268, #270, #272)
  • Rational fully reimplemented (#266)

Code Quality / Infrastructure

  • SAFETY comments on all unsafe blocks (#94, Jan 2026)
  • RubyHash trait for Hash abstraction (#76)
  • RubyEql, RubyDiv, RubyMod, RubyDivMod traits introduced
  • Local-frame capture prevented during JIT execution (#93, Jan 2026)
  • Library files copied to ~/.monoruby/lib/ at build time (#119)
  • Codecov coverage tracked continuously

Summary

Over this one-year period monoruby achieved:

  1. Onigmo regex engine integration — full Ruby-compatible regular expressions
  2. FFI / Fiddle / SQLite3 support — interoperability with native C libraries and gems
  3. Hundreds of builtin methods added or corrected
  4. ruby/spec pass rate raised from ~60 % to 73.6 % (F+E reduced 14,000 → 10,300)
  5. Continuous JIT improvements — fixpoint type inference, constant functions, continuation frames, constant folding
  6. Zero crashes in cargo test — from 10 failures to a clean 756/0