diff --git a/docs/conformance.md b/docs/conformance.md index 49d1412..ff3a2f6 100644 --- a/docs/conformance.md +++ b/docs/conformance.md @@ -188,7 +188,8 @@ interpreter, and blurring the two would be misleading: Both are gains in what the measurement can **see**, not in what the VM can **do**. The rest of the climb is the VM: the floor went from **6 000** when the ratchet landed on 2026-08-03 -([#263](https://github.com/go-embedded-ruby/ruby/pull/263)) to **22 475** today. +([#263](https://github.com/go-embedded-ruby/ruby/pull/263)) to **22 475** by the +time it was replaced by the per-file baseline, whose sum is **23 481** today. ### Known limitations diff --git a/docs/roadmap.md b/docs/roadmap.md index c8d47a9..0a2c95e 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -14,6 +14,6 @@ building whole subsystems in isolation. There are nine phases, 0 through 8. | 5 | Full front-end | Complete the lexer/parser/compiler to full Ruby 4.0 syntax (or settle the Prism-on-wazero decision). **Landed:** string interpolation, keyword args, endless methods (`def foo = expr`), beginless/endless ranges, the stabby lambda, **multiple assignment / destructuring**, **full pattern matching `case`/`in`** (value/bind/class/array/hash/find/pin/alternative patterns, guards, one-line `=>`/`in`, `deconstruct`/`deconstruct_keys`), **safe navigation `&.`**, **numbered params (`_1`/`_2`) and `it`**, **heredocs** (`<<`/`<<-`/`<<~`, interpolating and literal), **`%w`/`%i` arrays**, and the **`%q`/`%Q`/`%W`/`%I` literals**. | **Done** (core) | | 6 | Standard library | Pure-Go stdlib coverage, with the regexp engine from the `go-ruby-regexp` sibling org. **Regexp bridge landed:** `/re/imx` literals + `Regexp`/`MatchData` (`source`/`match`/`match?`/`=~`/`===`, `[]` by index or name, `pre_match`/`post_match`/`captures`/`named_captures`/`begin`/`end`/`size`), `String#=~`/`match`/`match?`/`scan`, and `sub`/`gsub`/`split` over a Regexp (backref templates, blocks, captured-group interpolation, field limit). CGO=0 via `go-ruby-regexp`; differential-tested against MRI. **Also landed:** `Time`/`Date`/`BigDecimal`, `Set`/`Bag`, and the Go-native leaves `JSON` (generate/parse/pretty_generate + `to_json`), `Digest` (MD5/SHA1/SHA256/SHA512), `Base64`, **`File`** (path helpers + read/write/stat/delete, `Errno::ENOENT`), a **MRI-faithful `Random`** (seeded MT19937, bit-exact), **`Zlib`** (crc32/adler32 + Deflate/Inflate), a **byte-exact `Marshal`** (`dump`/`load`, on the pure-Go `go-ruby-marshal` engine), **`Thread`/`Mutex`/`Queue`** on an emulated GVL (one Ruby thread at a time, MRI memory model, race-free), **`IO`/`StringIO`** (`$stdout`/`$stderr`/`$stdin` as real objects; `puts`/`print`/`p` route through `$stdout` so reassigning it to a `StringIO` captures output) and **`Dir`** (entries/children/glob, mkdir/rmdir/chdir, `Errno::ENOENT`/`Errno::EEXIST`), and **`File.open` streams** (`File < IO`, modes `r`/`w`/`a`/`+`, block form auto-flush/close, `File.readlines`/`foreach`). | **Substantially landed** | | 7 | Build toolchain | `rbgo build`. **Landed:** ahead-of-time **method compilation** to native Go (bytecode → Go → machine code), with **unboxed `int64` integer kernels** that deopt to the interpreter on overflow/`÷0` — the generated `fib(30)` beats **MRI + YJIT ~4×** while staying correct for every input ([AOT compiler](architecture/build.md#ahead-of-time-method-compilation-landed)). **Closed-world builds landed** (`rbgo build --closed`): the program is baked in as bytecode (and the prelude loads from frozen bytecode), the **lexer/parser/compiler are dropped** behind the `rbgo_closed` build tag, and a require-graph scan reports any `eval`/`require` that would then raise — yielding a smaller, self-contained binary that runs with no source file. (Per-class stdlib tree-shaking beyond the front-end was measured and skipped — the Go-implemented bindings are small pure-Go libraries, under 2% of a runtime-dominated binary; the front-end drop is the real saving.) | **Done** | -| 8 | Conformance & performance | ruby/spec conformance and representation/perf work (tagging, fast paths, allocation). **Started:** allocation cuts — **small-integer interning** (`object.IntValue` reuses a shared box for ints in [-256, 1024]; a small-int loop drops from ~245k allocs to 1) and **frame-environment recycling** (`exec` pools per-call `*Env`s via a capture-tracked free-list — fib's call allocations halve, ~14% faster). **Conformance & benchmark ladder:** a three-way differential oracle (rbgo / **MRI** / **JRuby**, `scripts/oracle.sh`), then pure-Ruby gem test suites as corpora (ActiveSupport `core_ext`), then real-world workloads. A heavyweight front-end sweep now accepts **~100% of all valid Ruby** across Rails + Puppet (**parse + compile** Rails 99.82% / Puppet 100%, 0 over-permissive), and on the runtime side **the real `puppet apply` CLI runs end-to-end** (Puppet 8.11.0): `require "puppet"` boots the framework and the genuine `Puppet::Util::CommandLine` → `Puppet::Application::Apply` path (real `OptionParser`, all types + providers, settings catalog applied to disk, then the user catalog via the transaction / RAL) applies a `notify` resource and emits real Puppet output (`Notice: hi from rbgo cli`), exiting 0. **Runtime conformance, since July:** the ruby/spec `language/` + `core/` suites run in CI as a shrink-only ratchet; the floor has gone from **6 000** (2026-08-03) to **22 475**, and a run measures **22 488** passing examples (2026-09-26) — see [Conformance](conformance.md#where-it-stands--measured-2026-09-26). **Active next milestone:** real file/package/service resource *providers* (host convergence) + run-report persistence. | **In progress** | +| 8 | Conformance & performance | ruby/spec conformance and representation/perf work (tagging, fast paths, allocation). **Started:** allocation cuts — **small-integer interning** (`object.IntValue` reuses a shared box for ints in [-256, 1024]; a small-int loop drops from ~245k allocs to 1) and **frame-environment recycling** (`exec` pools per-call `*Env`s via a capture-tracked free-list — fib's call allocations halve, ~14% faster). **Conformance & benchmark ladder:** a three-way differential oracle (rbgo / **MRI** / **JRuby**, `scripts/oracle.sh`), then pure-Ruby gem test suites as corpora (ActiveSupport `core_ext`), then real-world workloads. A heavyweight front-end sweep now accepts **~100% of all valid Ruby** across Rails + Puppet (**parse + compile** Rails 99.82% / Puppet 100%, 0 over-permissive), and on the runtime side **the real `puppet apply` CLI runs end-to-end** (Puppet 8.11.0): `require "puppet"` boots the framework and the genuine `Puppet::Util::CommandLine` → `Puppet::Application::Apply` path (real `OptionParser`, all types + providers, settings catalog applied to disk, then the user catalog via the transaction / RAL) applies a `notify` resource and emits real Puppet output (`Notice: hi from rbgo cli`), exiting 0. **Runtime conformance, since July:** the ruby/spec `language/` + `core/` suites run in CI against a **per-file** baseline, which names any spec file that regresses instead of absorbing it in a total; its sum is **23 481** (2026-10-04). It replaced a single shrink-only floor that had climbed from **6 000** (2026-08-03) to 22 475 — a threshold needed a margin wider than the largest spec file, so it could not see a regression smaller than that — see [Conformance](conformance.md#where-it-stands--measured-2026-09-26). **Active next milestone:** real file/package/service resource *providers* (host convergence) + run-report persistence. | **In progress** | See [Phase 0 — Vertical slice](phases/phase0.md) for what runs today.