Skip to content

runtime: Map/WeakMap.prototype.set reflective on invalid receiver crashes (SIGBUS) instead of TypeError (#3662) #4099

Description

@proggeramlug

Part of the #3662 cluster (collection prototype brand checks, originally PR #3739).

Map.prototype.set / WeakMap.prototype.set invoked reflectively on an invalid
receiver crashes the process (EXC_BAD_ACCESS, exit 138) instead of throwing
the spec TypeError. The sibling methods (Map.prototype.get, Set.prototype.add,
etc.) correctly throw — only .set crashes.

Repro

(Map.prototype.set as any).call(null, 1, 2);   // SIGBUS — should throw TypeError
$ perry repro.ts -o /tmp/r && /tmp/r
<no output>
$ echo $?
138

node --experimental-strip-types throws TypeError: Method Map.prototype.set called on incompatible receiver null.

Notes

  • Reproduces on a clean main build under both the default auto-optimize and
    PERRY_NO_AUTO_OPTIMIZE=1.
  • The merged runtime: builtins must throw spec-mandated TypeError/RangeError on invalid this/args #3662 gap test test-files/test_gap_3662_collection_brand_check.ts
    currently crashes on main at line 26 (Map.set null) — it prints 5 lines
    then aborts, so the brand-check suite is silently truncated.
  • map_proto_set_thunk itself looks correct (it calls map_receiver_or_throw
    before js_map_set); the fault is in the reflective .call dispatch reaching
    it / the BUILTIN_MAP_SET_VALUE_BITS "remembered set value" path. An lldb
    backtrace shows a type-confusion deref (EXC_BAD_ACCESS code=2) in a
    NaN-box-tag check, before the brand check runs.

Severity

High — a crash, and it masks the rest of the collection brand-check test.

Activity

  1. andrewtdiz commented on Jun 2, 2026

    @andrewtdiz
    Contributor

    I am taking this with #4100 and #4102 in one runtime reflective-builtins PR cut. Planned scope: fix reflective collection set receiver validation, primitive wrapper prototype brand/value dispatch, and dynamic instanceof / constructor @@hasInstance recognition for Array/Object/Date without taking the separate function-source or typed-array-view work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions