Summary
Function.prototype.call.bind(fn)(receiver, ...args) — the "uncurry-this" idiom —
returns the wrong value ([object Object], i.e. the receiver itself) instead of
invoking fn with that receiver, when the receiver is a builtin prototype
object such as Object.prototype or Error.prototype. Plain objects,
Array.prototype, and Math work correctly.
This idiom is the backbone of test262's propertyHelper.js
(__hasOwnProperty = Function.prototype.call.bind(Object.prototype.hasOwnProperty)),
so it gates verifyProperty for every test whose subject is Object.prototype /
Error.prototype / other affected prototypes — a large cross-category blocker.
Repro
var bc = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
bc({a:1}, "a"); // Node: true Perry: true
bc(Array.prototype, "push"); // Node: true Perry: true
bc(Math, "abs"); // Node: true Perry: true
bc(Object.prototype, "toString"); // Node: true Perry: [object Object] <-- BUG
bc(Error.prototype, "message"); // Node: true Perry: [object Object] <-- BUG
Narrowing — the direct form works; only the .call.bind indirection breaks, and
only for these receivers:
Object.prototype.hasOwnProperty.call(Object.prototype, "toString"); // true (ok)
var bc = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
var r = bc(Object.prototype, "toString");
typeof r; // Node: "boolean" Perry: "object" (r === Object.prototype)
So the bound-call machinery, when the eventual receiver IS a builtin prototype,
returns the receiver instead of the method's result — it appears to confuse the
this/return slot in the Function.prototype.call.bind(method) → invoke path for
that receiver class.
Impact
- Blocks
verifyProperty-based test262 cases on Object.prototype /
Error.prototype (e.g. all built-ins/Error/prototype/* and
built-ins/NativeErrors/* descriptor tests — ~57 NativeErrors+Error cases stay
red even though the underlying getOwnPropertyDescriptor / delete /
hasOwnProperty operations are all individually correct and Node-identical).
- Likely affects other categories that subject
Object.prototype to verifyProperty.
Note
A companion branch (fix-error-descriptors, unpushed) makes Error instance +
prototype getOwnPropertyDescriptor / getOwnPropertyNames / delete fully
Node-identical, but those gains are unobservable through test262 until this
dispatch bug is fixed. Recommend fixing this first, then that work lands the
Error cluster.
Filed from the parity-fix loop. Root cause localized to the Function.prototype.call.bind(method) invoke path for builtin-prototype receivers.
Summary
Function.prototype.call.bind(fn)(receiver, ...args)— the "uncurry-this" idiom —returns the wrong value (
[object Object], i.e. the receiver itself) instead ofinvoking
fnwith that receiver, when the receiver is a builtin prototypeobject such as
Object.prototypeorError.prototype. Plain objects,Array.prototype, andMathwork correctly.This idiom is the backbone of test262's
propertyHelper.js(
__hasOwnProperty = Function.prototype.call.bind(Object.prototype.hasOwnProperty)),so it gates
verifyPropertyfor every test whose subject isObject.prototype/Error.prototype/ other affected prototypes — a large cross-category blocker.Repro
Narrowing — the direct form works; only the
.call.bindindirection breaks, andonly for these receivers:
So the bound-call machinery, when the eventual receiver IS a builtin prototype,
returns the receiver instead of the method's result — it appears to confuse the
this/return slot in theFunction.prototype.call.bind(method)→ invoke path forthat receiver class.
Impact
verifyProperty-based test262 cases onObject.prototype/Error.prototype(e.g. allbuilt-ins/Error/prototype/*andbuilt-ins/NativeErrors/*descriptor tests — ~57 NativeErrors+Error cases stayred even though the underlying
getOwnPropertyDescriptor/delete/hasOwnPropertyoperations are all individually correct and Node-identical).Object.prototypeto verifyProperty.Note
A companion branch (
fix-error-descriptors, unpushed) makes Error instance +prototype
getOwnPropertyDescriptor/getOwnPropertyNames/deletefullyNode-identical, but those gains are unobservable through test262 until this
dispatch bug is fixed. Recommend fixing this first, then that work lands the
Error cluster.
Filed from the parity-fix loop. Root cause localized to the
Function.prototype.call.bind(method)invoke path for builtin-prototype receivers.