Skip to content

fix(runtime+codegen): ramda init — toString/slice/hasOwnProperty/length#978

Merged
proggeramlug merged 1 commit into
mainfrom
fix-ramda-init-prototype-methods
May 18, 2026
Merged

fix(runtime+codegen): ramda init — toString/slice/hasOwnProperty/length#978
proggeramlug merged 1 commit into
mainfrom
fix-ramda-init-prototype-methods

Conversation

@proggeramlug
Copy link
Copy Markdown
Contributor

Summary

Five coordinated fixes that get every ramda curry/variadic helper past module init after #970 landed Function.prototype.apply/.call:

  • js_object_to_string now discriminates primitive tags + Array/Error GC types so ramda's _isString / _isObject / _isRegExp / _isArguments IIFEs see the spec-exact "[object Tag]" strings.
  • js_native_call_method gains hasOwnProperty / propertyIsEnumerable arms (used by keys.js / _has.js / _clone.js).
  • populate_global_this_builtins installs Array.prototype.slice and Object.prototype.toString as real callable closures backed by IMPLICIT_THIS.
  • lower_call.rs no longer fast-paths well-known Object.prototype methods through the class dispatch tower for user-class receivers.
  • emit_string_pool now registers __perry_wrap_<name> arities and the closure property accessor intercepts .length so the converge / juxt / useWith chain (pluck('length', fns)reduce(max, 0, …)_arity(N, …)) sees real numbers.

Outcome

  • R.add(2, 3) / R.add(10)(20) work end-to-end via the direct module path (import add from 'ramda/src/add.js').
  • Full import * as R from 'ramda' still throws at module init — next blocker is the transducer prototype-on-callable pattern (XWrap.prototype['@@transducer/step'] = fn). That needs js_new_function_construct to link the constructor's prototype object into the per-instance method lookup chain — tracked as the next ramda blocker.

See CHANGELOG.md for the five-step root-cause walkthrough and file-by-file fix.

Test plan

  • test-files/test_ramda_sum.ts byte-for-byte against node --experimental-strip-types (5 mini-reproducers).
  • test_function_apply_call.ts / test_issue_711_function_prototype.ts / test_issue_838_prototype_methods.ts continue to pass.
  • cargo fmt --all + cargo build --release -p perry-runtime -p perry-stdlib -p perry.
  • CI: lint, cargo-test, parity, compile-smoke, api-docs-drift, security-audit.

Five coordinated fixes that get every ramda curry/variadic helper past
module init after #970 landed Function.prototype.apply/.call:

1. js_object_to_string (the codegen-inlined Object.prototype.toString.call
   helper) now discriminates primitive tags + GC_TYPE_ARRAY / GC_TYPE_ERROR
   so ramda's _isString/_isObject/_isRegExp/_isArguments IIFEs see the
   spec-exact "[object Tag]" strings instead of "[object Object]" across
   the board.
2. js_native_call_method gains hasOwnProperty / propertyIsEnumerable arms
   so keys.js / _has.js / _clone.js IIFEs don't throw `value is not a
   function` on the missing-method fall-through.
3. populate_global_this_builtins now installs `Array.prototype.slice` and
   `Object.prototype.toString` as real callable closures that read their
   receiver from IMPLICIT_THIS — covers `var ts = Object.prototype.toString;
   ts.call(x)` shapes that don't go through the inlined helper.
4. lower_call.rs no longer fast-paths well-known Object.prototype methods
   through the class dispatch tower for user-class instances, so the new
   arms in (2) actually fire on AnonShape receivers.
5. emit_string_pool now registers `__perry_wrap_<name>` wrappers' declared
   param counts in CLOSURE_ARITY_REGISTRY and the closure-property accessor
   intercepts `name == "length"` to return that arity. Unblocks the
   converge/juxt/useWith chain that builds curry arities via
   `pluck('length', fns)` → `reduce(max, 0, …)` → `_arity(N, …)`.

Validated against `node --experimental-strip-types` byte-for-byte via
new test-files/test_ramda_sum.ts (5 mini-reproducers). `R.add(2,3)` /
`R.add(10)(20)` work end-to-end through the direct module path. Full
`R.sum([1,2,3,4,5])` still blocks on the transducer prototype-on-callable
pattern (XWrap.prototype['@@transducer/step'] = fn) — tracked as the
next ramda blocker.
@proggeramlug proggeramlug force-pushed the fix-ramda-init-prototype-methods branch from 8bba0e8 to efebb2b Compare May 18, 2026 01:58
@proggeramlug proggeramlug merged commit 22f9f5a into main May 18, 2026
5 of 9 checks passed
@proggeramlug proggeramlug deleted the fix-ramda-init-prototype-methods branch May 18, 2026 01:58
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