Commit Graph
4353 Commits
Author SHA1 Message Date
Chris Tate ad33563c44 Merge main 2026-10-23 05:57:14 -05:00
Chris Tate 0222bb1058 Keep fiber stacks across short event-loop sleeps (#1977) 2026-10-23 04:52:57 -05:00
Chris Tate 50c8e1c693 Assign private fields through untyped receivers with logical assignment (#1983) 2026-10-23 04:46:35 -05:00
Chris Tate 900bd2cf01 Check generateKeyPair arguments and RSA parameters as Node does (#1973) 2026-10-23 04:39:34 -05:00
Malte UblandClaude Opus 5.5 72736211b1 Assign private fields through untyped receivers with logical assignment
`other.#x ??= value` (and `||=`, `&&=`) on a receiver JavaScript leaves
untyped read and wrote an ordinary property named "#x" instead of the
brand-checked private field, so the field kept its old value. Hono's
RegExpRouter numbers its parameter nodes with `next.#varIndex ??=
context.varIndex++`; without the stored index its regular expression lost
every parameter capture, and `c.req.param("id")` answered undefined.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 02:38:34 -07:00
Chris Tate 53838b39ec Call methods of bag-tracked class instances without building their views (#1979) 2026-10-23 04:37:54 -05:00
Chris Tate 58d3603549 Accept a callable Proxy as the generateKeyPair callback
generateKeyPair tested its callback, and a function in the options
position, by the checked-dynamic kind, so a Proxy whose target is a
function threw ERR_INVALID_ARG_TYPE. Node checks typeof, which answers
"function" for such a Proxy. Both tests now ask whether the value is
callable.
2026-10-23 04:33:56 -05:00
Chris Tate 695a90b0c1 Reuse the bundled declaration files' diagnostics across builds (#1981) 2026-10-23 04:32:18 -05:00
Chris Tate d8139c7bdb Test the function tag before comparing a class constructor's key (#1980) 2026-10-23 04:27:37 -05:00
Chris Tate fb200c1240 Reuse the bundled declaration files' diagnostics across builds 2026-10-23 04:27:14 -05:00
Chris Tate 8bb9ee8c57 Check generateKeyPair arguments and RSA parameters as Node does 2026-10-23 03:38:18 -05:00
Chris Tate 64db69aefc Declare the property-bag helpers in the runtime header (#1972) 2026-10-23 03:33:07 -05:00
Chris Tate 9e41d505b6 Declare the property-bag helpers in the runtime header
scr_dyn_bag_create_field and scr_dyn_is_class_capsule are declared by
the LLVM backend; their prototypes move from scr_json.c into scr_dyn.h,
which llvm-runtime-abi.test.ts checks the backend's declares against.
2026-10-23 03:30:06 -05:00
Malte UblandClaude Opus 5.5 5aef6597ab Test the function tag before comparing a class constructor's key
dyn.classIs went through the generic library call: retain the receiver,
call scr_dyn_class_is_key, release it (and buffer it as a cycle candidate).
A class's static property bag dispatch (%dyn.class.staticProperties) runs
one probe per compiled class for every untyped property read, so this cost
about 500 instructions per read in a Hono app. The probe now tests the
value's function tag inline, as the capsule probes test theirs, so LLVM
skips the chain for every other value, and borrows the receiver across a
literal key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 01:28:47 -07:00
Malte UblandClaude Opus 5.5 3cbd1740a8 Call methods of bag-tracked class instances without building their views
Untyped code calling a method on an instance of a compiled JavaScript class
whose own properties live in a property bag materialized the instance's
whole checked view on every call (copying the bag, boxing each field and
attaching the prototype) only to read one member. Hono's Context declares
its methods as arrow-function fields, so every c.header() or c.json() from
middleware rebuilt an 18-property view.

The materializer of such a class gives the view exactly the bag's
string-keyed properties, the declared fields among them with their native
slot values, and the class's prototype. The compiler now emits those parts
as ScrDynTypedBagClassOps (bag, prototype, declared field names, field
getter) and binds them to the class's capsules, and scr_dyn_invoke resolves
a member that is an ordinary data property, own or inherited, from them,
calling it with the capsule as this. Accessors, read-only fields, capsule
prototype links and everything else still build the view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 01:28:46 -07:00
Chris Tate 892758e86b Test catch bindings against class bindings (#1968) 2026-10-23 03:26:31 -05:00
Chris Tate 8d6bb60847 Test caught values against the class a class binding holds
A class binding may hold a subclass of the class it was declared with.
When the declared class has subclasses, a caught payload of that class is
now tested against the class the binding holds, as for other operands, so
a base-class instance no longer passes a test against a subclass.
2026-10-23 03:20:31 -05:00
Chris Tate 4511be6307 Give rebuilt property-bag stores their prototype (#1967) 2026-10-23 03:09:00 -05:00
Chris Tate 6e9023ed1f Merge main 2026-10-23 03:04:14 -05:00
Chris Tate 88d15a8ea7 Call own accessors over an Error's name and message from typed code (#1957) 2026-10-23 02:48:44 -05:00
Chris Tate 4d83db26bd Index strings through checker-any receivers (#1965) 2026-10-23 02:44:28 -05:00
Chris Tate a474ff7e8d Check for Error accessors after definitions over object-typed targets
The reflection gate turned on only for an untyped or Error-shaped
defineProperty target, so a helper taking `target: object` (or `{}`,
`Object`, a weak type, or a type parameter) installed a message or name
accessor that typed Error reads then skipped, returning the old slot
value. The gate now turns on for any target an Error may flow into: an
untyped or generic type, a type Error is assignable to, or an
Error-shaped type, alone or in a union or intersection.
2026-10-23 02:43:57 -05:00
Chris Tate b948d7946b Run match and search with untyped patterns (#1966) 2026-10-23 02:43:38 -05:00
Chris Tate 6318d35679 Iterate untyped Headers values (#1969) 2026-10-23 02:42:23 -05:00
Malte UblandClaude Opus 5.5 b1214f7607 Test catch bindings against class bindings
e instanceof E where e is a catch binding and E a binding holding a class expression (var E = class extends Error {}) refused with "'instanceof' right-hand sides other than classes declared in the program". The binding holds exactly that class, so the test is the class's caught test (hono's SmartRouter fallback on UnsupportedPathError).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 00:37:51 -07:00
Malte UblandClaude Opus 5.5 e269262d73 Iterate untyped Headers values
entries(), keys() and values() on a checked-dynamic Headers value threw 'is not a function'. They now return live native iterators over the sorted header list, re-read on every step with set-cookie values one by one, as Node's Headers iterator does (hono's Context copies response headers this way).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 00:37:51 -07:00
Malte UblandClaude Opus 5.5 fdcee191da Give rebuilt property-bag stores their prototype
Worklist passes that transform every function (the class-construction dispatch rewriting dyn.classBasePrototype) rebuild statement objects, so a recorded lazy bag store could be a detached copy. When the class gained prototype data later, only the copy was upgraded and the live store kept creating a bare {} bag: inherited methods read as undefined through the property bag (hono's SmartRouter.match once zod was in the program). Upgrades now also reach the stores as they stand in the generated bodies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 00:37:50 -07:00
Malte UblandClaude Opus 5.5 be6e63735a Index strings through checker-any receivers
An implicit-any package function specialized for a string argument lowered base?.[0] to the element-access refusal: the checker types the receiver any, so only the lowered string reached the string-index path. Hono's mergePath failed at startup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 00:37:49 -07:00
Malte UblandClaude Opus 5.5 b8d442e3ae Run match and search with untyped patterns
s.match(p) and s.search(p) with an untyped pattern now choose at run time, as Node does: a RegExp is used as is (with its lastIndex state), any other value builds new RegExp(value). The checked-dynamic receiver form previously threw 'method calls like path.match on a string are not supported yet' (hono's RegExpRouter matcher).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 00:37:49 -07:00
Chris Tate 3c8ccc7b97 Keep package results that pass their argument through out of the declaration boundary (#1964) 2026-10-23 02:30:41 -05:00
Malte UblandClaude Opus 5.5 1edb2fe92d Keep fiber stacks across short event-loop sleeps
Finished fiber stacks went back to a spare pool that the event loop
unmapped whenever it was about to sleep. A server's loop sleeps between
nearly every pair of requests, so each request that awaited mapped, faulted
in and unmapped a fresh 512 KiB stack: on a Hono server mmap, munmap and the
page faults were about a fifth of its CPU time. Spares now outlive short
sleeps. At most once a second a sleep unmaps the spares that no fiber took
since the previous trim, and a sleep longer than two seconds unmaps them
all, so an idle program still returns the memory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 00:29:27 -07:00
Chris Tate 358d2df536 Keep package results that pass their argument through out of the declaration boundary
A package function declared to return its own type parameter, which also
types one of its parameters (<T extends object>(obj: T) => T), hands back
the argument or something standing in for it, and the package may track
that object's identity. Effect's Equal.byReference returns a proxy it
keeps in a WeakSet. The declaration-typed boundary cast such a result to
the argument's type and built a separate native record, so
Equal.equals(a, b) on two by-reference objects compared them by value and
printed true where Node prints false. The result's type comes from the
caller's argument, not from data the package declares, so the projection
no longer casts these calls.

The package re-export coverage test now expects three dynamic statements:
since the boundary, readRows's declared number result keeps its type, so
count - 1 in 7004-package-declared-type-reexports is native arithmetic.
2026-10-23 02:23:33 -05:00
Chris Tate 94c00200ff Create untyped class instances' property-bag entries without the class tables (#1961) 2026-10-23 02:18:39 -05:00
Chris Tate b7d187f889 Keep inline caches for bag helpers with class-table exits 2026-10-23 02:10:57 -05:00
Chris Tate 2232c716a8 Compile instanceof against constructors held as values (#1909) 2026-10-23 01:56:13 -05:00
Chris Tate a71d15387d Exit the untyped class tables early for values that are not class capsules (#1962) 2026-10-23 01:55:52 -05:00
Chris Tate 6fba766e58 Merge main 2026-10-23 01:52:29 -05:00
Malte UblandClaude Opus 5.5 da546c05b3 Format the class-table exits
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:51:04 -07:00
Malte UblandClaude Opus 5.5 604f647e30 Update the normalization unit test for the hoisted receiver
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:50:59 -07:00
Malte UblandClaude Opus 5.5 756a93a8f2 Exit the untyped class tables early for values that are not class capsules
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:50:59 -07:00
Malte UblandClaude Opus 5.5 14a2769f58 Create untyped class instances' property-bag entries without the class tables
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:50:58 -07:00
Chris Tate f5cecccf5c Reflect the prototype of function-local classes without prototype members (#1958) 2026-10-23 01:46:06 -05:00
Chris Tate 1d68edc0f6 Give function-local class prototypes their own constructor
The prototype object of a function-local class, created once per evaluation
of the class, now starts with its own non-enumerable `constructor`, the
class value of that evaluation, as every class prototype does. Reflecting
the prototype of a function-local class without prototype members exposed
an object without it: `proto.constructor` answered the base class, and
`Object.hasOwn(proto, "constructor")` and its property descriptor did not
match Node.
2026-10-23 01:39:26 -05:00
Malte UblandClaude Opus 5.5 14ba361985 Call own accessors over an Error's name and message from typed code
zod 4 defines its error message with Object.defineProperty(inst, "message",
{ get, set }). The typed-ref commit of an Error subclass read the accessor
as a data value and threw "expected string". The commit and the slot sync
now leave the slot alone and mark the property absent; typed reads and
writes of name and message call the accessor when the program reflects on
an untyped or Error-shaped target.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:34:56 -07:00
Chris Tate 80f0bfada2 Resolve a forward local class per instance in hoisted functions (#1959) 2026-10-23 01:07:52 -05:00
Chris Tate 387419720e Support String.prototype.at on strings held in untyped values (#1948) 2026-10-23 01:03:32 -05:00
Chris Tate d942c27c2f Merge main 2026-10-23 01:01:03 -05:00
Chris Tate 468e0592bd Enumerate each record in the key order its object literal wrote (#1943) 2026-10-23 00:51:23 -05:00
Chris Tate 0418911874 Build the native compiler again after the two-counter while loop pass (#1956) 2026-10-23 00:50:32 -05:00
Chris Tate 341868ea9e Build fresh literals a JavaScript callee may reshape as plain objects (#1951) 2026-10-23 00:46:30 -05:00