Skip to content

Fix cross-module multi-method vtable corruption via decl-text object-vs-tuple printing - #263

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fix/cross-module-multi-method-vtable-abi
Jul 20, 2026
Merged

Fix cross-module multi-method vtable corruption via decl-text object-vs-tuple printing#263
ASDAlexander77 merged 1 commit into
mainfrom
fix/cross-module-multi-method-vtable-abi

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Summary

  • A structurally-typed export's method fields are physically stored as plain FunctionType (a raw 8-byte function pointer — this/the object is implicit via the container). The cross-module declaration-text printer (MLIRPrinter.h) described named-field (object-shaped) types using positional tuple syntax ([name: (args) => result]) instead of object syntax ({name(args): result}), so method fields round-tripped on import as the wider HybridFunctionType (16-byte {data,func} pair) instead of matching the exporter's actual storage.
  • This added a fixed +8-byte read-offset drift per method field on reimport: the first method field happened to still read correctly, the second read a plausible-looking wrong value, and the third read past the end of the real object entirely — crashing on a null function pointer call when casting a genuinely multi-method structurally-typed cross-module value to an interface.
  • Fix: printType's dispatch for TupleType/ConstTupleType/ObjectStorageType now calls printObjectType (method-signature-friendly) instead of printTupleType whenever every field has a real id (i.e. the type is object-shaped, not a positional tuple) — matching the pre-existing diagnosis already documented in printFields's own comment, just not previously wired up.

Test plan

  • New regression test export/import_object_literal_structural_typed_multi_method.ts (3-method interface add/addTwice/scaled), both test-compile-shared-... and test-jit-shared-... variants — verifies correct values end-to-end (3/7/14) where it previously crashed on the third method
  • Full 734-test suite: 100% pass, no regressions
  • Updated docs/interface-vtable-simplification-design.md to record the real root cause (the design doc's earlier "candidates worth checking" — vtable-patch-loop ordering, undersized heap clone — were both ruled out; this bug was upstream of that code entirely)

🤖 Generated with Claude Code

…vs-tuple printing

A structurally-typed export's method fields are physically stored as plain
FunctionType (raw 8-byte function pointer), but the decl-text printer
described named-field (object-shaped) types using positional tuple syntax
instead of object syntax, so method fields round-tripped on import as
HybridFunctionType (16-byte {data,func} pair). This added a fixed +8-byte
read-offset drift per method field, corrupting every field after the first
when casting a multi-method structurally-typed cross-module value to an
interface - crashing on a null function pointer call past the second method.

Fix: printType now prints named-field TupleType/ConstTupleType/ObjectStorageType
via printObjectType (method-signature-friendly) instead of printTupleType
whenever every field has a real id, matching the pre-existing (but previously
unapplied) diagnosis already documented in printFields' own comment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit ce8a53d into main Jul 20, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix/cross-module-multi-method-vtable-abi branch July 20, 2026 15:30
ASDAlexander77 added a commit that referenced this pull request Jul 20, 2026
…ods (#264)

export_object_literal_untyped.ts only ever exercised a single method (inc())
on a boxed ObjectType import. Adds a genuinely multi-method variant (add/
addTwice/scaled), covering both direct calls on the boxed global and an
interface cast of it - a combination only made correct by the decl-text
object-vs-tuple printer fix (#263), not previously tested. 736/736 suite.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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