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
Fix accessor vtable dispatch through base-typed references
Closes the "much bigger gap" flagged alongside super-accessor-crash-fix
(PR #278): overriding a get/set accessor pair in a subclass and
accessing it through a BASE-TYPED reference (an ordinary upcast, not
`super`) always resolved statically to the base's own accessor instead
of dispatching virtually to the override - a real correctness gap
(this is standard OOP virtual dispatch, not an edge case), unlike
ordinary methods which already dispatch through the vtable correctly.
Root cause: an accessor's backing get/set functions are ALREADY
registered as ordinary MethodInfo entries in ClassInfo::methods (same
list ordinary methods use) with a real vtable slot assigned via
registerClassMethodMember/getVirtualTable - accessors are virtual by
default exactly like methods. But ClassAccessorAccess never checked
isVirtual at all: it unconditionally built ThisAccessorOp with a
hardcoded FlatSymbolRefAttr naming THIS class's own get/set symbol,
completely bypassing the vtable that was already being correctly
built.
Fix: mirror ClassMethodAccess's own isVirtual/isStorageType check
(isStorageType is true for `super.<accessor>`'s raw-struct thisValue,
so super access is naturally excluded from virtual dispatch, same as
methods) and route through the vtable via VirtualSymbolRefOp (the same
op static virtual method access already uses) feeding into the
existing "indirect" (function-value) ThisIndirectAccessorOp, instead
of the hardcoded-symbol ThisAccessorOp. Checked before the
isDynamicImport branch, matching ClassMethodAccess's ordering - the
vtable's own construction already resolves dynamic-import-owned slots,
so virtual dispatch through it is correct regardless of module
boundaries.
One regression found and fixed during verification: getThisRefOfClass
only narrows `thisValue` for the isSuperClass case, so an ordinary
access whose static type is still a wider union (e.g. `T | null`
narrowed only at the type-info level, never cast at the value level -
hit by 00iterator_bug.ts's spread-operator-generated `.length` access)
reached the new vtable lookup with an un-narrowed union type, which
mlirGenPropertyAccessExpression's PropertyRefOp rejects (unlike the
old AnyType-typed ThisAccessorOp it replaces). Fixed by explicitly
casting to classInfo->classType before the vtable lookup.
New same-file regression test 00class_accessor_virtual.ts (compile +
jit tiers). Also closed the historical NOTE in
import_class_accessor.ts documenting this exact gap as deliberately
untested - now asserts virtual dispatch through a base-typed reference
works, cross-module, across all 3 tiers (plain, -shared compile,
-jit -shared). Full suite: 810/810 green.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
0 commit comments