Skip to content

Fix bytecode object literal define semantics#669

Merged
frostney merged 9 commits into
mainfrom
t3code/issue-649
May 20, 2026
Merged

Fix bytecode object literal define semantics#669
frostney merged 9 commits into
mainfrom
t3code/issue-649

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

  • Add OP_DEFINE_DATA_PROP and bump the bytecode format to v33 so bytecode object literal data properties use define semantics instead of ordinary [[Set]] assignment.
  • Route static, computed, and spread object literal data properties through own enumerable writable configurable data-property creation while leaving ordinary assignment on the existing OP_SET_* path.
  • Update bytecode VM docs and object tests for inherited read-only/accessor descriptor cases.
  • Closes Use define semantics for object literals in bytecode mode #649.

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
    • ./build/GocciaTestRunner tests/language/objects/basic-object-creation.js --asi
    • ./build/GocciaTestRunner tests/language/objects/basic-object-creation.js --mode=bytecode --asi
    • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-suite --filter "language/expressions/object/11.1.5_3-3-1.js" --mode=bytecode --jobs=1
    • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-suite --filter "built-ins/Array/prototype/indexOf/15.4.4.14-9-b-i-6.js" --mode=bytecode --jobs=1
    • ./build/GocciaTestRunner tests --asi --unsafe-ffi
    • ./format.pas --check
    • git diff --check
  • Updated documentation
  • Optional: Verified no regressions and confirmed the new feature or bugfix in native Pascal tests (if AST, scope, evaluator, or value types changed)
  • Optional: Verified no benchmark regressions or confirmed benchmark coverage for the change

Note: a sequential full bytecode run with --jobs=1 exposes an existing Goccia.gc() runner/runtime fatal in tests/built-ins/global-properties/goccia.js, tests/built-ins/WeakMap/gc.js, and tests/built-ins/WeakSet/gc.js; the same files fail individually in interpreted mode too, so this is separate from the bytecode object literal change.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Preview May 20, 2026 8:00am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds OP_DEFINE_DATA_PROP and OP_DEFINE_METHOD_PROP to the bytecode format (version 34), propagates method metadata from the parser, changes the compiler to emit define opcodes for object-literal properties, implements VM define-path helpers and opcode handling, updates evaluator skipping of superseded entries, and adds tests and documentation clarifying define vs set semantics.

Changes

Define Data Property Opcode for Object Literals

