Skip to content

Object(BigInt)/Object(Symbol) wrapper abstract equality bypasses valueOf/toString (ToPrimitive protocol skipped) #115

Description

@nooga

Found while triaging test262 regressions exposed by #112 (built-ins/BigInt/wrapper-object-ordinary-toprimitive.js and the analogous built-ins/Symbol/prototype/Symbol.toPrimitive/redefined-symbol-wrapper-ordinary-toprimitive.js). Pre-existing bug, unrelated to #65/#112's mechanism - just uncovered by it (the test previously died silently before reaching the failing assertion).

Repro

const BigIntValueOf = BigInt.prototype.valueOf;
Object.defineProperty(BigInt.prototype, "valueOf", {
  get: () => {
    console.log("valueOf getter called");
    return function () {
      console.log("valueOf() called");
      return BigIntValueOf.call(this) * 2n;
    };
  },
});
console.log(Object(1n) == 2n); // expected: true (via the overridden valueOf); actual: false, no logging at all

Nothing is logged - the overridden valueOf getter is never invoked. Abstract equality between an Object(1n) wrapper and a BigInt primitive isn't going through ToPrimitive/GetMethod(@@toPrimitive)/OrdinaryToPrimitive at all; it's using some internal fast path that unwraps the BigInt value directly, bypassing user-overridden valueOf/toString entirely.

Scope

The test262 file this surfaced from exercises this across ==, +, string-template interpolation, and property-key coercion, with both toString and valueOf overridden at different points - the failure is at the very first assertion (hint: default via ==), so the rest of the file's coverage is unverified against our implementation. The sibling Symbol.toPrimitive test suggests the same gap likely applies to Object(Symbol()) wrapper comparisons too, though not independently confirmed.

Needs tracing through wherever abstract equality (==) special-cases BigInt-vs-Object comparisons in the VM to find where it skips the ToPrimitive protocol.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions