Skip to content

fix: JSON.stringify Proxy bypass — Proxy traps don't fire during stringify walk #421

Description

@dowdiness

Context

PR #419 (0b3b69f) fixed `json_internalize` to use interpreter-aware abstract operations. Its counterpart — `json_stringify_value` — still accesses `PropertyBag` directly and unwraps Proxy before doing anything, so Proxy traps never fire during stringify.

Problem

`json_stringify_value` in `interpreter/stdlib/builtins_json.mbt` has three bag-bypass sites:

  • Line 610–624: Proxy is unwrapped to its `.target` before serializing — `get`, `ownKeys`, and `getOwnPropertyDescriptor` traps never fire.
  • Line 742: `toJSON` lookup walks `obj_data.bag.properties` directly — accessor getters on `toJSON` don't propagate errors.
  • Lines 815/831: Object key enumeration and value reads use `data.bag.properties` directly.

The pattern from PR #419's `json_internalize` is the template:

  • Replace `data.bag.properties.get(k)` with `interp.get_property(val, k, loc)`
  • Replace key enumeration with `@runtime.object_keys(interp, val)`
  • Replace Proxy unwrap at line 610 with routing through abstract operations (let Proxy dispatch handle it)

Suggested work

Rewrite the Object and Proxy branches of `json_stringify_value` to use interpreter-aware operations, following the same pattern as `json_internalize` in PR #419. `json_stringify_value` already accepts `interp : Interpreter?` — change the Object/Proxy branches to require `Some(ip)` and use it for property access.

Acceptance criteria

  • `make test262-filter FILTER=built-ins/JSON/stringify` improves from 64/116 (55.2%) with at least the Proxy-related tests now passing
  • No regressions in `built-ins/JSON/parse`
  • `moon test` passes clean

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