Skip to content

Fix boxed-object crash/garbage in isDynamicImport's shared-lib load - #262

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fix-boxed-dynamic-import-double-deref
Jul 20, 2026
Merged

Fix boxed-object crash/garbage in isDynamicImport's shared-lib load#262
ASDAlexander77 merged 1 commit into
mainfrom
fix-boxed-dynamic-import-double-deref

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Summary

  • isDynamicImport (the code path every ordinary import '...' actually takes) read a cross-module symbol's data inline, but an untyped/inferred object-literal export's symbol is actually a single boxed pointer to a separately-allocated tuple, not the tuple inline. This caused garbage field values or a JIT-lookup crash on wild addresses.
  • Re-adds a @boxed declaration decorator (same mechanism removed in 5b33995), but consumed correctly this time: inside isDynamicImport's load, which loads the pointer then dereferences through it, instead of the dead declarationMode-only branch used previously.
  • Re-enables both object-literal-untyped tests (disabled after PR Round-trip boxed-ness across @dllimport boundary via a sibling @boxed decorator #261 since they hung/crashed at the time) — they now pass end-to-end.

Reported with a live repro (I:\Playground\1.ts) and full crash stack trace showing the JIT-lookup failure.

Test plan

  • Full ctest suite: 732/732 passing, zero disabled, zero regressions
  • Manual repro from the reported crash: no crash, correct field values after the fix

The isDynamicImport branch (the code path every ordinary `import '...'`
actually takes, per mlirGenImportSharedLib's dynamic-by-default '.' hack)
resolved a cross-module symbol's address and read sizeof(reconstructed
type) bytes directly there. For an untyped/inferred object-literal export,
the exporter's global is a single boxed pointer (ObjectType lowers to a
bare `ptr`) to a separately-allocated tuple, not the tuple inline - so the
load read the pointer's own 8 bytes as the first field and unrelated
adjacent memory as the rest, producing garbage values or a JIT-lookup
crash on `0x100000000`-shaped wild addresses (reported with a live repro
and full stack trace).

Re-adds a `@boxed` decorator (DeclarationPrinter.cpp emits it, matching
the mechanism removed in 5b33995) but fixes where it's actually consumed
this time: isDynamicImport's load, not the dead declarationMode-only
branch from that earlier attempt. When set, loads the boxed pointer first,
then loads through it - two dereferences instead of one.

Re-enables both `object-literal-untyped` tests (disabled since they
previously hung/crashed) - they now pass, including direct field
read/mutate and the interface-cast path. 732/732 suite, zero regressions,
zero disabled.
@ASDAlexander77
ASDAlexander77 merged commit 91f0611 into main Jul 20, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix-boxed-dynamic-import-double-deref branch July 20, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant