feat(engine): add ShadowRealm behind --unsafe-shadowrealm#795
Conversation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Benchmark Results430 benchmarks Interpreted: 🟢 233 improved · 🔴 10 regressed · 187 unchanged · avg +12.0% arraybuffer.js — Interp: 🟢 6, 8 unch. · avg +11.6% · Bytecode: 🔴 14 · avg -29.7%
arrays.js — Interp: 🟢 12, 7 unch. · avg +10.6% · Bytecode: 🔴 18, 1 unch. · avg -29.5%
async-await.js — Interp: 🟢 4, 2 unch. · avg +15.6% · Bytecode: 🔴 6 · avg -33.0%
async-generators.js — Interp: 2 unch. · avg +9.0% · Bytecode: 🔴 2 · avg -32.7%
atomics.js — Interp: 🟢 3, 3 unch. · avg +14.1% · Bytecode: 🔴 6 · avg -29.4%
base64.js — Interp: 🟢 7, 3 unch. · avg +11.8% · Bytecode: 🔴 10 · avg -32.7%
classes.js — Interp: 🟢 22, 9 unch. · avg +10.3% · Bytecode: 🔴 27, 4 unch. · avg -28.4%
closures.js — Interp: 🟢 7, 4 unch. · avg +15.5% · Bytecode: 🔴 11 · avg -32.8%
collections.js — Interp: 🟢 6, 6 unch. · avg +11.0% · Bytecode: 🔴 12 · avg -35.9%
csv.js — Interp: 🟢 6, 7 unch. · avg +10.8% · Bytecode: 🔴 11, 2 unch. · avg -27.5%
destructuring.js — Interp: 🟢 17, 5 unch. · avg +16.8% · Bytecode: 🔴 21, 1 unch. · avg -29.9%
fibonacci.js — Interp: 🟢 5, 3 unch. · avg +13.8% · Bytecode: 🔴 7, 1 unch. · avg -32.2%
float16array.js — Interp: 🟢 23, 9 unch. · avg +12.7% · Bytecode: 🔴 29, 3 unch. · avg -29.7%
for-of.js — Interp: 🟢 3, 4 unch. · avg +7.5% · Bytecode: 🔴 7 · avg -32.8%
generators.js — Interp: 🟢 3, 1 unch. · avg +13.8% · Bytecode: 🔴 4 · avg -30.1%
intl.js — Interp: 🟢 6 · avg +20.0% · Bytecode: 🔴 6 · avg -34.9%
iterators.js — Interp: 🟢 15, 27 unch. · avg +6.9% · Bytecode: 🔴 41, 1 unch. · avg -26.5%
json.js — Interp: 🟢 13, 7 unch. · avg +16.0% · Bytecode: 🔴 20 · avg -30.0%
jsx.jsx — Interp: 🟢 6, 15 unch. · avg +10.8% · Bytecode: 🔴 18, 3 unch. · avg -28.8%
modules.js — Interp: 🟢 4, 5 unch. · avg +13.6% · Bytecode: 🔴 9 · avg -25.7%
numbers.js — Interp: 🟢 5, 6 unch. · avg +17.5% · Bytecode: 🔴 11 · avg -32.0%
objects.js — Interp: 🟢 2, 5 unch. · avg +14.8% · Bytecode: 🔴 7 · avg -28.7%
promises.js — Interp: 🟢 3, 9 unch. · avg +10.1% · Bytecode: 🔴 11, 1 unch. · avg -25.8%
property-access.js — Interp: 🟢 1, 4 unch. · avg +12.6% · Bytecode: 🔴 5 · avg -33.8%
regexp.js — Interp: 🟢 4, 7 unch. · avg +12.2% · Bytecode: 🔴 10, 1 unch. · avg -28.5%
strings.js — Interp: 🟢 13, 6 unch. · avg +13.9% · Bytecode: 🔴 19 · avg -31.0%
temporal.js — Interp: 🟢 4, 2 unch. · avg +15.1% · Bytecode: 🔴 6 · avg -34.5%
tsv.js — Interp: 🟢 3, 🔴 1, 5 unch. · avg +3.2% · Bytecode: 🔴 9 · avg -26.8%
typed-arrays.js — Interp: 🟢 18, 4 unch. · avg +29.5% · Bytecode: 🟢 1, 🔴 21 · avg -36.3%
uint8array-encoding.js — Interp: 🟢 11, 🔴 1, 6 unch. · avg +13.2% · Bytecode: 🟢 2, 🔴 14, 2 unch. · avg -21.3%
weak-collections.js — Interp: 🟢 1, 🔴 8, 6 unch. · avg -16.6% · Bytecode: 🟢 3, 🔴 10, 2 unch. · avg -22.8%
Deterministic profile diffDeterministic profile diff: no significant changes. Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context. |
Suite TimingTest Runner (interpreted: 10,834 passed; bytecode: 10,834 passed)
MemoryGC rows aggregate the main thread plus all worker thread-local GCs. Test runner worker shutdown frees thread-local heaps in bulk; that shutdown reclamation is not counted as GC collections or collected objects.
Benchmarks (interpreted: 430; bytecode: 430)
MemoryGC rows aggregate the main thread plus all worker thread-local GCs. Benchmark runner performs explicit between-file collections, so collection and collected-object counts can be much higher than the test runner.
Measured on ubuntu-latest x64. |
test262 Conformance
Areas closest to 100%
Per-test deltas (+83 / -5)Newly failing (5):
Newly passing (83):
Steady-state failures are non-blocking; regressions vs the cached main baseline (lower total pass count, or any PASS → non-PASS transition) fail the conformance gate. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached |
Summary
Implements the TC39 ShadowRealm proposal (stage 2.7) as an opt-in core language built-in, gated by a new
--unsafe-shadowrealmflag /"unsafe-shadowrealm": trueconfig key. It is off by default becauseShadowRealm.prototype.evaluateperforms dynamic source evaluation, which GocciaScript keeps out of normal runtimes — the same explicit-capability pattern as--unsafe-function-constructor.What's implemented
globalThis.ShadowRealmconstructor — engine-owned, installed only when the flag is set (genuinely absent otherwise).newrequired (ShadowRealm()throwsTypeError);length0,name"ShadowRealm",[[Prototype]]=Function.prototype;ShadowRealm.prototype[Symbol.toStringTag]="ShadowRealm".ShadowRealm.prototype.evaluate(sourceText)— runs source in a fresh child realm (its own intrinsics + global object) using eval-style declaration instantiation:var/functionpersist on the realm'sglobalThis,let/constare per-call. Parse failures throw a caller-realmSyntaxError; runtime errors throw a caller-realmTypeError. Nested realms are supported.TypeError, callables are wrapped (name/length copied, arguments/results marshaled across realms, thrown errors re-wrapped into the caller realm).ShadowRealm/realms-testsfeatures map to--unsafe-shadowrealmin the conformance runner.Key implementation notes
TGocciaEnginefreed at the creating engine's teardown (a GC sweep can't safely free a child engine from a collected instance). See ADR 0070.InvokeCallablenow routes callable non-function/class values (e.g. callable proxies) through the proxy apply hook so wrapped callable proxies work — previously they raised "object is not a function".Deferred / out of scope (follow-ups)
ShadowRealm.prototype.importValue(module import in the child realm) — a separate proposal method, not in this issue's expected behavior (~12 test262 cases).eval, consistent with the no-eval default.Symbol.forregistry sharing — a pre-existing per-realm limitation also visible via$262.createRealm.arguments) and native-functionlengthdeletability are pre-existing engine limitations surfaced by a few test262 cases.FWrappedHostsretains wrapped-function state for the realm's lifetime (memory bounded by engine lifetime; candidate for a future GC-owned wrapper).Closes #777
Testing
tests/built-ins/ShadowRealm/**tests. test262built-ins/ShadowRealmat the pinned SHA: 48/64 (was 0/64), 0 wrapper-infra failures; the remaining 16 are the deferredimportValue(12) and the pre-existing-limitation edge cases (4) noted above../format.pas --checkclean.docs/built-ins.md,docs/language-tables.md,docs/build-system.md, and ADR 0070.🤖 Generated with Claude Code