You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A block function used before its textual declaration inside a for body is
not initialized before that use in sloppy/script mode. The same program passes
when compiled as an ES module. This is independent of async/generator lowering
and does not require Claude Code or any application files.
Put fixture.ts in a directory outside an ESM package. Compile with:
PERRY_LL_OPT_LEVEL=0 perry compile fixture.ts -o fixture \
--no-cache --no-auto-optimize --no-codegen --platform bun
./fixture
Expected and Node26.5.1 output: 2,2,2, exit0. Perry instead exits1 with TypeError: value is not a function. Adding only a sibling package.json
containing {"type":"module"} makes the identical source pass. Both the
original long test filename and fixture.ts give the same context-sensitive
result; this is not filename-dependent.
Evidence / precise scope
Reproduced at O0/default native roots with frozen compiler 92e2161c9 and
all nine coherent Wasm/provider archives, hashes verified before/after. --enable-wasm-runtime was additionally used for that locally frozen graph.
The larger original control also fails in script context and passes in ESM
context on the older frozen 81b47b47c generator-fix toolchain. All generator,
ordinary yield/await, retained callback and TDZ/recursion assertions complete
before its isolated hoisted-var failure.
Retained IR explains the failure without a memory-safety hypothesis: script
lowering initializes the function binding to undefined, reads it into the
array, and only later allocates the block function. ESM IR allocates the
function before the corresponding array push.
Related prior implementation: #5297. This is distinct from #10051's repeated
lexical-TDZ reset issue. The module-context loss surfaced when #10047 copied a
fixture from the repository's ESM package into a plain temporary directory.
Acceptance
The standalone case must match Node in an explicitly non-module directory,
and retain the ESM behavior. Do not make the script case pass by adding an
ESM marker or strict directive to it.
Cover use before textual block declaration, repeated loop entry, shared
hoisted var identity, fresh lexical captures, and outside-block Annex B
binding updates without collapsing the lexical and outer var bindings.
Verify O0/Os/Oz, with fixtures that pin their package/module context instead
of inheriting the harness directory's package.json.
Local evidence: hoisted-var-script-92e2161c9-20260911.log (2 failures) and hoisted-var-esm-92e2161c9-20260911.log (2 passes), with complete source, retained
IR, exact outputs and artifact hashes in perry-generator-control-provenance-hulqzY
and perry-generator-control-provenance-8GEKYt under the macOS temp directory.
Problem
A block function used before its textual declaration inside a
forbody isnot initialized before that use in sloppy/script mode. The same program passes
when compiled as an ES module. This is independent of async/generator lowering
and does not require Claude Code or any application files.
Put
fixture.tsin a directory outside an ESM package. Compile with:Expected and Node26.5.1 output:
2,2,2, exit0. Perry instead exits1 withTypeError: value is not a function. Adding only a siblingpackage.jsoncontaining
{"type":"module"}makes the identical source pass. Both theoriginal long test filename and
fixture.tsgive the same context-sensitiveresult; this is not filename-dependent.
Evidence / precise scope
92e2161c9andall nine coherent Wasm/provider archives, hashes verified before/after.
--enable-wasm-runtimewas additionally used for that locally frozen graph.603b074acplus fix(codegen): let minsize choose ordinary shadow-root inlining #10076's minsize policy;it is not represented as an exact-main binary. The policy is inactive at
O0, and its HIR/transform source is byte-identical to main603b. fix(codegen): initialize missing cells in reused boxed declarations #10049's
generator fix is absent from this toolchain.
context on the older frozen
81b47b47cgenerator-fix toolchain. All generator,ordinary yield/await, retained callback and TDZ/recursion assertions complete
before its isolated hoisted-var failure.
lowering initializes the function binding to undefined, reads it into the
array, and only later allocates the block function. ESM IR allocates the
function before the corresponding array push.
Related prior implementation: #5297. This is distinct from #10051's repeated
lexical-TDZ reset issue. The module-context loss surfaced when #10047 copied a
fixture from the repository's ESM package into a plain temporary directory.
Acceptance
and retain the ESM behavior. Do not make the script case pass by adding an
ESM marker or strict directive to it.
hoisted
varidentity, fresh lexical captures, and outside-block Annex Bbinding updates without collapsing the lexical and outer var bindings.
of inheriting the harness directory's package.json.
Local evidence:
hoisted-var-script-92e2161c9-20260911.log(2 failures) andhoisted-var-esm-92e2161c9-20260911.log(2 passes), with complete source, retainedIR, exact outputs and artifact hashes in
perry-generator-control-provenance-hulqzYand
perry-generator-control-provenance-8GEKYtunder the macOS temp directory.