fix(runtime+codegen): ramda init — toString/slice/hasOwnProperty/length#978
Merged
Conversation
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.
8bba0e8 to
efebb2b
Compare
This was referenced May 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five coordinated fixes that get every ramda curry/variadic helper past module init after #970 landed Function.prototype.apply/.call:
js_object_to_stringnow discriminates primitive tags + Array/Error GC types so ramda's_isString/_isObject/_isRegExp/_isArgumentsIIFEs see the spec-exact"[object Tag]"strings.js_native_call_methodgainshasOwnProperty/propertyIsEnumerablearms (used bykeys.js/_has.js/_clone.js).populate_global_this_builtinsinstallsArray.prototype.sliceandObject.prototype.toStringas real callable closures backed byIMPLICIT_THIS.lower_call.rsno longer fast-paths well-known Object.prototype methods through the class dispatch tower for user-class receivers.emit_string_poolnow registers__perry_wrap_<name>arities and the closure property accessor intercepts.lengthso theconverge/juxt/useWithchain (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').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 needsjs_new_function_constructto link the constructor's prototype object into the per-instance method lookup chain — tracked as the next ramda blocker.See
CHANGELOG.mdfor the five-step root-cause walkthrough and file-by-file fix.Test plan
test-files/test_ramda_sum.tsbyte-for-byte againstnode --experimental-strip-types(5 mini-reproducers).test_function_apply_call.ts/test_issue_711_function_prototype.ts/test_issue_838_prototype_methods.tscontinue to pass.cargo fmt --all+cargo build --release -p perry-runtime -p perry-stdlib -p perry.lint,cargo-test,parity,compile-smoke,api-docs-drift,security-audit.