Layer / File(s) Summary
Bytecode format, opcode names, and docs
source/units/Goccia.Bytecode.pas, source/units/Goccia.Bytecode.OpCodeNames.pas, docs/bytecode-vm.md
Bumps bytecode format (GOCCIA_FORMAT_VERSION) and inserts OP_DEFINE_DATA_PROP / OP_DEFINE_METHOD_PROP enum entries and opcode-name mapping; docs describe object-literal compilation using define opcodes vs OP_SET_*.
Parser / AST metadata
source/units/Goccia.AST.Expressions.pas, source/units/Goccia.Parser.pas
Adds Skip: Boolean to TGocciaPropertySourceOrder and introduces TGocciaObjectMethodDefinition; parser records Skip=false for members, wraps method-shorthand into the wrapper, and marks earlier static entries as skipped for duplicate keys.
Compiler object-literal emission
source/units/Goccia.Compiler.Expressions.pas, source/units/Goccia.Compiler.pas
Adds EmitDefineDataPropertyByName, extends CompileObjectProperty to detect TGocciaObjectMethodDefinition and select OP_DEFINE_METHOD_PROP vs OP_DEFINE_DATA_PROP, skips Order[I].Skip entries, and emits define opcodes for named and computed properties; replaces CompileMethod with CompileFunctionExpression.
VM define helpers and opcode handler
source/units/Goccia.VM.pas
Adds DefineDataPropertyByKeyInternal/DefineDataPropertyByKey, inline helpers for string/symbol data property definition, updates SpreadObjectIntoValue to use definition helpers, and wires OP_DEFINE_DATA_PROP to call the new define path; method-property emission sets the home object.
Evaluator skip handling & function evaluation
source/units/Goccia.Evaluator.pas
EvaluateObject now respects PropertySourceOrder[I].Skip and ignores skipped entries during object literal evaluation; EvaluateFunctionExpression replaces the prior method-evaluation entry point and inferred-name logic includes TGocciaObjectMethodDefinition.
Tests
tests/language/objects/basic-object-creation.js, tests/language/classes/scope-walk-function-boundary.js
Adds tests asserting object literals and spreads create own data properties that override inherited non-writable/accessor properties; adds a class-arrow super boundary test and duplicate-key initializer test.
Docs and decision log
docs/language.md, docs/value-system.md, docs/decision-log.md
Update compatibility and value-system docs to reference TGocciaFunctionExpression / TGocciaObjectMethodDefinition for function/method desugaring and this-binding mapping.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • frostney/GocciaScript#390: Refactors function/method expression AST and compiler/evaluator entry points, touching related desugaring and naming behavior.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix bytecode object literal define semantics' directly and clearly summarizes the main change: introducing define-semantics opcodes for bytecode object literals instead of assignment-style operations.
Description check ✅ Passed The PR description provides a clear summary of changes, links the related issue (#649), lists comprehensive testing performed, confirms documentation was updated, and addresses all key requirements from the template.
Linked Issues check ✅ Passed The changes comprehensively address issue #649 by implementing define-semantics opcodes (OP_DEFINE_DATA_PROP and OP_DEFINE_METHOD_PROP), routing object literal properties through these new definition paths, and updating VM/compiler/AST components to distinguish literal property definition from ordinary assignment.
Out of Scope Changes check ✅ Passed All changes directly support the primary objective of fixing bytecode object literal define semantics. Refactoring TGocciaMethodExpression to TGocciaFunctionExpression and adding TGocciaObjectMethodDefinition are necessary supporting changes to enable the new define-semantic distinction, with no extraneous modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

Suite Timing

Test Runner (interpreted: 9,729 passed; bytecode: 9,729 passed)
Metric Interpreted Bytecode
Total 9729 9729
Passed 9729 ✅ 9729 ✅
Workers 4 4
Test Duration 3.11s 3.71s
Lex (cumulative) 435.9ms 330.3ms
Parse (cumulative) 314.5ms 300.6ms
Compile (cumulative) 657.5ms
Execute (cumulative) 3.26s 5.07s
Engine Total (cumulative) 4.01s 6.36s
Lex (avg/worker) 109.0ms 82.6ms
Parse (avg/worker) 78.6ms 75.1ms
Compile (avg/worker) 164.4ms
Execute (avg/worker) 815.2ms 1.27s
Engine Total (avg/worker) 1.00s 1.59s

Memory

GC 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.

Metric Interpreted Bytecode
GC Live 261.57 MiB 255.88 MiB
GC Peak Live 261.58 MiB 255.89 MiB
GC Allocated During Run 266.01 MiB 260.33 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 1 1
GC Collected Objects 88 88
Heap Start Allocated 157.8 KiB 157.8 KiB
Heap End Allocated 1.49 MiB 1.49 MiB
Heap Delta Allocated 1.34 MiB 1.34 MiB
Heap Delta Free 1.19 MiB 1.19 MiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.48min 2.33min

Memory

GC 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.

Metric Interpreted Bytecode
GC Live 3.69 MiB 3.68 MiB
GC Peak Live 107.53 MiB 77.15 MiB
GC Allocated During Run 13.73 GiB 9.96 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 2,822 2,656
GC Collected Objects 257,466,121 247,318,112
Heap Start Allocated 1.23 MiB 1.23 MiB
Heap End Allocated 1.23 MiB 1.23 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 51 improved · 🔴 58 regressed · 298 unchanged · avg +0.8%
Bytecode: 🟢 268 improved · 🔴 76 regressed · 63 unchanged · avg +4.8%

arraybuffer.js — Interp: 🟢 4, 🔴 1, 9 unch. · avg +0.7% · Bytecode: 🟢 11, 🔴 1, 2 unch. · avg +8.7%
Benchmark Interpreted Δ Bytecode Δ
create ArrayBuffer(0) 160,906 ops/sec [126,560..163,325] → 152,447 ops/sec [137,240..161,203] ~ overlap (-5.3%) 171,222 ops/sec [150,668..192,688] → 195,139 ops/sec [158,368..215,096] ~ overlap (+14.0%)
create ArrayBuffer(64) 155,164 ops/sec [151,558..156,089] → 156,337 ops/sec [155,132..157,977] ~ overlap (+0.8%) 185,219 ops/sec [181,371..185,587] → 202,449 ops/sec [198,139..204,738] 🟢 +9.3%
create ArrayBuffer(1024) 137,709 ops/sec [137,111..138,909] → 136,054 ops/sec [82,178..137,988] ~ overlap (-1.2%) 160,014 ops/sec [158,578..160,921] → 170,040 ops/sec [167,616..170,567] 🟢 +6.3%
create ArrayBuffer(8192) 76,749 ops/sec [75,990..77,547] → 77,341 ops/sec [76,390..78,312] ~ overlap (+0.8%) 85,308 ops/sec [84,157..86,466] → 82,002 ops/sec [79,832..83,610] 🔴 -3.9%
slice full buffer (64 bytes) 183,456 ops/sec [178,333..184,161] → 184,962 ops/sec [184,582..185,532] 🟢 +0.8% 232,394 ops/sec [230,867..235,745] → 250,805 ops/sec [249,400..251,937] 🟢 +7.9%
slice half buffer (512 of 1024 bytes) 164,494 ops/sec [140,779..166,357] → 169,000 ops/sec [166,392..170,879] 🟢 +2.7% 207,486 ops/sec [206,623..208,507] → 222,980 ops/sec [221,954..223,722] 🟢 +7.5%
slice with negative indices 159,529 ops/sec [158,811..159,619] → 154,809 ops/sec [153,778..156,797] 🔴 -3.0% 211,791 ops/sec [210,772..212,866] → 232,215 ops/sec [228,834..234,699] 🟢 +9.6%
slice empty range 173,817 ops/sec [172,666..187,315] → 179,329 ops/sec [178,017..181,509] ~ overlap (+3.2%) 222,181 ops/sec [219,098..223,162] → 243,473 ops/sec [240,261..244,526] 🟢 +9.6%
byteLength access 387,703 ops/sec [380,427..401,591] → 395,523 ops/sec [382,052..409,935] ~ overlap (+2.0%) 426,676 ops/sec [418,764..430,953] → 486,938 ops/sec [484,110..489,036] 🟢 +14.1%
Symbol.toStringTag access 338,526 ops/sec [335,500..344,556] → 344,026 ops/sec [341,475..344,715] ~ overlap (+1.6%) 307,656 ops/sec [302,108..315,893] → 341,484 ops/sec [341,242..345,358] 🟢 +11.0%
ArrayBuffer.isView 247,541 ops/sec [241,474..250,030] → 257,380 ops/sec [256,436..257,990] 🟢 +4.0% 281,435 ops/sec [276,937..286,666] → 313,790 ops/sec [312,517..314,094] 🟢 +11.5%
clone ArrayBuffer(64) 170,295 ops/sec [170,192..170,372] → 171,718 ops/sec [170,746..173,449] 🟢 +0.8% 205,427 ops/sec [203,426..209,488] → 216,061 ops/sec [215,875..216,449] 🟢 +5.2%
clone ArrayBuffer(1024) 145,303 ops/sec [143,578..146,983] → 148,552 ops/sec [146,160..149,851] ~ overlap (+2.2%) 171,575 ops/sec [169,794..171,891] → 185,053 ops/sec [150,729..189,670] ~ overlap (+7.9%)
clone ArrayBuffer inside object 115,502 ops/sec [114,659..115,939] → 115,805 ops/sec [114,874..116,896] ~ overlap (+0.3%) 129,292 ops/sec [127,813..130,257] → 144,352 ops/sec [142,828..146,728] 🟢 +11.6%
arrays.js — Interp: 🟢 1, 🔴 3, 15 unch. · avg -0.8% · Bytecode: 🟢 18, 1 unch. · avg +10.9%
Benchmark Interpreted Δ Bytecode Δ
Array.from length 100 3,800 ops/sec [3,584..3,835] → 3,753 ops/sec [3,680..3,845] ~ overlap (-1.2%) 5,244 ops/sec [5,074..5,350] → 6,138 ops/sec [5,267..6,210] ~ overlap (+17.0%)
Array.from 10 elements 87,917 ops/sec [86,864..88,286] → 88,503 ops/sec [86,926..90,190] ~ overlap (+0.7%) 92,376 ops/sec [91,234..95,280] → 102,548 ops/sec [101,937..103,004] 🟢 +11.0%
Array.of 10 elements 106,018 ops/sec [105,207..107,497] → 108,448 ops/sec [106,574..109,465] ~ overlap (+2.3%) 118,976 ops/sec [116,137..119,387] → 133,149 ops/sec [131,127..134,040] 🟢 +11.9%
spread into new array 133,593 ops/sec [130,691..134,413] → 132,888 ops/sec [130,892..136,237] ~ overlap (-0.5%) 73,802 ops/sec [71,885..76,213] → 80,284 ops/sec [76,588..81,893] 🟢 +8.8%
map over 50 elements 6,076 ops/sec [4,995..6,380] → 6,369 ops/sec [6,256..6,466] ~ overlap (+4.8%) 9,719 ops/sec [9,571..9,865] → 11,264 ops/sec [11,035..11,343] 🟢 +15.9%
filter over 50 elements 6,231 ops/sec [6,145..6,654] → 6,174 ops/sec [6,093..6,212] ~ overlap (-0.9%) 10,492 ops/sec [10,438..10,634] → 11,197 ops/sec [10,796..11,275] 🟢 +6.7%
reduce sum 50 elements 6,675 ops/sec [6,367..7,112] → 6,613 ops/sec [6,520..6,817] ~ overlap (-0.9%) 10,261 ops/sec [9,236..10,388] → 11,074 ops/sec [11,043..11,090] 🟢 +7.9%
forEach over 50 elements 6,008 ops/sec [5,964..6,050] → 6,032 ops/sec [5,976..6,135] ~ overlap (+0.4%) 11,183 ops/sec [10,915..11,251] → 11,989 ops/sec [11,950..12,030] 🟢 +7.2%
find in 50 elements 8,724 ops/sec [8,659..8,802] → 8,607 ops/sec [8,370..8,729] ~ overlap (-1.3%) 14,895 ops/sec [14,850..14,988] → 16,005 ops/sec [15,946..16,068] 🟢 +7.5%
sort 20 elements 3,382 ops/sec [3,322..3,461] → 3,312 ops/sec [3,247..3,365] ~ overlap (-2.1%) 5,824 ops/sec [5,778..5,830] → 6,243 ops/sec [6,193..6,288] 🟢 +7.2%
flat nested array 46,111 ops/sec [40,900..47,349] → 46,584 ops/sec [45,917..47,092] ~ overlap (+1.0%) 51,880 ops/sec [51,774..52,390] → 58,669 ops/sec [58,262..59,154] 🟢 +13.1%
flatMap 27,113 ops/sec [27,047..27,161] → 26,150 ops/sec [26,026..26,184] 🔴 -3.6% 32,696 ops/sec [32,517..33,612] → 37,301 ops/sec [37,093..37,729] 🟢 +14.1%
map inside map (5x5) 6,999 ops/sec [6,950..7,154] → 6,753 ops/sec [6,722..6,786] 🔴 -3.5% 9,382 ops/sec [9,349..9,421] → 10,454 ops/sec [10,287..10,525] 🟢 +11.4%
filter inside map (5x10) 4,826 ops/sec [4,806..4,860] → 4,716 ops/sec [4,599..4,765] 🔴 -2.3% 7,090 ops/sec [6,265..7,128] → 7,514 ops/sec [7,298..7,926] 🟢 +6.0%
reduce inside map (5x10) 5,479 ops/sec [5,424..5,516] → 5,383 ops/sec [5,196..5,533] ~ overlap (-1.7%) 7,301 ops/sec [7,243..7,398] → 8,240 ops/sec [8,111..8,329] 🟢 +12.9%
forEach inside forEach (5x10) 4,882 ops/sec [4,837..4,894] → 4,828 ops/sec [4,802..4,911] ~ overlap (-1.1%) 7,948 ops/sec [7,833..8,010] → 9,033 ops/sec [8,805..9,329] 🟢 +13.7%
find inside some (10x10) 4,018 ops/sec [3,951..4,061] → 3,779 ops/sec [3,714..3,952] ~ overlap (-5.9%) 5,812 ops/sec [5,712..5,826] → 6,645 ops/sec [6,428..6,755] 🟢 +14.3%
map+filter chain nested (5x20) 1,483 ops/sec [1,467..1,505] → 1,449 ops/sec [1,413..1,503] ~ overlap (-2.3%) 2,169 ops/sec [2,120..2,218] → 2,469 ops/sec [2,403..2,519] 🟢 +13.8%
reduce flatten (10x5) 15,725 ops/sec [15,268..15,745] → 16,249 ops/sec [15,942..16,304] 🟢 +3.3% 6,981 ops/sec [6,847..7,065] → 7,433 ops/sec [7,173..7,502] 🟢 +6.5%
async-await.js — Interp: 6 unch. · avg +0.8% · Bytecode: 🟢 5, 1 unch. · avg +6.4%
Benchmark Interpreted Δ Bytecode Δ
single await 141,504 ops/sec [139,027..142,182] → 142,337 ops/sec [114,441..144,859] ~ overlap (+0.6%) 150,394 ops/sec [127,029..151,725] → 154,597 ops/sec [98,050..167,152] ~ overlap (+2.8%)
multiple awaits 67,228 ops/sec [66,406..68,128] → 66,997 ops/sec [66,077..68,997] ~ overlap (-0.3%) 65,740 ops/sec [64,841..66,821] → 71,949 ops/sec [70,996..72,336] 🟢 +9.4%
await non-Promise value 267,687 ops/sec [263,134..272,565] → 269,406 ops/sec [205,317..273,333] ~ overlap (+0.6%) 361,115 ops/sec [358,702..378,321] → 401,729 ops/sec [399,452..402,810] 🟢 +11.2%
await with try/catch 111,370 ops/sec [109,490..116,909] → 111,369 ops/sec [110,522..114,662] ~ overlap (-0.0%) 150,038 ops/sec [147,958..151,206] → 156,665 ops/sec [155,073..157,845] 🟢 +4.4%
await Promise.all 22,408 ops/sec [22,235..22,500] → 22,627 ops/sec [22,013..23,202] ~ overlap (+1.0%) 22,247 ops/sec [21,920..22,549] → 23,392 ops/sec [23,324..23,478] 🟢 +5.1%
nested async function call 75,593 ops/sec [74,439..77,812] → 77,895 ops/sec [74,766..78,521] ~ overlap (+3.0%) 93,488 ops/sec [87,189..94,283] → 98,506 ops/sec [97,920..106,379] 🟢 +5.4%
async-generators.js — Interp: 2 unch. · avg -1.6% · Bytecode: 🟢 2 · avg +7.8%
Benchmark Interpreted Δ Bytecode Δ
for-await-of over async generator 2,150 ops/sec [1,994..2,164] → 2,115 ops/sec [1,701..2,156] ~ overlap (-1.6%) 2,430 ops/sec [2,299..2,444] → 2,631 ops/sec [2,561..2,647] 🟢 +8.3%
async generator with await in body 19,947 ops/sec [19,709..20,189] → 19,647 ops/sec [16,678..19,749] ~ overlap (-1.5%) 21,337 ops/sec [21,251..21,350] → 22,893 ops/sec [22,757..23,046] 🟢 +7.3%
base64.js — Interp: 10 unch. · avg +0.1% · Bytecode: 🟢 3, 🔴 7 · avg -2.3%
Benchmark Interpreted Δ Bytecode Δ
short ASCII (13 chars) 3,522 ops/sec [3,444..3,566] → 3,494 ops/sec [3,389..3,570] ~ overlap (-0.8%) 3,434 ops/sec [3,366..3,483] → 3,732 ops/sec [3,641..3,770] 🟢 +8.7%
medium ASCII (450 chars) 132 ops/sec [129..136] → 130 ops/sec [130..131] ~ overlap (-1.4%) 129 ops/sec [125..130] → 136 ops/sec [133..138] 🟢 +5.9%
Latin-1 characters 5,019 ops/sec [3,733..5,115] → 5,057 ops/sec [5,026..5,105] ~ overlap (+0.8%) 5,127 ops/sec [5,053..5,149] → 5,578 ops/sec [5,480..5,610] 🟢 +8.8%
short base64 (20 chars) 686 ops/sec [654..713] → 707 ops/sec [700..711] ~ overlap (+3.0%) 716 ops/sec [711..716] → 660 ops/sec [658..663] 🔴 -7.7%
medium base64 (600 chars) 26 ops/sec [26..26] → 26 ops/sec [26..26] ~ overlap (-0.6%) 26 ops/sec [25..26] → 24 ops/sec [24..24] 🔴 -8.1%
Latin-1 output 1,098 ops/sec [1,078..1,101] → 1,095 ops/sec [1,093..1,100] ~ overlap (-0.2%) 1,118 ops/sec [1,106..1,123] → 1,037 ops/sec [1,017..1,049] 🔴 -7.2%
forgiving (no padding) 1,710 ops/sec [1,690..1,732] → 1,727 ops/sec [1,693..1,744] ~ overlap (+1.0%) 1,767 ops/sec [1,754..1,777] → 1,617 ops/sec [1,614..1,625] 🔴 -8.5%
with whitespace 658 ops/sec [653..669] → 650 ops/sec [649..653] ~ overlap (-1.1%) 653 ops/sec [650..656] → 624 ops/sec [619..630] 🔴 -4.4%
atob(btoa(short)) 589 ops/sec [580..598] → 588 ops/sec [584..591] ~ overlap (-0.2%) 590 ops/sec [586..592] → 564 ops/sec [555..571] 🔴 -4.3%
atob(btoa(medium)) 22 ops/sec [21..22] → 22 ops/sec [21..22] ~ overlap (+0.6%) 22 ops/sec [21..22] → 20 ops/sec [20..21] 🔴 -5.6%
classes.js — Interp: 🟢 2, 🔴 3, 26 unch. · avg -0.3% · Bytecode: 🟢 24, 🔴 1, 6 unch. · avg +6.4%
Benchmark Interpreted Δ Bytecode Δ
simple class new 53,515 ops/sec [52,853..53,977] → 55,738 ops/sec [55,461..56,383] 🟢 +4.2% 70,516 ops/sec [69,735..70,561] → 81,022 ops/sec [80,107..81,657] 🟢 +14.9%
class with defaults 41,999 ops/sec [41,295..42,263] → 43,476 ops/sec [43,115..43,803] 🟢 +3.5% 47,357 ops/sec [47,116..47,370] → 52,269 ops/sec [51,617..53,370] 🟢 +10.4%
50 instances via Array.from 1,867 ops/sec [1,840..1,879] → 1,881 ops/sec [1,834..1,915] ~ overlap (+0.7%) 2,365 ops/sec [2,319..2,398] → 2,793 ops/sec [2,755..2,805] 🟢 +18.1%
instance method call 25,982 ops/sec [25,829..26,141] → 25,675 ops/sec [25,142..25,868] ~ overlap (-1.2%) 32,073 ops/sec [31,788..32,520] → 35,947 ops/sec [35,901..35,983] 🟢 +12.1%
static method call 42,459 ops/sec [42,254..42,916] → 42,167 ops/sec [41,711..42,838] ~ overlap (-0.7%) 72,595 ops/sec [70,506..74,532] → 78,241 ops/sec [77,992..79,580] 🟢 +7.8%
single-level inheritance 21,919 ops/sec [21,800..22,049] → 21,835 ops/sec [21,686..21,887] ~ overlap (-0.4%) 26,015 ops/sec [25,935..26,170] → 27,929 ops/sec [27,828..28,244] 🟢 +7.4%
two-level inheritance 19,244 ops/sec [19,073..19,465] → 19,084 ops/sec [18,798..19,306] ~ overlap (-0.8%) 20,861 ops/sec [20,619..20,959] → 23,071 ops/sec [20,332..23,846] ~ overlap (+10.6%)
private field access 28,789 ops/sec [28,413..29,001] → 28,529 ops/sec [28,079..28,969] ~ overlap (-0.9%) 23,990 ops/sec [23,262..24,064] → 26,392 ops/sec [26,368..26,611] 🟢 +10.0%
private methods 32,330 ops/sec [31,972..32,398] → 32,008 ops/sec [31,510..32,315] ~ overlap (-1.0%) 27,842 ops/sec [27,528..27,904] → 30,234 ops/sec [29,910..30,330] 🟢 +8.6%
getter/setter access 28,706 ops/sec [28,666..28,992] → 28,662 ops/sec [28,528..28,872] ~ overlap (-0.2%) 37,253 ops/sec [36,741..37,651] → 40,608 ops/sec [39,728..40,792] 🟢 +9.0%
class decorator (identity) 39,021 ops/sec [38,775..39,751] → 38,653 ops/sec [38,286..39,141] ~ overlap (-0.9%) 41,005 ops/sec [40,639..41,329] → 43,953 ops/sec [43,442..44,388] 🟢 +7.2%
class decorator (wrapping) 22,876 ops/sec [22,662..23,406] → 22,918 ops/sec [22,798..23,165] ~ overlap (+0.2%) 22,990 ops/sec [22,848..23,091] → 24,502 ops/sec [23,964..24,864] 🟢 +6.6%
identity method decorator 28,074 ops/sec [27,839..28,305] → 28,438 ops/sec [28,113..28,821] ~ overlap (+1.3%) 35,198 ops/sec [34,539..35,693] → 36,555 ops/sec [35,915..37,922] 🟢 +3.9%
wrapping method decorator 22,434 ops/sec [22,330..22,747] → 22,588 ops/sec [22,352..22,866] ~ overlap (+0.7%) 26,351 ops/sec [25,671..26,905] → 28,028 ops/sec [27,653..28,746] 🟢 +6.4%
stacked method decorators (x3) 15,528 ops/sec [15,332..15,803] → 15,522 ops/sec [15,384..15,556] ~ overlap (-0.0%) 18,206 ops/sec [17,841..18,805] → 19,001 ops/sec [18,733..19,652] ~ overlap (+4.4%)
identity field decorator 31,195 ops/sec [31,167..31,395] → 31,767 ops/sec [31,225..32,473] ~ overlap (+1.8%) 32,611 ops/sec [31,973..33,464] → 33,681 ops/sec [32,395..34,667] ~ overlap (+3.3%)
field initializer decorator 26,653 ops/sec [26,534..27,086] → 26,209 ops/sec [25,972..26,493] 🔴 -1.7% 28,527 ops/sec [28,244..28,625] → 29,966 ops/sec [29,748..30,324] 🟢 +5.0%
getter decorator (identity) 29,049 ops/sec [28,866..29,217] → 28,971 ops/sec [28,796..29,118] ~ overlap (-0.3%) 28,067 ops/sec [27,902..28,347] → 29,632 ops/sec [29,081..30,062] 🟢 +5.6%
setter decorator (identity) 24,114 ops/sec [23,616..24,352] → 23,495 ops/sec [23,428..23,585] 🔴 -2.6% 22,497 ops/sec [22,258..22,545] → 23,656 ops/sec [23,260..23,832] 🟢 +5.1%
static method decorator 29,468 ops/sec [28,952..29,633] → 29,491 ops/sec [29,272..30,355] ~ overlap (+0.1%) 37,423 ops/sec [36,806..37,821] → 37,495 ops/sec [36,567..38,172] ~ overlap (+0.2%)
static field decorator 36,355 ops/sec [36,054..36,652] → 35,643 ops/sec [35,445..36,793] ~ overlap (-2.0%) 40,628 ops/sec [39,132..41,851] → 40,849 ops/sec [39,819..41,512] ~ overlap (+0.5%)
private method decorator 23,453 ops/sec [23,050..23,578] → 23,848 ops/sec [23,264..24,288] ~ overlap (+1.7%) 26,731 ops/sec [26,307..27,228] → 28,924 ops/sec [28,271..29,420] 🟢 +8.2%
private field decorator 26,058 ops/sec [25,719..26,731] → 26,593 ops/sec [25,880..26,726] ~ overlap (+2.1%) 24,385 ops/sec [23,663..24,778] → 25,655 ops/sec [25,542..25,680] 🟢 +5.2%
plain auto-accessor (no decorator) 46,369 ops/sec [44,230..47,459] → 45,166 ops/sec [44,510..48,052] ~ overlap (-2.6%) 41,378 ops/sec [40,288..41,749] → 44,177 ops/sec [43,252..46,550] 🟢 +6.8%
auto-accessor with decorator 25,475 ops/sec [24,926..26,522] → 24,668 ops/sec [24,300..25,894] ~ overlap (-3.2%) 25,769 ops/sec [25,269..26,438] → 26,111 ops/sec [23,413..27,644] ~ overlap (+1.3%)
decorator writing metadata 19,802 ops/sec [19,563..20,443] → 19,594 ops/sec [19,315..20,000] ~ overlap (-1.1%) 22,305 ops/sec [21,382..22,678] → 23,737 ops/sec [22,807..23,798] 🟢 +6.4%
static getter read 52,949 ops/sec [52,377..53,111] → 52,094 ops/sec [51,772..53,079] ~ overlap (-1.6%) 67,444 ops/sec [66,140..68,435] → 69,769 ops/sec [69,168..70,069] 🟢 +3.4%
static getter/setter pair 39,256 ops/sec [38,835..40,102] → 38,625 ops/sec [37,961..39,311] ~ overlap (-1.6%) 49,865 ops/sec [49,475..50,450] → 52,184 ops/sec [51,189..52,788] 🟢 +4.7%
inherited static getter 34,120 ops/sec [33,959..34,645] → 34,637 ops/sec [34,223..34,992] ~ overlap (+1.5%) 43,118 ops/sec [42,878..43,529] → 41,533 ops/sec [41,325..42,200] 🔴 -3.7%
inherited static setter 37,031 ops/sec [36,580..37,267] → 36,894 ops/sec [36,568..37,351] ~ overlap (-0.4%) 42,531 ops/sec [40,926..42,986] → 43,939 ops/sec [43,105..44,972] 🟢 +3.3%
inherited static getter with this binding 29,770 ops/sec [29,265..30,140] → 28,461 ops/sec [28,197..28,751] 🔴 -4.4% 33,365 ops/sec [32,455..34,416] → 35,123 ops/sec [34,593..36,240] 🟢 +5.3%
closures.js — Interp: 🟢 3, 8 unch. · avg +2.7% · Bytecode: 🟢 9, 🔴 1, 1 unch. · avg +7.3%
Benchmark Interpreted Δ Bytecode Δ
closure over single variable 43,146 ops/sec [42,585..45,366] → 44,699 ops/sec [44,377..45,031] ~ overlap (+3.6%) 136,986 ops/sec [136,377..137,094] → 158,981 ops/sec [157,284..162,107] 🟢 +16.1%
closure over multiple variables 44,105 ops/sec [43,931..44,424] → 46,594 ops/sec [46,328..46,759] 🟢 +5.6% 122,031 ops/sec [120,304..122,291] → 133,705 ops/sec [131,095..135,491] 🟢 +9.6%
nested closures 48,912 ops/sec [48,736..48,937] → 51,300 ops/sec [50,744..52,012] 🟢 +4.9% 129,051 ops/sec [128,445..130,385] → 131,781 ops/sec [128,807..134,259] ~ overlap (+2.1%)
function as argument 31,908 ops/sec [31,324..32,489] → 33,955 ops/sec [32,480..34,227] ~ overlap (+6.4%) 120,100 ops/sec [119,263..121,418] → 130,641 ops/sec [129,669..131,472] 🟢 +8.8%
function returning function 42,064 ops/sec [40,835..42,616] → 42,002 ops/sec [41,831..42,674] ~ overlap (-0.1%) 141,484 ops/sec [139,835..144,103] → 148,774 ops/sec [146,724..150,066] 🟢 +5.2%
compose two functions 25,714 ops/sec [25,363..26,268] → 26,993 ops/sec [26,704..27,244] 🟢 +5.0% 80,450 ops/sec [79,789..82,087] → 85,533 ops/sec [84,654..86,985] 🟢 +6.3%
fn.call 59,213 ops/sec [57,082..59,525] → 60,940 ops/sec [58,330..61,259] ~ overlap (+2.9%) 83,709 ops/sec [82,202..84,072] → 94,383 ops/sec [93,471..95,388] 🟢 +12.8%
fn.apply 46,916 ops/sec [46,417..47,372] → 47,622 ops/sec [46,477..47,820] ~ overlap (+1.5%) 86,624 ops/sec [86,206..86,918] → 91,928 ops/sec [91,520..92,947] 🟢 +6.1%
fn.bind 50,346 ops/sec [49,848..51,046] → 50,493 ops/sec [50,302..50,613] ~ overlap (+0.3%) 118,890 ops/sec [118,269..119,787] → 129,039 ops/sec [127,998..129,741] 🟢 +8.5%
recursive sum to 50 3,844 ops/sec [3,804..3,864] → 3,807 ops/sec [3,781..3,834] ~ overlap (-1.0%) 16,316 ops/sec [16,238..16,401] → 18,064 ops/sec [17,906..18,165] 🟢 +10.7%
recursive tree traversal 6,897 ops/sec [6,806..7,054] → 6,934 ops/sec [6,867..7,011] ~ overlap (+0.5%) 16,179 ops/sec [15,829..16,566] → 15,256 ops/sec [15,131..15,314] 🔴 -5.7%
collections.js — Interp: 🟢 4, 8 unch. · avg +1.2% · Bytecode: 🟢 12 · avg +9.2%
Benchmark Interpreted Δ Bytecode Δ
add 50 elements 2,927 ops/sec [2,901..2,950] → 2,957 ops/sec [2,930..2,965] ~ overlap (+1.0%) 3,248 ops/sec [3,236..3,261] → 3,549 ops/sec [3,528..3,598] 🟢 +9.3%
has lookup (50 elements) 43,820 ops/sec [43,370..44,353] → 44,439 ops/sec [44,026..45,938] ~ overlap (+1.4%) 48,366 ops/sec [48,144..48,563] → 53,395 ops/sec [53,111..53,879] 🟢 +10.4%
delete elements 23,532 ops/sec [23,512..23,606] → 23,764 ops/sec [23,739..23,788] 🟢 +1.0% 25,225 ops/sec [24,962..25,416] → 28,383 ops/sec [28,196..28,539] 🟢 +12.5%
forEach iteration 5,106 ops/sec [5,087..5,113] → 5,272 ops/sec [5,212..5,293] 🟢 +3.3% 8,021 ops/sec [7,994..8,076] → 8,996 ops/sec [8,975..9,153] 🟢 +12.2%
spread to array 13,950 ops/sec [13,449..14,131] → 13,771 ops/sec [13,581..13,992] ~ overlap (-1.3%) 103,490 ops/sec [102,706..103,890] → 108,013 ops/sec [107,765..108,887] 🟢 +4.4%
deduplicate array 19,408 ops/sec [19,278..19,471] → 19,326 ops/sec [19,183..19,488] ~ overlap (-0.4%) 34,391 ops/sec [33,961..34,701] → 37,595 ops/sec [37,362..37,956] 🟢 +9.3%
set 50 entries 2,196 ops/sec [2,143..2,213] → 2,227 ops/sec [2,209..2,235] ~ overlap (+1.4%) 2,526 ops/sec [2,503..2,566] → 2,769 ops/sec [2,740..2,805] 🟢 +9.6%
get lookup (50 entries) 43,033 ops/sec [42,976..43,169] → 43,557 ops/sec [43,315..43,688] 🟢 +1.2% 46,153 ops/sec [45,976..46,301] → 48,775 ops/sec [48,135..49,597] 🟢 +5.7%
has check 61,205 ops/sec [59,961..63,970] → 62,727 ops/sec [61,960..63,557] ~ overlap (+2.5%) 68,489 ops/sec [68,054..68,667] → 73,244 ops/sec [72,498..73,917] 🟢 +6.9%
delete entries 23,393 ops/sec [22,794..23,819] → 23,523 ops/sec [23,340..23,723] ~ overlap (+0.6%) 24,155 ops/sec [23,947..24,217] → 26,460 ops/sec [26,161..26,523] 🟢 +9.5%
forEach iteration 5,140 ops/sec [5,074..5,232] → 5,216 ops/sec [5,164..5,231] ~ overlap (+1.5%) 8,106 ops/sec [7,951..8,182] → 9,213 ops/sec [9,150..9,283] 🟢 +13.7%
keys/values/entries 3,862 ops/sec [3,839..3,870] → 3,933 ops/sec [3,908..3,959] 🟢 +1.8% 14,206 ops/sec [14,106..14,370] → 15,125 ops/sec [14,901..15,282] 🟢 +6.5%
csv.js — Interp: 🟢 1, 12 unch. · avg +1.2% · Bytecode: 🟢 13 · avg +12.0%
Benchmark Interpreted Δ Bytecode Δ
parse simple 3-column CSV 43,072 ops/sec [42,417..43,928] → 43,434 ops/sec [43,099..43,786] ~ overlap (+0.8%) 44,727 ops/sec [43,614..45,298] → 49,928 ops/sec [48,831..51,260] 🟢 +11.6%
parse 10-row CSV 11,701 ops/sec [11,513..11,996] → 11,883 ops/sec [11,512..12,238] ~ overlap (+1.6%) 11,978 ops/sec [11,718..12,082] → 13,206 ops/sec [12,960..13,944] 🟢 +10.3%
parse 100-row CSV 1,820 ops/sec [1,810..1,840] → 1,877 ops/sec [1,829..1,942] ~ overlap (+3.2%) 1,898 ops/sec [1,865..1,929] → 2,083 ops/sec [2,029..2,203] 🟢 +9.7%
parse CSV with quoted fields 66,206 ops/sec [65,016..66,597] → 65,218 ops/sec [63,350..65,777] ~ overlap (-1.5%) 68,297 ops/sec [67,151..69,259] → 75,980 ops/sec [73,330..76,443] 🟢 +11.2%
parse without headers (array of arrays) 5,802 ops/sec [5,657..5,955] → 5,768 ops/sec [5,611..5,931] ~ overlap (-0.6%) 5,752 ops/sec [5,686..5,853] → 6,514 ops/sec [6,263..6,653] 🟢 +13.2%
parse with semicolon delimiter 8,566 ops/sec [8,376..8,814] → 8,931 ops/sec [8,635..9,145] ~ overlap (+4.3%) 8,833 ops/sec [8,775..8,942] → 9,924 ops/sec [9,467..10,438] 🟢 +12.4%
stringify array of objects 63,929 ops/sec [63,143..65,710] → 65,460 ops/sec [64,527..65,768] ~ overlap (+2.4%) 67,773 ops/sec [66,561..69,618] → 79,070 ops/sec [78,165..79,757] 🟢 +16.7%
stringify array of arrays 23,154 ops/sec [22,947..23,321] → 23,871 ops/sec [23,658..23,974] 🟢 +3.1% 24,048 ops/sec [23,896..24,359] → 27,727 ops/sec [27,113..28,355] 🟢 +15.3%
stringify with values needing escaping 49,535 ops/sec [48,782..50,300] → 49,802 ops/sec [48,673..50,591] ~ overlap (+0.5%) 51,103 ops/sec [50,868..51,928] → 60,185 ops/sec [58,161..61,234] 🟢 +17.8%
reviver converts numbers 1,250 ops/sec [1,204..1,277] → 1,254 ops/sec [1,219..1,268] ~ overlap (+0.3%) 1,375 ops/sec [1,363..1,398] → 1,527 ops/sec [1,443..1,550] 🟢 +11.1%
reviver filters empty to null 9,874 ops/sec [9,727..10,077] → 9,872 ops/sec [9,738..10,189] ~ overlap (-0.0%) 12,064 ops/sec [11,977..12,130] → 12,988 ops/sec [12,880..13,217] 🟢 +7.7%
parse then stringify 7,742 ops/sec [7,672..7,861] → 7,717 ops/sec [7,461..7,929] ~ overlap (-0.3%) 7,895 ops/sec [7,820..8,047] → 8,671 ops/sec [8,596..9,004] 🟢 +9.8%
stringify then parse 7,494 ops/sec [7,394..7,614] → 7,650 ops/sec [7,414..7,802] ~ overlap (+2.1%) 7,641 ops/sec [7,549..7,743] → 8,389 ops/sec [8,235..8,635] 🟢 +9.8%
destructuring.js — Interp: 🟢 3, 🔴 1, 18 unch. · avg +0.6% · Bytecode: 🟢 15, 🔴 5, 2 unch. · avg +2.3%
Benchmark Interpreted Δ Bytecode Δ
simple array destructuring 164,353 ops/sec [160,904..166,008] → 166,300 ops/sec [161,740..169,839] ~ overlap (+1.2%) 112,964 ops/sec [112,145..113,537] → 119,346 ops/sec [119,021..120,633] 🟢 +5.6%
with rest element 111,609 ops/sec [111,248..112,292] → 114,384 ops/sec [113,887..115,166] 🟢 +2.5% 87,769 ops/sec [84,738..88,111] → 90,801 ops/sec [90,411..91,404] 🟢 +3.5%
with defaults 165,292 ops/sec [164,208..167,138] → 167,114 ops/sec [166,801..167,698] ~ overlap (+1.1%) 121,382 ops/sec [120,768..121,451] → 125,726 ops/sec [125,088..126,305] 🟢 +3.6%
skip elements 171,618 ops/sec [171,210..173,543] → 173,695 ops/sec [169,799..175,915] ~ overlap (+1.2%) 125,529 ops/sec [124,338..125,895] → 128,377 ops/sec [127,531..129,084] 🟢 +2.3%
nested array destructuring 83,330 ops/sec [82,836..83,963] → 83,781 ops/sec [82,805..83,986] ~ overlap (+0.5%) 42,290 ops/sec [41,700..42,524] → 42,633 ops/sec [42,477..43,037] ~ overlap (+0.8%)
swap variables 192,230 ops/sec [191,324..193,996] → 193,328 ops/sec [187,884..201,741] ~ overlap (+0.6%) 149,074 ops/sec [144,915..149,702] → 154,873 ops/sec [154,328..156,934] 🟢 +3.9%
simple object destructuring 122,511 ops/sec [120,304..123,390] → 124,809 ops/sec [121,488..126,668] ~ overlap (+1.9%) 140,666 ops/sec [137,734..145,523] → 114,892 ops/sec [113,868..116,473] 🔴 -18.3%
with defaults 143,975 ops/sec [142,301..144,574] → 145,454 ops/sec [144,723..151,862] 🟢 +1.0% 188,049 ops/sec [184,037..190,031] → 184,061 ops/sec [182,955..185,141] ~ overlap (-2.1%)
with renaming 132,878 ops/sec [131,504..133,527] → 133,893 ops/sec [132,577..134,271] ~ overlap (+0.8%) 134,512 ops/sec [134,209..137,946] → 124,898 ops/sec [123,839..127,003] 🔴 -7.1%
nested object destructuring 67,615 ops/sec [66,742..69,529] → 67,024 ops/sec [66,765..68,577] ~ overlap (-0.9%) 71,811 ops/sec [70,666..72,746] → 64,261 ops/sec [62,997..66,734] 🔴 -10.5%
rest properties 49,600 ops/sec [49,409..50,972] → 50,259 ops/sec [49,734..51,852] ~ overlap (+1.3%) 65,790 ops/sec [65,181..66,464] → 61,197 ops/sec [59,890..62,716] 🔴 -7.0%
object parameter 39,342 ops/sec [38,898..39,701] → 39,760 ops/sec [39,617..40,089] ~ overlap (+1.1%) 61,760 ops/sec [61,466..62,126] → 57,385 ops/sec [56,636..58,058] 🔴 -7.1%
array parameter 50,210 ops/sec [49,907..51,250] → 50,352 ops/sec [48,947..50,883] ~ overlap (+0.3%) 55,336 ops/sec [54,888..55,587] → 60,558 ops/sec [59,969..61,156] 🟢 +9.4%
mixed destructuring in map 11,320 ops/sec [11,209..11,551] → 11,170 ops/sec [11,143..11,537] ~ overlap (-1.3%) 14,947 ops/sec [14,866..15,287] → 16,769 ops/sec [16,660..16,909] 🟢 +12.2%
forEach with array destructuring 25,636 ops/sec [25,221..26,007] → 25,780 ops/sec [25,200..26,120] ~ overlap (+0.6%) 21,369 ops/sec [20,974..21,784] → 22,492 ops/sec [22,100..22,672] 🟢 +5.3%
map with array destructuring 26,753 ops/sec [25,564..27,023] → 26,565 ops/sec [26,467..26,668] ~ overlap (-0.7%) 20,169 ops/sec [20,068..20,449] → 21,294 ops/sec [20,622..21,552] 🟢 +5.6%
filter with array destructuring 26,715 ops/sec [25,673..27,025] → 26,780 ops/sec [26,523..27,044] ~ overlap (+0.2%) 21,605 ops/sec [21,502..21,671] → 22,409 ops/sec [22,103..22,737] 🟢 +3.7%
reduce with array destructuring 29,593 ops/sec [29,506..29,872] → 28,928 ops/sec [28,868..29,414] 🔴 -2.2% 21,982 ops/sec [21,796..22,535] → 23,057 ops/sec [23,032..23,212] 🟢 +4.9%
map with object destructuring 25,318 ops/sec [24,785..25,665] → 25,648 ops/sec [25,561..25,684] ~ overlap (+1.3%) 31,582 ops/sec [30,533..32,074] → 34,895 ops/sec [34,678..36,566] 🟢 +10.5%
map with nested destructuring 22,065 ops/sec [21,329..22,225] → 21,889 ops/sec [21,792..22,248] ~ overlap (-0.8%) 30,158 ops/sec [29,758..30,551] → 33,106 ops/sec [32,183..34,110] 🟢 +9.8%
map with rest in destructuring 16,605 ops/sec [16,397..16,914] → 16,714 ops/sec [16,633..16,777] ~ overlap (+0.7%) 10,695 ops/sec [10,591..11,239] → 11,472 ops/sec [11,306..11,651] 🟢 +7.3%
map with defaults in destructuring 19,924 ops/sec [19,475..20,144] → 20,420 ops/sec [20,356..20,591] 🟢 +2.5% 24,252 ops/sec [24,027..25,147] → 27,656 ops/sec [27,379..27,926] 🟢 +14.0%
fibonacci.js — Interp: 🔴 1, 7 unch. · avg -0.7% · Bytecode: 🟢 5, 🔴 2, 1 unch. · avg +6.0%
Benchmark Interpreted Δ Bytecode Δ
recursive fib(15) 103 ops/sec [101..104] → 103 ops/sec [102..104] ~ overlap (-0.1%) 439 ops/sec [435..441] → 498 ops/sec [482..505] 🟢 +13.5%
recursive fib(20) 9 ops/sec [9..9] → 9 ops/sec [9..9] ~ overlap (+0.3%) 39 ops/sec [39..40] → 44 ops/sec [44..45] 🟢 +12.9%
recursive fib(15) typed 103 ops/sec [101..105] → 105 ops/sec [102..107] ~ overlap (+1.9%) 445 ops/sec [444..447] → 500 ops/sec [491..516] 🟢 +12.3%
recursive fib(20) typed 9 ops/sec [9..9] → 9 ops/sec [9..9] ~ overlap (+1.8%) 40 ops/sec [40..40] → 45 ops/sec [45..45] 🟢 +12.4%
iterative fib(20) via reduce 4,539 ops/sec [4,514..4,565] → 4,504 ops/sec [4,455..4,536] ~ overlap (-0.8%) 8,589 ops/sec [8,503..8,612] → 9,180 ops/sec [9,084..9,302] 🟢 +6.9%
iterator fib(20) 3,420 ops/sec [3,373..3,440] → 3,275 ops/sec [3,170..3,291] 🔴 -4.2% 5,632 ops/sec [5,466..5,748] → 5,352 ops/sec [5,319..5,447] 🔴 -5.0%
iterator fib(20) via Iterator.from + take 4,473 ops/sec [4,446..4,505] → 4,344 ops/sec [4,302..4,536] ~ overlap (-2.9%) 6,178 ops/sec [6,171..6,295] → 5,882 ops/sec [5,713..6,001] 🔴 -4.8%
iterator fib(20) last value via reduce 3,525 ops/sec [3,497..3,547] → 3,477 ops/sec [3,449..3,530] ~ overlap (-1.4%) 4,728 ops/sec [4,677..4,778] → 4,725 ops/sec [4,714..4,736] ~ overlap (-0.1%)
float16array.js — Interp: 🟢 3, 🔴 6, 23 unch. · avg -0.1% · Bytecode: 🟢 26, 🔴 1, 5 unch. · avg +6.4%
Benchmark Interpreted Δ Bytecode Δ
new Float16Array(0) 118,715 ops/sec [115,401..121,696] → 115,523 ops/sec [113,951..119,386] ~ overlap (-2.7%) 135,348 ops/sec [134,217..136,114] → 143,357 ops/sec [142,429..143,940] 🟢 +5.9%
new Float16Array(100) 114,499 ops/sec [113,282..115,323] → 112,097 ops/sec [110,679..112,705] 🔴 -2.1% 129,595 ops/sec [128,015..131,176] → 138,926 ops/sec [138,040..139,906] 🟢 +7.2%
new Float16Array(1000) 98,160 ops/sec [96,003..99,669] → 95,534 ops/sec [94,283..96,572] ~ overlap (-2.7%) 111,309 ops/sec [109,182..112,598] → 110,264 ops/sec [108,188..111,915] ~ overlap (-0.9%)
Float16Array.from([...100]) 3,832 ops/sec [3,815..3,850] → 3,839 ops/sec [3,676..3,946] ~ overlap (+0.2%) 3,968 ops/sec [3,904..4,109] → 4,201 ops/sec [4,150..4,276] 🟢 +5.9%
Float16Array.of(1.5, 2.5, 3.5, 4.5, 5.5) 112,834 ops/sec [112,477..113,352] → 117,450 ops/sec [113,200..118,403] ~ overlap (+4.1%) 96,746 ops/sec [94,530..98,408] → 102,010 ops/sec [101,226..103,295] 🟢 +5.4%
new Float16Array(float64Array) 31,709 ops/sec [31,624..31,883] → 32,004 ops/sec [31,360..32,593] ~ overlap (+0.9%) 33,932 ops/sec [33,666..34,033] → 35,673 ops/sec [34,593..36,039] 🟢 +5.1%
sequential write 100 elements 945 ops/sec [939..951] → 965 ops/sec [946..983] ~ overlap (+2.1%) 2,039 ops/sec [1,931..2,077] → 2,169 ops/sec [2,116..2,181] 🟢 +6.4%
sequential read 100 elements 1,086 ops/sec [1,074..1,108] → 1,096 ops/sec [1,050..1,118] ~ overlap (+0.9%) 2,284 ops/sec [2,271..2,346] → 2,517 ops/sec [2,458..2,571] 🟢 +10.2%
write special values (NaN, Inf, -0) 31,601 ops/sec [31,445..33,014] → 32,201 ops/sec [31,391..34,043] ~ overlap (+1.9%) 41,999 ops/sec [41,095..42,594] → 45,758 ops/sec [44,513..46,716] 🟢 +9.0%
Float16Array write 967 ops/sec [939..982] → 985 ops/sec [969..998] ~ overlap (+1.9%) 1,989 ops/sec [1,970..2,003] → 2,188 ops/sec [2,161..2,245] 🟢 +10.0%
Float32Array write 949 ops/sec [940..971] → 986 ops/sec [971..1,001] 🟢 +3.9% 2,014 ops/sec [2,013..2,021] → 2,205 ops/sec [2,191..2,210] 🟢 +9.5%
Float64Array write 965 ops/sec [960..967] → 1,008 ops/sec [996..1,017] 🟢 +4.5% 2,087 ops/sec [2,003..2,115] → 2,239 ops/sec [2,188..2,265] 🟢 +7.3%
Float16Array read 1,066 ops/sec [1,062..1,075] → 1,066 ops/sec [1,056..1,087] ~ overlap (-0.0%) 2,282 ops/sec [2,245..2,348] → 2,441 ops/sec [2,419..2,510] 🟢 +7.0%
Float32Array read 1,050 ops/sec [1,049..1,091] → 1,064 ops/sec [1,054..1,092] ~ overlap (+1.3%) 2,320 ops/sec [2,286..2,403] → 2,638 ops/sec [2,572..2,664] 🟢 +13.7%
Float64Array read 1,061 ops/sec [1,025..1,075] → 1,068 ops/sec [1,057..1,073] ~ overlap (+0.6%) 2,331 ops/sec [2,279..2,391] → 2,537 ops/sec [2,507..2,574] 🟢 +8.8%
fill(1.5) 4,215 ops/sec [4,128..4,271] → 4,221 ops/sec [4,172..4,279] ~ overlap (+0.1%) 4,292 ops/sec [4,228..4,351] → 4,596 ops/sec [4,570..4,789] 🟢 +7.1%
slice() 32,058 ops/sec [31,823..32,263] → 31,565 ops/sec [31,327..31,821] 🔴 -1.5% 32,964 ops/sec [32,936..33,079] → 35,621 ops/sec [35,027..36,101] 🟢 +8.1%
map(x => x * 2) 2,260 ops/sec [2,232..2,307] → 2,205 ops/sec [2,184..2,222] 🔴 -2.4% 2,976 ops/sec [2,887..3,063] → 3,287 ops/sec [3,206..3,461] 🟢 +10.5%
filter(x => x > 25) 2,281 ops/sec [2,238..2,305] → 2,278 ops/sec [2,246..2,288] ~ overlap (-0.1%) 3,244 ops/sec [3,166..3,344] → 3,552 ops/sec [3,547..3,563] 🟢 +9.5%
reduce (sum) 2,383 ops/sec [2,363..2,415] → 2,401 ops/sec [2,354..2,447] ~ overlap (+0.8%) 3,033 ops/sec [2,962..3,089] → 3,329 ops/sec [3,281..3,353] 🟢 +9.8%
sort() 10,405 ops/sec [10,371..10,479] → 10,300 ops/sec [10,276..10,401] ~ overlap (-1.0%) 10,577 ops/sec [10,413..10,673] → 10,412 ops/sec [10,301..10,519] ~ overlap (-1.6%)
indexOf() 28,904 ops/sec [28,731..29,102] → 28,407 ops/sec [27,909..28,730] 🔴 -1.7% 29,820 ops/sec [29,590..30,078] → 30,196 ops/sec [29,843..30,488] ~ overlap (+1.3%)
reverse() 34,868 ops/sec [34,441..35,236] → 34,852 ops/sec [34,354..35,757] ~ overlap (-0.0%) 35,795 ops/sec [35,434..36,575] → 39,281 ops/sec [38,515..39,728] 🟢 +9.7%
toReversed() 26,226 ops/sec [25,907..26,580] → 25,779 ops/sec [25,751..25,798] 🔴 -1.7% 26,898 ops/sec [26,832..27,047] → 26,852 ops/sec [26,679..26,947] ~ overlap (-0.2%)
toSorted() 381 ops/sec [376..382] → 370 ops/sec [364..376] 🔴 -2.8% 380 ops/sec [378..382] → 373 ops/sec [371..377] 🔴 -1.8%
create view over existing buffer 134,106 ops/sec [132,098..134,965] → 130,872 ops/sec [129,213..132,441] ~ overlap (-2.4%) 154,723 ops/sec [152,114..155,127] → 162,323 ops/sec [160,476..168,072] 🟢 +4.9%
subarray() 153,849 ops/sec [152,877..154,036] → 152,264 ops/sec [151,453..153,881] ~ overlap (-1.0%) 177,921 ops/sec [175,298..180,149] → 188,841 ops/sec [187,836..188,888] 🟢 +6.1%
set() from array 124,339 ops/sec [122,053..127,325] → 124,539 ops/sec [121,761..128,743] ~ overlap (+0.2%) 137,011 ops/sec [134,475..139,376] → 150,111 ops/sec [147,517..152,491] 🟢 +9.6%
for-of loop 1,942 ops/sec [1,912..1,967] → 1,920 ops/sec [1,914..1,939] ~ overlap (-1.1%) 7,689 ops/sec [7,559..7,736] → 8,274 ops/sec [8,151..8,290] 🟢 +7.6%
spread into array 7,200 ops/sec [7,142..7,294] → 7,159 ops/sec [7,069..7,215] ~ overlap (-0.6%) 28,240 ops/sec [28,155..28,460] → 28,996 ops/sec [28,243..29,961] ~ overlap (+2.7%)
f16round(1.337) 248,521 ops/sec [246,937..249,235] → 252,256 ops/sec [249,946..254,801] 🟢 +1.5% 244,444 ops/sec [243,412..246,338] → 250,783 ops/sec [246,795..263,013] 🟢 +2.6%
f16round over 100 values 1,455 ops/sec [1,409..1,495] → 1,417 ops/sec [1,402..1,420] ~ overlap (-2.6%) 2,844 ops/sec [2,817..2,880] → 3,124 ops/sec [3,114..3,130] 🟢 +9.9%
for-of.js — Interp: 7 unch. · avg -0.0% · Bytecode: 🟢 7 · avg +9.8%
Benchmark Interpreted Δ Bytecode Δ
for...of with 10-element array 18,286 ops/sec [18,112..18,354] → 18,207 ops/sec [18,027..18,455] ~ overlap (-0.4%) 106,787 ops/sec [105,289..110,199] → 119,604 ops/sec [118,391..120,096] 🟢 +12.0%
for...of with 100-element array 2,083 ops/sec [2,046..2,103] → 2,056 ops/sec [2,050..2,100] ~ overlap (-1.3%) 14,280 ops/sec [14,190..14,425] → 16,274 ops/sec [15,936..16,449] 🟢 +14.0%
for...of with string (10 chars) 13,500 ops/sec [13,367..13,591] → 13,706 ops/sec [13,523..13,931] ~ overlap (+1.5%) 31,454 ops/sec [31,302..32,051] → 35,070 ops/sec [34,718..35,450] 🟢 +11.5%
for...of with Set (10 elements) 18,179 ops/sec [17,941..18,276] → 18,662 ops/sec [18,180..18,684] ~ overlap (+2.7%) 105,610 ops/sec [103,693..106,244] → 117,038 ops/sec [116,787..117,703] 🟢 +10.8%
for...of with Map entries (10 entries) 12,704 ops/sec [12,420..12,787] → 12,548 ops/sec [12,405..12,895] ~ overlap (-1.2%) 16,114 ops/sec [15,776..16,321] → 16,982 ops/sec [16,781..17,342] 🟢 +5.4%
for...of with destructuring 15,472 ops/sec [15,415..15,729] → 15,283 ops/sec [15,071..15,476] ~ overlap (-1.2%) 20,832 ops/sec [20,022..21,036] → 22,168 ops/sec [21,434..22,355] 🟢 +6.4%
for-await-of with sync array 17,201 ops/sec [17,023..17,504] → 17,185 ops/sec [16,820..17,304] ~ overlap (-0.1%) 15,170 ops/sec [14,826..15,420] → 16,475 ops/sec [16,026..16,785] 🟢 +8.6%
generators.js — Interp: 4 unch. · avg +0.1% · Bytecode: 🟢 4 · avg +6.1%
Benchmark Interpreted Δ Bytecode Δ
manual next over object generator 819 ops/sec [798..833] → 824 ops/sec [822..829] ~ overlap (+0.6%) 917 ops/sec [911..981] → 1,011 ops/sec [984..1,032] 🟢 +10.2%
for...of over object generator 1,252 ops/sec [1,246..1,259] → 1,242 ops/sec [1,229..1,260] ~ overlap (-0.8%) 1,784 ops/sec [1,770..1,834] → 1,914 ops/sec [1,841..1,928] 🟢 +7.3%
yield delegation 1,244 ops/sec [1,215..1,271] → 1,254 ops/sec [1,195..1,262] ~ overlap (+0.8%) 1,824 ops/sec [1,781..1,832] → 1,893 ops/sec [1,881..1,962] 🟢 +3.7%
class generator method 1,289 ops/sec [1,256..1,295] → 1,286 ops/sec [1,258..1,310] ~ overlap (-0.2%) 1,803 ops/sec [1,774..1,817] → 1,862 ops/sec [1,819..1,960] 🟢 +3.3%
iterators.js — Interp: 🟢 9, 🔴 1, 32 unch. · avg +1.0% · Bytecode: 🟢 11, 🔴 17, 14 unch. · avg -1.0%
Benchmark Interpreted Δ Bytecode Δ
Iterator.from({next}).toArray() — 20 elements 4,097 ops/sec [3,931..4,137] → 4,083 ops/sec [4,016..4,151] ~ overlap (-0.3%) 6,119 ops/sec [6,084..6,166] → 5,512 ops/sec [5,390..5,653] 🔴 -9.9%
Iterator.from({next}).toArray() — 50 elements 1,712 ops/sec [1,703..1,722] → 1,728 ops/sec [1,698..1,737] ~ overlap (+1.0%) 2,562 ops/sec [2,553..2,576] → 2,403 ops/sec [2,386..2,555] ~ overlap (-6.2%)
spread pre-wrapped iterator — 20 elements 4,033 ops/sec [4,021..4,088] → 4,109 ops/sec [4,031..4,172] ~ overlap (+1.9%) 5,914 ops/sec [5,812..6,299] → 5,436 ops/sec [5,385..5,659] 🔴 -8.1%
Iterator.from({next}).forEach — 50 elements 1,285 ops/sec [1,257..1,288] → 1,306 ops/sec [1,290..1,331] 🟢 +1.6% 1,992 ops/sec [1,956..2,041] → 1,917 ops/sec [1,886..1,967] ~ overlap (-3.7%)
Iterator.from({next}).reduce — 50 elements 1,297 ops/sec [1,282..1,317] → 1,296 ops/sec [1,282..1,315] ~ overlap (-0.0%) 1,917 ops/sec [1,897..1,953] → 1,895 ops/sec [1,881..1,925] ~ overlap (-1.1%)
wrap array iterator 71,223 ops/sec [70,221..71,793] → 72,099 ops/sec [70,016..72,719] ~ overlap (+1.2%) 75,368 ops/sec [73,446..76,531] → 77,843 ops/sec [77,370..77,945] 🟢 +3.3%
wrap plain {next()} object 2,790 ops/sec [2,759..2,850] → 2,767 ops/sec [2,738..2,796] ~ overlap (-0.8%) 4,203 ops/sec [4,154..4,228] → 3,933 ops/sec [3,871..4,121] 🔴 -6.4%
map + toArray (50 elements) 1,315 ops/sec [1,293..1,341] → 1,336 ops/sec [1,303..1,363] ~ overlap (+1.6%) 2,053 ops/sec [2,044..2,056] → 1,907 ops/sec [1,834..1,918] 🔴 -7.1%
filter + toArray (50 elements) 1,303 ops/sec [1,291..1,307] → 1,317 ops/sec [1,289..1,328] ~ overlap (+1.1%) 2,058 ops/sec [2,040..2,101] → 1,926 ops/sec [1,911..1,928] 🔴 -6.4%
take(10) + toArray (50 element source) 7,930 ops/sec [7,817..7,974] → 7,759 ops/sec [7,622..7,835] ~ overlap (-2.1%) 11,213 ops/sec [10,667..11,484] → 10,402 ops/sec [9,879..10,647] 🔴 -7.2%
drop(40) + toArray (50 element source) 1,738 ops/sec [1,728..1,751] → 1,781 ops/sec [1,756..1,799] 🟢 +2.5% 2,647 ops/sec [2,624..2,681] → 2,399 ops/sec [2,362..2,450] 🔴 -9.4%
chained map + filter + take (100 element source) 2,553 ops/sec [2,500..2,579] → 2,554 ops/sec [2,496..2,580] ~ overlap (+0.0%) 3,882 ops/sec [3,821..3,964] → 3,715 ops/sec [3,662..3,735] 🔴 -4.3%
some + every (50 elements) 752 ops/sec [744..764] → 762 ops/sec [747..780] ~ overlap (+1.2%) 1,208 ops/sec [1,206..1,213] → 1,171 ops/sec [1,168..1,174] 🔴 -3.0%
find (50 elements) 1,630 ops/sec [1,623..1,633] → 1,661 ops/sec [1,641..1,675] 🟢 +1.9% 2,552 ops/sec [2,500..2,576] → 2,487 ops/sec [2,445..2,556] ~ overlap (-2.5%)
concat 2 arrays (10 + 10 elements) 65,486 ops/sec [64,009..66,271] → 67,698 ops/sec [66,578..68,941] 🟢 +3.4% 73,106 ops/sec [72,990..73,642] → 76,255 ops/sec [75,552..77,411] 🟢 +4.3%
concat 5 arrays (10 elements each) 38,431 ops/sec [38,018..39,261] → 39,269 ops/sec [38,521..39,655] ~ overlap (+2.2%) 43,913 ops/sec [43,713..44,286] → 45,802 ops/sec [45,281..46,441] 🟢 +4.3%
concat 2 arrays (20 + 20 elements) 55,222 ops/sec [55,064..56,031] → 57,101 ops/sec [55,709..58,325] ~ overlap (+3.4%) 63,088 ops/sec [62,956..63,178] → 64,590 ops/sec [63,515..65,484] 🟢 +2.4%
concat + filter + toArray (20 + 20 elements) 5,631 ops/sec [5,585..5,768] → 5,889 ops/sec [5,830..5,910] 🟢 +4.6% 8,384 ops/sec [8,330..8,434] → 9,709 ops/sec [9,285..10,027] 🟢 +15.8%
concat + map + take (20 + 20 elements, take 10) 17,915 ops/sec [17,289..18,096] → 18,462 ops/sec [18,212..18,561] 🟢 +3.1% 23,026 ops/sec [22,601..23,933] → 25,860 ops/sec [25,784..26,026] 🟢 +12.3%
concat Sets (15 + 15 elements) 62,851 ops/sec [62,232..63,559] → 65,887 ops/sec [64,866..66,429] 🟢 +4.8% 67,880 ops/sec [67,006..68,066] → 68,884 ops/sec [68,173..70,426] 🟢 +1.5%
concat strings (13 + 13 characters) 46,270 ops/sec [45,568..46,504] → 46,478 ops/sec [46,092..46,981] ~ overlap (+0.4%) 45,816 ops/sec [45,118..46,606] → 46,175 ops/sec [45,915..47,421] ~ overlap (+0.8%)
zip 2 arrays (10 + 10 elements) 27,901 ops/sec [27,749..28,286] → 27,942 ops/sec [27,760..28,096] ~ overlap (+0.1%) 29,174 ops/sec [29,040..29,358] → 29,470 ops/sec [28,953..29,783] ~ overlap (+1.0%)
zip 3 arrays (10 elements each) 25,897 ops/sec [25,662..25,975] → 25,952 ops/sec [25,871..26,053] ~ overlap (+0.2%) 26,879 ops/sec [26,600..27,125] → 26,964 ops/sec [26,239..27,377] ~ overlap (+0.3%)
zip 2 arrays (20 + 20 elements) 18,736 ops/sec [18,576..19,069] → 18,947 ops/sec [18,523..19,485] ~ overlap (+1.1%) 19,391 ops/sec [19,242..19,501] → 18,933 ops/sec [18,727..19,201] 🔴 -2.4%
zip 2 arrays (50 + 50 elements) 9,350 ops/sec [9,109..9,482] → 9,456 ops/sec [9,345..9,610] ~ overlap (+1.1%) 9,683 ops/sec [9,625..9,845] → 9,254 ops/sec [9,124..9,445] 🔴 -4.4%
zip shortest mode (20 + 10 elements) 28,015 ops/sec [27,762..28,179] → 28,515 ops/sec [28,020..29,008] ~ overlap (+1.8%) 29,579 ops/sec [29,268..29,644] → 28,723 ops/sec [28,075..29,911] ~ overlap (-2.9%)
zip longest mode (10 + 20 elements) 17,499 ops/sec [16,612..17,641] → 16,921 ops/sec [16,670..17,244] ~ overlap (-3.3%) 17,002 ops/sec [16,901..17,148] → 16,099 ops/sec [15,814..16,396] 🔴 -5.3%
zip strict mode (20 + 20 elements) 18,919 ops/sec [18,882..18,991] → 18,220 ops/sec [17,929..18,548] 🔴 -3.7% 19,314 ops/sec [18,451..19,476] → 17,521 ops/sec [17,259..18,244] 🔴 -9.3%
zip + map + toArray (20 + 20 elements) 7,577 ops/sec [7,170..7,688] → 7,294 ops/sec [7,235..7,441] ~ overlap (-3.7%) 5,580 ops/sec [5,369..5,664] → 5,493 ops/sec [5,377..5,548] ~ overlap (-1.6%)
zip + filter + toArray (20 + 20 elements) 6,963 ops/sec [6,884..7,078] → 7,164 ops/sec [7,052..7,272] ~ overlap (+2.9%) 5,576 ops/sec [5,522..5,625] → 5,708 ops/sec [5,600..5,786] ~ overlap (+2.4%)
zip Sets (15 + 15 elements) 24,394 ops/sec [23,749..24,714] → 23,690 ops/sec [23,587..23,795] ~ overlap (-2.9%) 23,766 ops/sec [23,454..24,762] → 22,846 ops/sec [22,588..23,094] 🔴 -3.9%
zipKeyed 2 keys (10 elements each) 25,369 ops/sec [25,236..27,208] → 25,994 ops/sec [25,785..26,705] ~ overlap (+2.5%) 25,835 ops/sec [25,779..27,156] → 26,329 ops/sec [25,810..26,793] ~ overlap (+1.9%)
zipKeyed 3 keys (20 elements each) 12,888 ops/sec [12,805..13,416] → 13,149 ops/sec [12,331..13,540] ~ overlap (+2.0%) 13,330 ops/sec [12,987..13,393] → 12,594 ops/sec [12,343..12,854] 🔴 -5.5%
zipKeyed longest mode (10 + 20 elements) 15,420 ops/sec [15,310..15,492] → 15,608 ops/sec [15,229..15,756] ~ overlap (+1.2%) 15,463 ops/sec [15,187..15,587] → 14,302 ops/sec [14,262..14,616] 🔴 -7.5%
zipKeyed strict mode (20 + 20 elements) 15,920 ops/sec [15,415..16,066] → 16,077 ops/sec [15,986..16,242] ~ overlap (+1.0%) 16,134 ops/sec [15,310..16,610] → 15,530 ops/sec [15,132..15,580] ~ overlap (-3.7%)
zipKeyed + filter + map (20 elements) 4,825 ops/sec [4,775..4,878] → 4,859 ops/sec [4,783..4,962] ~ overlap (+0.7%) 5,997 ops/sec [5,927..6,054] → 6,478 ops/sec [6,319..6,506] 🟢 +8.0%
array.values().map().filter().toArray() 2,573 ops/sec [2,541..2,616] → 2,572 ops/sec [2,476..2,587] ~ overlap (-0.0%) 4,049 ops/sec [3,995..4,063] → 4,331 ops/sec [4,258..4,497] 🟢 +7.0%
array.values().take(5).toArray() 94,293 ops/sec [93,853..94,719] → 91,860 ops/sec [89,824..94,385] ~ overlap (-2.6%) 102,294 ops/sec [101,042..104,127] → 102,359 ops/sec [101,367..103,676] ~ overlap (+0.1%)
array.values().drop(45).toArray() 76,415 ops/sec [75,009..76,631] → 77,347 ops/sec [75,908..78,739] ~ overlap (+1.2%) 82,565 ops/sec [81,629..83,114] → 83,706 ops/sec [82,362..86,642] ~ overlap (+1.4%)
map.entries() chained helpers 3,856 ops/sec [3,829..3,905] → 3,859 ops/sec [3,793..3,929] ~ overlap (+0.1%) 2,869 ops/sec [2,834..2,909] → 2,787 ops/sec [2,774..2,832] 🔴 -2.8%
set.values() chained helpers 5,948 ops/sec [5,851..6,012] → 6,174 ops/sec [6,072..6,281] 🟢 +3.8% 8,795 ops/sec [8,719..8,898] → 9,694 ops/sec [9,625..9,785] 🟢 +10.2%
string iterator map + toArray 5,114 ops/sec [5,070..5,166] → 5,314 ops/sec [5,226..5,371] 🟢 +3.9% 5,541 ops/sec [5,523..5,558] → 5,760 ops/sec [5,649..5,933] 🟢 +3.9%
json.js — Interp: 🟢 3, 🔴 2, 15 unch. · avg +0.5% · Bytecode: 🟢 18, 2 unch. · avg +9.5%
Benchmark Interpreted Δ Bytecode Δ
parse simple object 67,907 ops/sec [66,204..68,741] → 70,534 ops/sec [70,186..70,984] 🟢 +3.9% 67,892 ops/sec [67,608..68,653] → 79,107 ops/sec [78,788..80,371] 🟢 +16.5%
parse nested object 45,280 ops/sec [43,952..46,309] → 44,458 ops/sec [43,429..45,150] ~ overlap (-1.8%) 44,412 ops/sec [43,743..45,072] → 51,530 ops/sec [50,417..52,166] 🟢 +16.0%
parse array of objects 27,409 ops/sec [26,490..27,781] → 27,175 ops/sec [26,308..27,851] ~ overlap (-0.9%) 26,913 ops/sec [26,402..27,323] → 30,015 ops/sec [29,526..30,184] 🟢 +11.5%
parse large flat object 28,249 ops/sec [27,665..30,144] → 28,266 ops/sec [27,691..28,970] ~ overlap (+0.1%) 28,664 ops/sec [28,482..28,783] → 31,998 ops/sec [30,205..33,162] 🟢 +11.6%
parse mixed types 33,914 ops/sec [33,075..34,140] → 33,906 ops/sec [33,317..34,303] ~ overlap (-0.0%) 33,508 ops/sec [33,113..34,014] → 37,592 ops/sec [36,800..38,891] 🟢 +12.2%
stringify simple object 72,420 ops/sec [71,015..74,269] → 71,707 ops/sec [70,782..73,905] ~ overlap (-1.0%) 68,591 ops/sec [68,283..68,816] → 69,968 ops/sec [69,573..70,590] 🟢 +2.0%
stringify nested object 41,924 ops/sec [41,455..43,106] → 41,934 ops/sec [41,168..42,515] ~ overlap (+0.0%) 38,640 ops/sec [38,168..39,114] → 39,184 ops/sec [38,855..39,910] ~ overlap (+1.4%)
stringify array of objects 18,344 ops/sec [17,811..18,616] → 18,646 ops/sec [18,319..19,883] ~ overlap (+1.6%) 18,576 ops/sec [18,134..18,808] → 21,362 ops/sec [19,685..21,535] 🟢 +15.0%
stringify mixed types 27,584 ops/sec [27,476..28,114] → 29,751 ops/sec [29,074..30,069] 🟢 +7.9% 26,184 ops/sec [25,758..26,567] → 27,194 ops/sec [26,578..27,443] 🟢 +3.9%
reviver doubles numbers 13,794 ops/sec [13,491..13,995] → 13,662 ops/sec [13,538..13,698] ~ overlap (-1.0%) 16,370 ops/sec [16,337..16,700] → 18,849 ops/sec [18,484..19,043] 🟢 +15.1%
reviver filters properties 12,990 ops/sec [12,949..13,645] → 12,965 ops/sec [12,960..13,061] ~ overlap (-0.2%) 14,218 ops/sec [14,137..14,397] → 15,831 ops/sec [15,660..16,274] 🟢 +11.3%
reviver on nested object 16,201 ops/sec [16,033..16,440] → 16,047 ops/sec [15,677..16,214] ~ overlap (-1.0%) 17,787 ops/sec [17,587..17,924] → 20,235 ops/sec [19,979..20,571] 🟢 +13.8%
reviver on array 8,657 ops/sec [8,567..8,733] → 8,438 ops/sec [8,406..8,518] 🔴 -2.5% 10,461 ops/sec [10,435..10,560] → 11,718 ops/sec [11,533..12,052] 🟢 +12.0%
replacer function doubles numbers 15,849 ops/sec [15,763..15,902] → 15,554 ops/sec [15,415..15,738] 🔴 -1.9% 19,443 ops/sec [19,329..19,893] → 20,689 ops/sec [20,603..21,107] 🟢 +6.4%
replacer function excludes properties 21,340 ops/sec [21,141..21,932] → 21,405 ops/sec [20,566..21,564] ~ overlap (+0.3%) 24,372 ops/sec [24,285..24,451] → 25,695 ops/sec [25,433..25,809] 🟢 +5.4%
array replacer (allowlist) 44,211 ops/sec [43,786..45,435] → 44,626 ops/sec [44,156..45,370] ~ overlap (+0.9%) 41,614 ops/sec [40,982..42,248] → 41,453 ops/sec [41,003..41,795] ~ overlap (-0.4%)
stringify with 2-space indent 36,950 ops/sec [36,513..37,393] → 37,460 ops/sec [36,558..38,423] ~ overlap (+1.4%) 36,407 ops/sec [36,161..36,807] → 37,960 ops/sec [37,701..38,949] 🟢 +4.3%
stringify with tab indent 37,454 ops/sec [37,085..37,919] → 37,166 ops/sec [36,478..38,822] ~ overlap (-0.8%) 35,980 ops/sec [35,191..36,299] → 37,341 ops/sec [36,912..37,813] 🟢 +3.8%
parse then stringify 22,539 ops/sec [22,406..22,594] → 23,169 ops/sec [22,613..23,740] 🟢 +2.8% 22,765 ops/sec [22,326..23,013] → 25,869 ops/sec [25,333..26,732] 🟢 +13.6%
stringify then parse 13,251 ops/sec [12,828..13,647] → 13,642 ops/sec [12,716..13,757] ~ overlap (+2.9%) 13,179 ops/sec [11,229..13,614] → 14,958 ops/sec [14,723..15,424] 🟢 +13.5%
jsx.jsx — Interp: 🔴 16, 5 unch. · avg -3.9% · Bytecode: 🔴 20, 1 unch. · avg -9.5%
Benchmark Interpreted Δ Bytecode Δ
simple element 87,031 ops/sec [84,822..88,365] → 83,548 ops/sec [83,293..84,038] 🔴 -4.0% 120,418 ops/sec [118,961..124,866] → 111,375 ops/sec [108,939..112,979] 🔴 -7.5%
self-closing element 90,280 ops/sec [90,009..90,627] → 87,692 ops/sec [87,000..88,505] 🔴 -2.9% 130,935 ops/sec [128,431..134,778] → 115,598 ops/sec [114,101..116,488] 🔴 -11.7%
element with string attribute 76,322 ops/sec [75,677..76,537] → 71,527 ops/sec [71,240..72,647] 🔴 -6.3% 97,810 ops/sec [96,373..100,504] → 87,378 ops/sec [86,095..89,206] 🔴 -10.7%
element with multiple attributes 68,315 ops/sec [67,963..69,327] → 65,477 ops/sec [65,196..65,699] 🔴 -4.2% 72,516 ops/sec [70,154..73,974] → 62,999 ops/sec [61,890..64,254] 🔴 -13.1%
element with expression attribute 70,646 ops/sec [70,374..71,152] → 68,935 ops/sec [67,894..69,632] 🔴 -2.4% 98,684 ops/sec [97,184..100,270] → 92,028 ops/sec [87,941..92,566] 🔴 -6.7%
text child 89,677 ops/sec [87,802..90,388] → 89,183 ops/sec [88,746..89,760] ~ overlap (-0.6%) 121,350 ops/sec [120,047..123,225] → 111,705 ops/sec [108,810..118,842] 🔴 -7.9%
expression child 87,029 ops/sec [85,929..87,403] → 81,720 ops/sec [81,170..84,618] 🔴 -6.1% 114,642 ops/sec [113,268..116,527] → 107,126 ops/sec [104,787..108,645] 🔴 -6.6%
mixed text and expression 84,668 ops/sec [80,924..85,308] → 79,186 ops/sec [78,720..80,454] 🔴 -6.5% 99,925 ops/sec [99,297..100,401] → 94,832 ops/sec [94,177..101,009] ~ overlap (-5.1%)
nested elements (3 levels) 33,342 ops/sec [32,724..33,827] → 32,122 ops/sec [31,557..32,497] 🔴 -3.7% 46,490 ops/sec [45,408..47,615] → 42,004 ops/sec [41,242..43,724] 🔴 -9.6%
sibling children 24,897 ops/sec [24,758..25,009] → 24,546 ops/sec [23,970..25,087] ~ overlap (-1.4%) 34,161 ops/sec [33,531..35,281] → 30,473 ops/sec [30,004..31,058] 🔴 -10.8%
component element 66,139 ops/sec [64,421..66,606] → 64,121 ops/sec [63,630..64,724] ~ overlap (-3.1%) 91,075 ops/sec [88,961..91,872] → 81,838 ops/sec [80,989..84,098] 🔴 -10.1%
component with children 40,510 ops/sec [40,219..41,192] → 39,277 ops/sec [38,771..39,389] 🔴 -3.0% 55,246 ops/sec [54,425..56,323] → 48,498 ops/sec [47,357..48,866] 🔴 -12.2%
dotted component 56,846 ops/sec [55,299..58,039] → 53,885 ops/sec [53,362..55,400] ~ overlap (-5.2%) 70,888 ops/sec [69,723..71,618] → 63,128 ops/sec [61,862..63,934] 🔴 -10.9%
empty fragment 90,304 ops/sec [88,708..90,830] → 88,252 ops/sec [87,094..89,190] ~ overlap (-2.3%) 145,174 ops/sec [144,512..145,824] → 127,749 ops/sec [124,674..128,166] 🔴 -12.0%
fragment with children 25,505 ops/sec [25,092..26,093] → 24,209 ops/sec [23,798..24,738] 🔴 -5.1% 35,143 ops/sec [34,610..35,407] → 30,863 ops/sec [30,641..31,174] 🔴 -12.2%
spread attributes 47,085 ops/sec [46,338..47,782] → 45,775 ops/sec [45,599..46,148] 🔴 -2.8% 51,429 ops/sec [50,356..52,247] → 48,706 ops/sec [47,812..48,917] 🔴 -5.3%
spread with overrides 42,326 ops/sec [41,730..42,841] → 40,645 ops/sec [39,872..40,989] 🔴 -4.0% 44,249 ops/sec [43,795..45,727] → 42,733 ops/sec [42,288..43,124] 🔴 -3.4%
shorthand props 68,677 ops/sec [66,308..69,110] → 66,031 ops/sec [65,574..66,207] 🔴 -3.9% 79,445 ops/sec [78,601..81,264] → 73,178 ops/sec [72,618..74,098] 🔴 -7.9%
nav bar structure 12,283 ops/sec [11,857..12,709] → 11,679 ops/sec [11,414..11,804] 🔴 -4.9% 15,803 ops/sec [15,730..15,889] → 14,033 ops/sec [13,894..14,103] 🔴 -11.2%
card component tree 14,202 ops/sec [14,194..14,307] → 13,708 ops/sec [13,671..13,811] 🔴 -3.5% 17,916 ops/sec [17,447..18,244] → 15,525 ops/sec [15,279..15,614] 🔴 -13.3%
10 list items via Array.from 6,446 ops/sec [6,428..6,482] → 6,094 ops/sec [5,970..6,126] 🔴 -5.5% 7,750 ops/sec [7,675..7,808] → 6,921 ops/sec [6,913..6,961] 🔴 -10.7%
modules.js — Interp: 9 unch. · avg -1.2% · Bytecode: 🟢 9 · avg +16.3%
Benchmark Interpreted Δ Bytecode Δ
call imported function 152,389 ops/sec [149,025..154,081] → 152,795 ops/sec [150,717..153,223] ~ overlap (+0.3%) 542,301 ops/sec [535,694..543,719] → 615,766 ops/sec [611,564..619,450] 🟢 +13.5%
call two imported functions 84,216 ops/sec [82,721..86,947] → 86,884 ops/sec [85,275..87,337] ~ overlap (+3.2%) 360,155 ops/sec [354,042..361,736] → 400,994 ops/sec [383,104..419,419] 🟢 +11.3%
read imported constant 498,042 ops/sec [484,020..502,433] → 484,419 ops/sec [480,290..486,009] ~ overlap (-2.7%) 1,295,349 ops/sec [1,294,441..1,298,860] → 1,526,869 ops/sec [1,483,902..1,562,372] 🟢 +17.9%
read imported string 487,284 ops/sec [455,967..501,217] → 476,838 ops/sec [464,722..480,717] ~ overlap (-2.1%) 1,299,037 ops/sec [1,288,127..1,302,080] → 1,537,451 ops/sec [1,527,795..1,551,080] 🟢 +18.4%
read JSON string property 492,563 ops/sec [488,986..508,252] → 488,413 ops/sec [484,007..493,564] ~ overlap (-0.8%) 1,294,880 ops/sec [1,282,163..1,300,792] → 1,534,508 ops/sec [1,476,660..1,593,269] 🟢 +18.5%
read JSON number property 494,367 ops/sec [473,037..497,875] → 485,434 ops/sec [474,402..490,859] ~ overlap (-1.8%) 1,288,376 ops/sec [1,286,497..1,295,913] → 1,532,369 ops/sec [1,524,010..1,537,293] 🟢 +18.9%
read JSON boolean property 485,827 ops/sec [478,464..511,811] → 478,759 ops/sec [469,741..497,592] ~ overlap (-1.5%) 1,290,506 ops/sec [1,281,310..1,302,480] → 1,546,337 ops/sec [1,538,239..1,556,838] 🟢 +19.8%
read JSON array property 487,648 ops/sec [477,077..491,861] → 465,985 ops/sec [458,976..488,231] ~ overlap (-4.4%) 1,291,260 ops/sec [1,255,927..1,304,954] → 1,537,048 ops/sec [1,515,025..1,537,889] 🟢 +19.0%
read multiple JSON properties 291,448 ops/sec [284,550..299,359] → 288,925 ops/sec [283,832..293,049] ~ overlap (-0.9%) 1,126,837 ops/sec [1,122,535..1,131,103] → 1,230,714 ops/sec [1,213,299..1,241,495] 🟢 +9.2%
numbers.js — Interp: 🟢 1, 10 unch. · avg +1.2% · Bytecode: 🟢 10, 1 unch. · avg +10.1%
Benchmark Interpreted Δ Bytecode Δ
integer arithmetic 154,453 ops/sec [149,017..157,431] → 153,300 ops/sec [148,307..158,953] ~ overlap (-0.7%) 650,741 ops/sec [646,333..656,228] → 701,997 ops/sec [684,093..764,026] 🟢 +7.9%
floating point arithmetic 178,861 ops/sec [171,128..182,929] → 180,135 ops/sec [174,490..186,580] ~ overlap (+0.7%) 277,274 ops/sec [272,424..280,746] → 308,932 ops/sec [301,467..312,653] 🟢 +11.4%
number coercion 70,210 ops/sec [68,584..72,576] → 72,229 ops/sec [68,656..73,579] ~ overlap (+2.9%) 88,586 ops/sec [86,941..89,769] → 103,577 ops/sec [97,390..105,268] 🟢 +16.9%
toFixed 41,342 ops/sec [40,902..42,778] → 41,192 ops/sec [40,554..41,592] ~ overlap (-0.4%) 39,626 ops/sec [39,323..39,942] → 43,318 ops/sec [42,277..43,933] 🟢 +9.3%
toString 64,957 ops/sec [64,592..65,541] → 64,014 ops/sec [62,106..64,635] ~ overlap (-1.5%) 69,196 ops/sec [68,703..70,875] → 71,934 ops/sec [70,798..75,729] ~ overlap (+4.0%)
valueOf 97,206 ops/sec [95,281..98,611] → 96,995 ops/sec [93,988..99,647] ~ overlap (-0.2%) 105,470 ops/sec [104,979..105,771] → 107,402 ops/sec [106,293..108,722] 🟢 +1.8%
toPrecision 36,688 ops/sec [36,008..37,222] → 37,253 ops/sec [36,417..38,089] ~ overlap (+1.5%) 35,675 ops/sec [35,208..36,531] → 38,634 ops/sec [38,481..39,040] 🟢 +8.3%
Number.isNaN 110,377 ops/sec [108,599..112,148] → 113,512 ops/sec [112,917..113,989] 🟢 +2.8% 112,733 ops/sec [109,560..115,317] → 129,287 ops/sec [126,541..130,632] 🟢 +14.7%
Number.isFinite 111,189 ops/sec [108,985..112,202] → 112,414 ops/sec [108,822..113,672] ~ overlap (+1.1%) 98,648 ops/sec [97,105..99,773] → 111,244 ops/sec [110,134..113,001] 🟢 +12.8%
Number.isInteger 114,870 ops/sec [112,289..118,223] → 118,664 ops/sec [116,465..119,768] ~ overlap (+3.3%) 106,597 ops/sec [105,993..107,317] → 117,352 ops/sec [114,643..121,040] 🟢 +10.1%
Number.parseInt and parseFloat 91,538 ops/sec [89,780..92,962] → 94,570 ops/sec [91,989..95,114] ~ overlap (+3.3%) 79,568 ops/sec [79,018..80,890] → 90,470 ops/sec [87,754..90,928] 🟢 +13.7%
objects.js — Interp: 🔴 3, 4 unch. · avg -3.9% · Bytecode: 🟢 3, 🔴 4 · avg -3.5%
Benchmark Interpreted Δ Bytecode Δ
create simple object 183,123 ops/sec [179,392..185,467] → 176,377 ops/sec [175,113..177,821] 🔴 -3.7% 204,983 ops/sec [202,306..207,228] → 168,009 ops/sec [167,076..169,265] 🔴 -18.0%
create nested object 96,689 ops/sec [95,168..97,959] → 90,694 ops/sec [89,803..91,383] 🔴 -6.2% 89,048 ops/sec [87,392..91,676] → 73,580 ops/sec [73,264..74,250] 🔴 -17.4%
create 50 objects via Array.from 3,713 ops/sec [3,656..3,737] → 3,490 ops/sec [3,392..3,550] 🔴 -6.0% 3,675 ops/sec [3,651..3,776] → 3,411 ops/sec [3,351..3,461] 🔴 -7.2%
property read 189,027 ops/sec [183,967..191,212] → 183,192 ops/sec [182,759..184,113] ~ overlap (-3.1%) 264,776 ops/sec [257,386..267,713] → 300,752 ops/sec [290,166..305,741] 🟢 +13.6%
Object.keys 120,157 ops/sec [118,687..123,106] → 117,045 ops/sec [116,262..120,155] ~ overlap (-2.6%) 128,331 ops/sec [126,801..130,047] → 139,821 ops/sec [138,585..142,159] 🟢 +9.0%
Object.entries 50,376 ops/sec [50,074..50,671] → 50,055 ops/sec [49,606..50,391] ~ overlap (-0.6%) 49,952 ops/sec [49,351..50,456] → 53,005 ops/sec [52,286..53,186] 🟢 +6.1%
spread operator 77,305 ops/sec [76,282..79,212] → 73,394 ops/sec [72,144..76,971] ~ overlap (-5.1%) 82,570 ops/sec [81,955..83,026] → 73,764 ops/sec [73,006..74,096] 🔴 -10.7%
promises.js — Interp: 12 unch. · avg +1.2% · Bytecode: 🟢 7, 5 unch. · avg +4.6%
Benchmark Interpreted Δ Bytecode Δ
Promise.resolve(value) 197,880 ops/sec [194,349..203,349] → 199,850 ops/sec [197,158..203,929] ~ overlap (+1.0%) 214,658 ops/sec [211,994..216,316] → 214,205 ops/sec [202,504..224,861] ~ overlap (-0.2%)
new Promise(resolve => resolve(value)) 76,159 ops/sec [72,423..78,382] → 77,221 ops/sec [74,958..78,546] ~ overlap (+1.4%) 97,703 ops/sec [96,114..99,112] → 104,129 ops/sec [99,985..105,762] 🟢 +6.6%
Promise.reject(reason) 202,922 ops/sec [198,893..204,931] → 203,240 ops/sec [201,565..206,969] ~ overlap (+0.2%) 219,476 ops/sec [218,175..220,409] → 225,966 ops/sec [220,224..227,367] ~ overlap (+3.0%)
resolve + then (1 handler) 74,799 ops/sec [73,848..75,246] → 74,791 ops/sec [74,483..75,494] ~ overlap (-0.0%) 90,993 ops/sec [88,674..91,553] → 93,280 ops/sec [90,095..95,481] ~ overlap (+2.5%)
resolve + then chain (3 deep) 30,602 ops/sec [30,387..30,609] → 30,881 ops/sec [30,405..31,178] ~ overlap (+0.9%) 38,254 ops/sec [36,519..38,734] → 39,428 ops/sec [38,617..39,527] ~ overlap (+3.1%)
resolve + then chain (10 deep) 10,035 ops/sec [9,976..10,325] → 10,225 ops/sec [9,953..10,330] ~ overlap (+1.9%) 12,276 ops/sec [12,061..12,497] → 13,382 ops/sec [13,366..13,450] 🟢 +9.0%
reject + catch + then 44,313 ops/sec [43,487..45,148] → 44,534 ops/sec [43,221..45,191] ~ overlap (+0.5%) 50,418 ops/sec [50,197..51,208] → 53,932 ops/sec [52,058..54,438] 🟢 +7.0%
resolve + finally + then 38,699 ops/sec [38,087..39,108] → 38,780 ops/sec [37,864..39,167] ~ overlap (+0.2%) 41,632 ops/sec [40,853..42,234] → 44,778 ops/sec [42,633..46,024] 🟢 +7.6%
Promise.all (5 resolved) 16,044 ops/sec [15,732..16,267] → 16,633 ops/sec [15,603..16,803] ~ overlap (+3.7%) 15,142 ops/sec [15,068..15,411] → 15,776 ops/sec [15,576..15,952] 🟢 +4.2%
Promise.race (5 resolved) 17,168 ops/sec [16,966..17,332] → 17,798 ops/sec [17,237..17,944] ~ overlap (+3.7%) 16,048 ops/sec [15,849..16,169] → 16,857 ops/sec [16,525..17,447] 🟢 +5.0%
Promise.allSettled (5 mixed) 13,285 ops/sec [13,055..13,529] → 13,428 ops/sec [12,962..14,198] ~ overlap (+1.1%) 12,925 ops/sec [12,863..12,936] → 13,288 ops/sec [12,921..13,531] ~ overlap (+2.8%)
Promise.any (5 mixed) 15,882 ops/sec [15,690..15,999] → 15,923 ops/sec [15,545..16,766] ~ overlap (+0.3%) 15,474 ops/sec [15,383..15,549] → 16,129 ops/sec [15,705..16,927] 🟢 +4.2%
regexp.js — Interp: 🟢 1, 10 unch. · avg +0.3% · Bytecode: 🟢 5, 🔴 5, 1 unch. · avg +2.7%
Benchmark Interpreted Δ Bytecode Δ
regex literal creation 7,339 ops/sec [7,249..7,430] → 7,414 ops/sec [7,405..7,438] ~ overlap (+1.0%) 7,064 ops/sec [6,850..7,251] → 7,917 ops/sec [7,863..7,964] 🟢 +12.1%
new RegExp(pattern, flags) 7,130 ops/sec [6,971..7,218] → 7,297 ops/sec [7,153..7,322] ~ overlap (+2.3%) 6,856 ops/sec [6,693..6,973] → 8,040 ops/sec [7,977..8,090] 🟢 +17.3%
RegExp(existingRegex) returns the same regex 236,419 ops/sec [231,074..238,037] → 243,924 ops/sec [238,620..246,682] 🟢 +3.2% 336,221 ops/sec [331,525..340,056] → 385,061 ops/sec [382,764..390,360] 🟢 +14.5%
test() on a global regex 37,252 ops/sec [36,485..37,687] → 37,735 ops/sec [37,087..38,137] ~ overlap (+1.3%) 38,498 ops/sec [38,074..38,656] → 42,609 ops/sec [41,975..42,836] 🟢 +10.7%
exec() with capture groups 14,973 ops/sec [14,181..15,418] → 15,348 ops/sec [15,035..15,361] ~ overlap (+2.5%) 15,148 ops/sec [14,993..15,497] → 14,449 ops/sec [14,324..14,580] 🔴 -4.6%
toString() 193,047 ops/sec [191,605..198,754] → 193,112 ops/sec [189,357..195,443] ~ overlap (+0.0%) 224,875 ops/sec [218,137..227,076] → 249,532 ops/sec [246,453..252,220] 🟢 +11.0%
match() with global regex 1,684 ops/sec [1,649..1,743] → 1,647 ops/sec [1,605..1,719] ~ overlap (-2.2%) 1,664 ops/sec [1,635..1,684] → 1,539 ops/sec [1,526..1,542] 🔴 -7.5%
matchAll() with capture groups 3,643 ops/sec [3,564..3,702] → 3,568 ops/sec [3,503..3,632] ~ overlap (-2.1%) 3,810 ops/sec [3,792..3,940] → 3,802 ops/sec [3,789..3,875] ~ overlap (-0.2%)
replace() with global regex 1,654 ops/sec [1,604..1,713] → 1,631 ops/sec [1,608..1,665] ~ overlap (-1.4%) 1,642 ops/sec [1,601..1,667] → 1,516 ops/sec [1,503..1,519] 🔴 -7.7%
search() with regex 1,802 ops/sec [1,755..1,908] → 1,805 ops/sec [1,789..1,829] ~ overlap (+0.2%) 1,818 ops/sec [1,782..1,875] → 1,657 ops/sec [1,635..1,668] 🔴 -8.9%
split() with regex separator 1,341 ops/sec [1,307..1,366] → 1,318 ops/sec [1,308..1,320] ~ overlap (-1.7%) 1,324 ops/sec [1,276..1,348] → 1,231 ops/sec [1,217..1,239] 🔴 -7.0%
strings.js — Interp: 🔴 7, 12 unch. · avg -2.7% · Bytecode: 🟢 18, 1 unch. · avg +10.7%
Benchmark Interpreted Δ Bytecode Δ
string concatenation 151,839 ops/sec [147,745..153,106] → 144,020 ops/sec [142,075..145,698] 🔴 -5.1% 817,234 ops/sec [811,758..818,196] → 879,901 ops/sec [817,955..920,538] ~ overlap (+7.7%)
template literal 283,669 ops/sec [278,042..289,788] → 275,676 ops/sec [271,046..284,101] ~ overlap (-2.8%) 565,706 ops/sec [557,831..568,744] → 634,828 ops/sec [613,715..678,892] 🟢 +12.2%
string repeat 171,829 ops/sec [170,379..174,316] → 164,768 ops/sec [159,516..172,425] ~ overlap (-4.1%) 189,531 ops/sec [188,072..192,559] → 201,895 ops/sec [198,476..215,072] 🟢 +6.5%
split and join 28,319 ops/sec [27,612..28,988] → 27,702 ops/sec [26,944..28,191] ~ overlap (-2.2%) 28,727 ops/sec [28,116..28,952] → 32,371 ops/sec [31,552..33,768] 🟢 +12.7%
indexOf and includes 52,900 ops/sec [48,770..54,463] → 51,456 ops/sec [50,138..53,181] ~ overlap (-2.7%) 49,087 ops/sec [47,851..49,510] → 55,030 ops/sec [53,689..55,678] 🟢 +12.1%
toUpperCase and toLowerCase 86,710 ops/sec [86,222..88,595] → 82,673 ops/sec [81,623..84,350] 🔴 -4.7% 84,886 ops/sec [82,209..86,292] → 101,153 ops/sec [99,614..102,179] 🟢 +19.2%
slice and substring 52,511 ops/sec [50,803..53,684] → 49,778 ops/sec [49,475..52,042] ~ overlap (-5.2%) 53,634 ops/sec [53,074..54,143] → 60,128 ops/sec [59,614..61,018] 🟢 +12.1%
trim operations 77,987 ops/sec [77,049..78,893] → 73,984 ops/sec [72,577..75,221] 🔴 -5.1% 76,280 ops/sec [74,499..77,714] → 87,797 ops/sec [80,604..88,899] 🟢 +15.1%
replace and replaceAll 52,360 ops/sec [51,779..52,925] → 52,024 ops/sec [51,490..52,790] ~ overlap (-0.6%) 49,564 ops/sec [48,847..49,865] → 53,286 ops/sec [52,549..54,274] 🟢 +7.5%
startsWith and endsWith 49,170 ops/sec [48,312..50,868] → 48,155 ops/sec [47,506..48,675] ~ overlap (-2.1%) 43,975 ops/sec [43,203..44,312] → 46,699 ops/sec [45,752..46,989] 🟢 +6.2%
padStart and padEnd 72,415 ops/sec [70,350..73,948] → 71,465 ops/sec [70,050..72,473] ~ overlap (-1.3%) 71,099 ops/sec [70,580..71,236] → 75,813 ops/sec [74,579..78,700] 🟢 +6.6%
identity tag, no substitutions 157,311 ops/sec [153,002..159,809] → 156,655 ops/sec [154,954..161,006] ~ overlap (-0.4%) 457,869 ops/sec [443,504..458,239] → 505,574 ops/sec [502,658..511,028] 🟢 +10.4%
tag with 1 substitution 34,519 ops/sec [34,302..34,989] → 34,130 ops/sec [33,624..34,211] 🔴 -1.1% 46,632 ops/sec [46,442..47,171] → 52,124 ops/sec [51,957..52,426] 🟢 +11.8%
tag with 3 substitutions 18,187 ops/sec [18,042..18,669] → 18,048 ops/sec [17,827..18,410] ~ overlap (-0.8%) 27,114 ops/sec [25,948..27,298] → 29,811 ops/sec [29,010..30,528] 🟢 +9.9%
tag with 6 substitutions 10,963 ops/sec [10,746..11,278] → 10,894 ops/sec [10,638..10,966] ~ overlap (-0.6%) 16,026 ops/sec [15,828..16,441] → 17,481 ops/sec [17,244..17,923] 🟢 +9.1%
String.raw, no substitutions 231,345 ops/sec [228,694..234,065] → 220,426 ops/sec [218,809..224,324] 🔴 -4.7% 211,628 ops/sec [209,827..219,775] → 235,053 ops/sec [232,368..241,913] 🟢 +11.1%
String.raw, 2 substitutions 163,548 ops/sec [163,100..163,883] → 154,957 ops/sec [149,915..156,348] 🔴 -5.3% 142,324 ops/sec [140,348..143,294] → 157,857 ops/sec [157,139..160,773] 🟢 +10.9%
tag accessing .raw array 67,610 ops/sec [67,064..68,138] → 66,473 ops/sec [66,429..66,718] 🔴 -1.7% 79,800 ops/sec [79,316..80,576] → 86,847 ops/sec [85,317..89,198] 🟢 +8.8%
method as tag (this binding) 25,311 ops/sec [25,228..25,440] → 25,121 ops/sec [24,455..25,446] ~ overlap (-0.8%) 35,925 ops/sec [35,215..36,521] → 40,420 ops/sec [39,974..41,088] 🟢 +12.5%
tsv.js — Interp: 9 unch. · avg +0.0% · Bytecode: 🟢 9 · avg +9.0%
Benchmark Interpreted Δ Bytecode Δ
parse simple 3-column TSV 44,342 ops/sec [43,486..44,901] → 44,009 ops/sec [43,493..44,512] ~ overlap (-0.8%) 44,666 ops/sec [43,915..45,080] → 47,942 ops/sec [47,446..51,020] 🟢 +7.3%
parse 10-row TSV 11,510 ops/sec [11,292..12,561] → 11,712 ops/sec [11,642..11,740] ~ overlap (+1.8%) 11,640 ops/sec [11,422..11,695] → 12,608 ops/sec [12,470..12,803] 🟢 +8.3%
parse 100-row TSV 1,874 ops/sec [1,808..1,919] → 1,817 ops/sec [1,800..1,908] ~ overlap (-3.1%) 1,853 ops/sec [1,808..1,876] → 1,978 ops/sec [1,939..2,051] 🟢 +6.7%
parse TSV with backslash-escaped fields 8,978 ops/sec [8,748..9,149] → 8,873 ops/sec [8,645..9,026] ~ overlap (-1.2%) 8,916 ops/sec [8,908..8,923] → 9,509 ops/sec [9,305..9,783] 🟢 +6.7%
parse without headers (array of arrays) 5,829 ops/sec [5,763..5,908] → 5,727 ops/sec [5,597..6,129] ~ overlap (-1.7%) 5,859 ops/sec [5,809..6,001] → 6,219 ops/sec [6,088..6,353] 🟢 +6.1%
stringify array of objects 38,857 ops/sec [37,888..39,052] → 38,605 ops/sec [38,440..39,044] ~ overlap (-0.6%) 39,535 ops/sec [38,849..39,972] → 44,187 ops/sec [44,135..44,467] 🟢 +11.8%
stringify array of arrays 11,134 ops/sec [11,077..11,228] → 11,091 ops/sec [11,067..11,302] ~ overlap (-0.4%) 11,244 ops/sec [11,076..11,296] → 12,624 ops/sec [12,512..12,677] 🟢 +12.3%
stringify with values needing escaping 30,896 ops/sec [30,737..31,153] → 31,231 ops/sec [30,865..32,040] ~ overlap (+1.1%) 31,942 ops/sec [31,553..32,113] → 35,952 ops/sec [35,418..36,432] 🟢 +12.6%
parse then stringify 6,712 ops/sec [6,463..6,827] → 7,042 ops/sec [6,563..7,164] ~ overlap (+4.9%) 6,726 ops/sec [6,595..6,792] → 7,367 ops/sec [7,295..7,395] 🟢 +9.5%
typed-arrays.js — Interp: 🟢 10, 🔴 1, 11 unch. · avg +24.4% · Bytecode: 🟢 11, 🔴 2, 9 unch. · avg -0.1%
Benchmark Interpreted Δ Bytecode Δ
new Int32Array(0) 117,149 ops/sec [115,377..117,595] → 116,263 ops/sec [115,810..118,480] ~ overlap (-0.8%) 134,538 ops/sec [133,151..138,749] → 143,984 ops/sec [142,112..144,431] 🟢 +7.0%
new Int32Array(100) 111,630 ops/sec [111,032..112,124] → 111,831 ops/sec [109,929..114,233] ~ overlap (+0.2%) 125,479 ops/sec [121,454..126,119] → 135,724 ops/sec [132,465..137,086] 🟢 +8.2%
new Int32Array(1000) 85,923 ops/sec [83,968..86,752] → 83,562 ops/sec [82,856..84,012] ~ overlap (-2.7%) 95,681 ops/sec [94,644..96,777] → 92,982 ops/sec [91,012..94,734] ~ overlap (-2.8%)
new Float64Array(100) 109,607 ops/sec [107,265..110,142] → 108,829 ops/sec [105,924..109,969] ~ overlap (-0.7%) 125,266 ops/sec [124,348..126,993] → 125,471 ops/sec [123,305..128,505] ~ overlap (+0.2%)
Int32Array.from([...]) 3,901 ops/sec [3,846..3,972] → 3,972 ops/sec [3,894..4,095] ~ overlap (+1.8%) 3,869 ops/sec [3,843..3,920] → 4,076 ops/sec [3,982..4,228] 🟢 +5.4%
Int32Array.of(1, 2, 3, 4, 5) 116,503 ops/sec [113,934..119,934] → 118,048 ops/sec [116,292..119,278] ~ overlap (+1.3%) 130,178 ops/sec [129,149..131,590] → 137,014 ops/sec [135,200..140,121] 🟢 +5.3%
sequential write 100 elements 1,042 ops/sec [1,020..1,090] → 1,040 ops/sec [1,026..1,069] ~ overlap (-0.1%) 4,149 ops/sec [2,439..4,228] → 2,650 ops/sec [2,620..2,692] ~ overlap (-36.1%)
sequential read 100 elements 1,100 ops/sec [1,085..1,118] → 1,090 ops/sec [1,071..1,123] ~ overlap (-0.9%) 2,432 ops/sec [2,407..4,004] → 2,591 ops/sec [2,572..2,659] ~ overlap (+6.5%)
Float64Array write 100 elements 986 ops/sec [956..1,516] → 1,019 ops/sec [1,003..1,044] ~ overlap (+3.4%) 2,031 ops/sec [2,009..3,322] → 2,211 ops/sec [2,201..2,241] ~ overlap (+8.8%)
fill(42) 7,221 ops/sec [7,200..7,250] → 4,433 ops/sec [4,341..4,521] 🔴 -38.6% 7,250 ops/sec [7,215..7,278] → 4,805 ops/sec [4,706..4,885] 🔴 -33.7%
slice() 34,395 ops/sec [34,257..34,547] → 34,958 ops/sec [34,687..35,363] 🟢 +1.6% 58,302 ops/sec [35,582..58,871] → 38,723 ops/sec [38,326..39,042] ~ overlap (-33.6%)
map(x => x * 2) 2,353 ops/sec [2,324..2,370] → 3,835 ops/sec [2,331..3,864] ~ overlap (+63.0%) 3,095 ops/sec [3,081..3,101] → 3,342 ops/sec [3,299..3,362] 🟢 +8.0%
filter(x => x > 50) 2,369 ops/sec [2,337..2,387] → 3,907 ops/sec [3,873..3,926] 🟢 +64.9% 3,298 ops/sec [3,240..3,307] → 3,599 ops/sec [3,562..3,659] 🟢 +9.1%
reduce (sum) 2,467 ops/sec [2,441..2,570] → 4,127 ops/sec [4,126..4,140] 🟢 +67.2% 3,133 ops/sec [3,100..3,196] → 3,397 ops/sec [3,341..3,407] 🟢 +8.4%
sort() 20,643 ops/sec [20,374..21,116] → 34,599 ops/sec [34,568..34,618] 🟢 +67.6% 21,039 ops/sec [20,979..21,156] → 22,507 ops/sec [22,319..22,972] 🟢 +7.0%
indexOf() 32,821 ops/sec [32,614..33,302] → 53,590 ops/sec [53,219..53,894] 🟢 +63.3% 33,647 ops/sec [33,320..34,061] → 56,582 ops/sec [34,688..57,455] 🟢 +68.2%
reverse() 37,763 ops/sec [37,282..38,263] → 63,062 ops/sec [62,584..63,432] 🟢 +67.0% 39,166 ops/sec [38,183..39,537] → 42,815 ops/sec [42,490..64,787] 🟢 +9.3%
create view over existing buffer 133,624 ops/sec [132,722..133,915] → 214,058 ops/sec [212,155..215,216] 🟢 +60.2% 152,859 ops/sec [152,420..154,867] → 168,068 ops/sec [164,976..169,126] 🟢 +9.9%
subarray() 151,269 ops/sec [150,667..151,678] → 233,393 ops/sec [232,945..236,568] 🟢 +54.3% 218,329 ops/sec [165,720..278,853] → 178,348 ops/sec [176,711..179,017] ~ overlap (-18.3%)
set() from array 126,091 ops/sec [124,656..127,184] → 207,342 ops/sec [206,389..210,323] 🟢 +64.4% 239,165 ops/sec [237,123..240,141] → 149,053 ops/sec [148,668..153,428] 🔴 -37.7%
for-of loop 3,146 ops/sec [3,104..3,166] → 3,186 ops/sec [3,178..3,194] 🟢 +1.3% 14,963 ops/sec [14,918..14,988] → 14,896 ops/sec [10,086..14,978] ~ overlap (-0.4%)
spread into array 11,573 ops/sec [11,478..11,655] → 11,492 ops/sec [11,376..11,619] ~ overlap (-0.7%) 45,210 ops/sec [45,086..45,364] → 44,715 ops/sec [44,270..45,175] ~ overlap (-1.1%)
uint8array-encoding.js — Interp: 🟢 3, 🔴 9, 6 unch. · avg -13.8% · Bytecode: 🟢 2, 🔴 8, 8 unch. · avg -20.6%
Benchmark Interpreted Δ Bytecode Δ
short (5 bytes) 206,768 ops/sec [202,889..209,900] → 217,122 ops/sec [216,364..218,017] 🟢 +5.0% 259,319 ops/sec [254,826..262,212] → 266,952 ops/sec [260,570..279,450] ~ overlap (+2.9%)
medium (450 bytes) 130,681 ops/sec [127,269..134,773] → 130,016 ops/sec [129,794..130,684] ~ overlap (-0.5%) 143,835 ops/sec [143,592..147,177] → 155,444 ops/sec [152,712..160,928] 🟢 +8.1%
large (4096 bytes) 31,945 ops/sec [31,679..32,220] → 31,573 ops/sec [31,126..31,925] ~ overlap (-1.2%) 33,556 ops/sec [32,265..33,818] → 34,077 ops/sec [33,244..34,684] ~ overlap (+1.5%)
base64url alphabet 95,235 ops/sec [94,167..96,797] → 136,934 ops/sec [135,986..137,632] 🟢 +43.8% 97,176 ops/sec [96,601..98,898] → 98,002 ops/sec [97,800..98,476] ~ overlap (+0.8%)
omitPadding 131,228 ops/sec [130,633..207,493] → 207,626 ops/sec [204,458..210,088] ~ overlap (+58.2%) 142,691 ops/sec [141,285..146,801] → 142,463 ops/sec [141,075..144,512] ~ overlap (-0.2%)
short (8 chars) 221,964 ops/sec [220,479..223,457] → 145,441 ops/sec [144,713..145,801] 🔴 -34.5% 154,088 ops/sec [150,190..155,674] → 158,573 ops/sec [156,373..160,703] 🟢 +2.9%
medium (600 chars) 115,994 ops/sec [114,854..116,577] → 71,790 ops/sec [71,064..72,066] 🔴 -38.1% 74,212 ops/sec [73,935..74,293] → 75,656 ops/sec [73,965..76,537] ~ overlap (+1.9%)
large (5464 chars) 23,743 ops/sec [23,437..24,283] → 13,829 ops/sec [13,710..14,105] 🔴 -41.8% 24,013 ops/sec [13,992..24,908] → 14,129 ops/sec [14,039..14,880] ~ overlap (-41.2%)
short (5 bytes) 337,362 ops/sec [335,477..341,661] → 215,885 ops/sec [214,661..218,193] 🔴 -36.0% 498,033 ops/sec [496,916..499,616] → 288,007 ops/sec [286,620..291,703] 🔴 -42.2%
medium (450 bytes) 185,375 ops/sec [183,542..186,519] → 111,975 ops/sec [111,719..114,241] 🔴 -39.6% 224,113 ops/sec [222,964..224,613] → 144,288 ops/sec [143,376..144,351] 🔴 -35.6%
large (4096 bytes) 40,041 ops/sec [39,722..40,153] → 23,792 ops/sec [23,255..23,843] 🔴 -40.6% 41,304 ops/sec [41,117..41,392] → 27,046 ops/sec [25,936..27,552] 🔴 -34.5%
short (10 chars) 239,399 ops/sec [236,988..241,337] → 158,953 ops/sec [157,993..159,125] 🔴 -33.6% 283,541 ops/sec [282,532..285,010] → 179,100 ops/sec [177,832..180,731] 🔴 -36.8%
medium (900 chars) 171,798 ops/sec [170,951..172,024] → 101,643 ops/sec [100,000..102,234] 🔴 -40.8% 190,322 ops/sec [188,568..191,721] → 108,914 ops/sec [107,061..111,056] 🔴 -42.8%
large (8192 chars) 49,538 ops/sec [49,453..49,583] → 24,864 ops/sec [24,772..25,338] 🔴 -49.8% 51,576 ops/sec [51,317..51,786] → 26,437 ops/sec [24,323..27,052] 🔴 -48.7%
setFromBase64 (450 bytes) 99,758 ops/sec [98,732..100,643] → 99,085 ops/sec [97,798..99,934] ~ overlap (-0.7%) 109,124 ops/sec [108,717..109,441] → 70,733 ops/sec [70,297..71,024] 🔴 -35.2%
setFromHex (450 bytes) 39,269 ops/sec [38,927..39,495] → 39,406 ops/sec [39,297..39,692] ~ overlap (+0.3%) 40,030 ops/sec [39,773..40,364] → 25,612 ops/sec [25,497..25,971] 🔴 -36.0%
toBase64 → fromBase64 (450 bytes) 78,942 ops/sec [78,074..79,247] → 79,834 ops/sec [79,457..80,108] 🟢 +1.1% 81,282 ops/sec [51,221..82,487] → 54,178 ops/sec [53,551..54,456] ~ overlap (-33.3%)
toHex → fromHex (450 bytes) 99,843 ops/sec [99,791..100,652] → 100,537 ops/sec [99,363..101,216] ~ overlap (+0.7%) 69,129 ops/sec [62,429..111,037] → 67,802 ops/sec [66,101..69,857] ~ overlap (-1.9%)
weak-collections.js — Interp: 🟢 3, 🔴 4, 8 unch. · avg +4.2% · Bytecode: 🟢 11, 🔴 2, 2 unch. · avg +33.0%
Benchmark Interpreted Δ Bytecode Δ
constructor from 50 entries 12,457 ops/sec [12,365..12,501] → 13,391 ops/sec [13,072..13,455] 🟢 +7.5% 11,998 ops/sec [11,730..12,271] → 13,695 ops/sec [13,408..14,103] 🟢 +14.1%
set 50 object keys 7,162 ops/sec [7,013..7,230] → 4,432 ops/sec [4,335..4,483] 🔴 -38.1% 5,310 ops/sec [5,203..6,383] → 5,700 ops/sec [5,664..5,722] ~ overlap (+7.3%)
get lookups (50 entries) 58,820 ops/sec [57,861..93,684] → 56,956 ops/sec [56,669..57,552] 🔴 -3.2% 147,312 ops/sec [146,760..148,340] → 93,555 ops/sec [92,893..93,845] 🔴 -36.5%
has checks (50 entries) 75,977 ops/sec [74,744..77,457] → 75,150 ops/sec [74,140..75,511] ~ overlap (-1.1%) 185,512 ops/sec [183,592..186,143] → 115,911 ops/sec [114,294..121,971] 🔴 -37.5%
delete entries 4,118 ops/sec [4,097..4,124] → 4,073 ops/sec [4,026..4,123] ~ overlap (-1.1%) 5,047 ops/sec [4,959..8,617] → 5,272 ops/sec [5,205..5,418] ~ overlap (+4.4%)
non-registered symbol keys 9,953 ops/sec [9,699..10,032] → 9,787 ops/sec [9,703..10,031] ~ overlap (-1.7%) 12,100 ops/sec [12,012..12,343] → 12,858 ops/sec [12,589..12,898] 🟢 +6.3%
getOrInsert 4,072 ops/sec [4,058..4,102] → 4,024 ops/sec [4,009..4,076] ~ overlap (-1.2%) 4,730 ops/sec [4,694..4,787] → 5,024 ops/sec [4,954..5,180] 🟢 +6.2%
getOrInsertComputed 2,085 ops/sec [2,074..2,097] → 2,045 ops/sec [2,024..2,064] 🔴 -1.9% 2,479 ops/sec [2,427..2,516] → 2,597 ops/sec [2,561..3,979] 🟢 +4.8%
forced gc live-key retention 4,305 ops/sec [4,177..4,328] → 4,051 ops/sec [4,004..4,171] 🔴 -5.9% 4,534 ops/sec [4,479..4,615] → 6,924 ops/sec [6,838..7,022] 🟢 +52.7%
constructor from 50 values 16,594 ops/sec [15,716..16,756] → 16,123 ops/sec [15,542..16,484] ~ overlap (-2.8%) 16,423 ops/sec [15,991..16,898] → 29,905 ops/sec [29,133..30,493] 🟢 +82.1%
add 50 object values 4,764 ops/sec [4,661..4,788] → 4,622 ops/sec [4,578..4,676] ~ overlap (-3.0%) 5,732 ops/sec [5,663..5,828] → 10,381 ops/sec [10,368..10,391] 🟢 +81.1%
has checks (50 values) 75,706 ops/sec [74,828..78,187] → 75,043 ops/sec [74,613..75,672] ~ overlap (-0.9%) 114,458 ops/sec [111,552..116,332] → 194,782 ops/sec [192,928..197,094] 🟢 +70.2%
delete values 12,408 ops/sec [11,996..12,755] → 12,612 ops/sec [12,294..20,462] ~ overlap (+1.6%) 13,684 ops/sec [13,574..13,804] → 25,919 ops/sec [25,668..26,069] 🟢 +89.4%
non-registered symbol values 10,322 ops/sec [10,238..10,358] → 16,639 ops/sec [16,423..16,794] 🟢 +61.2% 12,469 ops/sec [12,271..12,642] → 23,259 ops/sec [23,076..23,359] 🟢 +86.5%
forced gc pruning smoke 5,186 ops/sec [5,147..5,240] → 7,967 ops/sec [7,838..8,014] 🟢 +53.6% 5,704 ops/sec [5,643..5,752] → 9,316 ops/sec [9,162..9,434] 🟢 +63.3%

Deterministic profile diff

arraybuffer

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 2 (NEW)
  • 🔴 OP_SET_PROP_CONST: 2 → 0 (REMOVED)

arrays

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 47 (NEW)
  • 🔴 OP_LOAD_CONST: 0 → 47 (NEW)
  • 🔴 OP_SET_PROP_CONST: 47 → 0 (REMOVED)

classes

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 3 (NEW)

closures

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 21 (NEW)
  • 🔴 OP_SET_PROP_CONST: 21 → 0 (REMOVED)
  • Total instructions: 1,357 → 1,378 (+1.5%)

collections

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 11 (NEW)
  • 🔴 OP_SET_PROP_CONST: 11 → 0 (REMOVED)

csv

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 123 (NEW)
  • 🔴 OP_SET_PROP_CONST: 123 → 0 (REMOVED)
  • 🔴 OP_LOAD_CONST: 739 → 862 (+16.6%)
  • Total instructions: 7,948 → 8,071 (+1.5%)

destructuring

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 139 (NEW)
  • 🔴 OP_SET_PROP_CONST: 139 → 0 (REMOVED)
  • 🔴 OP_LOAD_CONST: 28 → 167 (+496.4%)
  • Total instructions: 2,146 → 2,285 (+6.5%)

fibonacci

  • 🔴 OP_LOAD_CONST: 0 → 126 (NEW)
  • 🔴 OP_DEFINE_DATA_PROP: 0 → 123 (NEW)
  • 🔴 OP_DEFINE_METHOD_PROP: 0 → 4 (NEW)
  • 🔴 OP_SET_PROP_CONST: 126 → 0 (REMOVED)
  • 🔴 OP_SET_INDEX: 1 → 0 (REMOVED)

float16array

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 2 (NEW)
  • 🔴 OP_SET_PROP_CONST: 2 → 0 (REMOVED)

generators

  • 🔴 OP_DEFINE_METHOD_PROP: 0 → 3 (NEW)
  • 🔴 OP_LOAD_CONST: 0 → 3 (NEW)
  • 🔴 OP_SET_PROP_CONST: 3 → 0 (REMOVED)

iterators

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 1,126 (NEW)
  • 🔴 OP_DEFINE_METHOD_PROP: 0 → 14 (NEW)
  • 🔴 OP_SET_PROP_CONST: 1,140 → 0 (REMOVED)
  • 🔴 OP_LOAD_CONST: 57 → 1,197 (+2000%)
  • Total instructions: 15,136 → 16,276 (+7.5%)

json

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 72 (NEW)
  • 🔴 OP_SET_PROP_CONST: 72 → 0 (REMOVED)

jsx

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 201 (NEW)
  • 🔴 OP_SET_PROP_CONST: 201 → 0 (REMOVED)
  • 🔴 OP_LOAD_CONST: 107 → 308 (+187.9%)
  • Total instructions: 899 → 1,100 (+22.4%)

objects

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 136 (NEW)
  • 🔴 OP_SET_PROP_CONST: 136 → 0 (REMOVED)
  • 🔴 OP_LOAD_CONST: 51 → 187 (+266.7%)
  • Total instructions: 445 → 581 (+30.6%)

regexp

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 4 (NEW)

tsv

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 70 (NEW)
  • 🔴 OP_SET_PROP_CONST: 70 → 0 (REMOVED)
  • Total instructions: 5,746 → 5,816 (+1.2%)

typed-arrays

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 2 (NEW)
  • 🔴 OP_SET_PROP_CONST: 2 → 0 (REMOVED)

uint8array-encoding

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 2 (NEW)
  • 🔴 OP_SET_PROP_CONST: 2 → 0 (REMOVED)

weak-collections

  • 🔴 OP_DEFINE_DATA_PROP: 0 → 786 (NEW)
  • 🔴 OP_SET_PROP_CONST: 786 → 0 (REMOVED)
  • 🔴 OP_LOAD_CONST: 41 → 827 (+1917%)
  • Total instructions: 7,680 → 8,466 (+10.2%)

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.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

test262 Conformance

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,449 16,056 +3 7,388 68.5% ±0pp
harness 116 72 ±0 44 62.1% ±0pp
intl402 3,324 892 +3 2,432 26.8% +0.1pp
language 23,635 14,203 +2 9,432 60.1% ±0pp
staging 1,484 571 +1 910 38.5% +0.1pp
total 52,008 31,794 +9 20,206 61.1% ±0pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
built-ins/WeakMap 99.3% ±0pp 140 / 141
built-ins/WeakSet 98.8% ±0pp 84 / 85
language/future-reserved-words 98.1% ±0pp 53 / 54
Per-test deltas (+9 / -0)

Newly passing (9):

  • built-ins/Array/prototype/indexOf/15.4.4.14-9-b-i-6.js
  • built-ins/Array/prototype/lastIndexOf/15.4.4.15-8-b-i-6.js
  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js
  • intl402/Collator/taint-Object-prototype.js
  • intl402/DateTimeFormat/taint-Object-prototype.js
  • intl402/NumberFormat/taint-Object-prototype.js
  • language/expressions/object/11.1.5_3-3-1.js
  • language/expressions/object/11.1.5_4-5-1.js
  • staging/sm/object/duplProps.js

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 main baseline.

@frostney frostney marked this pull request as ready for review May 19, 2026 21:43
@coderabbitai coderabbitai Bot added bug Something isn't working documentation Improvements or additions to documentation spec compliance Mismatch against official JavaScript/TypeScript specification internal Refactoring, CI, tooling, cleanup labels May 19, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@source/units/Goccia.VM.pas`:
- Around line 5087-5089: OP_DEFINE_DATA_PROP is assigning a data property but
currently calls SetBytecodeHomeObject(AValue, TargetObject) after TargetObject
:= TGocciaObjectValue(ATarget), which incorrectly assigns a HomeObject and
changes super resolution for bytecode function values; remove the
SetBytecodeHomeObject call from the data-property path (leave other code paths
that legitimately set a home intact) so AValue is created/overwritten as a plain
own data property without modifying its HomeObject.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 24ac2af6-d858-4518-80c1-e631a73e6a71

📥 Commits

Reviewing files that changed from the base of the PR and between b53ef8d and a247240.

📒 Files selected for processing (6)
  • docs/bytecode-vm.md
  • source/units/Goccia.Bytecode.OpCodeNames.pas
  • source/units/Goccia.Bytecode.pas
  • source/units/Goccia.Compiler.Expressions.pas
  • source/units/Goccia.VM.pas
  • tests/language/objects/basic-object-creation.js

Comment thread source/units/Goccia.VM.pas
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
source/units/Goccia.Parser.pas (1)

2920-2988: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Multiple conflicting define instructions generated for duplicate static keys

When duplicate keys appear like { a() {}, a: 1 }, the parser stores each occurrence in PropertySourceOrder with its own IsMethod flag, but the Properties dictionary only retains the final value (line 2975). The compiler loop (lines 2613–2650) processes ALL PropertySourceOrder entries without deduplication, generating separate OP_DEFINE_METHOD_PROP and OP_DEFINE_DATA_PROP instructions for the same key with mismatched metadata. This causes incorrect [[HomeObject]] setup when methods with super references are shadowed by later non-method definitions.

Fix: Either deduplicate PropertySourceOrder entries for duplicate keys or skip entries whose keys have already been processed in the loop.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/units/Goccia.Parser.pas` around lines 2920 - 2988, The parser is
recording every property occurrence in PropertySourceOrder even when Properties
(the Properties dictionary) is later overwritten, causing the compiler loop to
emit conflicting OP_DEFINE_METHOD_PROP/OP_DEFINE_DATA_PROP for the same static
key; update the parser (in the object literal handling around
PropertySourceOrder/Properties/PropertyOrder and the IsMethod logic) to avoid
adding duplicate static-key entries to PropertySourceOrder (or mark them as
skipped) when Properties already contains the key (i.e., when
Properties.ContainsKey(Key) is true you should not append another pstStatic
entry), so the compiler that iterates PropertySourceOrder will only see the
final effective definition for each static key (alternatively add a de-dup pass
in the compiler loop before emitting OP_DEFINE_* instructions to skip
already-processed StaticKey values).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@source/units/Goccia.Compiler.Expressions.pas`:
- Around line 2457-2461: The code trusts AIsMethod only when choosing DefineOp,
causing synthetic or unordered literals where the value is a
TGocciaMethodExpression to be emitted as OP_DEFINE_DATA_PROP; update the
decision before calling EmitDefineDataPropertyByName to set DefineOp to
OP_DEFINE_METHOD_PROP if AIsMethod is true OR the value expression is a
TGocciaMethodExpression (inspect the value node represented by ValReg / the AST
node for the value), otherwise use OP_DEFINE_DATA_PROP; adjust the logic in the
method containing AIsMethod/DefineOp (the block that calls
EmitDefineDataPropertyByName with ACtx, ADest, AKey, ValReg) so method semantics
are derived from the value expression as well.

---

Outside diff comments:
In `@source/units/Goccia.Parser.pas`:
- Around line 2920-2988: The parser is recording every property occurrence in
PropertySourceOrder even when Properties (the Properties dictionary) is later
overwritten, causing the compiler loop to emit conflicting
OP_DEFINE_METHOD_PROP/OP_DEFINE_DATA_PROP for the same static key; update the
parser (in the object literal handling around
PropertySourceOrder/Properties/PropertyOrder and the IsMethod logic) to avoid
adding duplicate static-key entries to PropertySourceOrder (or mark them as
skipped) when Properties already contains the key (i.e., when
Properties.ContainsKey(Key) is true you should not append another pstStatic
entry), so the compiler that iterates PropertySourceOrder will only see the
final effective definition for each static key (alternatively add a de-dup pass
in the compiler loop before emitting OP_DEFINE_* instructions to skip
already-processed StaticKey values).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d123423a-9cca-4e28-aff1-372393080fa0

📥 Commits

Reviewing files that changed from the base of the PR and between a247240 and f854839.

📒 Files selected for processing (8)
  • docs/bytecode-vm.md
  • source/units/Goccia.AST.Expressions.pas
  • source/units/Goccia.Bytecode.OpCodeNames.pas
  • source/units/Goccia.Bytecode.pas
  • source/units/Goccia.Compiler.Expressions.pas
  • source/units/Goccia.Parser.pas
  • source/units/Goccia.VM.pas
  • tests/language/classes/scope-walk-function-boundary.js
✅ Files skipped from review due to trivial changes (1)
  • docs/bytecode-vm.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • source/units/Goccia.Bytecode.OpCodeNames.pas
  • source/units/Goccia.VM.pas

Comment thread source/units/Goccia.Compiler.Expressions.pas Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/language/objects/basic-object-creation.js (1)

88-104: ⚡ Quick win

Suppress the Biome duplicate-key warning.

The duplicate value key at lines 96-99 is intentional test behavior to verify object literal define semantics handle duplicate keys correctly (final definition wins). The static analysis warning is a false positive.

🔕 Proposed suppression comment

Add a suppression comment before the object literal:

   };
 
