Repository navigation
Makes the whole-bundle output parse end to end on Static Hermes (HBC 98), names captures and imports from what the bytecode binds, and adds end-to-end tests that fail on a crash, on top of v0.2.3.
What's new
- Every module parses: on a 17,781-module HBC 98 reference bundle, modules that failed to parse go from 2,089 to 0 and unrendered function bodies (
{ ... }holes) from 370,854 to 274. The causes were in the IR builder:JmpBuiltinIswas read as atypeoftest and printedtypeof x === "unknown"7,606 times, aJmpadopted its target block and truncated everytry/catchthat followed, a derived class whose class and home object share one register exported its prototype under the class name, and a class binding's block environment was written over the factory's slot 0 (const MessageQueue = globalnext toclass MessageQueue). - Rendering is bounded: hermesc creates a non-escaping closure afresh at every call site and a chainable API creates a closure of itself, so embedding bodies by id never converged and one pass reached 5 GB of text. Repeated, immediately-called and cyclic closures are declared once (Tarjan SCC over the creation graph), never outside the scope of their free names, and class methods are rendered from the whole-program bodies. Lines go from 4.3M to 2.76M while moment, whose 8,825 class methods were missing, grows from 3,514 lines to 111,379.
- Captures take the name their owner binds: a closure created with a block environment now has that block scope as parent, capture origins are recorded when they are baked and a late pass renames every capture to the owner's current binding, uninitialised slots are declared, and
superforces an arrow. Identifiers never declared drop from 331,732 to 85,079,closure_Nreferences from 598,388 to 118,852,argNparameters from 293,231 to 116,975. - Imports resolve: the
requireparameter kept its positional role next toimportDefaulton modern factories (it wasarg1in 5,592 modules), every factory is named from its roles, a module's default-export function name identifies it and survives sharing, and React, react-native and AssetRegistry are recognised by their complete export surface. Imports to an unnamedmodule_Nfall from 22,821 to 15,782 while imports as a whole rise from 68,306 to 91,748. - Codegen: labels are emitted only when a jump names them (5,654 to 0), a
letassigned in a branch and read after it is declared where the read can see it, a captured store is never reduced to its side effect (set = new Set()had becomenew Set();),let t = A; if (!A)folds tot = A || B, and non-ASCII object keys are escaped. - The cache loads: the msgpack decoder's depth limit refused every whole-bundle snapshot and silently rebuilt, so each
--modulesor--jsoninspection cost a full run. A refusal is now logged and the limit lifted; an inspection takes seconds. - End-to-end tests: the built binary is run on every corpus bytecode in a child process with a time budget, and on tracked crash-regression fixtures that run in CI. The round trip now fails on a decompiler that aborts instead of counting it as "no output".
Fixed issues
- #24 by @luca-regne: a JSX props object holding an element built from itself (
props.children = React.createElement(View, props)) overflowed the stack in the props substitution on every HBC version. The expansion now stops at the cycle and keeps the variable reference, as proposed in #25; the reproducer is a tracked fixture for v59, v84, v96 and v98. - #21 by @FlexUnder: the assembler stripped the leading letters of a mnemonic that starts with a hex digit (
CreateEnvironmentread asreateEnvironment,Call1asll1). An offset prefix must now be a token of its own, as in #22 by @Abel-Guta.
Downloads
Each archive contains the hermes-decomp and hermes-mcp binaries. Verify with shasum -a 256 -c SHA256SUMS.
| File | SHA256 |
|---|---|
| hermes-decomp-v0.2.4-linux-x86_64.tar.gz | 6e070410432575698657b38d3497f66fd91c0c00f63880d6776703d81d99b5ac |
| hermes-decomp-v0.2.4-linux-arm64.tar.gz | 09d70f25ae159a815c71d6ab29e0779af94b194606a7917c8a74485698298b45 |
| hermes-decomp-v0.2.4-macos-arm64.tar.gz | 4794eb85476c5c223a0d8553228cc9e8e1a7d0a1730d31570f63c555753f891c |
| hermes-decomp-v0.2.4-windows-x86_64.zip | 2609474a9099fe5887a54d92ac3fd1c5101ce1d8adb310465798021f8422e860 |