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
{{ message }}
Repository navigation
util.inherits(SomeClass, …) throws "Object.defineProperty called on non-object" — set_super_property has no class-ref arm #9362
node : function true
perry: Uncaught TypeError: Object.defineProperty called on non-object rc=1
Note the asymmetry — only a class in the first position fails:
call
node
perry
util.inherits(function(){}, function(){})
ok
ok
util.inherits(function(){}, SomeClass)
ok
ok
util.inherits(SomeClass, function(){})
ok
TypeError
util.inherits(SomeClass, OtherClass)
ok
TypeError
Long-standing, not a regression: it reproduces identically on 83754818e (#9242) and on a03be729c (#9336).
Cause
set_super_property in crates/perry-runtime/src/util_inherits.rs handles exactly two receiver shapes — a closure ctor and a heap-object ctor:
fnset_super_property(ctor:f64,super_ctor:f64){let ctor_closure = closure_ptr(ctor);if ctor_closure != 0{/* closure dynamic prop */return;}let obj = object_ptr(ctor);if obj.is_null(){crate::object::throw_object_type_error(b"Object.defineProperty called on non-object");}
…
}
A class constructor arrives as an INT32-tagged class ref (0x7FFE_…), which is neither a closure nor a heap object, so it falls to the throw. Confirmed by instrumenting the site — the ctor value is 0x7ffe000000000008, i.e. class ref, class id 8.
Object.defineProperty(SomeClass, "super_", …) on the same value works, because define_property.rs has the third arm this function is missing:
Give set_super_property the class-ref arm, mirroring what define_property.rs does for a static own property — for a constructor-half class ref (class_ref_id(ctor).is_some() && class_prototype_ref_id(ctor).is_none()):
which matches Node's descriptor ({ value: superCtor, writable: true, configurable: true }) and the attrs the closure arm already uses. ensure_function_prototype / js_object_set_prototype_of on the ctor side should be checked at the same time, since the throw currently masks whatever they do with a class ref.
Why it is worth a fixture
Found while bisecting #9341: this is the other of the only two sites in the tree that emit Object.defineProperty called on non-object, and the two are byte-identical strings, so this shape is a standing source of misattribution when that message shows up in a bundle. A regression test pinning util.inherits across {function, class} x {function, class} would keep them distinguishable.
Found with the fixture above; not filed as a blocker for #9341 — that one is the define_property.rs site.
Activity