fix(runtime): Temporal.PlainTime/PlainYearMonth/PlainMonthDay/Now test262 parity (33.6%→82.1%)#4818
Merged
Merged
Conversation
ec460a1 to
debbb67
Compare
…ed infra (squashed)
debbb67 to
1f38a69
Compare
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
Raises built-ins/Temporal test262 parity dramatically. The fixes split into Temporal-specific work (my assigned types) and cross-cutting fixes that lift every Temporal type (and general codegen):
Zero regressions across the full built-ins/Temporal suite (verified by diffing failure sets against the
origin/mainbaseline binary), and zero non-Temporal regressions across abuilt-ins languageshard-0/12 run. Scored Perry-only (self-validating; the Node oracle has no Temporal). Sweepjobs=16 timeout=90on the shared Linux box (contention at higher jobs yields spurious "Wrote executable" compile-fails — all real failures are runtime-fails).Root causes fixed
instanceoffor Temporal values (~241) — Temporal cells are NaN-boxed with no JS class chain, sox instanceof Temporal.PlainTimewas always false (everyTemporalHelpers.assert*opens with it).temporal_ctor_kind(matches the ctor closure'sfunc_ptr) wired intojs_instanceof_dynamic;Temporal.Xmember RHS routed through the dynamic-instanceof path in HIR lowering.Closure-call wrappers dropped args beyond the 5th (cross-cutting general codegen fix) —
__perry_wrap_*wrappers hardcoded a 5-arg signature (stale "js_closure_call only goes up to 5" comment). Any function/method with >5 params invoked as a value or via the method-dispatch tower (obj.m(...), apply, callbacks) silently zeroed args 6+. Surfaced viaassertDuration(12 params) /assertPlainTime(7). Cap raised to 16 (4 wrapper sites) +js_native_call_value's per-arity dispatch extended 8→16 (+array fallback). The dispatch tower already pads short calls to the declared arity.Real
Temporal.<Type>.prototypeobjects (~176) — prototypes were empty, so prop-desc / branding / length / name / builtin / not-a-constructor introspection all failed. Populated each prototype (all 9 types) with brand-checking accessor getters and method functions (spec.length/.name, non-constructable) sharing two generic thunks, plus@@toStringTag+constructor. Built without touching globalThis (population runs inside the singleton init whereGLOBAL_THIS_READYis still false — the obviousjs_function_prototype_value_for_readroute deadlocks onjs_get_global_this); registered in the synthetic-class-id prototype cache sonew Temporal.X()doesn't overwrite it.Options / coercion spec compliance (~150+, all types) —
toStringhonors its options (calendarName/fractionalSecondDigits/smallestUnit/roundingMode, plus ZDToffset/timeZoneNameand InstanttimeZone) across Duration/PlainDate/PlainDateTime/PlainTime/PlainYearMonth/PlainMonthDay/ZonedDateTime/Instant;until/since/add/subtract/round/with/fromparse their option bags; GetOption ToString-coerces present-but-wrong-type values (number→RangeError, Symbol→TypeError) instead of ignoring them;roundingIncrementvalidates NaN/Infinity/0/0.9/1e9+1; GetOptionsObject rejects primitives; ToTemporalX of a non-string primitive / Symbol / empty property bag → TypeError; non-finite numeric fields → RangeError;from()applies overflow (constrain default); YearMonth/MonthDay coerce viafrom_partial(monthCode support); calendar must be a string. Fixed.toString(optionsObj)mis-routing to the numerictoString(radix)path for Temporal receivers.Cell immutability / getPrototypeOf — writes to a Temporal cell are no-ops (fixes segfaults from subclassing probes that did
instance.constructor = …);Object.getPrototypeOf(temporalValue)returns its prototype via a per-kind class-id registry instead of derefing the cell.Key files
crates/perry-codegen/src/codegen/artifacts.rs(wrapper arity 5→16),expr/instance_misc1.rs,crates/perry-hir/src/lower/lower_expr.rs(instanceof routing)crates/perry-runtime/src/closure/dispatch.rs(arity 8→16),value/to_string.rs(radix routing),value/dyn_index.rs+object/field_set_by_name.rs(cell-write no-op),object/object_ops.rs(getPrototypeOf)crates/perry-runtime/src/object/{instanceof.rs, global_this.rs, temporal_proto.rs (new)}crates/perry-runtime/src/temporal/*(options + all type modules)Remaining (deferred)
order-of-operations observable read-ordering; leap-second string parsing;
@@toStringTagwritable descriptor (pre-existing symbol-attr staleness, affects Now too); Temporal subclassing/@@species; PlainTime/YM/MDvalueOfinterception; a few calendar/field edge cases.