Repository navigation
fix(runtime): expose global builtin function values + rebound builtin constructors - #3487
Merged
Merged
Conversation
added 2 commits
May 31, 2026 01:27
… constructors Closes #2905, closes #2889. #2905: parseInt/parseFloat/isNaN/isFinite/encodeURI/decodeURI/ encodeURIComponent/decodeURIComponent are now function-valued properties on globalThis with real dispatch, so globalThis.parseInt and const p = parseInt; p(...) match Node. Added thunks delegating to the existing runtime helpers, registered them in GLOBAL_THIS_BUILTIN_FUNCTIONS, mirrored in codegen is_global_this_builtin_name and HIR is_builtin_global_value_name. #2889: rebound global builtin constructors go through real semantics. Number/ Boolean call-form thunks (Object/String already had them); js_new_function_ construct now constructs Error subclasses, RegExp, and typed arrays through a rebound value; Object (keys/values/entries/freeze/create/getPrototypeOf/ getOwnPropertyNames/fromEntries/assign) and Array (isArray/from/of) statics installed on the constructor closures so const O = Object; O.keys(x) works.
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.
Closes #2905
Closes #2889
#2905 — standard global function values on globalThis
parseInt,parseFloat,isNaN,isFinite,encodeURI,decodeURI,encodeURIComponent, anddecodeURIComponentare now function-valued properties onglobalThiswith real dispatch. Reading them (globalThis.parseInt, bareconst p = parseInt) yields a callable closure (typeof === "function"), and calling that closure goes through Perry's existing runtime helpers — matching Node.Implementation:
object/global_this.rsdelegating tojs_parse_int/js_parse_float/js_is_nan/js_is_finite/js_encode_uri*/js_decode_uri*, and listed the names inGLOBAL_THIS_BUILTIN_FUNCTIONSwith their dispatch arms.is_global_this_builtin_namesoglobalThis.<name>property reads route through the singleton instead of the0.0sentinel.is_builtin_global_value_nameso a bare value read (const p = parseInt) lowers toPropertyGet { GlobalGet, name }. Bare calls (parseInt(x)) are still picked off earlier bytry_global_builtins→Expr::ParseInt/etc., so the call fast paths are unchanged.#2889 — rebound global builtin constructors through real semantics
Number/Boolean(Object/String already had them):const N = Number; N("42")→42,const B = Boolean; B(0)→false.js_new_function_constructnow constructs through a rebound global value forErrorand its subclasses (TypeError/RangeError/ReferenceError/SyntaxError/EvalError/URIError),RegExp, and all typed arrays (Uint8Array, …).Array/Object/Datewere already handled.Objectconstructor closure (keys/values/entries/freeze/create/getPrototypeOf/getOwnPropertyNames/fromEntries/assign) and theArrayclosure (isArray/from/of), soconst O = Object; O.keys(x)andArray.isArray(new A(1))dispatch through the real helpers.Validation
Gap test
test-files/test_gap_global_builtins_2905_2889.tsis byte-identical tonode --experimental-strip-typesunder the DEFAULT auto-optimize compile. Coverstypeof globalThis.<fn>,const p = parseInt; p("42px"),const A = Array; new A(2).length/Array.isArray(new A(1)),const O = Object; O.keys({a:1,b:2}), and reboundNumber/String/Booleancall-form. Additional manual checks (reboundTypeError/Uint8Array/RegExpconstruct, direct-call non-regression) also match Node.cargo test -p perry-hirandcargo test -p perry-runtime object::green;cargo fmt --all -- --checkclean;./scripts/check_file_size.shexit 0 (no file pushed over the 2000-line cap). No new HIR variant, no new#[no_mangle]fn (thunks are referenced by pointer from live code), no manifest/docs change.Scope notes (not in this PR)
escape/unescapeglobal functions: Perry has no runtime helper for the legacy%XXescape codec yet, so they remain unimplemented (a separate runtime addition).new Number(x)/new Boolean(x)/new String(x)returning a boxed object): Perry does not model primitive wrapper objects, so the reboundnew-form for these falls back to the existing behavior. Call-form coercion (the common case) works.Objectstatics (defineProperty,getOwnPropertyDescriptor,setPrototypeOf, …) is not reified on the rebound constructor value; directObject.defineProperty(...)is unaffected.