Skip to content

feat(codemode): native coercion parity in interpreter#37608

Merged
rekram1-node merged 2 commits into
v2from
coercion-parity
Jul 18, 2026
Merged

feat(codemode): native coercion parity in interpreter#37608
rekram1-node merged 2 commits into
v2from
coercion-parity

Conversation

@rekram1-node

Copy link
Copy Markdown
Collaborator

Closes six coercion-parity gaps from interpreter-support.md where ordinary model-written JavaScript failed in CodeMode but works natively.

Changes

  • String method argument coercion: "v1.2".includes(1), "abc".slice("1"), "a1b".replace(1, 2) coerce like native JS (including the callback-replacer path). Opaque runtime references still reject as data errors; includes/startsWith/endsWith reject regular expressions with a native-style TypeError; split(undefined) returns the whole string with zero limits honored.
  • Zero-argument Number() and String() produce 0 and ""; Number(undefined) stays NaN.
  • Global coercing isFinite/isNaN, usable as callbacks (values.filter(isFinite)).
  • match()/matchAll()/search() with no argument behave as an empty pattern.
  • ++/-- use CodeMode numeric coercion instead of host Number(...). This also fixes a real crash: x = {}; x++ previously surfaced a raw host TypeError because SafeObjects are null-prototype and host ToPrimitive throws. coerceToNumber now routes arrays through interpreter string coercion for the same reason ([{}] no longer leaks "No default value").
  • Unknown static members read as undefined on global namespaces and the coercion functions, so feature detection (typeof Math.sumPrecise, Object.groupBy === undefined) works like native JS. Reads are gated on the same known-member sets the invoke switches use; calling an undefined value reports a native-style TypeError naming the callee (Math.sumPrecise is not a function.). Blocked members (constructor, __proto__, ...) still throw, and unknown Promise statics keep their descriptive error.

Deliberate documented deviations kept: repeat still requires a finite non-negative count (now branded RangeError), match/search arguments must still be a regex or string pattern, and opaque runtime references reject everywhere coercion happens.

Testing

  • ~45 new direct behavior tests in test/parity.test.ts, with odd edges (split(undefined, 0), padStart("3", 0), "abc".match().index) cross-checked against native JS.
  • 910 tests pass from packages/codemode; typecheck clean.
  • interpreter-support.md checklist updated in the same PR.

@rekram1-node
rekram1-node merged commit 5f437a0 into v2 Jul 18, 2026
10 of 12 checks passed
@rekram1-node
rekram1-node deleted the coercion-parity branch July 18, 2026 17:01
github-actions Bot pushed a commit to ReStranger/opencode that referenced this pull request Jul 18, 2026
* upstream/v2:
  feat(core): publish pending MCP status during connect (anomalyco#37605)
  feat(codemode): native coercion parity in interpreter (anomalyco#37608)
  test(core): stabilize shell progress test (anomalyco#37643)
  fix(ai): parse compatible reasoning deltas (anomalyco#37558)
  fix(core): remove session import cycle (anomalyco#37596)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant