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
| Period | Key themes |
|---|---|
| Apr–Jun 2025 | Standard library expansion, Onigmo regex engine integration |
| Jul–Sep 2025 | Full keyword-argument support, Hash/Enumerable improvements, JIT refactoring |
| Oct–Dec 2025 | JIT abstract-interpretation improvements, optimizations, ruby-bench support |
| Jan–Feb 2026 | FFI/Fiddle support, continuation frames, further optimizations |
| Mar–Apr 2026 | Large-scale ruby/spec compatibility push, crash/panic elimination |
Language Features
Parser
- Splat in multiple-assignment LHS:
*a = 100 when *arysyntax%Wword-array literals=begin/=endblock 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...endblock incorrectly attaching toFoo::BARinstead of the outer call (#144)
Runtime / Closures
defined? super- SIGINT handled as a Ruby-level exception
retrystatement (#109)returninsideevalnow propagates correctly (#232)yieldcorrectly traverses Fiber boundaries (#187, #188)method_missingaccepts 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
Regexpclass implementationMatchDataclass ([], 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.newsucc!/next!,insert,byteindex,to_c,to_rencode/encode!(stubs),codepoints(#260)concat,prepend,reverse,chop,squeeze,partition,uptoString#bytesizeJIT-inlined (#139)
Hash
replace,clone,filter!assoc,rassoc,shift,key,keep_ifdelete_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_whileeach_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.readlinesFile.stat/File::Stat,File.umask,File.fnmatch,File.absolute_path,File.splitFile.zero?(#260)Dir.glob/Dir[](#106),Dir.mkdir/Dir.rmdir/Dir.entriesDir.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
Mathmodule 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.findexpanded to ~70 encoding names and aliases (#246)- ~60
Encodingconstants added (US_ASCII, ISO-8859-, Shift_JIS, EUC_JP, IBM, …) (#242) Encoding.default_external/internalstubs
Module / Class / Object
Module#ancestors,Module#private_instance_methodsModule#undef_method(#73, Jun 2025)Module#method_added,Kernel#__method__Module#define_method(fully correct)Object#singleton_methods,Object#methodsModule.newwith block (#174)Class.newwith block (#163)- Per-class
Class#allocate(#164) Object#clone,initialize_copy,initialize_clone,initialize_dup(#153, #154)define_singleton_method(#155)BasicObjectspec compliance improvements (#166, #168)singleton_classfixes (#167)
Other Classes
- Marshal support (#125, Mar 2026)
- Thread class — minimal single-threaded implementation (#222)
- SizedQueue, ConditionVariable (#260)
Method#to_proc,Method#source_locationMethod/UnboundMethodbuiltin methods (#216)Exception#set_backtrace(#156)Range#bsearch,Range#min/max/count/minmax(endless-range support)Structsubclass supportKernel#autoload,Kernel#load(#105)Kernel#exec(#145),Kernel#format/Kernel#sprintf(#162)$0,Dir.pwd,Dir.chdirProcess::Status,Signal.list- Frozen-object support (#240) — correct
freeze/frozen?behavior throughout - Stack-overflow detection
JIT Compiler Improvements
Architecture
CacheMapintroduction (#75, Sep 2025) — better inline-cache managementStackFrameintroduction — abstraction for JIT stack frames- Constant functions (#77, Sep 2025) — pure constant computations optimized away
Effecttracking (#89, Dec 2025) — side-effect information per functionImmediatebytecode 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)Codegendetached fromGlobalsRecompileReasonintroduced
Optimizations
- Binary-op JIT optimization (#87, Dec 2025) — faster Float/Integer arithmetic
f ** 2special-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#bytesizeinlined (#139, Mar 2026)- Constant folding across method/block boundaries (#90, Dec 2025)
Array#[]and#[]=inlined (#269, Apr 2026)inlinegencan 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
ffigem - SQLite3 FFI bridge (#160, Mar 2026) — support for the
sqlite3gem - 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.rbcalls them instead of a duplicate registration underFFI(which also gains the JIT inliners for___read/___write), and thesqlite3bridge calls them directly rather than throughFFI::Library, so it no longer needs the hostffigem.
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-parsevendored into the workspace (Apr 2025)CLAUDE.mdAI-assistant guide added (#107)bin/spec— script for batch-running all 58 ruby/spec core categoriesbin/comparecommand added (Mar 2026)--disable-gemsCLI option (Mar 2026)
ruby/spec Compatibility
A large-scale compatibility drive (mainly Feb–Apr 2026) pushed ruby/spec core pass rates substantially:
| Metric | Before (≈ Feb 2026) | After (Apr 2026) |
|---|---|---|
| F+E (Fail + Error) | ~14,000 | ~10,300 |
| Pass rate | ~60 % | ~73.6 % |
| Crashes | many | 0 |
cargo test | 568 pass / 10 fail | 756 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 exceptions —
RuntimeError→ properErrno::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
SAFETYcomments on allunsafeblocks (#94, Jan 2026)RubyHashtrait for Hash abstraction (#76)RubyEql,RubyDiv,RubyMod,RubyDivModtraits 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:
- Onigmo regex engine integration — full Ruby-compatible regular expressions
- FFI / Fiddle / SQLite3 support — interoperability with native C libraries and gems
- Hundreds of builtin methods added or corrected
- ruby/spec pass rate raised from ~60 % to 73.6 % (F+E reduced 14,000 → 10,300)
- Continuous JIT improvements — fixpoint type inference, constant functions, continuation frames, constant folding
- Zero crashes in
cargo test— from 10 failures to a clean 756/0