+  // biome-ignore lint/suspicious/noDuplicateObjectKeys: intentionally testing duplicate key behavior
   const obj = {
     value() {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/language/objects/basic-object-creation.js` around lines 88 - 104, This
test intentionally uses duplicate static object keys in the test "duplicate
static object keys evaluate final definition once" (see the obj literal with
duplicate key value and the helper function mark), so suppress the Biome
duplicate-key warning by adding the appropriate suppression comment immediately
before the object literal; keep the comment scoped to that literal so the
duplicate behavior is preserved for the test and no other warnings are globally
disabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/language/objects/basic-object-creation.js`:
- Around line 88-104: This test intentionally uses duplicate static object keys
in the test "duplicate static object keys evaluate final definition once" (see
the obj literal with duplicate key value and the helper function mark), so
suppress the Biome duplicate-key warning by adding the appropriate suppression
comment immediately before the object literal; keep the comment scoped to that
literal so the duplicate behavior is preserved for the test and no other
warnings are globally disabled.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c6c379b2-cf8d-40cf-a559-74cebee7d482

📥 Commits

Reviewing files that changed from the base of the PR and between f854839 and de73b5d.

📒 Files selected for processing (5)
  • source/units/Goccia.AST.Expressions.pas
  • source/units/Goccia.Compiler.Expressions.pas
  • source/units/Goccia.Evaluator.pas
  • source/units/Goccia.Parser.pas
  • tests/language/objects/basic-object-creation.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • source/units/Goccia.AST.Expressions.pas
  • source/units/Goccia.Parser.pas

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
source/units/Goccia.Evaluator.pas (1)

1451-1452: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Don't skip overwritten data-property initializers.

Line 1451 now bypasses evaluation entirely, but Lines 1458-1461 rehydrate static properties from AObjectExpression.Properties, which is already deduplicated by key. For { a: sideEffect(1), a: sideEffect(2) }, the earlier initializer never runs, so its side effects disappear instead of just being overwritten. Object literals still need to evaluate each property definition in source order; only the final descriptor should win. This likely needs the source-order entry to carry its own expression node instead of looking it up through the deduplicated map.

Also applies to: 1458-1461

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/units/Goccia.Evaluator.pas` around lines 1451 - 1452, The loop over
AObjectExpression.PropertySourceOrder must still evaluate every source-order
property definition (to preserve side effects) even when the property was
deduplicated; stop using "if ... Skip then Continue" to bypass evaluation.
Instead, evaluate the expression node carried by the source-order entry (add or
use a field like PropertySourceOrder[].Expression) for each entry in source
order, then, separately, use AObjectExpression.Properties (the deduplicated map)
only to pick the final property descriptor to assign to the resulting object;
update the rehydration logic around the current use of
AObjectExpression.Properties so it only applies descriptors but does not replace
evaluation of skipped entries.
source/units/Goccia.Parser.pas (2)

2013-2028: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the async-function start position before consuming the optional name.

Token gets reused for the identifier, so named async function foo(){} / async function* foo(){} expressions end up calling ParseFunctionBodyExpression and ExtractSourceRange from foo instead of from async. That truncates SourceText and shifts the function node’s location metadata.

Suggested fix
-              Name := '';
+              Line := Token.Line;
+              Column := Token.Column;
+              Name := '';
               if Check(gttIdentifier) then
               begin
                 Token := Advance;
                 ValidateIdentifierBinding(Token);
                 Name := Token.Lexeme;
               end;
               CollectGenericParameters;
-              Result := ParseFunctionBodyExpression(Token.Line, Token.Column, True, IsGenerator);
-              TGocciaFunctionExpression(Result).SourceText := ExtractSourceRange(Token.Line, Token.Column);
+              Result := ParseFunctionBodyExpression(Line, Column, True, IsGenerator);
+              TGocciaFunctionExpression(Result).SourceText := ExtractSourceRange(Line, Column);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/units/Goccia.Parser.pas` around lines 2013 - 2028, The async-function
start position is lost when you Advance into the optional identifier (Token is
reused), so capture the async start Token (or its Line/Column) before calling
Check/Advance for the name: when entering the async function handling code, save
the current Token (or Token.Line/Token.Column) into a local variable (e.g.
AsyncStartTokenLine/AsyncStartTokenColumn or StartToken) before calling
Advance/ValidateIdentifierBinding/CollectGenericParameters; then pass those
saved start coordinates into ParseFunctionBodyExpression and use them with
ExtractSourceRange and when assigning
TGocciaFunctionExpression(SourceText)/location fields so the function node
reflects the async keyword position rather than the identifier position.

2975-2997: ⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

Don’t discard earlier duplicate property initializers.

This path overwrites Properties[Key] and then marks the earlier source-order entry as skipped, so duplicate data properties lose the earlier value expression entirely. For { a: f(), a: g() }, the AST no longer has any way to evaluate f(), even though ECMAScript still evaluates both property definitions in order and only lets the final descriptor win. The source-order representation needs to retain each static property’s original Value node, not just the deduplicated key.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/units/Goccia.Parser.pas` around lines 2975 - 2997, The current logic
overwrites Properties[Key] and marks earlier PropertySourceOrder entries as
Skip, losing earlier static property Value nodes; instead ensure every static
property still appends a PropertySourceOrder entry that preserves its Value
expression so earlier initializers can be evaluated in source order while
Properties[Key] reflects the final value. Concretely: stop setting
PropertySourceOrder[OrderIndex].Skip for earlier static entries and do not
discard their Value nodes — store the Value in the PropertySourceOrder record
for pstStatic (add a field if needed) and always
Inc(SourceOrderCount)/SetLength/assign PropertySourceOrder[SourceOrderCount-1]
with PropertyType = pstStatic, StaticKey = Key and the Value node; maintain
Properties[Key] as the last seen value and keep PropertyOrder as-is for
insertion tracking.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@source/units/Goccia.Evaluator.pas`:
- Around line 1451-1452: The loop over AObjectExpression.PropertySourceOrder
must still evaluate every source-order property definition (to preserve side
effects) even when the property was deduplicated; stop using "if ... Skip then
Continue" to bypass evaluation. Instead, evaluate the expression node carried by
the source-order entry (add or use a field like
PropertySourceOrder[].Expression) for each entry in source order, then,
separately, use AObjectExpression.Properties (the deduplicated map) only to pick
the final property descriptor to assign to the resulting object; update the
rehydration logic around the current use of AObjectExpression.Properties so it
only applies descriptors but does not replace evaluation of skipped entries.

In `@source/units/Goccia.Parser.pas`:
- Around line 2013-2028: The async-function start position is lost when you
Advance into the optional identifier (Token is reused), so capture the async
start Token (or its Line/Column) before calling Check/Advance for the name: when
entering the async function handling code, save the current Token (or
Token.Line/Token.Column) into a local variable (e.g.
AsyncStartTokenLine/AsyncStartTokenColumn or StartToken) before calling
Advance/ValidateIdentifierBinding/CollectGenericParameters; then pass those
saved start coordinates into ParseFunctionBodyExpression and use them with
ExtractSourceRange and when assigning
TGocciaFunctionExpression(SourceText)/location fields so the function node
reflects the async keyword position rather than the identifier position.
- Around line 2975-2997: The current logic overwrites Properties[Key] and marks
earlier PropertySourceOrder entries as Skip, losing earlier static property
Value nodes; instead ensure every static property still appends a
PropertySourceOrder entry that preserves its Value expression so earlier
initializers can be evaluated in source order while Properties[Key] reflects the
final value. Concretely: stop setting PropertySourceOrder[OrderIndex].Skip for
earlier static entries and do not discard their Value nodes — store the Value in
the PropertySourceOrder record for pstStatic (add a field if needed) and always
Inc(SourceOrderCount)/SetLength/assign PropertySourceOrder[SourceOrderCount-1]
with PropertyType = pstStatic, StaticKey = Key and the Value node; maintain
Properties[Key] as the last seen value and keep PropertyOrder as-is for
insertion tracking.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5e97d53b-82f9-4f6b-9ec5-0f4e88af8a32

📥 Commits

Reviewing files that changed from the base of the PR and between 348247d and 0605c5b.

📒 Files selected for processing (11)
  • docs/decision-log.md
  • docs/language.md
  • docs/value-system.md
  • source/units/Goccia.AST.Expressions.pas
  • source/units/Goccia.AST.Statements.pas
  • source/units/Goccia.Compiler.Expressions.pas
  • source/units/Goccia.Compiler.Statements.pas
  • source/units/Goccia.Compiler.pas
  • source/units/Goccia.Evaluator.pas
  • source/units/Goccia.Parser.pas
  • source/units/Goccia.Types.Enforcement.pas
✅ Files skipped from review due to trivial changes (2)
  • docs/value-system.md
  • docs/decision-log.md

@frostney frostney merged commit 51ff745 into main May 20, 2026
14 checks passed
@frostney frostney deleted the t3code/issue-649 branch May 20, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation internal Refactoring, CI, tooling, cleanup spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use define semantics for object literals in bytecode mode

1 participant