)]}'
{
  "log": [
    {
      "commit": "0eba3a2a339ab82ff2bd3448ab6c7d83eadd5027",
      "tree": "8e1c1d6fe9b4142c2146be021875c1216e5bd767",
      "parents": [
        "64f128f87f3ec3b50870dd3172e471c080f803e4"
      ],
      "author": {
        "name": "Akshat Lakhera",
        "email": "akshatlnct2024@gmail.com",
        "time": "Tue Oct 20 06:28:21 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 20 06:28:21 2026"
      },
      "message": "LegalizeJSInterface: Pick unique names for generated stubs (#9276)\n\nLegalizeJSInterface could read freed memory when the module already\ncontained a function with the name it wanted to give a generated stub.\n\nFor each illegal import, makeLegalStubForCalledImport builds two\nfunctions, a stub named legalfunc$ plus the import name and an import\nnamed legalimport$ plus the import name, and returns a raw pointer to\nthe stub. The caller stores that pointer in illegalImportsToLegal, and\nFixer::visitCall later uses it to rewrite calls.\n\nBoth functions were only added to the module when no function with that\nname already existed. When one did exist (in the issue, a user function\ncalled $legalfunc$imp), the stub was not added, so its unique_ptr freed\nit when the function returned. The pointer saved in\nillegalImportsToLegal then pointed at freed memory, and Fixer::visitCall\nread it. That\u0027s the heap-use-after-free in the report, and with a\nRelease build the repro segfaults.\n\nThe stub and the legalimport function now get their names from\nNames::getValidFunctionName, which returns the requested name if it\u0027s\nfree and otherwise adds a numeric suffix. Since the names are now always\nunique, both functions are always added and the \"only if absent\" checks\nare gone, so the stored pointer always refers to a function owned by the\nmodule. makeLegalStubForCalledImport is called once per illegal import,\nso this doesn\u0027t create duplicate stubs. Modules without a name collision\nget the same names as before.\n\nFixes #9243"
    },
    {
      "commit": "64f128f87f3ec3b50870dd3172e471c080f803e4",
      "tree": "21c61e4c7036b0276d29e8939e44f3e0d43f445f",
      "parents": [
        "ed1fb9d29f9355d703f3f2344e072db01d506868"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Mon Oct 19 20:14:28 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 19 20:14:28 2026"
      },
      "message": "[GTO] Avoid newly exposing prototypes when supertype fields are removed (#9278)\n\nWhen GlobalTypeOptimization removes all fields from a non-empty\nsupertype descriptor, a subtype descriptor whose unread supertype fields\nare also removed can shift a subsequent externref field to index 0.\nCheck whether the supertype retained any kept fields after removal\n(!superHasKeptFields) rather than checking whether the unoptimized\nsupertype had empty fields (!super-\u003egetStruct().fields.empty()) when\ndeciding whether to insert an i8 placeholder at index 0 for\nexposedNoProtoDescs."
    },
    {
      "commit": "ed1fb9d29f9355d703f3f2344e072db01d506868",
      "tree": "21abbd6e52228e8f95b1bab49addc7eded558915",
      "parents": [
        "ee75844135005f439bd97d056f067b052f297a83"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Mon Oct 19 19:49:38 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 19 19:49:38 2026"
      },
      "message": "[NFC] Do a string search using a character rather than a full string (#9277)\n\nThis may be slightly faster."
    },
    {
      "commit": "ee75844135005f439bd97d056f067b052f297a83",
      "tree": "dcbeec6b5c13d097b25d105106d966896b185763",
      "parents": [
        "d605ab34969dd8de74d01305a7821b744ee81e6d"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Mon Oct 19 17:19:35 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 19 17:19:35 2026"
      },
      "message": "Experimental Gemini Code Assist configuration (#9273)\n\nAdd configuration for the Gemini Code Assist GitHub app to experiment\nwith automatic code reviews. The hope is that this will especially help\nwith initial feedback for PRs from new contributors."
    },
    {
      "commit": "d605ab34969dd8de74d01305a7821b744ee81e6d",
      "tree": "0e57025040a6e4983136f396d6b94539c17f49a9",
      "parents": [
        "c98a53504f1469adfc9fa0371b2f11b1d3bff534"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Mon Oct 19 17:19:01 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 19 17:19:01 2026"
      },
      "message": "[Heap2Local] Refinalize when cmpxchg-to-get rewrite refines type (#9270)\n\nWhen a non-escaping allocation flows into the `expected` operand of a\n`struct.atomic.rmw.cmpxchg` or `array.atomic.rmw.cmpxchg`,\n`Struct2Local` rewrites the cmpxchg into a block ending with a\n`struct.atomic.get` or `array.atomic.get` on a scratch local holding\n`curr-\u003eref`. When `curr-\u003eref` has a null reference type, the original\ncmpxchg takes its result type from `curr-\u003ereplacement`, whereas the\nreplacement `struct.get` or `array.get` refines its result type to `(ref\nnone)`. Refinalize to propagate the refined type when this happens."
    },
    {
      "commit": "c98a53504f1469adfc9fa0371b2f11b1d3bff534",
      "tree": "2531c482df2992238efa05f2e36662a7282ba9d5",
      "parents": [
        "a631c1445ced72a905b3303b26f148fc706647dd"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Mon Oct 19 17:17:43 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 19 17:17:43 2026"
      },
      "message": "[wasm-shell] Use 1 GiB host memory limit in both init and growMemory (#9269)\n\nPreviously, `ShellExternalInterface::init` only checked for 64-bit\nbyte-size shift overflow and allocation failure, allowing modules with\ninitial memories larger than the interpreter\u0027s 1 GiB cap (`MaxMemorySize\n\u003d 1024 * 1024 * 1024`) to instantiate, while\n`ShellExternalInterface::growMemory` checked `newSize \u003e 1024 * 1024 *\n1024` and returned `false` (producing a Wasm `-1` result even for\n`memory.grow(0)`). When a module with an initial memory exceeding 1 GiB\n(or growing past 1 GiB while remaining within its declared maximum) was\nexecuted under differential fuzzing, the Binaryen interpreter returned\n`-1` from `memory.grow` while other VMs succeeded.\n\nCheck `bytes \u003e MaxMemorySize` in `ShellExternalInterface::init` and call\n`hostLimit(\"memory too large\")` in both `init` and `growMemory` when the\ninterpreter\u0027s 1 GiB allocation cap is exceeded so that\n`ExecutionResults` and differential fuzzing treat it as a host limit\nrather than a semantic divergence."
    },
    {
      "commit": "a631c1445ced72a905b3303b26f148fc706647dd",
      "tree": "7791ff1fa709bfa794180131e096fa8804f99d3a",
      "parents": [
        "b9f3a215a11089d985953c72d688ee41ea54c47e"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 16 20:03:53 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 16 20:03:53 2026"
      },
      "message": "[RemoveUnusedBrs] Skip BrOn when descriptor is unreachable (#9268)\n\nIn `RemoveUnusedBrs::optimizeGC`, `Optimizer` walks and optimizes `BrOn`\nexpressions bottom-up without running `ReFinalize` until the walk\ncompletes. When an inner `BrOn` in the `desc` operand of a\n`BrOnCastDescEq` or `BrOnCastDescEqFail` is optimized into an\nunconditional branch, `curr-\u003edesc-\u003etype` becomes `Type::unreachable`\nwhile `curr-\u003etype` still holds its old reference type. If the outer\n`BrOn` then refines `curr-\u003ecastType` and calls `curr-\u003efinalize()`,\n`curr-\u003etype` becomes `Type::unreachable`, causing `maybeCast(curr,\noldType)` to fail its reference-type assertion. Check `curr-\u003edesc \u0026\u0026\ncurr-\u003edesc-\u003etype \u003d\u003d Type::unreachable` in the early return at the start\nof `Optimizer::visitBrOn` alongside `curr-\u003eref-\u003etype \u003d\u003d\nType::unreachable`."
    },
    {
      "commit": "b9f3a215a11089d985953c72d688ee41ea54c47e",
      "tree": "88896b448a8ae9c6f69a9346c8140286826e915f",
      "parents": [
        "c8a002dde8726115fe0402f9f2e9962febcaf621"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Fri Oct 16 19:25:51 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 16 19:25:51 2026"
      },
      "message": "Fix missing SIMD validation error (#9267)\n\nFixes\nhttps://github.com/WebAssembly/binaryen/pull/9206#issuecomment-6196743667"
    },
    {
      "commit": "c8a002dde8726115fe0402f9f2e9962febcaf621",
      "tree": "13a65d4cc32ade26696b782e624ef23720d8b877",
      "parents": [
        "b459ff822321759b79ec561d633fa2d364cc3269"
      ],
      "author": {
        "name": "tamaron",
        "email": "20992019+tamaroning@users.noreply.github.com",
        "time": "Fri Oct 16 18:54:26 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 16 18:54:26 2026"
      },
      "message": "OptimizeInstructions: Check mayNotReturn when refining ref.cast under TNH (#9256)\n\nfix #9246"
    },
    {
      "commit": "b459ff822321759b79ec561d633fa2d364cc3269",
      "tree": "38245e58510385fe605ca41cb072c5b99801f4dc",
      "parents": [
        "29765863a6039991a7f94b2ea71d87400b39a2c4"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Fri Oct 16 15:39:15 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 16 15:39:15 2026"
      },
      "message": "Run mingw build in parallel (#9266)\n\nBefore this PR, the mingw task was the slowest.\n\nThis makes the job 2x faster, and no longer the slowest."
    },
    {
      "commit": "29765863a6039991a7f94b2ea71d87400b39a2c4",
      "tree": "6415976413e35f1294682ea2af888bc6a127abee",
      "parents": [
        "57ee9917b8dcbbf0c9c2ef176287ac6c798394c4"
      ],
      "author": {
        "name": "Goktug Gokdogan",
        "email": "goktug@google.com",
        "time": "Thu Oct 15 15:48:59 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 15 15:48:59 2026"
      },
      "message": "Lower constant array.new_data in OptimizeInstructions (#9248)\n\narray.new_data is not a constant expression, which blocks optimizations\nsuch as hoisting array literals into immutable globals, and passes like\nPrecompute, Heap2Local, GUFA and SimplifyGlobals don\u0027t understand it.\n\nWhen the offset and size are constant and in bounds of a passive\nsegment, lower it to:\n\n  * array.new_default, if all elements are zero\n  * array.new, if all elements are equal\n  * array.new_fixed, if there are at most 64 elements\n\nNon-empty slices are only lowered with --traps-never-happen, since\narray.new_data traps if the segment was dropped. An empty slice at\noffset 0 can never trap, so it is always lowered.\n\nThe 64-element limit exists because array.new_fixed costs a full\n*.const per element, while a data segment stores raw bytes. On large\nJ2Wasm applications this removes over 99.7% of passive data segments and\nreduces binary size by ~1.8% (~1.3% gzipped)."
    },
    {
      "commit": "57ee9917b8dcbbf0c9c2ef176287ac6c798394c4",
      "tree": "787e1d6ca9c2461215d17a022fcc209c01367c1b",
      "parents": [
        "a885222570e7b794c6580bc7107f8366546ddf57"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Oct 14 22:14:47 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 14 22:14:47 2026"
      },
      "message": "Fuzzer: Emit SIMD lane load and store instructions (#9206)\n\nAdd makeSIMDLoadStoreLane and call it from _makenone, makeSIMD,\nmakeNonAtomicLoad, and makeNonAtomicStore. Also guard makeSIMDLoad with\nallowMemory."
    },
    {
      "commit": "a885222570e7b794c6580bc7107f8366546ddf57",
      "tree": "321df886b161fce80c83205607a642e660e31edc",
      "parents": [
        "74d78de607e03a62193511306f3da094e8f027f1"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Wed Oct 14 15:58:28 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 14 15:58:28 2026"
      },
      "message": "ConstraintAnalysis: Optimize self-comparisons (x ? x) (#9252)\n\nEven with no known constraints on `x`, we can evaluate things like\n`x \u003d\u003d x` and `x \u003c x`.\n\nFixes #7672"
    },
    {
      "commit": "74d78de607e03a62193511306f3da094e8f027f1",
      "tree": "e768bbec76cc3f26e536526ccbfa957c81faaa67",
      "parents": [
        "91d343741e6e6acc8f0fdc1b9cbd5173c68c7247"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Oct 14 01:50:12 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 14 01:50:12 2026"
      },
      "message": "Fuzzer: Emit table.size and table.grow (#9205)\n\nAdd makeTableSize and makeTableGrow and include them in _makeConcrete\nwhen generating an integer matching any table\u0027s address type. Also cap\ntable-\u003emax at ReasonableMaxTableSize instead of kUnlimitedSize in\nfinalizeTable so table.grow cannot allocate unbounded memory during\nfuzzing."
    },
    {
      "commit": "91d343741e6e6acc8f0fdc1b9cbd5173c68c7247",
      "tree": "b5ac10d38b20ac3d0debad7f31b957fe30b20900",
      "parents": [
        "ca1cf60a6b41fbb20c4d0c1bfb98523b9cabe8ee"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Oct 14 00:40:52 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 14 00:40:52 2026"
      },
      "message": "Fuzzer: Emit memory.size and memory.grow (#9204)\n\nAdd makeMemorySize and makeMemoryGrow and include them in _makeConcrete\nwhen generating an integer matching the memory address type."
    },
    {
      "commit": "ca1cf60a6b41fbb20c4d0c1bfb98523b9cabe8ee",
      "tree": "1163b8dd9f3b445b41ee1fbe43cbce6f9dc5ba9a",
      "parents": [
        "0b8d88ee62b8f248ee8cf7ff094666c1667778ab"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Tue Oct 13 23:45:55 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 13 23:45:55 2026"
      },
      "message": "[ConstraintAnalysis] Fix asymmetry in provesPair overlap check (#9258)\n\nFixes `provesPair` to symmetrically check disjointness using proven\nspans rather than exact spans, since a disjoint superset implies\ndisjoint subsets. This addresses an assertion failure in `approximateOr`\nwhere asymmetric comparison of constraints incorrectly produced an\nOR-induced contradiction.\n\nRemoves unreachable `empty()` span checks in `provesPair` since empty\nspans are only produced by immediate contradictions, which are evaluated\nto contradictions prior to reaching `provesPair`."
    },
    {
      "commit": "0b8d88ee62b8f248ee8cf7ff094666c1667778ab",
      "tree": "5b9b774b0d9bfa614bb7aa1950d7882800660f01",
      "parents": [
        "99482c7a18f4f1b3db8cf965426a50af91c5bf2c"
      ],
      "author": {
        "name": "Brendan Dahl",
        "email": "brendan.dahl@gmail.com",
        "time": "Tue Oct 13 21:26:46 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 13 21:26:46 2026"
      },
      "message": "Parallelize initial content wasm test conversion with ThreadPool (#9077)\n\n- Convert initial wasm tests in memory using ThreadPool and stdin/stdout\npiping\n- Add add_bytes_to_tar helper and write initial/num.txt in memory\nwithout disk I/O\n- Stream initial content directly into the tar archive with in-place\nprogress output\n\nReduces test_cluster_fuzz test runtime from ~265s to ~76s (~3.5x\nfaster),\nwith bundling time dropping from ~125s to ~24s (~5x faster)."
    },
    {
      "commit": "99482c7a18f4f1b3db8cf965426a50af91c5bf2c",
      "tree": "b25d1010d731141977efd27e27487b160e67ccaf",
      "parents": [
        "eb441bad531da98711267fe6ed4ede2fc5f7294e"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Tue Oct 13 17:45:25 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 13 17:45:25 2026"
      },
      "message": "[subtype-exprs] Fix nullability for extern conversions (#9255)\n\nThe SubtypingDiscoverer previously assigned a hardcoded Nullable\nexpected subtype to the input of ExternConvertAny and no expected\nsubtype to the input of AnyConvertExtern. However, both of these\ninstructions preserve the nullability of their inputs, meaning their\nrequired input nullability depends on the expected output nullability.\n\nThis issue caused passes like StripRefiningCasts to strip valid,\nnon-redundant non-null casts (ref.as_non_null or ref.cast) from the\ninputs to these operations when a non-nullable result was expected. That\nwould leave the AnyConvertExtern or ExternConvertAny yielding a nullable\ntype in a context requiring a non-nullable type, causing WebAssembly\nvalidation errors.\n\nThis fix updates SubtypingDiscoverer::visitRefAs to constrain the input\nof both AnyConvertExtern and ExternConvertAny according to the\nnullability of the instruction\u0027s own type constraint."
    },
    {
      "commit": "eb441bad531da98711267fe6ed4ede2fc5f7294e",
      "tree": "7c535ba3d8280ac3fb1d5bea2320fa444c12e52d",
      "parents": [
        "0edef6462d5cf04f1f01d0878a2342bfd50f332a"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Tue Oct 13 17:03:49 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 13 17:03:49 2026"
      },
      "message": "[GSI] Cast globals to the operand type of struct.get (#9254)\n\nWhen optimizing a `struct.get` or `ref.get_desc` against an immutable\nglobal in closed-world mode, the pass replaces the struct reference with\na `global.get`. However, a global\u0027s declared type can be a strict\nsupertype of its initializer. If the instruction attempts to access a\nfield that exists on the initializer\u0027s subtype but not on the global\u0027s\nsupertype, or that has a less refined field type in the global\u0027s\nsupertype, the resulting code may be invalid. Fix the bug by explicitly\ninserting a `ref.cast` around the `global.get` when necessary."
    },
    {
      "commit": "0edef6462d5cf04f1f01d0878a2342bfd50f332a",
      "tree": "7acae60fa0d7ed9a8ef2387d43eadf1c25c148cd",
      "parents": [
        "5c4a31dcf0238e322a1b1e2be80c032545808603"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Mon Oct 12 22:48:14 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 12 22:48:14 2026"
      },
      "message": "wasm2js: Populate functionsCallableFromOutside after optimization passes (#9251)\n\nWhen Wasm2JSBuilder processes a module, lowering and optimization passes\nsuch as duplicate-function-elimination can merge functions together. If\nan exported function is merged into an unexported function, the export\nis redirected to the unexported function, and the original exported\nfunction is removed.\n\nPreviously, functionsCallableFromOutside was populated before running\nthese optimization passes. As a result, it contained the deleted\nfunction and failed to include the newly exported target function. When\nprocessFunction generated JavaScript, it treated the newly exported\nfunction as an internal function and omitted parameter and return value\ncoercions. If the function returned a boolean expression, it incorrectly\nreturned a JavaScript boolean instead of a WebAssembly i32 number,\nviolating the WebAssembly JS ABI.\n\nSimilarly, the legalstub functions that replace exports with i64\nparameters or results were not included in functionsCallableFromOutside,\nso were also not getting the required coercions.\n\nMoving the population of functionsCallableFromOutside to run after the\noptimization passes ensures that it correctly includes new exported\nstubs and functions that become exported due to merging, and properly\ngenerates coercions for them."
    },
    {
      "commit": "5c4a31dcf0238e322a1b1e2be80c032545808603",
      "tree": "1f557e39193e357358d7861a8cc161b4f28ba007",
      "parents": [
        "6de3a0bd2655952d8e08db4d03a6c7b4a3d7fde3"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Mon Oct 12 22:00:33 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 12 22:00:33 2026"
      },
      "message": "OptimizeInstructions: Don\u0027t turn memory.fill of 16 bytes into two 8-byte stores (#9253)\n\nIf the latter traps, the first has already written data, which is the\nwrong semantics.\n\nOnly do this if trapsNeverHappen.\n\nFixes #9180"
    },
    {
      "commit": "6de3a0bd2655952d8e08db4d03a6c7b4a3d7fde3",
      "tree": "606de83e7bb76d4c4d9086b43a7850716b9f3ad3",
      "parents": [
        "f091fecf6c6a9ae39632aa1923330a178a63d112"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 23:16:47 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 23:16:47 2026"
      },
      "message": "Flatten WeakTopologicalOrdering into a single entry vector (#9220)\n\nReplace the recursive std::variant/Cycle representation of\nWeakTopologicalOrdering with a single contiguous std::vector\u003cEntry\u003e\nwhere cycle ends store the header block and jump target index. This\navoids per-cycle vector allocations and recursive evaluation in\nWTOWorklist::run.\n\nBenchmark results across 16 WebAssembly modules (3 iterations,\ninterleaved):\n- --constraint-analysis:\n  - Geomean: 1.606s -\u003e 1.592s (-0.9%)\n  - Total time: 64.05s -\u003e 63.67s (-0.6%; faster on 11/16 modules)\n- --rse:\n  - Geomean: 0.871s -\u003e 0.852s (-2.2%)\n  - Total time: 26.03s -\u003e 25.39s (-2.5%; faster on 12/16 modules)"
    },
    {
      "commit": "f091fecf6c6a9ae39632aa1923330a178a63d112",
      "tree": "5bfe8d63bdb34104feed66b13d1bc83af68d8675",
      "parents": [
        "5799303e82f6cf5d00b4dd6f8eb03ba670027bc6"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 22:36:35 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 22:36:35 2026"
      },
      "message": "Fuzzer: Increase generation of tuple-valued wide arithmetic (#9203)\n\nFor i64 pair tuples in _makeConcrete, add makeWideIntExpression with\nVeryImportant weight (requiring Multivalue as well as WideArithmetic)\nalongside makeTupleMake instead of replacing it half the time with\ndefault weight. This increases generation of unextracted (i64, i64)\nwide arithmetic expressions by ~4.2x."
    },
    {
      "commit": "5799303e82f6cf5d00b4dd6f8eb03ba670027bc6",
      "tree": "f6289bd691227789a17600bf4f91929aaca98abc",
      "parents": [
        "7be09684aae1c5d6108b6b04ac49b7d08dff9b29"
      ],
      "author": {
        "name": "tamaron",
        "email": "20992019+tamaroning@users.noreply.github.com",
        "time": "Fri Oct 09 20:18:40 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 20:18:40 2026"
      },
      "message": "Mark memory.grow and table.grow as generative (#9227)\n\nmemory.grow and table.grow return the old size and increase it, so two\nidentical-looking instances can return different values.\n\nFixes #9181"
    },
    {
      "commit": "7be09684aae1c5d6108b6b04ac49b7d08dff9b29",
      "tree": "6709d160722acc04576eaff66f04523f0f59ce14",
      "parents": [
        "3a742a2f911c13c3909e259c43cb57d1c4f469b2"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 19:46:45 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 19:46:45 2026"
      },
      "message": "Fuzzer: Emit extern.convert_any instructions (#9202)\n\nGenerate extern.convert_any in makeBasicRef for HeapType::ext when GC is\nenabled."
    },
    {
      "commit": "3a742a2f911c13c3909e259c43cb57d1c4f469b2",
      "tree": "19bd460035d6cecbbaf87f2deb0a0c0956939bed",
      "parents": [
        "4095868d64d16259dfe8d7dded87b1ca5b39f578"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 18:59:03 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 18:59:03 2026"
      },
      "message": "wasm2js: Fix memory.grow semantics and return -1 on failure (#9223)\n\nPreviously, visitMemoryGrow checked `max \u003e initial` and emitted\n`wasm2js_trap()` when false. This incorrectly dropped the delta\nexpression\u0027s side effects and caused memory.grow to trap at runtime,\nwhich is invalid WebAssembly semantics. WebAssembly memory.grow never\ntraps.\n\nUnconditionally emit the WASM_MEMORY_GROW call in visitMemoryGrow, and\nadd needsMemoryGrow to emit the __wasm_memory_grow helper when\nmemory.grow is used in the module or when growable memory is imported\nor exported.\n\nAlso, when memory.grow fails at runtime (for example when exceeding\ndeclared memory maximum or passing invalid delta operands), return -1\ninstead of the previous memory size. Also ensure growing by 0 pages\nsucceeds and returns the previous memory size without reallocating the\nbuffer."
    },
    {
      "commit": "4095868d64d16259dfe8d7dded87b1ca5b39f578",
      "tree": "6eafcc700b08d0ae4fe59da6be374e31c7391c78",
      "parents": [
        "508116df73e71e576653c8f7560aad765b095c95"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 18:45:02 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 18:45:02 2026"
      },
      "message": "Fuzzer: Handle all traps in BranchHintPreservation (#9240)\n\nFor the purposes of fuzzing correct preservation of branch hints, a trap\ndue to an `unreachable` instruction is no different from e.g. a trap due\nto a divide by zero."
    },
    {
      "commit": "508116df73e71e576653c8f7560aad765b095c95",
      "tree": "02b01a4a222e133280567e2e86eb96dfd0541f3a",
      "parents": [
        "f082dd97f46ce26474c460b52ea484a9238c3955"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 18:34:59 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 18:34:59 2026"
      },
      "message": "Fuzzer: Emit elem.drop instructions (#9201)\n\nAdd makeElemDrop and call it from makeBulkMemory."
    },
    {
      "commit": "f082dd97f46ce26474c460b52ea484a9238c3955",
      "tree": "8ee02692224fb463dab1752bedf8ade0e217b07d",
      "parents": [
        "120bb7cc78e7fd624a9a3acdf8a0236032d542c5"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 18:17:10 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 18:17:10 2026"
      },
      "message": "Fast-path loop-free CFGs in WTOWorklist (#9219)\n\nWhen the CFG has no backedges (checked via CFGWalker::loopTops),\nevaluate queued blocks in a single reverse-postorder pass in\nWTOWorklist::run without constructing DomTree or\nWeakTopologicalOrdering.\n\nBenchmark results across 16 WebAssembly modules (3 iterations,\ninterleaved):\n- --constraint-analysis:\n  - Geomean: 1.610s -\u003e 1.606s (-0.2%)\n- Total time: 64.36s -\u003e 64.05s (-0.5%; dart_essentials: 2.92s -\u003e 2.59s,\n-11.6%)\n- --rse:\n  - Geomean: 0.870s -\u003e 0.871s (+0.1%)\n- Total time: 26.10s -\u003e 26.03s (-0.3%; dart_essentials: 2.00s -\u003e 1.71s,\n-14.4%)"
    },
    {
      "commit": "120bb7cc78e7fd624a9a3acdf8a0236032d542c5",
      "tree": "6a1260112b96de368e8e94a4af3c3047e6ae005b",
      "parents": [
        "d84f5b345e19fde9472c3726e39f4109b5394bd2"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Fri Oct 09 17:52:58 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 17:52:58 2026"
      },
      "message": "Add a flag to expect later toolchain opts, and use it to know which are the last opts (#9238)\n\nIt is sometimes useful to know when we are in the \"last stretch\" of\noptimizations. We can do things there which are helpful but that\nwhich might inhibit later opts, because there are no later opts - so\nthe usual carefulness we apply can be put aside. For example,\nif two functions are identical, and one is marked `@binaryen.js.called`,\nthen we can technically merge them - but we did not, because that\nhas downsides (specifically, after the merge, we can no longer\noptimize calls to the unmarked function as well as before - now all\ncalls go to a js.called target, so we must preserve stuff for JS). But,\nif we knew when we are in the last stretch of opts, we could just\nmerge. (See the added test for concrete details.)\n\nThis PR adds a way to do that, initially to fix this js.called issue,\nbut we have a bunch more things that could benefit. First, there\nis now a flag `--expect-later-toolchain-opts`. If set, then we\nassume more wasm-opt invocations will happen later, or some\nother optimizing toolchain, so we cannot assume anything we do\nis in the final set of opts. A toolchain might do this:\n\n```\nwasm-opt -O3 -O3 --expect-later-toolchain-opts\nwasm-opt -O3 -O3 --expect-later-toolchain-opts\nwasm-opt -O3 -O3\n``` \n\nThe first two invocations use the flag to hint to wasm-opt that\nthere are more invocations later.\n\nSecond, if this flag was not passed - so there are no more toolchain\nopts - then we identify the \"last set\" of opts, and mark a new internal\nflag\n\"lastOpts\". If we get\n\n```\nwasm-opt -O3 -O3 -O3\n``` \n\nthen the last of these is the \"last set\". Only then are we comfortable\nto apply optimizations that hinder other optimizations, because no\nmajor optimizations happen after.\n\nThese two things, together, should let us reliably identify the set of\nlast opts, both in the case of multiple wasm-opt invocations and not.\n\nOne risk here is if someone does\n\n```\nwasm-opt -O3 -O3\nwasm-opt -O3 -O3\nwasm-opt -O3 -O3\n``` \n\ni.e. 3 invocations as before, but without the flag on the first two.\nIn this case we assume the lasst `-O3` in each is the last set of\nopts, which might have a downside for the others. I think this\nrisk is reasonable: multi-stage pipelines like this are rarer, and\nthose toolchain authors need to be careful in using wasm-opt\nthere. But also, the downside of getting this wrong is not huge:\nthis is basically a hint to prefer some opts over others, but no\nmajor set of opts is missed."
    },
    {
      "commit": "d84f5b345e19fde9472c3726e39f4109b5394bd2",
      "tree": "50b0e03b0cf0ef9d4ed24ef5c337ba9212ebb440",
      "parents": [
        "c0aee78a288f6741ab3dda1fb3d50bdfac7a440f"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 17:32:06 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 17:32:06 2026"
      },
      "message": " CFGWalker: Fix delegate through try_table (#9239)\n\nWhen searching `tryStack` for the outer target of a `try-delegate` in\n`CFGWalker::doEndThrowingInst`, use `dynCast\u003cTry\u003e` instead of\n`cast\u003cTry\u003e` because intermediate `try_table` expressions may also be on\nthe stack."
    },
    {
      "commit": "c0aee78a288f6741ab3dda1fb3d50bdfac7a440f",
      "tree": "acdb6c8079211dc2414c73c8c9238ff68e47a3a2",
      "parents": [
        "233ae9c242d37107066db05a52b4feb77eabb272"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 17:21:34 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 17:21:34 2026"
      },
      "message": "Fix uncastable types in TypeRefiningGUFA (#9242)\n\nWhen computing refined struct field types in TypeRefiningGUFA,\nuncastable types (e.g.  continuation types) were previously being\nrefined when their LUB was the basic continuation type `cont` (because\n`isContinuation()` only checks for user-defined continuation types), or\nwhen an initially null/empty GUFA type was widened to a non-null\ncontinuation type by global `struct.new` operands or supertype\npropagation. Check `!lub.isCastable() \u0026\u0026 !lub.isNull()` after global\nrestrictions and supertype propagation to keep the original field type\nwhenever a field\u0027s LUB is a non-null uncastable type, while still\nallowing refinement to null bottom types that `WriteUpdater` can\nmaterialize directly with `ref.null`."
    },
    {
      "commit": "233ae9c242d37107066db05a52b4feb77eabb272",
      "tree": "1f32da1b49ccef9423ed120dd2f98fa095ddc8b0",
      "parents": [
        "78dab1e09dba0ab8207d01174a36c12bc3ff60f4"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 17:01:52 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 17:01:52 2026"
      },
      "message": "Collapse inner loops with union-find during WTO construction (#9241)\n\nDuring reverse-RPO natural loop discovery in WeakTopologicalOrdering,\ncollapse each discovered loop body into its header using union-find with\npath compression, and skip over already-collapsed inner loops when\nwalking immediate dominators in dominates(). This prevents outer loops\nfrom re-traversing inner loop bodies, bounding natural loop discovery to\nO(E alpha(N)) instead of O(N * depth) on deeply nested loops.\n\nBenchmark results across 16 WebAssembly modules (3 iterations,\ninterleaved):\n- --constraint-analysis:\n  - Geomean: 1.576s -\u003e 1.564s (-0.7%)\n  - Total time: 62.82s -\u003e 62.40s (-0.7%)\n- --rse:\n  - Geomean: 0.859s -\u003e 0.853s (-0.7%)\n  - Total time: 25.40s -\u003e 25.06s (-1.3%)"
    },
    {
      "commit": "78dab1e09dba0ab8207d01174a36c12bc3ff60f4",
      "tree": "8605f741991c7312b85890a3b646d3eec1ff1ca0",
      "parents": [
        "7a65f762ddcb574cd1a8eec49d506a729e188882"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 17:00:45 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 17:00:45 2026"
      },
      "message": "Use BasicBlock::contents.index in DomTree (#9217)\n\nRead each basic block\u0027s reverse-postorder index from contents.index in\nDomTree instead of allocating and populating an\nunordered_map\u003cBasicBlock*, Index\u003e, and skip self-loop backedges\nimmediately with predIndex \u003e\u003d index. Update OnceReduction and\ntest/example/domtree.cpp to initialize contents.index, and remove the\nredundant index initialization loop in WeakTopologicalOrdering.\n\nBenchmark results across 16 WebAssembly modules (3 iterations,\ninterleaved):\n- --constraint-analysis:\n  - Geomean: 1.646s -\u003e 1.576s (-4.3%)\n  - Total time: 64.83s -\u003e 62.82s (-3.1%)\n- --rse:\n  - Geomean: 0.922s -\u003e 0.859s (-6.8%)\n  - Total time: 27.09s -\u003e 25.40s (-6.3%)"
    },
    {
      "commit": "7a65f762ddcb574cd1a8eec49d506a729e188882",
      "tree": "8357765f35db084318a818278c2764b876f798bb",
      "parents": [
        "3eff819e3bedb3f188deff145918cc8ed6bd29ec"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Fri Oct 09 16:09:42 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 16:09:42 2026"
      },
      "message": "SignatureRefining: Refine call_indirects (#9236)"
    },
    {
      "commit": "3eff819e3bedb3f188deff145918cc8ed6bd29ec",
      "tree": "d97367786828161aecd9131c34439bca367bf7ae",
      "parents": [
        "207bbaec4b300579115979fac92bca106bc972c9"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 05:04:28 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 05:04:28 2026"
      },
      "message": "Fuzzer: Emit try-delegate instructions (#9200)\n\nAdd try-delegate generation to TranslateToFuzzReader::makeTry and\nupdate fixAfterChanges to preserve DELEGATE_CALLER_TARGET on\ntry-delegates.\n\nAlso fix three bugs uncovered by fuzzing delegate and add regression\ntests:\n- Preserve concrete stack types on StackInst::Delegate in\n  StackIRGenerator.\n- Increment controlFlowDepth after printing the condition in\n  PrintSExpression::visitIf and pop catchIndexStack on\n  StackInst::Delegate in printStackIR.\n- Use dynCast\u003cTry\u003e() instead of cast\u003cTry\u003e() when walking tryStack in\n  CFGWalker."
    },
    {
      "commit": "207bbaec4b300579115979fac92bca106bc972c9",
      "tree": "4698dc120ff80c2617ea375a5528a0f49531e82b",
      "parents": [
        "611832f3397d49aef175bab4cf90b337df5f8f46"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Oct 09 03:17:36 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 09 03:17:36 2026"
      },
      "message": " Fuzzer: Emit more br_on_cast_desc_eq{_fail} (#9198)\n\nPreviously, br_on_cast_desc_eq and br_on_cast_desc_eq_fail were rarely\nemitted (~0.2 per module) because:\n1. makeBrOn had low selection weight despite covering 6 instructions.\n2. breakableStack searches stopped immediately on Type::none targets\n   (forcing br_on_null) and often lacked reference targets.\n3. Descriptor casts were only emitted when getSubType happened by\n   chance to pick a struct with a descriptor.\n\nFix this by:\n- Tracking described struct types by Shareability in describedTypes and\n  adding hasDescribedSubType / getDescribedSubType helpers.\n- Increasing makeBrOn weight to Important.\n- Preferring reference targets (especially those with described\n  subtypes) with randomness when searching breakableStack, and wrapping\n  in a new target block when makeBrOn is called for a reference type\n  without a suitable target.\n- Selecting BrOnCastDescEq and BrOnCastDescEqFail directly when\n  described subtypes are available instead of upgrading BrOnCast /\n  BrOnCastFail.\n\nAcross 200 fuzzer modules, this increases br_on_cast_desc_eq from 0.20\nto 2.69 per module (16.0% -\u003e 48.0% of modules) and\nbr_on_cast_desc_eq_fail from 0.18 to 2.88 per module (11.5% -\u003e 50.0% of\nmodules), while also increasing br_on_null from 27.40 to 34.46 per\nmodule."
    },
    {
      "commit": "611832f3397d49aef175bab4cf90b337df5f8f46",
      "tree": "7fed0b11fc3385b0dc822cc75f9865fb3868c759",
      "parents": [
        "c2b304d8c3271c5f2a96c3a6444ee50db287cb61"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Thu Oct 08 22:50:42 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 22:50:42 2026"
      },
      "message": "Interpreter: Fix delegate through try_table (#9234)\n\nWhen an exception is delegated to an outer scope via legacy\ntry-delegate, the interpreter would previously fail to propagate it\nthrough try_table to the delegate target."
    },
    {
      "commit": "c2b304d8c3271c5f2a96c3a6444ee50db287cb61",
      "tree": "2eba0ff666c76ff6e058fc85189222f59b72e1b4",
      "parents": [
        "57bc6bad9898a2178401d72c1d8af35bf8f2a914"
      ],
      "author": {
        "name": "Steven Fontanella",
        "email": "stevenfont@google.com",
        "time": "Thu Oct 08 22:13:07 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 22:13:07 2026"
      },
      "message": "Generate memory.atomic.wait with a 0 timeout in fuzzer (#9170)\n\nFollowup to #9012 to make `memory.atomic.wait` more similar to\n`struct.wait`. Probably fixes #8429, although we don\u0027t have a way to\nverify.\n\nPreviously we never attempted to generate `memory.atomic.wait`. In\naddition, if our seed file (e.g. from an existing test case) happened to\ncontain `memory.atomic.wait`, we had no guarantee that the resulting\nbinary wouldn\u0027t hang forever due to not being notified and having a\ntimeout of -1 or excessively long.\n\nChange the fuzzer to instead generate `memory.atomic.wait`, but force\nits timeout param to always be 0.\n\nAs a drive-by change, remove the hardcoded constant `ATOMIC_WAITS`,\nwhich was always `false`.\n\nTo verify, ran the fuzzer for 129k iterations with no issues. Also\nverified that `memory.atomic.wait` was generated with a 0 timeout in\nsome cases."
    },
    {
      "commit": "57bc6bad9898a2178401d72c1d8af35bf8f2a914",
      "tree": "4b078d2ab000246bb25f55a34cbb9250b1ae5be2",
      "parents": [
        "2f9f575abc471c49c44fcac38828e7fc70d0c4ed"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Thu Oct 08 17:51:52 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 17:51:52 2026"
      },
      "message": "Add a MarkNoReturn pass (#9229)\n\nThis adds the `@binaryen.noreturn` annotation where we can infer the\nfunction does not return. Other passes can then use that information.\n\nThis does not run by default yet. Design-wise, we don\u0027t want this to\nrun and add annotations, as then they need to be stripped by the user\n(that is, just adding these annotations now will add to binary size, for\nusers that don\u0027t run `--strip-toolchain-annotations`). "
    },
    {
      "commit": "2f9f575abc471c49c44fcac38828e7fc70d0c4ed",
      "tree": "d39ad8ff1b7546ea56400cabb0c0743cd3abbe02",
      "parents": [
        "64722e141b9796f2778b9cccfbfa6405eb5bcc7f"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Thu Oct 08 17:20:11 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 17:20:11 2026"
      },
      "message": "Fixes in coverage-diff.py (#9193)\n\nImprove error messages to include more details about potentially missing\nflags. Remove binaryen-lit from the example build commands because it is\nnot a build target. Fix the repo root to account for being two\ndirectories deep to fix the automatic search for coverage builds and\ndiffs."
    },
    {
      "commit": "64722e141b9796f2778b9cccfbfa6405eb5bcc7f",
      "tree": "f3964ae141ee7e85fd60a40c5046a0aaa0992b9e",
      "parents": [
        "93d6e9de7e1d99be22a49b8952426906a65df397"
      ],
      "author": {
        "name": "Jérôme Vouillon",
        "email": "jerome.vouillon@gmail.com",
        "time": "Thu Oct 08 15:51:55 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 15:51:55 2026"
      },
      "message": "[DAE] Recompute callers in each iteration (#9235)\n\nThe set of callers was computed once, in the first iteration. But\noptimizing functions between iterations can create new direct calls, for\nexample by turning a `call_ref` of a `ref.func` into a `call`. When the\nreturn type of the callee was later refined, these new callers were not\nrefinalized, which left stale types.\n\nRecompute the callers in each iteration, together with the calls. This\nis cheap, as each caller appears at most once per callee in the scan\nresults.\n\nFixes #9233."
    },
    {
      "commit": "93d6e9de7e1d99be22a49b8952426906a65df397",
      "tree": "f472ea9b6243ca8b7f41623196617edd45abcd67",
      "parents": [
        "6fddddf71fabf2c81f86b2541308c9bdc2dbf059"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Thu Oct 08 01:51:20 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 01:51:20 2026"
      },
      "message": "Use WTOWorklist in ConstraintAnalysis and RedundantSetElimination (#9216)\n\nReplace RPOQueue with WTOWorklist in ConstraintAnalysis and\nRedundantSetElimination so that loops stabilize before flow values\npropagate to downstream blocks. This avoids quadratic/cubic blowups on\nfunctions with sequential loops while also speeding up general\nworkloads.\n\nBenchmark results across 16 WebAssembly modules (3 iterations):\n- --constraint-analysis:\n  - esbuild.wasm: 381.60s -\u003e 7.59s (-98.0%, 50.3x speedup)\n  - 15 non-esbuild modules geomean: 1.564s -\u003e 1.487s (-4.9%)\n  - 15 non-esbuild modules total: 72.00s -\u003e 57.24s (-20.5%)\n  - All 16 modules geomean: 2.205s -\u003e 1.646s (-25.4%)\n  - All 16 modules total: 453.60s -\u003e 64.83s (-85.7%)\n- --rse:\n  - esbuild.wasm: \u003e600s (timeout) -\u003e 1.62s (\u003e370x speedup)\n  - 15 non-esbuild modules total: 26.40s -\u003e 25.47s (-3.5%)\n  - All 16 modules geomean: N/A -\u003e 0.922s (total: 27.09s)"
    },
    {
      "commit": "6fddddf71fabf2c81f86b2541308c9bdc2dbf059",
      "tree": "1e4ff72fca74c7951571d467789e91cf5314bd74",
      "parents": [
        "387259f2aef2ce7d73ce9367d7dc1cea336a0733"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Thu Oct 08 00:10:07 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 00:10:07 2026"
      },
      "message": "Do not read overwritten locals in TupleOptimization (#9213)\n\nWhen TupleOptimization splits a tuple local.set into several local.sets,\nif a set\u0027s value contained a get of a prior tuple element, that value\nwould previously have incorrectly been the updated rather than original\nelement. Avoid reading trampled values by copying the original values to\nscratch locals before starting to emit the sequence of local sets. Do so\nonly when there is interference that would make it necessary.\n\nFixes #9210."
    },
    {
      "commit": "387259f2aef2ce7d73ce9367d7dc1cea336a0733",
      "tree": "63d3eb76366b0a44e49f386ef114f1aba1116d2e",
      "parents": [
        "fcf7932da25098ff076b275a3b2ab7c16b3dd25f"
      ],
      "author": {
        "name": "tamaron",
        "email": "20992019+tamaroning@users.noreply.github.com",
        "time": "Thu Oct 08 00:01:11 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 00:01:11 2026"
      },
      "message": "AvoidReinterprets: Do not optimize atomic loads (#9228)\n\nFixes #9185"
    },
    {
      "commit": "fcf7932da25098ff076b275a3b2ab7c16b3dd25f",
      "tree": "3c0fbdef2997388bfca9efee0737429cac176780",
      "parents": [
        "a6f7285842984824d5e9608d466e12cecda4f591"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Oct 07 23:31:53 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 23:31:53 2026"
      },
      "message": "wasm2js: Support elem.drop (#9224)\n\nIn wasm2js, element segments are statically initialized into\nFUNCTION_TABLE at module startup, and table.init is not supported,\nso elem.drop has no observable effect and can be treated as a no-op."
    },
    {
      "commit": "a6f7285842984824d5e9608d466e12cecda4f591",
      "tree": "eee76537b21cf32c33bb152d1105bb3426c97e4b",
      "parents": [
        "bee0b57cf3b67c26fd1963cb424c6eb7d89880da"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Wed Oct 07 23:26:50 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 23:26:50 2026"
      },
      "message": "SignatureRefining: Do not entirely give up when seeing tables (#9231)\n\nPreviously this pass would just not run if even a single table was\npresent. Instead, skip types in tables/element segments.\n\nThis is important for e.g. Dart, which so far has gotten no benefit\nout of SignatureRefining, because they do use a few tables."
    },
    {
      "commit": "bee0b57cf3b67c26fd1963cb424c6eb7d89880da",
      "tree": "314949c2f3b70d83dd26c25001014bd165d95636",
      "parents": [
        "a63f313c1bda1351483f9b56ebc52354d6711100"
      ],
      "author": {
        "name": "Steven Fontanella",
        "email": "stevenfont@google.com",
        "time": "Wed Oct 07 22:11:09 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 22:11:09 2026"
      },
      "message": "Revert \"Fuzz waitqueue instructions (#9012)\" (#9230)\n\nReverts #9012. The fuzzing code for waitqueues is correct but it exposes\na bug with how waitqueues are handled in ctor-eval. Revert for now to\ndisable fuzzing while the underlying issue is fixed. The only flag\nguarding waitqueue instructions is `--shared-everything` which we don\u0027t\nwant to disable since it covers other features too."
    },
    {
      "commit": "a63f313c1bda1351483f9b56ebc52354d6711100",
      "tree": "24e8ed0436d00edea7679ee9615f8d4cc73f8db2",
      "parents": [
        "ceceed6ef32436a43c4e9ff15765b73086255654"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Oct 07 18:52:22 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 18:52:22 2026"
      },
      "message": "Add a dominator-tree WTO utility for reducible CFGs (#9215)\n\nAdd `src/cfg/wto.h` with `WeakTopologicalOrdering` (`WTO`) and\n`WTOWorklist` built on top of `DomTree`. In a reducible CFG ordered in\nreverse postorder, every cycle is a natural loop headed by a block that\ndominates all blocks in the cycle, allowing a Bourdoncle Weak\nTopological Ordering to be constructed directly from the dominator tree\nand natural loops of the CFG."
    },
    {
      "commit": "ceceed6ef32436a43c4e9ff15765b73086255654",
      "tree": "a457a0fe600db6d0146349413f30b80dc4149042",
      "parents": [
        "3297f90120045f3fff7b2d918593275391106229"
      ],
      "author": {
        "name": "tamaron",
        "email": "20992019+tamaroning@users.noreply.github.com",
        "time": "Wed Oct 07 17:59:42 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 17:59:42 2026"
      },
      "message": "GSI: Mark struct.new in elem and table initializer as unoptimizable (#9209)\n\nFixes #9183 "
    },
    {
      "commit": "3297f90120045f3fff7b2d918593275391106229",
      "tree": "0b71ebffb9eb60e19d3f15cb297620d8bdaa4c1b",
      "parents": [
        "b8e22b47d3034c4a886a7cd9776331bf31a268fd"
      ],
      "author": {
        "name": "tamaron",
        "email": "20992019+tamaroning@users.noreply.github.com",
        "time": "Wed Oct 07 17:52:52 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 17:52:52 2026"
      },
      "message": "LICM: Do not move generative code out of loops (#9226)\n\nFix https://github.com/WebAssembly/binaryen/issues/9184"
    },
    {
      "commit": "b8e22b47d3034c4a886a7cd9776331bf31a268fd",
      "tree": "9eea62d338aa58875ffe31a51457efdcc604e6e4",
      "parents": [
        "9edaabc1f8df1eeee3e0a8502a1bcca57969f014"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Wed Oct 07 16:09:44 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 16:09:44 2026"
      },
      "message": "Fuzzer: Respect the noInvokes flag when adding interposing invokes (#9221)\n\nnoInvokes already stopped us from emitting new invokes. We also emit\ncalls to invokes, basically adding more invoke executions, by\n\"interposing\" on exports - sticking a call in an export, where the call is to an\ninvoke. Respect the flag in that case too: if the user doesn\u0027t want the code\ngrowth of invokes, they don\u0027t want either new invokes or new calls to existing\ninvokes."
    },
    {
      "commit": "9edaabc1f8df1eeee3e0a8502a1bcca57969f014",
      "tree": "4503ba3d939a832acea0c194fd0414b984f6116c",
      "parents": [
        "a7a6b52c69f394f723583ae03ee46f0f77137a88"
      ],
      "author": {
        "name": "Brendan Dahl",
        "email": "brendan.dahl@gmail.com",
        "time": "Wed Oct 07 15:53:05 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 15:53:05 2026"
      },
      "message": "[multibyte] Encode typeidx before offset (#9222)\n\nThe multibyte array access proposal updated the binary format of memarg\nto place typeidx immediately after flags and before offset (flags:u32\ntypeidx:u32 offset:u32), matching the position of memidx in multi-memory\naccesses. Update the binary reader and writer accordingly.\n\nSee https://github.com/WebAssembly/multibyte-array-access/issues/10"
    },
    {
      "commit": "a7a6b52c69f394f723583ae03ee46f0f77137a88",
      "tree": "912b9872c5b0d1cca3c0054e355840fdf3e9cdb2",
      "parents": [
        "84692ae3d15e3c19823e36404c90b3f5977b1af8"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Tue Oct 06 20:40:00 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 06 20:40:00 2026"
      },
      "message": "Fuzzer: Add a flag to control the hang limit (#9214)\n\nSetting it to 0 disables hang limit checks, which is nice for fuzzers\nthat have their own timeout handling anyhow.\n\nTo expose this in a nice way, add a `setFuzzParams()` method on the\nfuzzer. And to make that simple, remove some ancient\n\"FuzzParamContext\" logic that was apparently an idea to have\nstacks of fuzz params. We never implemented that, so it seems better\nto remove all that complexity."
    },
    {
      "commit": "84692ae3d15e3c19823e36404c90b3f5977b1af8",
      "tree": "bc19a8e8c9ac12acfc88b98699eee2e6be28b9af",
      "parents": [
        "1d7748aa4ef48ac93f90712c2437ef88c6441389"
      ],
      "author": {
        "name": "Goktug Gokdogan",
        "email": "goktug@google.com",
        "time": "Tue Oct 06 19:55:52 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 06 19:55:52 2026"
      },
      "message": "Add StripRefiningCasts pass to eliminate redundant subtype casts and … (#9188)\n\n…null assertions\n\nIn traps-never-happen mode, values flowing into typed slots (locals,\nglobals, call parameters, function results, struct fields, array\nelements, control-flow branches and fallthroughs, etc.) and the inputs\nof `ref.test` often contain downcasts or non-null assertions where the\noperand already statically satisfies the required type.\n\nSuch casts can narrow the value beyond the slot type, and that narrower\ntype is information that refining passes (GUFA, signature-refining,\ntype-refining, local-subtyping, cfp-reftest, ...) can use to refine the\nslot itself or to resolve a `ref.test`. Instead of removing them in\n`OptimizeInstructions`, which runs throughout the pipeline, add a\nstandalone `StripRefiningCasts` pass (`--strip-refining-casts`) meant to\nrun late in the pipeline:\n\n- Uses `SubtypingDiscoverer` to find all value-flowing expression slots\nand removes `ref.cast` and `ref.as_non_null` when the uncast value is\nalready a subtype of all types required of that slot.\n- Removes `ref.cast` and `ref.as_non_null` on `ref.test` inputs when the\noutcome of the test is not determined by the input\u0027s type (otherwise\nleaving the test for `OptimizeInstructions` to resolve).\n- Preserves descriptor casts whose descriptor operand has side effects,\nand preserves casts on arguments to `call.without.effects` (which must\nmatch the parameters of the actual target rather than those of the\nintrinsic import)."
    },
    {
      "commit": "1d7748aa4ef48ac93f90712c2437ef88c6441389",
      "tree": "669c0c747582575f0c85f42560b2ac5ed8ef0a69",
      "parents": [
        "9d6999b6d3d43eb89c26916436cc5258ebc96b35"
      ],
      "author": {
        "name": "Brendan Dahl",
        "email": "brendan.dahl@gmail.com",
        "time": "Tue Oct 06 00:23:17 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 06 00:23:17 2026"
      },
      "message": "[multibyte] Support all array element types in the interpreter (#9115)\n\nSince primitive GC arrays are stored as raw byte buffers (#9051) the\ninterpreter now only needs to be updated to handle calculating the\neffective address with the offset.\n\nAlso fix a printing bug that only showed up once arrays of wider element\ntypes were executed: an unreachable access was printed as\ni32.load/i32.store regardless of its alignment, e.g. \"i32.load align\u003d8\",\nwhich fails validation. Print a type that is valid for the alignment, as\nwe do for loads from memory.\n\nAdd execution tests for all the valid element types (i8, i16, i32, i64,\nf32, f64, v128): a new lit exec test that runs them in the interpreter\nbefore and after optimization, new spec test modules that perform the\nsame accesses on arrays of each element type and cover the offset and\nalign immediates, and a ctor-eval test that evaluates multibyte stores\nand serializes the results back as elements. Also expand the validation\ntest with immutable non-i8 arrays, non-numeric element types, alignment\nand offset limits, and the feature requirement."
    },
    {
      "commit": "9d6999b6d3d43eb89c26916436cc5258ebc96b35",
      "tree": "5c4f855537c3c1db58b49a158439145f020a3ae1",
      "parents": [
        "36a0c5e49cb36c1747c797122bed83766bca52af"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Mon Oct 05 23:31:18 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 23:31:18 2026"
      },
      "message": "Fuzzer: Add a flag to avoid emitting invokes (#9212)\n\nBy default we emit invoker functions for things, basically new exports\nthat call functions that might not be called otherwise. This gets more\nthings to execute. However, in fuzzers like Fuzzilli, we don\u0027t want to\nadd this extra size to things, so add a flag to control it."
    },
    {
      "commit": "36a0c5e49cb36c1747c797122bed83766bca52af",
      "tree": "5f03ac1b662cebfb36297371db75648b8ec71ecc",
      "parents": [
        "5fcecf3318de449861e65d3940d185ad8d26facb"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Mon Oct 05 20:45:53 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 20:45:53 2026"
      },
      "message": "EffectAnalyzer: Do not reorder mayNotReturn with traps or global writes (#9211)\n\nExpressions that may not return (loops, atomic.wait, struct.wait) can\nfail to terminate, which would prevent a subsequent trap or global state\nwrite (including calls) from ever executing. Update\nEffectAnalyzer::orderedBefore to disallow reordering mayNotReturn with\ntraps or global writes, set mayNotReturn on AtomicWait, and clear\nloopEffects.mayNotReturn in LoopInvariantCodeMotion for the whole loop\nsummary.\n\nFixes #9182."
    },
    {
      "commit": "5fcecf3318de449861e65d3940d185ad8d26facb",
      "tree": "347eb73874b9ca8f1eabf4e89d37a2419382b33d",
      "parents": [
        "941e923299aa39c099e42c9b0af6b4393bfd5b91"
      ],
      "author": {
        "name": "Jérôme Vouillon",
        "email": "jerome.vouillon@gmail.com",
        "time": "Mon Oct 05 19:55:51 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 19:55:51 2026"
      },
      "message": "Read and write label names from the name section (#9166)\n\nThis is the only section of the Extended Name Section proposal which is\ncurrently not handled."
    },
    {
      "commit": "941e923299aa39c099e42c9b0af6b4393bfd5b91",
      "tree": "28e1623174ebcbe424892a1a34f9746d7585aa60",
      "parents": [
        "82439ad019a4f8eb1f118e600c5fa2dc96d39130"
      ],
      "author": {
        "name": "tamaron",
        "email": "20992019+tamaroning@users.noreply.github.com",
        "time": "Mon Oct 05 04:08:53 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 04:08:53 2026"
      },
      "message": "precompute: fix handling of bitselect and laneselect (#9208)\n\nFix #9207"
    },
    {
      "commit": "82439ad019a4f8eb1f118e600c5fa2dc96d39130",
      "tree": "63569547efbacbed14189b7ce53c529a08d13f3f",
      "parents": [
        "ee134268758cd537b7e7b5b07fbe259ae3fa2580"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Fri Oct 02 18:33:00 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 02 18:33:00 2026"
      },
      "message": "OptimizeNoReturn: Handle pops (#9197)"
    },
    {
      "commit": "ee134268758cd537b7e7b5b07fbe259ae3fa2580",
      "tree": "5673b84296c76039a23827637bcb5c1bb546f420",
      "parents": [
        "928796206f58c28675f6686f95dc10fa57703507"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Fri Oct 02 16:37:53 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 02 16:37:53 2026"
      },
      "message": "Instrinsic: binaryen.noreturn (#9189)\n\n#9169 refines the results of never-returning functions to bottom, but that\ndoes not help functions without a return value, or ones with MVP-typed\nreturn values (the mechanism there is to use an uninhabitable type).\n\nTo generalize that, add a new intrinsic, `@binaryen.noreturn`, which\nmeans the function does not return, and the optimizer can assume that.\nBy adding an intrinsic, users can annotate functions that the optimizer\ncannot infer the noreturnability of (complex logic, imports, etc.).\n\nThis PR adds the intrinsic + a pass that uses it: when a function is\nnoreturn, we can put an unreachable after all calls to it (like LLVM).\nA later PR will infer this intrinsic where possible (replacing code from\n#9169)."
    },
    {
      "commit": "928796206f58c28675f6686f95dc10fa57703507",
      "tree": "5793ee976eb8b7311309ebf2f3f3a576b1682153",
      "parents": [
        "f3ab99600941a36e5b03636fd6941d269a9f0de8"
      ],
      "author": {
        "name": "Goktug Gokdogan",
        "email": "goktug@google.com",
        "time": "Fri Oct 02 16:30:29 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 02 16:30:29 2026"
      },
      "message": "Check for side effects on descriptor in OptimizeInstructions::skipCast (#9190)\n\nIn traps-never-happen mode, `skipCast` removes casts whose type does not\nmatter to the parent, which it does for the operands of `ref.is_null`\n(with no required type) and `ref.eq` (requiring `eqref`). When the cast\nis a descriptor cast (`ref.cast_desc_eq`), removing it also removes its\ndescriptor operand, along with any side effects the operand has. For\nexample:\n\n```wat\n(ref.is_null (ref.cast_desc_eq (ref null $A) (local.get $x) (call $get)))\n```\n\nwas optimized to:\n\n```wat\n(ref.is_null (local.get $x))\n```\n\ndropping the call.\n\nCheck that the descriptor operand has no side effects before removing a\ndescriptor cast in skipCast."
    },
    {
      "commit": "f3ab99600941a36e5b03636fd6941d269a9f0de8",
      "tree": "7dacfbec5db20a933702d7855fef5e69c593a48f",
      "parents": [
        "6212e86b002ef0bd73cc1056bfe0695ffee5c69f"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Thu Oct 01 23:50:55 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 23:50:55 2026"
      },
      "message": "Clear loopTops in CFGWalker (#9191)\n\nCFGWalker clears all its local state when visiting a function, but it\npreviously did not clear loopTops. If CFGWalker were to be used in a\nnon-function-parallel pass, this would lead to dangling BasicBlock\npointers in loopTops. There does not happen to be such a use of\nCFGWalker today, but it is still worth fixing."
    },
    {
      "commit": "6212e86b002ef0bd73cc1056bfe0695ffee5c69f",
      "tree": "8f5c3d6a685d00d6da30b1cde80fbfcbce4324a1",
      "parents": [
        "b125d2e19542df72458bc916a2d0aa4bf72500fd"
      ],
      "author": {
        "name": "Steven Fontanella",
        "email": "stevenfont@google.com",
        "time": "Thu Oct 01 18:32:40 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 18:32:40 2026"
      },
      "message": "Require GC for waitqueues (#9177)\n\nWaitqueue instructions only make sense when GC is enabled. e.g.\n`struct.wait` takes a struct reference which requires GC anyway, and\nwaitqueues live on the GC heap. This is also needed for #9172 to pass\n[this\ncheck](https://github.com/WebAssembly/binaryen/blob/4d8ac549e2ab9b283246ea95e79ebe139ca579ac/src/tools/wasm-ctor-eval.cpp#L598-L599).\n\nPart of #8315."
    },
    {
      "commit": "b125d2e19542df72458bc916a2d0aa4bf72500fd",
      "tree": "f39c9507c9d407847a210d9627066b48e87ccaa5",
      "parents": [
        "d2a7cc3b8a4a2cc5c90a50e98d8b13680984bdd7"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Thu Oct 01 18:26:59 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 18:26:59 2026"
      },
      "message": "RemoveUnusedBrs: When turning an if-br into br_if, consider the value\u0027s cost (#9187)\n\nTurning\n```wat\n(if (condition)\n (then\n  (br\n   (value))))\n```\ninto\n```wat\n(br_if (value) (condition))\n```\nsaves size, but it means the value now executes unconditionally. We\nconsidered other factors here but forgot to measure the value\u0027s cost."
    },
    {
      "commit": "d2a7cc3b8a4a2cc5c90a50e98d8b13680984bdd7",
      "tree": "5e9e1205a2b689602dca1ddab2928f40e26dc225",
      "parents": [
        "06f14fc522372ed89e2b350ca0948eb34006d981"
      ],
      "author": {
        "name": "Jérôme Vouillon",
        "email": "jerome.vouillon@gmail.com",
        "time": "Thu Oct 01 16:18:56 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 16:18:56 2026"
      },
      "message": "[wasm-merge] Handle table initializer referring to imported global (#9167)\n\nUnlike global initializers and element segments (which under GC may\nrefer to preceding module-defined globals), a table initializer\nexpression may only refer to imported globals. Fusing can turn an\nimported global that a table initializer refers to into a module-defined\none, which would make the initializer invalid. When that happens, inline\nthe referenced global\u0027s (immutable, constant) value so the initializer\nremains valid."
    },
    {
      "commit": "06f14fc522372ed89e2b350ca0948eb34006d981",
      "tree": "69dafce9ef2f090b0832f82608b329aa8658c9ce",
      "parents": [
        "4d8ac549e2ab9b283246ea95e79ebe139ca579ac"
      ],
      "author": {
        "name": "Li Jie",
        "email": "cpunion@gmail.com",
        "time": "Thu Oct 01 16:04:00 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 16:04:00 2026"
      },
      "message": "Repair invalid DWARF scope ranges after transforms (#8964)\n\n## Summary\n\n- preserve the DWARF all-ones tombstone and LLVM\u0027s legacy max-minus-one\nencoding instead of remapping dead DIEs to address zero\n- reject lost or reversed low/high PC pairs without unsigned wraparound\n- normalize updated range lists and rebuild range-list parents from\nsurviving child scopes\n- repair scope trees bottom-up and make ambiguous overlapping sibling\nsubtrees unavailable\n\nBinaryen currently updates DWARF range endpoints independently. When\noptimization or Asyncify removes or reorders expressions, the resulting\nendpoints can wrap, overlap, or escape their parent scope. This is the\nsame failure mode reported in #6406, extended to range lists and scope\ntopology.\n\nThe repair is conservative: representable parent unions are preserved,\nwhile ambiguous scopes fail closed. Empty replacement range lists are\nappended rather than mutating lists that another DIE may share.\n\n## Implementation\n\nRange-set normalization, union, containment, and overlap are isolated in\n`DwarfRanges` and directly unit-tested. The DWARF adapter keeps\nencoding-specific constants and tombstone rules in `wasm-debug.cpp`,\nincluding the distinction between a valid `low_pc \u003d 0` and range-list\nterminators.\n\nThe repair builds an explicit parent/child index for each compilation\nunit. It first propagates malformed or unavailable scopes through that\ntree, then processes children before parents so sibling overlap checks\nsee final ranges and range-list parents can be extended before their own\ncontainment check. This also avoids repeated descendant scans and avoids\nrelying on default depths for null DIE terminators.\n\n## Tombstone handling\n\n\"Nonzero tombstone\" was imprecise shorthand. DWARF issue\n[200609.1](https://dwarfstd.org/issues/200609.1.html), accepted for\nDWARF v6, reserves the largest representable target address (for\nexample, `0xffffffff` for wasm32) for a non-existent entity. LLVM\nimplements this as `dwarf::computeTombstoneAddress` and has a\n[WebAssembly-specific\ntest](https://github.com/llvm/llvm-project/blob/main/llvm/test/tools/llvm-debuginfo-analyzer/WebAssembly/wasm-32bit-tombstone.s)\nfor a dead wasm32 subprogram.\n\nThe max-minus-one value (`-2`) is an LLVM legacy compatibility encoding\nrather than a general DWARF value. It is recognized for legacy\n`.debug_ranges`/`.debug_loc` data because all-ones is already the\nbase-address-selection marker and `(0, 0)` terminates the list. See\n[LLVM D81784](https://reviews.llvm.org/D81784) and\n[DWARFDebugRangeList.cpp](https://github.com/llvm/llvm-project/blob/main/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp).\n\nBinaryen already recognizes `0`, `-1`, and `-2` in tombstone-aware\ncontexts. This change prevents `updateDIE` from passing `-1`/`-2`\nthrough the instruction-offset mapper, where they can be rewritten to\nzero and make a dead DIE appear to refer to address zero.\n\nFixes #6406."
    },
    {
      "commit": "4d8ac549e2ab9b283246ea95e79ebe139ca579ac",
      "tree": "81fff55c7f8608dd0efcb6a95aa54d3d5d9f24cc",
      "parents": [
        "b0155c5bdb9ca702b5daa5134d31f76c213fe1f1"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 30 20:41:36 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 30 20:41:36 2026"
      },
      "message": "Add a coverage-diff.py script (#9176)\n\nAdd a (vibe coded) script for collecting LLVM code coverage reports and\nintersecting them with git diffs to produce coverage reports for the\ncurrent change. The script can be used by both LLMs and humans to ensure\nthat a change has proper test coverage in a deterministic, trustworthy\nmanner.\n\nUpdate the lit config so that the config at the project root does not\noverride the config in a particular output directory. This ensures that\nwhen the new script runs lit tests with the coverage build in a separate\nbuild directory, it uses the binaries from the coverage build, not the\nnormal in-tree build.\n\nAlso update the early exit logic to do a normal exit when collecting\ncoverage. This ensures that the cleanup handlers run and the coverage is\nactually written to the coverage file."
    },
    {
      "commit": "b0155c5bdb9ca702b5daa5134d31f76c213fe1f1",
      "tree": "4a3efef6b9a8a40a19fedde7aa5ab040b1341aa3",
      "parents": [
        "4064a84684d821765a2630e4f3dacc3aaee5164c"
      ],
      "author": {
        "name": "Jérôme Vouillon",
        "email": "jerome.vouillon@gmail.com",
        "time": "Wed Sep 30 16:49:11 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 30 16:49:11 2026"
      },
      "message": "[DAE] Optimize callers after refining return types (#9165)\n\nOptimizations opportunities can exist in the callers, such as casts that the\nrefined type makes statically known to succeed."
    },
    {
      "commit": "4064a84684d821765a2630e4f3dacc3aaee5164c",
      "tree": "6bf6da8610cf26e4ac80f1b8aa710ff40c03d56f",
      "parents": [
        "cc0b0b7ea911e47ea591cc2c6c0993b9951194c3"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 30 00:26:04 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 30 00:26:04 2026"
      },
      "message": "Tweak AI contribution policy wording (#9174)\n\n\"Contributors must self-review and understand all code and documentation\nupdates (with or without AI tooling) before sending them for review to\nensure the correctness, design, and style meet the standards of the\nproject\"\n\n\u003d\u003e\n\n\"Contributors must understand their contributions before sending them\nfor review and must ensure that their correctness, design, and style\nmeet the standards of the project\""
    },
    {
      "commit": "cc0b0b7ea911e47ea591cc2c6c0993b9951194c3",
      "tree": "d1797a5fac5915e187926ce509fe8e941789af92",
      "parents": [
        "6f8d66d9531d83c2e1d97852f1ef26c4524b12fe"
      ],
      "author": {
        "name": "Steven Fontanella",
        "email": "stevenfont@google.com",
        "time": "Tue Sep 29 23:28:02 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 23:28:02 2026"
      },
      "message": "[NFC] Ruff fixes (#9173)\n\nResolves some ruff errors that my pre-commit script picked up."
    },
    {
      "commit": "6f8d66d9531d83c2e1d97852f1ef26c4524b12fe",
      "tree": "04dc0aae5516d27e833d13f9ca8cbd764e367513",
      "parents": [
        "a93fe20bd85da2cb1a4d53bad344657203fda3c9"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Tue Sep 29 22:17:39 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 22:17:39 2026"
      },
      "message": "[NFC] Make SortedVector inherit privately from std::vector (#9171)\n\nThis prohibits referring to a SortedVector using an upcast, as the\nupcast might manipulate the contents in a non-sorted way."
    },
    {
      "commit": "a93fe20bd85da2cb1a4d53bad344657203fda3c9",
      "tree": "1e3b65400490ea4ca49eb574e251ca34663dd4d4",
      "parents": [
        "6c1a3cb74dd4d07eb6d79fc3e58cc4877e6f84f9"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Tue Sep 29 21:16:08 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 21:16:08 2026"
      },
      "message": "Add AI contribution policy (#9168)"
    },
    {
      "commit": "6c1a3cb74dd4d07eb6d79fc3e58cc4877e6f84f9",
      "tree": "38d9451ea39405c685af1f6113bc0e73a48edde5",
      "parents": [
        "53bf1f8e1c50a97502e3f38dcf18a00bad3ef348"
      ],
      "author": {
        "name": "Steven Fontanella",
        "email": "stevenfont@google.com",
        "time": "Tue Sep 29 20:22:00 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 20:22:00 2026"
      },
      "message": "Fuzz waitqueue instructions (#9012)\n\nPart of #8315. Generate `waitqueue.new`, `waitqueue.notify`, and\n`struct.wait` in the fuzzer.\n\nWhen `!ATOMIC_WAITS`, the timeout argument on all `struct.wait`s is\nforced to be equal to 0 so that programs can\u0027t block. In this case it\nwill return either 1 (not equal) or 2 (equal and timed out waiting), but\nnever 0 (blocked and got notified).\n\nRan for 57k iterations with no issues. For fuzzing against V8:\n`shared-everything` is already disabled when fuzzing against V8:\n[link](https://github.com/WebAssembly/binaryen/blob/1c0c9f3836e858e01c4f94ac2e5a936d16a6ba1d/scripts/fuzz_opt.py#L74).\nWaitqueues are mostly implemented in V8 but currently only support i32\ncontrol words and not i64 or subtypes of eqref:\nhttps://chromium-review.googlesource.com/c/v8/v8/+/8449412/2."
    },
    {
      "commit": "53bf1f8e1c50a97502e3f38dcf18a00bad3ef348",
      "tree": "a760c4a2d0175f12fc4e0e44aada35127d3c6696",
      "parents": [
        "13b6e64bb796f74dd547ac686afc9cead80639e7"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Tue Sep 29 19:48:12 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 19:48:12 2026"
      },
      "message": "[NFC] Use a sorted vector instead of a map in ConstraintAnalysis (#9154)\n\nWe usually have only a few useful constraints, so the map is mostly\nempty. An `unordered_map` is then pretty inefficient, and it is better\nto use a vector. Sorting it makes lookup still pretty fast.\n\nThis especially helps in ORing two sets of constraints, as we can\njust do an intersection (the OR result is only interesting if we had\nsomething in both inputs - otherwise we can prove nothing), which\nis efficient on sorted vectors.\n\nTo implement this, generalize the existing SortedVector.\n\nThis makes the pass 50% faster on average, though the spread\nis wide (20%-almost 2X faster). I tested around 10 real-world\nwasm files and did not see a single one with less than an 18%\nspeedup, and never a regression."
    },
    {
      "commit": "13b6e64bb796f74dd547ac686afc9cead80639e7",
      "tree": "a987a3b7498590db81443efac695ad2f1ec406e4",
      "parents": [
        "5bcf13596e7728d40cefae7f24639e27d7d9436c"
      ],
      "author": {
        "name": "Jérôme Vouillon",
        "email": "jerome.vouillon@gmail.com",
        "time": "Tue Sep 29 18:55:01 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 18:55:01 2026"
      },
      "message": "[DAE] Refine the results of never-returning functions to bottom (#9169)\n\nWhen no value can flow out of a function, DAE leaves the result type\nalone. Such functions are common in compiled code (e.g. functions that\njust throw an exception).\n\nFor example, with `--dae`:\n```wasm\n  (func $fail (param $0 (ref eq)) (result (ref eq))\n    (throw $exn (local.get $0)))\n  (func $f (param $0 i32) (result (ref eq))\n    (if (local.get $0)\n      (then (return (ref.i31 (i32.const 0)))))\n    (return_call $fail (global.get $msg)))\n```\n`$f` stayed at `(ref eq)` although it can only return an i31.\n\nWhen the result is a single reference type and no value is noted, we\nrefine it to the non-nullable bottom type of its hierarchy (e.g. `(ref\nnone)`), under the same conditions as other result refinements (all\ncalls are known). `$fail` now returns `(ref none)` and `$f` `(ref i31)`."
    },
    {
      "commit": "5bcf13596e7728d40cefae7f24639e27d7d9436c",
      "tree": "f074e35ed4f99b2297ef083c0adedb0d4ed61138",
      "parents": [
        "39cd18ac41d242990a36ec8704627c83043a0c65"
      ],
      "author": {
        "name": "artemkulyk",
        "email": "88086187+artemkulyk@users.noreply.github.com",
        "time": "Tue Sep 29 17:27:14 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 17:27:14 2026"
      },
      "message": "[ReorderFunctions] Count ref.func uses in bodies and globals (#9160)\n\nReorderFunctions ordered functions using calls, plus exports, start and\nelement segments. It did not count ref.func, so a function that is only\nused through a reference could be sorted as if it were unused. Count\nref.func in function bodies, and in global initializers, as well.\n\nThe size effect is small, but the counts now match how functions are\nactually used."
    },
    {
      "commit": "39cd18ac41d242990a36ec8704627c83043a0c65",
      "tree": "53c784100e7288896cb5b9fb0b4f81e6e806c106",
      "parents": [
        "d1a6b253c7f75a3da7f0951102840013e46d6b7b"
      ],
      "author": {
        "name": "artemkulyk",
        "email": "88086187+artemkulyk@users.noreply.github.com",
        "time": "Tue Sep 29 15:50:42 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 29 15:50:42 2026"
      },
      "message": "[StackIR] Drop a set/get pair across a symmetric operation (#9162)\n\nlocal2Stack gives up when a value sits between a local.set and the\nmatching local.get. If that value and the get are consumed by the\nsame operation whose operands can be swapped, the pair can be\nremoved anyway.\n\nThis also removes the one size regression of the late\noptimize-instructions round (4 bytes on a float test module), and\nis a small win on average."
    },
    {
      "commit": "d1a6b253c7f75a3da7f0951102840013e46d6b7b",
      "tree": "092abbb8ce2b675fe3fda8cf311f617695334da2",
      "parents": [
        "eacbf2333a8c7c7ca65b2d08c7a92d1bf4b12650"
      ],
      "author": {
        "name": "Goktug Gokdogan",
        "email": "goktug@google.com",
        "time": "Mon Sep 28 20:58:18 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 28 20:58:18 2026"
      },
      "message": "Sink drop into arms of concrete if expressions in Vacuum pass (#9155)\n\nIn Binaryen\u0027s Vacuum pass, a drop of an if expression was previously\nonly sunk into an arm if the other arm ended in an unreachable. When\nboth arms were concrete, the drop was kept wrapping the if expression,\nforcing the if to retain a concrete block type (requiring multi-byte\ntype index headers for GC types) and preventing dead-code elimination,\nvacuuming, and PruneDroppedReturns from optimizing dropped expressions\nwithin the branches.\n\nFurthermore, visitIf contained logic that hoisted drops back outside of\nthe if if both arms were dropped with identical types, which was\ndetrimental for Wasm GC reference types (where block type indexes exceed\n1 byte) and broke optimization cascades across passes.\n\nThis change:\n1. Sinks drops into both arms of concrete if-else expressions in\nvisitDrop.\n2. Removes the conflicting drop-hoisting logic in visitIf.\n3. Adds unit tests and updates lit tests accordingly."
    },
    {
      "commit": "eacbf2333a8c7c7ca65b2d08c7a92d1bf4b12650",
      "tree": "0c9026cbbe143bc4e7282e4ca4f719cc6f2398d0",
      "parents": [
        "172e9822cdfbfbc19380a31f7a9a163a38cb4d0d"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Sep 25 01:58:21 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 25 01:58:21 2026"
      },
      "message": "[WATParser] Restore position on failed typeuse in skipFunctionBody (#9145)\n\nWhen typeuse() inside ParseDeclsCtx::skipFunctionBody failed after\nconsuming an opening parenthesis (such as \u0027(type $)\u0027), not restoring the\nlexer position left depth un-incremented so the closing \u0027)\u0027 decremented\ndepth early and caused skipFunctionBody to exit the function\nprematurely."
    },
    {
      "commit": "172e9822cdfbfbc19380a31f7a9a163a38cb4d0d",
      "tree": "2ad0a5286992bf2ebe9b446a773da822020b43f9",
      "parents": [
        "c6b98aa5da3cbfbddfb40221ab15439cacdf6a14"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Sep 25 01:58:21 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 25 01:58:21 2026"
      },
      "message": "[WATParser] Skip identifiers in ParseDeclsCtx::skipFunctionBody (#9144)\n\nWithout taking identifiers in ParseDeclsCtx::skipFunctionBody, an\nidentifier starting with a block or indirect call keyword (such as\n$block or $call_indirect) would have only its leading \u0027$\u0027 consumed by\nin.take(1) and then be misparsed as a keyword on the next iteration,\nadding a spurious implicit function type."
    },
    {
      "commit": "c6b98aa5da3cbfbddfb40221ab15439cacdf6a14",
      "tree": "0a9e888affe7c47cfd14beab98832f2490a8d402",
      "parents": [
        "1447734bc724a07cc42877367a804ef7f5b21fe9"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Sep 25 01:58:20 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 25 01:58:20 2026"
      },
      "message": "[WATParser] Do not clear earlier annotations when lexing annotations (#9143)\n\nLexer::takeAnnotation called takeKeyword and takeLParen, which are\npublic token methods that call advance(). Calling advance() executes\nannotations.clear(), wiping out any earlier annotations already\ncollected during the same skipSpace() pass whenever a subsequent\nannotation contains a keyword or nested parenthesis. Use peekKeyword() +\ntake() and takePrefix() instead."
    },
    {
      "commit": "1447734bc724a07cc42877367a804ef7f5b21fe9",
      "tree": "8f4d71175b849ba660bca1caa75454bfc805dea0",
      "parents": [
        "b40790ffeb79aa540970141ec8820683b1d7a6e7"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Fri Sep 25 01:58:20 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 25 01:58:20 2026"
      },
      "message": "[WATParser] Do not advance position on unterminated block comments (#9142)\n\nWhen an unterminated block comment directly followed an annotation and\nended with whitespace, Lexer::takeComment advanced pos to the last\ncharacter of the buffer without restoring startPos. Because takeComment\nreturned false after takeAnnotation returned true, skipSpace terminated\nwith pos pointing at the trailing whitespace instead of the start of the\nunterminated comment, causing mismatched implicit type positions between\nparsing phases.\n\nFixes #8634."
    },
    {
      "commit": "b40790ffeb79aa540970141ec8820683b1d7a6e7",
      "tree": "d7848a58953c5f2a13433a1665495797a0325b4c",
      "parents": [
        "b67e498fc4bd29fdc9dafb519f055f4f3a77c717"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Thu Sep 24 17:36:36 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 24 17:36:36 2026"
      },
      "message": "ConstraintAnalysis: Optimize local.get (#9136)\n\nE.g.\n```wat\n(if\n  (local.get $x)\n  (then ..)\n  (else\n    ..(local.get $x)..   ;; this must be 0.\n  )\n)\n```\n\nThis removes the \"markRelevant\" logic that tried to only track locals\nthat have interesting operations on them that we can optimize,\nbecause now anything with a `local.get` might get optimized - which\nis pretty much anything.\n\nOn one large Dart testcase I saw a total binary size reduction\nof 0.3% from this PR.\n\nSome existing tests needed adjustment, as constants are now\npropagated in cases that can be confusing."
    },
    {
      "commit": "b67e498fc4bd29fdc9dafb519f055f4f3a77c717",
      "tree": "c860df7f73088f876f7d1d8bd67792ee6a1a0ed9",
      "parents": [
        "2dc30e28281e9857e703cd3379539cb9e57f2571"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Thu Sep 24 17:34:31 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 24 17:34:31 2026"
      },
      "message": "[NFC] Use RPOQueue in RedundantSetElimination (#9151)\n\nThis makes the pass 25% faster, for similar reasons as #9149."
    },
    {
      "commit": "2dc30e28281e9857e703cd3379539cb9e57f2571",
      "tree": "717c67a1c4e37a4a1349a14de449d56972475b63",
      "parents": [
        "296af3158ff3fb02e93b7ed5ef35ceba61dc5771"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Thu Sep 24 17:10:29 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 24 17:10:29 2026"
      },
      "message": "[NFC] Use RPOQueue in liveness-traversal (#9152)\n\nThis makes CoalesceLocals 15% faster, for similar reasons as #9149."
    },
    {
      "commit": "296af3158ff3fb02e93b7ed5ef35ceba61dc5771",
      "tree": "ce59f6d1143494134f4af18d3b0b25b7d33b3499",
      "parents": [
        "d001112229969548b4f2e37444ca687bd3dba9c6"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Thu Sep 24 15:54:42 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 24 15:54:42 2026"
      },
      "message": "[NFC] Add a reverse-postorder queue utility and use it in ConstraintAnalysis flow (#9149)\n\nThis is a lot more efficient in the case of large functions: processing\nin reverse postorder means we finish up an if/loop before we look onwards.\nThe `UniqueDeferredQueue` tries to do this automatically in a cheap\nway: when we see a thing twice, we defer it, so it is processed after\nthe children - but there is no guarantee it works out, depending on how we\ntraverse the children. The new utility does this deterministically.\n\nThis makes ConstraintAnalysis 2-3x faster on a few large testcases I\nam looking at. I see smaller wins elsewhere, and I have not found a\nsingle case where this is slower. Even though we now use a priority\nqueue (logN push/pop), this approach stores the block index and whether\nit is in the queue already in the block itself, which is more efficient\nthan before."
    },
    {
      "commit": "d001112229969548b4f2e37444ca687bd3dba9c6",
      "tree": "c3133faa4e7a0cd6abadcdef456279922f4f2086",
      "parents": [
        "ec6b8fbb32c066b617c9760935bc61e6b5c970c6"
      ],
      "author": {
        "name": "Goktug Gokdogan",
        "email": "goktug@google.com",
        "time": "Thu Sep 24 00:01:57 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 24 00:01:57 2026"
      },
      "message": "Accurately mark CallIndirect and CallRef as calls in Inlining (#9146)\n\nIn Binaryen\u0027s Inlining pass, multi-use functions (refs \u003e 1) are eligible\nfor inlining at -O3 only if they have no calls and no loops (!hasCalls\n\u0026\u0026 !hasLoops), as leaf inlining eliminates function call overhead\nwithout code explosion.\n\nHowever, FunctionInfoScanner previously omitted CallIndirect and CallRef\nfrom hasCalls tracking. In WasmGC / Java, polymorphic method dispatch is\ncompiled as call_ref. Widely-used utilities containing virtual calls\n(such as String.valueOf(Object), which performs a null-check and an\nindirect call to x.toString()) were misclassified as leaf functions and\naggressively inlined into thousands of call sites. Inlining non-leaf\nfunctions with call_ref does not eliminate the indirect call; it only\nduplicates the caller-side parameter preparation, null checks, and\nvtable indexing.\n\nThis change marks hasCalls \u003d true in visitCallIndirect and visitCallRef\nso that multi-caller non-leaf functions containing indirect/reference\ncalls are not duplicated across the binary."
    },
    {
      "commit": "ec6b8fbb32c066b617c9760935bc61e6b5c970c6",
      "tree": "66008be10cc1325b392ae18b919f54e800f03a4b",
      "parents": [
        "1c0c9f3836e858e01c4f94ac2e5a936d16a6ba1d"
      ],
      "author": {
        "name": "Spotandjake",
        "email": "40705786+spotandjake@users.noreply.github.com",
        "time": "Wed Sep 23 22:24:56 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 22:24:56 2026"
      },
      "message": "fix: Correct type signature of `BinaryenRefNull` (#9150)\n\nI noticed that in #8981 the underlying type of `BinaryenRefNull` was\nchanged in the cpp file. This pr corrects the type in the c api."
    },
    {
      "commit": "1c0c9f3836e858e01c4f94ac2e5a936d16a6ba1d",
      "tree": "a65d9a0ae63bed1e0b0af8f384b3a35360c0f2b6",
      "parents": [
        "f4510a6a04aaa0f8d900f6f23c8093abb979d408"
      ],
      "author": {
        "name": "Steven Fontanella",
        "email": "stevenfont@google.com",
        "time": "Wed Sep 23 21:23:50 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 21:23:50 2026"
      },
      "message": "Allow struct.wait expected value to be a supertype (#9139)\n\nFor `ref` fields, the `expected` ref that\u0027s passed in does not need to\nbe a subtype of the struct\u0027s field\u0027s type. See [the typing\nrules](https://github.com/WebAssembly/shared-everything-threads/blob/main/proposals/shared-everything-threads/Overview.md#managed-waiter-queues)\nfrom the proposal, and\nhttps://github.com/WebAssembly/shared-everything-threads/pull/92 which\nexplains why. From the spec:\n\n```\nwait_expected(i32) \u003d i32\nwait_expected(i64) \u003d i64\nwait_expected(t) \u003d (ref null (shared eq)) -- if t \u003c: (ref null (shared eq))\n\nC |- struct.wait x y : [(ref null x) (ref null (shared waitqueue)) t i64] -\u003e [i32]\n -- C.types[x] \u003d shared? struct ft*\n -- ft*[y] \u003d mut? t\u0027\n -- t \u003d wait_expected(t\u0027)\n```\n\nIn this case `t \u003c: (ref null (shared eq))` and it\u0027s not required that `t\n\u003c: t\u0027`.\n\n---\n\nSince the expected value isn\u0027t required to be a subtype of the field\ntype, we no longer need the fixing code in TypeRefining.cpp. This\nmatches the behavior for the expected field of atomic cmpxchg, which\ndoesn\u0027t touch `curr-\u003eexpected`. The `type-refining-gufa` test was a\nmis-optimization before, because it caused the struct.wait to block (by\nchanging the expected value to `ref.null`) when it did not block in the\noriginal program."
    },
    {
      "commit": "f4510a6a04aaa0f8d900f6f23c8093abb979d408",
      "tree": "049e05a1f4b37f4807b8f477222bb1f31d759844",
      "parents": [
        "d2c23335def7f4622a20aaa4accfa060655c3fb1"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 23 18:08:59 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 18:08:59 2026"
      },
      "message": "[Interpreter] Support partial cont.bind (#9140)\n\nThe interpreter previously supported cont.bind only when all of the\ncontinuation arguments were bound, but the fuzzer produced a module that\nexecuted a partial evaluation (after 2.6 million iterations). Add the\nmissing functionality."
    },
    {
      "commit": "d2c23335def7f4622a20aaa4accfa060655c3fb1",
      "tree": "341571e2d1a41c3adc59e36b972c4d8225ea304f",
      "parents": [
        "816181d140d6890e0fae41727ce74f099cb69e8e"
      ],
      "author": {
        "name": "Alon Zakai",
        "email": "azakai@google.com",
        "time": "Wed Sep 23 17:29:18 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 17:29:18 2026"
      },
      "message": "ConstraintAnalysis: Parse EqZ recursively (#9138)\n\nThis allows us to parse things like `(eqz (ref.is_null ..))` which means\n\"is not null\". It also cleans up the code a little: just recurse into\nthe EqZ argument, and negate the result.\n\nRecursion does in theory risk a stack overflow, but eqzs are not\ndeeply nested in code (certainly not optimized code, which is what\nthis pass sees, as we run it late)."
    },
    {
      "commit": "816181d140d6890e0fae41727ce74f099cb69e8e",
      "tree": "b3ba13f1628f226128a3db873ffec94b8ac034db",
      "parents": [
        "6c97a76b08eea63ee6f9da0a159bd6bd3d869671"
      ],
      "author": {
        "name": "Matthias Liedtke",
        "email": "mliedtke@chromium.org",
        "time": "Wed Sep 23 17:12:10 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 17:12:10 2026"
      },
      "message": "[scripts] Update name of experimental Wasm V8 flags (#9134)\n\nThese flags got renamed in https://crrev.com/c/8426472.\n\nNote that this is just the code change, I don\u0027t know if there is any\npipeline in place to automatically update the ClusterFuzz fuzzer."
    },
    {
      "commit": "6c97a76b08eea63ee6f9da0a159bd6bd3d869671",
      "tree": "86dbab60d32980c303ea98936b912e1ca64ba583",
      "parents": [
        "5611af00c1533ce7c3edcf7db0e7d07b8ad37c64"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 23 01:58:37 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 01:58:37 2026"
      },
      "message": "Add a wasm-embed tool (#9127)\n\nThe tool embeds a given sequence of Wasm modules in place of the Wasm\nmodules already present in a given JS file. Alternatively, with the\n--extract option, it extracts the embedded modules from the JS file and\nwrites them as standalone Wasm files. This replaces the embed_wasms.py\nand extract_wasms.py scripts, reusing the C++ embedded module parsing\nlogic added for wasm-reduce --js. The differences in behavior from the\nreplaced scripts are that the new tool 1) can accept .wat files as\ninput, assembling them before embedding, and 2) does not modify the\noriginal source when extracting modules and does not rely on a sentinel\nplaceholder to determine where to embed new modules."
    },
    {
      "commit": "5611af00c1533ce7c3edcf7db0e7d07b8ad37c64",
      "tree": "e59c542c040c8dd4270c85138f96ff1ed539f669",
      "parents": [
        "5227aed2448cf0d0a7558b2c2cd1f0e8cc75eb0b"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 23 01:20:01 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 01:20:01 2026"
      },
      "message": " [wasm-reduce] Add --js mode for embedded modules (#9121)\n\nIn the new mode, parse the input JS file to find all its embedded\nmodules, then run a full reduction on each of them in sequence. Add a\nnew JSTestCaseHandler that handles splicing the module bytes into the JS\nat the correct location. Reducing each module in sequence is simple, but\nin principle can miss reduction opportunities that would require\nchanging multiple modules at once, for example reducing types that are\nused in inter-module communication. Its expected that the current\nimplementation will be good enough in the common case."
    },
    {
      "commit": "5227aed2448cf0d0a7558b2c2cd1f0e8cc75eb0b",
      "tree": "e342701f693c003f3072e136beb7f2588d78421b",
      "parents": [
        "49769e35181fccef8aaad41ccf675fb5cf39cd16"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 23 01:20:01 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 01:20:01 2026"
      },
      "message": "Add a utility for handling modules embedded in JS (#9119)\n\nAdd a function that will search JS source for literal byte arrays that\nmight contain Wasm modules. Handle skipping strings and comments, and\nhandle signed and unsigned byte values in decimal, octal, and hex\nformats. Reject byte arrays that do not begin with the Wasm magic\nvalues, but do not otherwise verify that the bytes encode a well-formed\nor valid Wasm module.\n\nAlso add a function for printing a byte sequence as a JS byte array,\nformatted with 16 hex values per line.\n\nA future PR will use these functions in wasm-reduce to reduce Wasm\nmodules embedded in JS files."
    },
    {
      "commit": "49769e35181fccef8aaad41ccf675fb5cf39cd16",
      "tree": "0440af8e9a0c1dbd045e5bbeefc895ed1bca393a",
      "parents": [
        "0ed8f896900eb25d0a07850a6f14bb28b4cbb90c"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 23 01:20:00 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 01:20:00 2026"
      },
      "message": "[NFC][wasm-reduce] Introduce TestCaseHandler and WasmTestCaseHandler (#9118)\n\nParameterize Reducer, pre-flight checks, and reduceModule with a\nTestCaseHandler interface and WasmTestCaseHandler implementation to\nprepare for reducing embedded Wasm modules in JS files. TestCaseHandler\nabstracts how module bytes are read from and written to the test and\nworking files. The next PR will add an alternative implementation that\nreads the bytes from byte arrays embedded in JS files and splices\nreduced module bytes back into the same JS files."
    },
    {
      "commit": "0ed8f896900eb25d0a07850a6f14bb28b4cbb90c",
      "tree": "83f4951fd68aa391831aafb17d0de877b252fde5",
      "parents": [
        "0791ab63dbc593d13c91e2c5233dd7c1be6518ae"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 23 01:20:00 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 01:20:00 2026"
      },
      "message": "[NFC][wasm-reduce] Use byte vectors for I/O (#9117)\n\nThis refactoring prepares for a follow-on PR that will abstract how the\nmodule bytes are read from and written to the test and working files to\nsupport reducing Wasm modules embedded in JS files."
    },
    {
      "commit": "0791ab63dbc593d13c91e2c5233dd7c1be6518ae",
      "tree": "8ac03bc99247ed3347781b55992f930494d91e56",
      "parents": [
        "8c70866bbfa4ba7ed1e9a03768bc754f7eb69758"
      ],
      "author": {
        "name": "Thomas Lively",
        "email": "tlively@google.com",
        "time": "Wed Sep 23 01:19:59 2026"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 01:19:59 2026"
      },
      "message": "[NFC][wasm-reduce] Extract helper functions (#9116)\n\nBreak up some of the larger functions into smaller helpers. Some of\nthese helpers will be necessary to reduce duplication in future\nrefactors that will support reducing Wasm modules embedded in JS files."
    }
  ],
  "next": "8c70866bbfa4ba7ed1e9a03768bc754f7eb69758"
}
