@scriptc/compiler 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +12 -9
- package/ambient/scriptc.d.ts +2 -2
- package/dist/backend/cc.d.ts +2 -2
- package/dist/backend/emission/emit-async.js +1 -1
- package/dist/backend/emission/emit-exprs.js +97 -52
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-island.js +1 -1
- package/dist/backend/emission/emit-shapes.js +1 -1
- package/dist/backend/emission/emit-walkers.d.ts +14 -14
- package/dist/backend/emission/emit-walkers.js +44 -44
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +3 -3
- package/dist/backend/emission/emitter.js +8 -8
- package/dist/backend/emission/may-throw.js +1 -1
- package/dist/backend/llvm/dyn.d.ts +10 -10
- package/dist/backend/llvm/dyn.js +26 -26
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +97 -43
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +1 -1
- package/dist/backend/llvm/walkers.js +2 -2
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +1 -1
- package/dist/diagnostics/diagnostic.js +4 -3
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +5 -5
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +12 -12
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +7 -7
- package/dist/frontend/lowering/lower-builtins.js +92 -31
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +4 -4
- package/dist/frontend/lowering/lower-calls.js +66 -66
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +31 -5
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +5 -5
- package/dist/frontend/lowering/lower-containers.js +19 -19
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.js +2 -2
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +7 -7
- package/dist/frontend/lowering/lower-exprs.js +158 -112
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +5 -5
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +12 -3
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +16 -16
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +11 -1
- package/dist/frontend/lowering/lower-namespaces.js +41 -6
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +11 -11
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
- package/dist/frontend/lowering/lower-stmts.js +191 -30
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +66 -22
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +10 -10
- package/dist/frontend/lowering/lowerer.js +51 -37
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.js +2 -2
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/program.js +1 -1
- package/dist/frontend/shared.js +7 -7
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +2 -2
- package/dist/frontend/types.js +15 -15
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.js +38 -7
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +110 -98
- package/dist/ir/nodes.js +48 -21
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +44 -34
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/int-infer.js +13 -0
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/profile.d.ts +8 -6
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar-validate.js +1 -1
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +1 -1
- package/dist/library/sidecar.js +20 -7
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { canMarshalFuncIntoIsland, CAUGHT, DYN, F64, islandCallbackRet, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesProcessEvents, moduleUsesStream, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, typeEquals, typeKey, VOID } from "../../ir/nodes.js";
|
|
1
|
+
import { canMarshalFuncIntoIsland, CAUGHT, DYN, F64, islandCallbackRet, islandPromisePayloadTag, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, moduleUsesDynInvoke, moduleUsesFetch, moduleUsesFsWatch, moduleUsesHttpServer, moduleUsesNet, moduleUsesProcessEvents, moduleUsesStream, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, STRING, typeEquals, typeKey, VOID } from "../../ir/nodes.js";
|
|
2
2
|
import { computeMayThrow } from "../emission/may-throw.js";
|
|
3
3
|
import { mangleArgPack, mangleAsyncSpawn, mangleClassNew, mangleClassObj, mangleClassRetain, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenResThunk, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordNew, mangleRecordStruct, mangleResolveThunk, mangleTrampoline, mangleVtStruct, mangleWrapper } from "../mangle.js";
|
|
4
4
|
import { BlockBuilder } from "./blocks.js";
|
|
@@ -340,7 +340,7 @@ const LIB_FN_SYMS = {
|
|
|
340
340
|
"sym.toString": "scr_sym_to_string",
|
|
341
341
|
"error.toString": "scr_error_to_string",
|
|
342
342
|
"class.name": "scr_classobj_name",
|
|
343
|
-
// The dyn (ScrDyn
|
|
343
|
+
// The dyn (ScrDyn dyn) surface (scr_json.c / scr_dyn_invoke.c):
|
|
344
344
|
// json.parse throws the catchable SyntaxError; keySet/toString/
|
|
345
345
|
// defineProps throw Node's TypeErrors (all in the may-throw seed set —
|
|
346
346
|
// the generic path emits the standard pending check). typeof and the
|
|
@@ -348,6 +348,8 @@ const LIB_FN_SYMS = {
|
|
|
348
348
|
"json.parse": "scr_json_parse",
|
|
349
349
|
"dyn.keySet": "scr_dyn_key_set",
|
|
350
350
|
"dyn.iterPack": "scr_dyn_iter_pack",
|
|
351
|
+
"dyn.arrLen": "scr_dyn_arr_len",
|
|
352
|
+
"dyn.arrAt": "scr_dyn_arr_at",
|
|
351
353
|
"dyn.defineProps": "scr_dyn_define_props",
|
|
352
354
|
"dyn.typeof": "scr_dyn_typeof",
|
|
353
355
|
"dyn.toString": "scr_dyn_to_string_method",
|
|
@@ -535,7 +537,7 @@ const LIB_FN_SYMS = {
|
|
|
535
537
|
"dc.tcTraceCallback": "scr_dc_tc_trace_callback",
|
|
536
538
|
"dc.tcTracePromise": "scr_dc_tc_trace_promise",
|
|
537
539
|
// AsyncLocalStorage (scr_async_dyn.c): store ids are doubles, values
|
|
538
|
-
// ride the
|
|
540
|
+
// ride the checked-dynamic tree; run/exitRun dispatch user callbacks (may-throw).
|
|
539
541
|
// The dc bind-store trio shares the als id space.
|
|
540
542
|
"als.new": "scr_als_new",
|
|
541
543
|
"als.get": "scr_als_get",
|
|
@@ -547,7 +549,7 @@ const LIB_FN_SYMS = {
|
|
|
547
549
|
"dc.chanUnbindStore": "scr_dc_chan_unbind_store",
|
|
548
550
|
"dc.chanRunStores": "scr_dc_chan_run_stores",
|
|
549
551
|
// process warning/rejection events (scr_lib.c / scr_async_dyn.c):
|
|
550
|
-
//
|
|
552
|
+
// dyn listeners are borrowed (the runtime retains its copy);
|
|
551
553
|
// onUnhandledRejection marks the loop live (the loop-end report
|
|
552
554
|
// dispatches the listeners).
|
|
553
555
|
"process.onWarning": "scr_process_on_warning",
|
|
@@ -568,7 +570,7 @@ const LIB_FN_SYMS = {
|
|
|
568
570
|
"regexp.escape": "scr_regexp_escape",
|
|
569
571
|
// The dyn Object walks (throw on nullish receivers), structuredClone
|
|
570
572
|
// (option/DataClone/cycle errors), and new RegExp's eager compile
|
|
571
|
-
// (catchable SyntaxError) — all may-throw generics over the
|
|
573
|
+
// (catchable SyntaxError) — all may-throw generics over the checked-dynamic tree.
|
|
572
574
|
"dyn.objKeys": "scr_dyn_obj_keys",
|
|
573
575
|
"dyn.hasOwn": "scr_dyn_has_own",
|
|
574
576
|
"dyn.assign": "scr_dyn_assign",
|
|
@@ -719,7 +721,7 @@ class LlEmitter {
|
|
|
719
721
|
* rewriter, union ToString/join) — interned per typeKey/unionId, defs
|
|
720
722
|
* flushed with the shape helpers. */
|
|
721
723
|
walkers = new LlWalkers(this);
|
|
722
|
-
/** The dyn (ScrDyn
|
|
724
|
+
/** The dyn (ScrDyn dyn) helper registry — dyn.ts's interned ports of
|
|
723
725
|
* emit-walkers.ts's dyn slice. */
|
|
724
726
|
dyn = new LlDyn(this);
|
|
725
727
|
/** External declarations, in first-use order. */
|
|
@@ -2036,7 +2038,7 @@ class LlEmitter {
|
|
|
2036
2038
|
return t;
|
|
2037
2039
|
}
|
|
2038
2040
|
case "dyn": {
|
|
2039
|
-
// ToBoolean over the
|
|
2041
|
+
// ToBoolean over the dyn kind (scr_dyn_truthy — JS-exact for
|
|
2040
2042
|
// every kind; borrowed, never throws): `v || dflt` and condition
|
|
2041
2043
|
// descent on checked-dynamic values.
|
|
2042
2044
|
this.declare(`declare zeroext i1 @scr_dyn_truthy(ptr)`);
|
|
@@ -3714,7 +3716,7 @@ class LlEmitter {
|
|
|
3714
3716
|
return this.own({ name: t, type: e.type });
|
|
3715
3717
|
}
|
|
3716
3718
|
if (v.type.kind === "dyn") {
|
|
3717
|
-
// String(unknown): dispatch over the
|
|
3719
|
+
// String(unknown): dispatch over the dyn kind (dyn.ts's sc_ds —
|
|
3718
3720
|
// Node's String() incl. arrays-join and "[object Object]").
|
|
3719
3721
|
const helper = this.dyn.dynToStrHelper();
|
|
3720
3722
|
const t = B.tmp();
|
|
@@ -4015,7 +4017,7 @@ class LlEmitter {
|
|
|
4015
4017
|
this.unionTagSwitch(u.name, def, (arm) => {
|
|
4016
4018
|
if (isUnitType(arm)) {
|
|
4017
4019
|
if (e.type.kind === "dyn") {
|
|
4018
|
-
// A dyn-typed chain: the unit path is the undefined
|
|
4020
|
+
// A dyn-typed chain: the unit path is the undefined dyn
|
|
4019
4021
|
// value — dyn represents undefined directly.
|
|
4020
4022
|
this.declare(`declare ptr @scr_dyn_undefined()`);
|
|
4021
4023
|
this.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
|
|
@@ -4311,9 +4313,9 @@ class LlEmitter {
|
|
|
4311
4313
|
// the frame's release is a no-op) and the body reads it through
|
|
4312
4314
|
// chainRecv.
|
|
4313
4315
|
if (e.receiver.type.kind === "dyn") {
|
|
4314
|
-
// A dyn (
|
|
4316
|
+
// A dyn (dyn) receiver — the `rawName?.match(re)` step: the
|
|
4315
4317
|
// nullish test reads the node's kind tag; the unit path is the
|
|
4316
|
-
// undefined
|
|
4318
|
+
// undefined dyn singleton (dyn results) or nothing (void
|
|
4317
4319
|
// bodies), the body runs over the bound receiver otherwise.
|
|
4318
4320
|
const r = this.emitExpr(e.receiver);
|
|
4319
4321
|
const kd = this.dynKind(r.name);
|
|
@@ -4465,7 +4467,7 @@ class LlEmitter {
|
|
|
4465
4467
|
}
|
|
4466
4468
|
if (e.type.kind === "dyn") {
|
|
4467
4469
|
// A dyn-typed chain (`pricing?.[key]` over an unknown-valued
|
|
4468
|
-
// index signature): the unit path is the undefined
|
|
4470
|
+
// index signature): the unit path is the undefined dyn value —
|
|
4469
4471
|
// dyn represents undefined directly, no union wrapper exists.
|
|
4470
4472
|
const slotD = B.slot();
|
|
4471
4473
|
B.entryAllocas.push(`${slotD} = alloca ptr`);
|
|
@@ -4912,14 +4914,14 @@ class LlEmitter {
|
|
|
4912
4914
|
}
|
|
4913
4915
|
case "jsonStringify": {
|
|
4914
4916
|
// Type-directed serialization: the STATIC type picks an emitted
|
|
4915
|
-
// serializer (interned per typeKey) — no
|
|
4917
|
+
// serializer (interned per typeKey) — no dyn, no runtime dispatch.
|
|
4916
4918
|
// The value temp is BORROWED (released with this statement's
|
|
4917
4919
|
// frame); the result string is owned (+1). Never throws — except
|
|
4918
4920
|
// the dyn root below.
|
|
4919
4921
|
const v = this.emitExpr(e.value);
|
|
4920
4922
|
let compact;
|
|
4921
4923
|
if (e.value.type.kind === "dyn") {
|
|
4922
|
-
// A dyn root: the runtime's
|
|
4924
|
+
// A dyn root: the runtime's dyn walker (scr_dyn_format_j — the
|
|
4923
4925
|
// C backend's dispatch exactly): number/string/bool/null/array/
|
|
4924
4926
|
// object exact, dropped members omitted, and a dropped ROOT
|
|
4925
4927
|
// becomes the TEXT "undefined" (JSON.stringify(undefined) is
|
|
@@ -5084,7 +5086,7 @@ class LlEmitter {
|
|
|
5084
5086
|
if (e.arg === null) {
|
|
5085
5087
|
if (genT.nextT.kind === "dyn") {
|
|
5086
5088
|
// Valueless resume on a dyn channel: JS's undefined — the
|
|
5087
|
-
//
|
|
5089
|
+
// dyn singleton rides the IN slot (+1 moves in).
|
|
5088
5090
|
this.declare(`declare ptr @scr_dyn_undefined()`);
|
|
5089
5091
|
this.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
|
|
5090
5092
|
this.declare(`declare void @scr_dyn_release_v(ptr)`);
|
|
@@ -5552,10 +5554,10 @@ class LlEmitter {
|
|
|
5552
5554
|
return { name: "", type: e.type };
|
|
5553
5555
|
}
|
|
5554
5556
|
case "dynFrom": {
|
|
5555
|
-
// Static value → fresh
|
|
5557
|
+
// Static value → fresh dyn tree (+1) through the interned per-type
|
|
5556
5558
|
// converter; the operand stays borrowed (frame-released as usual).
|
|
5557
5559
|
// Bare unit literals (an `undefined`/`null` stored under an
|
|
5558
|
-
// `unknown` index signature) are the
|
|
5560
|
+
// `unknown` index signature) are the dyn unit values directly.
|
|
5559
5561
|
if (e.value.kind === "unitLit") {
|
|
5560
5562
|
const t = B.tmp();
|
|
5561
5563
|
if (e.value.unit === "undefined") {
|
|
@@ -5573,7 +5575,7 @@ class LlEmitter {
|
|
|
5573
5575
|
}
|
|
5574
5576
|
const v = this.emitExpr(e.value);
|
|
5575
5577
|
if (v.type.kind === "func") {
|
|
5576
|
-
// A closure boxes as the
|
|
5578
|
+
// A closure boxes as the checked-dynamic tree's function kind: retained closure +
|
|
5577
5579
|
// the per-signature call thunk + the interned signature key. The
|
|
5578
5580
|
// best-effort name rides along (null when the lowering had none).
|
|
5579
5581
|
const name = e.fnName !== undefined && e.fnName !== "" ? this.cstr(e.fnName) : "null";
|
|
@@ -5589,8 +5591,8 @@ class LlEmitter {
|
|
|
5589
5591
|
return this.own({ name: t, type: e.type });
|
|
5590
5592
|
}
|
|
5591
5593
|
case "dynFromJsval": {
|
|
5592
|
-
// Island value →
|
|
5593
|
-
// retains the cell in; engine scalars normalize to native
|
|
5594
|
+
// Island value → dyn: the by-reference wrap (scr_dyn_from_jsval
|
|
5595
|
+
// retains the cell in; engine scalars normalize to native dyn
|
|
5594
5596
|
// kinds at wrap time). Operand borrowed, result +1, never throws.
|
|
5595
5597
|
const v = this.emitExpr(e.value);
|
|
5596
5598
|
this.declare(`declare ptr @scr_dyn_from_jsval(ptr)`);
|
|
@@ -5609,7 +5611,7 @@ class LlEmitter {
|
|
|
5609
5611
|
return this.own({ name: t, type: e.type });
|
|
5610
5612
|
}
|
|
5611
5613
|
case "dynCheck": {
|
|
5612
|
-
// The dynamic boundary: validate the
|
|
5614
|
+
// The dynamic boundary: validate the checked-dynamic tree against the target type
|
|
5613
5615
|
// and BUILD the typed value (+1) — or throw the catchable
|
|
5614
5616
|
// path-annotated TypeError. The dyn temp is BORROWED; the result
|
|
5615
5617
|
// joins the frame BEFORE the pending check so an unwind releases
|
|
@@ -5630,11 +5632,11 @@ class LlEmitter {
|
|
|
5630
5632
|
// spelling rides along for Node's "<name> is not a function".
|
|
5631
5633
|
const callee = this.emitExpr(e.callee);
|
|
5632
5634
|
if (e.spreads !== undefined && e.spreads.length > 0) {
|
|
5633
|
-
// The RUNTIME-ARITY form (`f(...args)`): one fresh
|
|
5635
|
+
// The RUNTIME-ARITY form (`f(...args)`): one fresh dyn array
|
|
5634
5636
|
// collects the arguments left-to-right — plain args move in
|
|
5635
5637
|
// (push takes ownership), spread args FLATTEN (push_spread
|
|
5636
5638
|
// retains elements in and throws V8's spread-call TypeError for
|
|
5637
|
-
// non-iterable
|
|
5639
|
+
// non-iterable dyn kinds, checked per spread — JS's
|
|
5638
5640
|
// ArgumentListEvaluation order) — then apply calls through the
|
|
5639
5641
|
// array's elements (borrowed, exactly scr_dyn_call).
|
|
5640
5642
|
this.declare(`declare ptr @scr_dyn_new_arr()`);
|
|
@@ -5707,7 +5709,7 @@ class LlEmitter {
|
|
|
5707
5709
|
return out;
|
|
5708
5710
|
}
|
|
5709
5711
|
case "dynArrLit": {
|
|
5710
|
-
// A
|
|
5712
|
+
// A dyn array built element-by-element: ownership of each dyn
|
|
5711
5713
|
// element MOVES into the array (scr_dyn_arr_push's contract).
|
|
5712
5714
|
this.declare(`declare ptr @scr_dyn_new_arr()`);
|
|
5713
5715
|
this.declare(`declare void @scr_dyn_arr_push(ptr, ptr)`);
|
|
@@ -5722,7 +5724,7 @@ class LlEmitter {
|
|
|
5722
5724
|
return out;
|
|
5723
5725
|
}
|
|
5724
5726
|
case "dynObjLit": {
|
|
5725
|
-
// A
|
|
5727
|
+
// A dyn object built member-by-member: key then value, source
|
|
5726
5728
|
// order. scr_dyn_key_set BORROWS all three (the member retains the
|
|
5727
5729
|
// value in); the receiver is a fresh OBJ, so the non-object throw
|
|
5728
5730
|
// paths are unreachable here.
|
|
@@ -5739,7 +5741,7 @@ class LlEmitter {
|
|
|
5739
5741
|
return out;
|
|
5740
5742
|
}
|
|
5741
5743
|
case "dynKeyGet": {
|
|
5742
|
-
// Keyed read on the
|
|
5744
|
+
// Keyed read on the checked-dynamic tree through the one interned helper — the
|
|
5743
5745
|
// non-optional form throws JS's TypeError on an undefined/null
|
|
5744
5746
|
// receiver, and HANDLE receivers can throw the loud unmodeled-
|
|
5745
5747
|
// property ladder on EITHER form; the result is owned (+1).
|
|
@@ -5824,7 +5826,7 @@ class LlEmitter {
|
|
|
5824
5826
|
const [d, s, st] = e.left.type.kind === "dyn" ? [l, r, e.right.type] : [r, l, e.left.type];
|
|
5825
5827
|
let test;
|
|
5826
5828
|
if (st.kind === "dyn") {
|
|
5827
|
-
// dyn vs dyn: whole-
|
|
5829
|
+
// dyn vs dyn: whole-dyn strict equality.
|
|
5828
5830
|
this.declare(`declare zeroext i1 @scr_dyn_strict_eq(ptr, ptr)`);
|
|
5829
5831
|
test = B.tmp();
|
|
5830
5832
|
B.line(`${test} = call zeroext i1 @scr_dyn_strict_eq(ptr ${l.name}, ptr ${r.name})`);
|
|
@@ -5877,7 +5879,7 @@ class LlEmitter {
|
|
|
5877
5879
|
return { name: neg, type: e.type };
|
|
5878
5880
|
}
|
|
5879
5881
|
case "dynTest": {
|
|
5880
|
-
// A pure kind compare on the
|
|
5882
|
+
// A pure kind compare on the dyn node — borrowed; only the truthy
|
|
5881
5883
|
// form also reads a scalar payload (the runtime's ToBoolean).
|
|
5882
5884
|
const d = this.emitExpr(e.value);
|
|
5883
5885
|
let test;
|
|
@@ -5887,7 +5889,7 @@ class LlEmitter {
|
|
|
5887
5889
|
B.line(`${test} = call zeroext i1 @scr_dyn_truthy(ptr ${d.name})`);
|
|
5888
5890
|
}
|
|
5889
5891
|
else if (e.test === "error") {
|
|
5890
|
-
// `u instanceof Error`: the
|
|
5892
|
+
// `u instanceof Error`: the checked-dynamic tree's error encoding — an object
|
|
5891
5893
|
// carrying the reserved "%error" marker key — or a real engine
|
|
5892
5894
|
// Error held by reference (the isl helper answers false for
|
|
5893
5895
|
// every non-JSVAL kind, so the call is unconditional).
|
|
@@ -5954,7 +5956,7 @@ class LlEmitter {
|
|
|
5954
5956
|
test = orIsl(oneOf([DK.OBJ, DK.ARR, DK.BYTES, DK.HANDLE, DK.PROMISE, DK.NULL]), "scr_dyn_isl_typeof_is", this.cstr("object"));
|
|
5955
5957
|
}
|
|
5956
5958
|
else if (e.test === "array") {
|
|
5957
|
-
// Array.isArray: the
|
|
5959
|
+
// Array.isArray: the checked-dynamic tree's array kind, or the engine's own
|
|
5958
5960
|
// answer for an engine-held value.
|
|
5959
5961
|
test = orIsl(oneOf([DK.ARR]), "scr_dyn_isl_is_array");
|
|
5960
5962
|
}
|
|
@@ -5980,7 +5982,7 @@ class LlEmitter {
|
|
|
5980
5982
|
return { name: neg, type: e.type };
|
|
5981
5983
|
}
|
|
5982
5984
|
case "dynDestrCheck": {
|
|
5983
|
-
// RequireObjectCoercible with V8's destructuring TypeError.
|
|
5985
|
+
// RequireObjectCoercible with V8's destructuring TypeError. dyn
|
|
5984
5986
|
// values check in the runtime helper and pass through unchanged
|
|
5985
5987
|
// (same temp, same ownership); island values check in the engine
|
|
5986
5988
|
// (a fresh +1 cell for the same value comes back).
|
|
@@ -6001,7 +6003,7 @@ class LlEmitter {
|
|
|
6001
6003
|
}
|
|
6002
6004
|
case "dynIterN": {
|
|
6003
6005
|
// GetIterator + first-N steps as a fresh array (V8's exact
|
|
6004
|
-
// not-iterable TypeError on non-iterables): the
|
|
6006
|
+
// not-iterable TypeError on non-iterables): the dyn helper for
|
|
6005
6007
|
// dyn operands, the engine's real iterator protocol for island
|
|
6006
6008
|
// ones.
|
|
6007
6009
|
const v = this.emitExpr(e.value);
|
|
@@ -6033,7 +6035,9 @@ class LlEmitter {
|
|
|
6033
6035
|
const v = this.emitExpr(e.value);
|
|
6034
6036
|
const payload = e.type.kind === "promise" && e.type.inner.kind === "void"
|
|
6035
6037
|
? 0 // SCR_ISLP_VOID
|
|
6036
|
-
:
|
|
6038
|
+
: e.type.kind === "promise" && e.type.inner.kind === "array" && e.type.inner.elem.kind === "jsval"
|
|
6039
|
+
? 5 // SCR_ISLP_JSVAL_ARR: the Array.isArray-gated by-reference exit at settle
|
|
6040
|
+
: 4; // SCR_ISLP_JSVAL
|
|
6037
6041
|
this.declare(`declare ptr @scr_jsval_bridge_promise(ptr, i32)`);
|
|
6038
6042
|
const t = B.tmp();
|
|
6039
6043
|
B.line(`${t} = call ptr @scr_jsval_bridge_promise(ptr ${v.name}, i32 ${payload})`);
|
|
@@ -6081,7 +6085,7 @@ class LlEmitter {
|
|
|
6081
6085
|
case "string":
|
|
6082
6086
|
return simple("scr_jsval_from_str", "ptr", false);
|
|
6083
6087
|
case "dyn":
|
|
6084
|
-
// A CHECKED-DYNAMIC (
|
|
6088
|
+
// A CHECKED-DYNAMIC (dyn) value entering the island: deep copy,
|
|
6085
6089
|
// data kinds only — boxed functions/handles/promises throw the
|
|
6086
6090
|
// catchable TypeError in the runtime, and a wrapped island value
|
|
6087
6091
|
// unwraps to the SAME engine value (the identity round trip).
|
|
@@ -6093,6 +6097,25 @@ class LlEmitter {
|
|
|
6093
6097
|
case "url":
|
|
6094
6098
|
// A URL crossing IN: an engine URL instance built from href.
|
|
6095
6099
|
return simple("scr_jsval_from_url", "ptr", true);
|
|
6100
|
+
case "promise": {
|
|
6101
|
+
// A STATIC promise crossing IN: a real engine thenable settled
|
|
6102
|
+
// when the scriptc promise settles (the async-callback return
|
|
6103
|
+
// bridge). from_promise takes ownership of a +1 — retain past
|
|
6104
|
+
// the borrowed frame temp. The C emitter's rule, mirrored.
|
|
6105
|
+
const tag = islandPromisePayloadTag(e.value.type.inner);
|
|
6106
|
+
if (!tag)
|
|
6107
|
+
throw new Error("llvm emitter bug: jsMarshal of a promise outside the bridge payload domain");
|
|
6108
|
+
const tagN = { void: 0, f64: 1, bool: 2, string: 3, jsval: 4, jsvalArr: 5 }[tag];
|
|
6109
|
+
this.declare(`declare ptr @scr_promise_retain(ptr)`);
|
|
6110
|
+
this.declare(`declare ptr @scr_jsval_from_promise(ptr, i32)`);
|
|
6111
|
+
const pr = B.tmp();
|
|
6112
|
+
B.line(`${pr} = call ptr @scr_promise_retain(ptr ${v.name})`);
|
|
6113
|
+
const t = B.tmp();
|
|
6114
|
+
B.line(`${t} = call ptr @scr_jsval_from_promise(ptr ${pr}, i32 ${tagN})`);
|
|
6115
|
+
const out = this.own({ name: t, type: e.type });
|
|
6116
|
+
this.emitPendingCheck();
|
|
6117
|
+
return out;
|
|
6118
|
+
}
|
|
6096
6119
|
case "func": {
|
|
6097
6120
|
// A closure entering the island as a host function: from_closure
|
|
6098
6121
|
// retains it; the engine's finalizer releases it at teardown. The
|
|
@@ -6424,6 +6447,17 @@ class LlEmitter {
|
|
|
6424
6447
|
return out;
|
|
6425
6448
|
}
|
|
6426
6449
|
default: {
|
|
6450
|
+
// `any[]`-declared slot: Array.isArray-gated, elements BY
|
|
6451
|
+
// REFERENCE (identity crosses; the spine is a snapshot copy).
|
|
6452
|
+
// JSON-safe element types keep the round trip below.
|
|
6453
|
+
if (e.type.kind === "array" && e.type.elem.kind === "jsval") {
|
|
6454
|
+
this.declare(`declare ptr @scr_jsval_exit_jsval_arr(ptr)`);
|
|
6455
|
+
const t = B.tmp();
|
|
6456
|
+
B.line(`${t} = call ptr @scr_jsval_exit_jsval_arr(ptr ${v.name})`);
|
|
6457
|
+
const out = this.own({ name: t, type: e.type });
|
|
6458
|
+
this.emitPendingCheck();
|
|
6459
|
+
return out;
|
|
6460
|
+
}
|
|
6427
6461
|
// An undefined-armed union target: the engine's undefined takes
|
|
6428
6462
|
// the undefined arm FIRST (JSON cannot spell it); then null and
|
|
6429
6463
|
// data ride the round trip into the union's dynCheck like any
|
|
@@ -6460,11 +6494,31 @@ class LlEmitter {
|
|
|
6460
6494
|
B.br(lj);
|
|
6461
6495
|
B.startBlock(ld);
|
|
6462
6496
|
this.frames.push([]);
|
|
6463
|
-
const
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6497
|
+
const unionDef = this.unionsById.get(e.type.unionId);
|
|
6498
|
+
const dataArms = unionDef ? unionDef.arms.flatMap((a, i) => (isUnitType(a) ? [] : [{ a, i }])) : [];
|
|
6499
|
+
const jsvalArr = dataArms.length === 1 && dataArms[0].a.kind === "array" && dataArms[0].a.elem.kind === "jsval" ? dataArms[0] : null;
|
|
6500
|
+
let t;
|
|
6501
|
+
if (jsvalArr) {
|
|
6502
|
+
// The `any[] | undefined` defaulted-parameter spelling: the
|
|
6503
|
+
// engine array exits BY REFERENCE into the data arm.
|
|
6504
|
+
this.declare(`declare ptr @scr_jsval_exit_jsval_arr(ptr)`);
|
|
6505
|
+
this.declare(`declare ptr @scr_union_new_ref(i32, ptr, ptr, ptr, ptr)`);
|
|
6506
|
+
this.declare(`declare ptr @scr_arr_retain_v(ptr)`);
|
|
6507
|
+
this.declare(`declare void @scr_arr_release_v(ptr)`);
|
|
6508
|
+
const arr = B.tmp();
|
|
6509
|
+
B.line(`${arr} = call ptr @scr_jsval_exit_jsval_arr(ptr ${v.name})`);
|
|
6510
|
+
this.emitPendingCheck();
|
|
6511
|
+
t = B.tmp();
|
|
6512
|
+
B.line(`${t} = call ptr @scr_union_new_ref(i32 ${jsvalArr.i}, ptr ${arr}, ptr @scr_arr_retain_v, ptr @scr_arr_release_v, ptr null)`);
|
|
6513
|
+
B.line(`store ptr ${t}, ptr ${slot}`);
|
|
6514
|
+
}
|
|
6515
|
+
else {
|
|
6516
|
+
t = roundTrip();
|
|
6517
|
+
this.own({ name: t, type: e.type });
|
|
6518
|
+
this.emitPendingCheck();
|
|
6519
|
+
this.moveTemp({ name: t, type: e.type });
|
|
6520
|
+
B.line(`store ptr ${t}, ptr ${slot}`);
|
|
6521
|
+
}
|
|
6468
6522
|
this.releaseFrame(this.frames.pop());
|
|
6469
6523
|
B.br(lj);
|
|
6470
6524
|
B.startBlock(lj);
|
|
@@ -6677,7 +6731,7 @@ class LlEmitter {
|
|
|
6677
6731
|
d.push(` %r = call ptr %fn(${passed.join(", ")})`, ` %rn = icmp eq ptr %r, null`, ` br i1 %rn, label %snull, label %sok`, `snull:`, ` ret ptr null`, `sok:`, ` %j = call ptr @scr_jsval_from_str(ptr %r)`, ` call void @scr_str_release(ptr %r)`, ` ret ptr %j`);
|
|
6678
6732
|
break;
|
|
6679
6733
|
case "dyn":
|
|
6680
|
-
// A checked-dynamic (+1
|
|
6734
|
+
// A checked-dynamic (+1 dyn) result: deep copy into the engine
|
|
6681
6735
|
// (the jsMarshal dyn rule); NULL is the throw-path dummy.
|
|
6682
6736
|
this.declare(`declare ptr @scr_jsval_from_dyn(ptr)`);
|
|
6683
6737
|
this.declare(`declare void @scr_dyn_release(ptr)`);
|
|
@@ -6708,7 +6762,7 @@ class LlEmitter {
|
|
|
6708
6762
|
this.resolveThunkDefs.push(...d);
|
|
6709
6763
|
return sym;
|
|
6710
6764
|
}
|
|
6711
|
-
/** Loads a
|
|
6765
|
+
/** Loads a dyn node's kind tag (i32 at +8) — the dyn expression tests'
|
|
6712
6766
|
* shared read. */
|
|
6713
6767
|
dynKind(d) {
|
|
6714
6768
|
const B = this.B;
|
|
@@ -8537,7 +8591,7 @@ class LlEmitter {
|
|
|
8537
8591
|
// A dyn JOIN (the C helper's `surface` dyn arm): declared hits
|
|
8538
8592
|
// convert through the per-type toDyn walker (borrowed read → fresh
|
|
8539
8593
|
// +1 tree), a dyn-valued overflow hit passes through (+1 from the
|
|
8540
|
-
// map get), and a miss is JS's undefined — the
|
|
8594
|
+
// map get), and a miss is JS's undefined — the dyn singleton.
|
|
8541
8595
|
this.declare(`declare zeroext i1 @scr_str_eq(ptr, ptr)`);
|
|
8542
8596
|
for (const f of overflowOnly ? [] : shape.fields) {
|
|
8543
8597
|
const lit = this.internLiteral(f.name);
|
|
@@ -8615,7 +8669,7 @@ class LlEmitter {
|
|
|
8615
8669
|
B.br(join);
|
|
8616
8670
|
B.startBlock(ln);
|
|
8617
8671
|
}
|
|
8618
|
-
// The miss path: JS's undefined — the
|
|
8672
|
+
// The miss path: JS's undefined — the dyn singleton, retained.
|
|
8619
8673
|
this.declare(`declare ptr @scr_dyn_undefined()`);
|
|
8620
8674
|
this.declare(`declare ptr @scr_dyn_retain_v(ptr)`);
|
|
8621
8675
|
const u = B.tmp();
|