@scriptc/compiler 0.1.1 → 0.1.2
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 +45 -17
- package/ambient/scriptc.d.ts +2 -1
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/c/async.js +24 -2
- package/dist/backend/c/async.js.map +1 -1
- package/dist/backend/c/c-emitter.d.ts +22 -10
- package/dist/backend/c/c-emitter.js +60 -15
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.js +220 -10
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/island.js.map +1 -1
- package/dist/backend/c/may-throw.js.map +1 -1
- package/dist/backend/c/stmts.d.ts +3 -5
- package/dist/backend/c/stmts.js +58 -17
- package/dist/backend/c/stmts.js.map +1 -1
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/c/walkers.js +31 -5
- package/dist/backend/c/walkers.js.map +1 -1
- package/dist/backend/external-c.js.map +1 -1
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/dyn.js +56 -3
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +98 -19
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +85 -3
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +1 -0
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +6 -3
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +220 -9
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +2 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +18 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +6 -3
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/unsupported.js.map +1 -1
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +2 -0
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/compat/fetch-profile.js +4 -2
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +12 -0
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +6 -5
- package/dist/diagnostics/diagnostic.js +7 -6
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/ffi/ffi-manifest.js.map +1 -1
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +10 -0
- package/dist/frontend/input-tracker.js +26 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +8 -1
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +4 -0
- package/dist/frontend/lowering/array-values.js +18 -2
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/callback-arg.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +35 -0
- package/dist/frontend/lowering/containers/bytes.js +1021 -0
- package/dist/frontend/lowering/containers/bytes.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +17 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +345 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.d.ts +13 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +76 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -0
- package/dist/frontend/lowering/expressions/object-literals.d.ts +44 -0
- package/dist/frontend/lowering/expressions/object-literals.js +1815 -0
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +31 -0
- package/dist/frontend/lowering/expressions/optional-chains.js +382 -0
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.d.ts +7 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.js +26 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.js +7 -2
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +7 -0
- package/dist/frontend/lowering/lower-async-iteration.js +657 -0
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +18 -0
- package/dist/frontend/lowering/lower-builtins.js +219 -48
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +13 -4
- package/dist/frontend/lowering/lower-calls.js +407 -64
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +7 -13
- package/dist/frontend/lowering/lower-classes.js +128 -35
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +1 -47
- package/dist/frontend/lowering/lower-containers.js +135 -1467
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +51 -5
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +0 -78
- package/dist/frontend/lowering/lower-exprs.js +402 -2351
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +18 -3
- package/dist/frontend/lowering/lower-generators.js +145 -9
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +3 -3
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +6 -0
- package/dist/frontend/lowering/lower-island.js +37 -5
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +52 -15
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +18 -0
- package/dist/frontend/lowering/lower-node-module.js +302 -0
- package/dist/frontend/lowering/lower-node-module.js.map +1 -0
- package/dist/frontend/lowering/lower-server.js +1 -1
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +5 -24
- package/dist/frontend/lowering/lower-stmts.js +519 -253
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +4 -4
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +37 -34
- package/dist/frontend/lowering/lowerer.js +143 -57
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.d.ts +9 -0
- package/dist/frontend/lowering/optional-arguments.js +57 -0
- package/dist/frontend/lowering/optional-arguments.js.map +1 -0
- package/dist/frontend/npm-static-declarations.d.ts +35 -0
- package/dist/frontend/npm-static-declarations.js +506 -0
- package/dist/frontend/npm-static-declarations.js.map +1 -0
- package/dist/frontend/npm-static-declarations.test.d.ts +1 -0
- package/dist/frontend/npm-static-declarations.test.js +122 -0
- package/dist/frontend/npm-static-declarations.test.js.map +1 -0
- package/dist/frontend/npm-static.d.ts +2 -0
- package/dist/frontend/npm-static.js +26 -10
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +60 -0
- package/dist/frontend/npm.js +38 -4
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.d.ts +1 -0
- package/dist/frontend/npm.test.js +50 -0
- package/dist/frontend/npm.test.js.map +1 -0
- package/dist/frontend/program.d.ts +3 -2
- package/dist/frontend/program.js +495 -68
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.d.ts +10 -2
- package/dist/frontend/resolve.js +90 -14
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +4 -1
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/runtime-resolve.d.ts +22 -0
- package/dist/frontend/runtime-resolve.js +101 -0
- package/dist/frontend/runtime-resolve.js.map +1 -0
- package/dist/frontend/runtime-resolve.test.d.ts +1 -0
- package/dist/frontend/runtime-resolve.test.js +18 -0
- package/dist/frontend/runtime-resolve.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.js +12 -13
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/census-check.js +3 -3
- package/dist/frontend/ts7/census-check.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +3 -0
- package/dist/frontend/ts7/checker.js +12 -3
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/program-adapter.js +42 -3
- package/dist/frontend/ts7/program-adapter.js.map +1 -1
- package/dist/frontend/type-mapper.js +120 -7
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/ir.d.ts +60 -30
- package/dist/ir/ir.js +57 -6
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/validate.js +44 -59
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/cache-reset.test.js.map +1 -1
- package/dist/library/compiler-self-identity.js.map +1 -1
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.js.map +1 -1
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasi-paths.js.map +1 -1
- package/package.json +18 -18
- package/surface-manifest.json +60 -4
package/dist/backend/c/exprs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InternalCompilerError } from "../../errors.js";
|
|
2
|
-
import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, islandPromisePayloadTag, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/ir.js";
|
|
2
|
+
import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, islandPromisePayloadTag, isClassOwnEnumerableFieldName, isDynTypedRefType, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/ir.js";
|
|
3
3
|
import { boxAccess, BYTES_NUM_KIND_C, BYTES_NUM_VAR_C, bytesElemKindC, cDecl, cFnPtrCast, cNumberLiteral, cStringLiteral, cType, DV_GET_KIND_C, DV_SET_KIND_C, elemAccess, mapKeyAccess, mapKeyKindC, mapValKindC, releaseCallC, retainCallC, vAdapters } from "./types.js";
|
|
4
4
|
import { mangleClassNew, mangleClassRetain, mangleClassStruct, mangleField, mangleFnClosure, mangleFunction, mangleGlobal, mangleLocal, mangleRecordClone, mangleRecordNew, mangleRecordStruct, mangleVtStruct } from "../mangle.js";
|
|
5
5
|
import { OVERFLOW_MEMBER } from "./shapes.js";
|
|
@@ -20,6 +20,23 @@ function streamTypedRefCommitAdapter(emitter, t, snapshot, defs) {
|
|
|
20
20
|
defs.push(`static void ${commit}(void *sc_p, const ScrDyn *sc_d) {`, ` ScrArr *sc_target = (ScrArr *)sc_p;`, ` ScrArr *sc_next = ${emitter.dynCheckHelper(t)}(sc_d, NULL);`, ` if (!sc_next) return;`, ` size_t sc_target_len = sc_target->len;`, ` size_t sc_target_cap = sc_target->cap;`, ` uint64_t *sc_target_data = sc_target->data;`, ` uint8_t *sc_target_present = sc_target->present;`, ` ScrArrSparseSlot *sc_target_sparse = sc_target->sparse;`, ` size_t sc_target_sparse_len = sc_target->sparse_len;`, ` size_t sc_target_sparse_cap = sc_target->sparse_cap;`, ` ScrArrProp *sc_target_props = sc_target->props;`, ` size_t sc_target_prop_len = sc_target->prop_len;`, ` size_t sc_target_prop_cap = sc_target->prop_cap;`, ` sc_target->len = sc_next->len;`, ` sc_target->cap = sc_next->cap;`, ` sc_target->data = sc_next->data;`, ` sc_target->present = sc_next->present;`, ` sc_target->sparse = sc_next->sparse;`, ` sc_target->sparse_len = sc_next->sparse_len;`, ` sc_target->sparse_cap = sc_next->sparse_cap;`, ` sc_target->props = sc_next->props;`, ` sc_target->prop_len = sc_next->prop_len;`, ` sc_target->prop_cap = sc_next->prop_cap;`, ` sc_next->len = sc_target_len;`, ` sc_next->cap = sc_target_cap;`, ` sc_next->data = sc_target_data;`, ` sc_next->present = sc_target_present;`, ` sc_next->sparse = sc_target_sparse;`, ` sc_next->sparse_len = sc_target_sparse_len;`, ` sc_next->sparse_cap = sc_target_sparse_cap;`, ` sc_next->props = sc_target_props;`, ` sc_next->prop_len = sc_target_prop_len;`, ` sc_next->prop_cap = sc_target_prop_cap;`, ` scr_arr_release(sc_next);`, `}`, ``);
|
|
21
21
|
return `&${commit}`;
|
|
22
22
|
}
|
|
23
|
+
if (isDynTypedRefType(t)) {
|
|
24
|
+
const meta = emitter.classMeta.get(t.className);
|
|
25
|
+
if (!meta) {
|
|
26
|
+
throw new InternalCompilerError(`emitter bug: typed-ref commit of unknown class ${t.className}`);
|
|
27
|
+
}
|
|
28
|
+
const commit = `${snapshot}_commit`;
|
|
29
|
+
emitter.walkerProtos.push(`static void ${commit}(void *sc_p, const ScrDyn *sc_d); /* commit unknown class ${typeKey(t)} */`);
|
|
30
|
+
defs.push(`static void ${commit}(void *sc_p, const ScrDyn *sc_d) {`, ` ${cDecl(t, "sc_target")} = (${cType(t).trim()})sc_p;`);
|
|
31
|
+
for (const field of meta.def.fields.filter((f) => isClassOwnEnumerableFieldName(f.name))) {
|
|
32
|
+
const member = mangleField(field.name);
|
|
33
|
+
const keyLit = cStringLiteral(Buffer.from(field.name, "utf8"));
|
|
34
|
+
const keyLen = Buffer.byteLength(field.name, "utf8");
|
|
35
|
+
defs.push(` {`, ` const ScrDyn *sc_member = scr_dyn_obj_get(sc_d, ${keyLit}, ${keyLen});`, ` ${cDecl(field.type, "sc_next")} = ${emitter.dynCheckHelper(field.type)}(sc_member ? sc_member : scr_dyn_undefined(), NULL);`, ` if (scr_exc_pending()) return;`, ` ${cDecl(field.type, "sc_old")} = sc_target->${member};`, ` sc_target->${member} = sc_next;`, ...(isRefCounted(field.type) ? [` ${releaseCallC(field.type, "sc_old")};`] : [" (void)sc_old;"]), ` }`);
|
|
36
|
+
}
|
|
37
|
+
defs.push(`}`, ``);
|
|
38
|
+
return `&${commit}`;
|
|
39
|
+
}
|
|
23
40
|
if (t.kind !== "record")
|
|
24
41
|
return "NULL";
|
|
25
42
|
const shape = emitter.recordsById.get(t.shapeId);
|
|
@@ -39,6 +56,51 @@ function streamTypedRefCommitAdapter(emitter, t, snapshot, defs) {
|
|
|
39
56
|
defs.push(` ${releaseCallC(t, "sc_next")};`, `}`, ``);
|
|
40
57
|
return `&${commit}`;
|
|
41
58
|
}
|
|
59
|
+
/** Boxes a union selected at runtime, preserving mutable/class arm identity
|
|
60
|
+
* while converting scalar and unit arms normally. It shares the enclosing
|
|
61
|
+
* adapter context so recursive class fields reuse the prototype already
|
|
62
|
+
* registered by streamTypedRefAdapter instead of recursing forever. */
|
|
63
|
+
function nestedTypedRefUnionAdapter(emitter, t, ctx) {
|
|
64
|
+
const key = typeKey(t);
|
|
65
|
+
const unions = (ctx.unions ??= new Map());
|
|
66
|
+
const existing = unions.get(key);
|
|
67
|
+
if (existing)
|
|
68
|
+
return existing;
|
|
69
|
+
const def = emitter.unionsById.get(t.unionId);
|
|
70
|
+
if (!def)
|
|
71
|
+
throw new InternalCompilerError(`emitter bug: typed-ref union ${t.unionId} is undeclared`);
|
|
72
|
+
const sym = `${ctx.prefix}_union_${unions.size}`;
|
|
73
|
+
unions.set(key, sym);
|
|
74
|
+
emitter.walkerProtos.push(`static ScrDyn *${sym}(ScrUnion *sc_u); /* typed-ref union ${key} */`);
|
|
75
|
+
const lines = [`static ScrDyn *${sym}(ScrUnion *sc_u) {`, ` switch (sc_u->tag) {`];
|
|
76
|
+
def.arms.forEach((arm, tag) => {
|
|
77
|
+
if (streamTypedRefEligible(arm) || isDynTypedRefType(arm)) {
|
|
78
|
+
const adapter = streamTypedRefAdapter(emitter, arm, ctx);
|
|
79
|
+
const rc = vAdapters(arm);
|
|
80
|
+
const armKey = typeKey(arm);
|
|
81
|
+
const keyLit = cStringLiteral(Buffer.from(armKey, "utf8"));
|
|
82
|
+
lines.push(` case ${tag}: return scr_dyn_new_typed_ref(scr_union_peek(sc_u), &${rc.retain}, &${rc.release}, ${keyLit}, ${Buffer.byteLength(armKey, "utf8")}, &${adapter.snapshot}, ${adapter.commit});`);
|
|
83
|
+
}
|
|
84
|
+
else if (arm.kind === "undefinedT") {
|
|
85
|
+
lines.push(` case ${tag}: return scr_dyn_retain(scr_dyn_undefined());`);
|
|
86
|
+
}
|
|
87
|
+
else if (arm.kind === "nullT") {
|
|
88
|
+
lines.push(` case ${tag}: return scr_dyn_new_null();`);
|
|
89
|
+
}
|
|
90
|
+
else if (arm.kind === "f64") {
|
|
91
|
+
lines.push(` case ${tag}: return scr_dyn_new_num(scr_union_get_f64(sc_u));`);
|
|
92
|
+
}
|
|
93
|
+
else if (arm.kind === "bool") {
|
|
94
|
+
lines.push(` case ${tag}: return scr_dyn_new_bool(scr_union_get_bool(sc_u));`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
lines.push(` case ${tag}: return ${emitter.toDynHelper(arm)}((${cType(arm).trim()})scr_union_peek(sc_u));`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
lines.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`, ` }`, `}`, ``);
|
|
101
|
+
ctx.defs.push(...lines);
|
|
102
|
+
return sym;
|
|
103
|
+
}
|
|
42
104
|
/** Build the live dyn view of one typed stream value. Mutable reference
|
|
43
105
|
* children are capsules of their own, so a write through `v.child.x` or
|
|
44
106
|
* `v.items[0]` commits directly to that child's static source instead of
|
|
@@ -57,7 +119,11 @@ function streamTypedRefAdapter(emitter, t, ctx, preferredSnapshot) {
|
|
|
57
119
|
emitter.walkerProtos.push(`static ScrDyn *${snapshot}(void *sc_p); /* materialize live stream value ${key} */`);
|
|
58
120
|
adapter.commit = streamTypedRefCommitAdapter(emitter, t, snapshot, ctx.defs);
|
|
59
121
|
const box = (child, expr) => {
|
|
60
|
-
if (
|
|
122
|
+
if (child.kind === "union" &&
|
|
123
|
+
(emitter.unionsById.get(child.unionId)?.arms.some((arm) => streamTypedRefEligible(arm) || isDynTypedRefType(arm)) ?? false)) {
|
|
124
|
+
return `${nestedTypedRefUnionAdapter(emitter, child, ctx)}(${expr})`;
|
|
125
|
+
}
|
|
126
|
+
if (!streamTypedRefEligible(child) && !isDynTypedRefType(child)) {
|
|
61
127
|
return `${emitter.toDynHelper(child)}(${expr})`;
|
|
62
128
|
}
|
|
63
129
|
const nested = streamTypedRefAdapter(emitter, child, ctx);
|
|
@@ -70,7 +136,19 @@ function streamTypedRefAdapter(emitter, t, ctx, preferredSnapshot) {
|
|
|
70
136
|
`static ScrDyn *${snapshot}(void *sc_p) { /* materialize live stream value ${key} */`,
|
|
71
137
|
` ${cDecl(t, "v")} = (${cType(t).trim()})sc_p;`,
|
|
72
138
|
];
|
|
73
|
-
if (t
|
|
139
|
+
if (isDynTypedRefType(t)) {
|
|
140
|
+
const meta = emitter.classMeta.get(t.className);
|
|
141
|
+
if (!meta) {
|
|
142
|
+
throw new InternalCompilerError(`emitter bug: typed-ref materialize of unknown class ${t.className}`);
|
|
143
|
+
}
|
|
144
|
+
lines.push(` ScrDyn *d = scr_dyn_new_obj();`);
|
|
145
|
+
for (const field of meta.def.fields.filter((f) => isClassOwnEnumerableFieldName(f.name))) {
|
|
146
|
+
const keyLit = cStringLiteral(Buffer.from(field.name, "utf8"));
|
|
147
|
+
lines.push(` scr_dyn_obj_set(d, ${keyLit}, ${Buffer.byteLength(field.name, "utf8")}, ${box(field.type, `v->${mangleField(field.name)}`)});`);
|
|
148
|
+
}
|
|
149
|
+
lines.push(` return d;`);
|
|
150
|
+
}
|
|
151
|
+
else if (t.kind === "record") {
|
|
74
152
|
const shape = emitter.recordsById.get(t.shapeId);
|
|
75
153
|
if (!shape) {
|
|
76
154
|
throw new InternalCompilerError(`emitter bug: stream typed-ref materialize of unknown shape ${t.shapeId}`);
|
|
@@ -132,7 +210,7 @@ function liveDynRefAdapter(emitter, t) {
|
|
|
132
210
|
const existing = emitter.liveDynRefAdapters.get(key);
|
|
133
211
|
if (existing)
|
|
134
212
|
return existing;
|
|
135
|
-
if (!streamTypedRefEligible(t)) {
|
|
213
|
+
if (!streamTypedRefEligible(t) && !isDynTypedRefType(t)) {
|
|
136
214
|
throw new InternalCompilerError(`emitter bug: live dyn ref of ${key}`);
|
|
137
215
|
}
|
|
138
216
|
const prefix = `sc_ldr_${emitter.liveDynRefAdapters.size}`;
|
|
@@ -157,7 +235,7 @@ function liveDynUnionRefAdapter(emitter, t) {
|
|
|
157
235
|
}
|
|
158
236
|
const mutableArms = union.arms
|
|
159
237
|
.map((arm, tag) => ({ arm, tag }))
|
|
160
|
-
.filter(({ arm }) => streamTypedRefEligible(arm));
|
|
238
|
+
.filter(({ arm }) => streamTypedRefEligible(arm) || isDynTypedRefType(arm));
|
|
161
239
|
if (mutableArms.length === 0) {
|
|
162
240
|
throw new InternalCompilerError(`emitter bug: live dyn ref of immutable union ${key}`);
|
|
163
241
|
}
|
|
@@ -179,7 +257,27 @@ function liveDynUnionRefAdapter(emitter, t) {
|
|
|
179
257
|
const keyLit = cStringLiteral(Buffer.from(armKey, "utf8"));
|
|
180
258
|
defs.push(` case ${tag}:`, ` return scr_dyn_new_typed_ref(scr_union_peek(sc_u), &${rc.retain}, &${rc.release}, ${keyLit}, ${Buffer.byteLength(armKey, "utf8")}, &${adapter.snapshot}, ${adapter.commit});`);
|
|
181
259
|
}
|
|
182
|
-
|
|
260
|
+
const mutableTags = new Set(mutableArms.map(({ tag }) => tag));
|
|
261
|
+
union.arms.forEach((arm, tag) => {
|
|
262
|
+
if (mutableTags.has(tag))
|
|
263
|
+
return;
|
|
264
|
+
if (arm.kind === "undefinedT") {
|
|
265
|
+
defs.push(` case ${tag}: return scr_dyn_retain(scr_dyn_undefined());`);
|
|
266
|
+
}
|
|
267
|
+
else if (arm.kind === "nullT") {
|
|
268
|
+
defs.push(` case ${tag}: return scr_dyn_new_null();`);
|
|
269
|
+
}
|
|
270
|
+
else if (arm.kind === "f64") {
|
|
271
|
+
defs.push(` case ${tag}: return scr_dyn_new_num(scr_union_get_f64(sc_u));`);
|
|
272
|
+
}
|
|
273
|
+
else if (arm.kind === "bool") {
|
|
274
|
+
defs.push(` case ${tag}: return scr_dyn_new_bool(scr_union_get_bool(sc_u));`);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
defs.push(` case ${tag}: return ${emitter.toDynHelper(arm)}((${cType(arm).trim()})scr_union_peek(sc_u));`);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
defs.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`, ` }`, `}`, ``);
|
|
183
281
|
emitter.walkerDefs.push(...defs);
|
|
184
282
|
return sym;
|
|
185
283
|
}
|
|
@@ -2390,7 +2488,10 @@ function emitDynamicExpr(emitter, e) {
|
|
|
2390
2488
|
: "scr_dyn_new_null()");
|
|
2391
2489
|
}
|
|
2392
2490
|
const v = emitter.emitExpr(e.value);
|
|
2393
|
-
|
|
2491
|
+
const identityRef = isDynTypedRefType(v.type) ||
|
|
2492
|
+
(v.type.kind === "union" &&
|
|
2493
|
+
(emitter.unionsById.get(v.type.unionId)?.arms.some(isDynTypedRefType) ?? false));
|
|
2494
|
+
if (e.liveRef || identityRef) {
|
|
2394
2495
|
if (v.type.kind === "union") {
|
|
2395
2496
|
const adapter = liveDynUnionRefAdapter(emitter, v.type);
|
|
2396
2497
|
return emitter.newTemp(e.type, `${adapter}(${v.name})`);
|
|
@@ -3072,6 +3173,8 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3072
3173
|
throw new InternalCompilerError("emitter bug: yieldExpr with no operand (frontend fills undefined)");
|
|
3073
3174
|
const v = emitter.emitExpr(e.value);
|
|
3074
3175
|
const yt = e.value.type;
|
|
3176
|
+
if (e.awaited)
|
|
3177
|
+
emitter.line(`scr_async_gen_hop_done();`);
|
|
3075
3178
|
if (yt.kind === "f64" || yt.kind === "date") {
|
|
3076
3179
|
emitter.line(`scr_gen_yield_f64(${v.name});${emitter.srcComment(e.loc)}`);
|
|
3077
3180
|
}
|
|
@@ -3105,8 +3208,9 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3105
3208
|
const genT = e.gen.type;
|
|
3106
3209
|
if (genT.kind !== "generator")
|
|
3107
3210
|
throw new InternalCompilerError("emitter bug: genResume on a non-generator");
|
|
3108
|
-
|
|
3109
|
-
|
|
3211
|
+
const resultT = genT.async ? (e.type.kind === "promise" ? e.type.inner : null) : e.type;
|
|
3212
|
+
if (resultT?.kind !== "record")
|
|
3213
|
+
throw new InternalCompilerError("emitter bug: genResume result is not an IteratorResult record");
|
|
3110
3214
|
const g = emitter.emitExpr(e.gen); // borrowed for the calls below
|
|
3111
3215
|
const sendArg = (store) => {
|
|
3112
3216
|
const a = emitter.emitExpr(e.arg);
|
|
@@ -3114,6 +3218,76 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3114
3218
|
emitter.moveTemp(a); // the slot takes ownership
|
|
3115
3219
|
emitter.line(store(a));
|
|
3116
3220
|
};
|
|
3221
|
+
if (genT.async) {
|
|
3222
|
+
let call;
|
|
3223
|
+
if (e.mode === "next") {
|
|
3224
|
+
if (e.arg === null) {
|
|
3225
|
+
if (genT.nextT.kind === "dyn") {
|
|
3226
|
+
call = `scr_async_gen_next_ref(${g.name}, scr_dyn_retain(scr_dyn_undefined()), scr_dyn_release_v)`;
|
|
3227
|
+
}
|
|
3228
|
+
else {
|
|
3229
|
+
call = `scr_async_gen_next_none(${g.name})`;
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
else {
|
|
3233
|
+
const a = emitter.emitExpr(e.arg);
|
|
3234
|
+
const t = e.arg.type;
|
|
3235
|
+
if (isRefCounted(t))
|
|
3236
|
+
emitter.moveTemp(a);
|
|
3237
|
+
call = t.kind === "f64" || t.kind === "date"
|
|
3238
|
+
? `scr_async_gen_next_f64(${g.name}, ${a.name})`
|
|
3239
|
+
: t.kind === "bool"
|
|
3240
|
+
? `scr_async_gen_next_bool(${g.name}, ${a.name})`
|
|
3241
|
+
: `scr_async_gen_next_ref(${g.name}, ${a.name}, ${vAdapters(t).release})`;
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
else if (e.mode === "return") {
|
|
3245
|
+
if (e.arg === null) {
|
|
3246
|
+
call = `scr_async_gen_return_none(${g.name})`;
|
|
3247
|
+
}
|
|
3248
|
+
else {
|
|
3249
|
+
const a = emitter.emitExpr(e.arg);
|
|
3250
|
+
const t = e.arg.type;
|
|
3251
|
+
if (isRefCounted(t))
|
|
3252
|
+
emitter.moveTemp(a);
|
|
3253
|
+
call = t.kind === "f64" || t.kind === "date"
|
|
3254
|
+
? `scr_async_gen_return_f64(${g.name}, ${a.name})`
|
|
3255
|
+
: t.kind === "bool"
|
|
3256
|
+
? `scr_async_gen_return_bool(${g.name}, ${a.name})`
|
|
3257
|
+
: `scr_async_gen_return_ref(${g.name}, ${a.name}, ${vAdapters(t).release})`;
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3260
|
+
else {
|
|
3261
|
+
if (e.arg === null)
|
|
3262
|
+
throw new InternalCompilerError("emitter bug: async genResume throw with no payload");
|
|
3263
|
+
const a = emitter.emitExpr(e.arg);
|
|
3264
|
+
const t = e.arg.type;
|
|
3265
|
+
if (isRefCounted(t))
|
|
3266
|
+
emitter.moveTemp(a);
|
|
3267
|
+
if (t.kind === "date") {
|
|
3268
|
+
throw new InternalCompilerError("emitter bug: Date async-generator throw reached backend");
|
|
3269
|
+
}
|
|
3270
|
+
else if (t.kind === "f64") {
|
|
3271
|
+
emitter.line(`scr_throw_f64(${a.name});${emitter.srcComment(e.loc)}`);
|
|
3272
|
+
}
|
|
3273
|
+
else if (t.kind === "bool") {
|
|
3274
|
+
emitter.line(`scr_throw_bool(${a.name});${emitter.srcComment(e.loc)}`);
|
|
3275
|
+
}
|
|
3276
|
+
else if (t.kind === "string") {
|
|
3277
|
+
emitter.line(`scr_throw_str(${a.name});${emitter.srcComment(e.loc)}`);
|
|
3278
|
+
}
|
|
3279
|
+
else if (t.kind === "object" && emitter.classMeta.get(t.className)?.hierarchy) {
|
|
3280
|
+
const rc = vAdapters(t);
|
|
3281
|
+
emitter.line(`scr_throw_obj(${a.name}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(t)});${emitter.srcComment(e.loc)}`);
|
|
3282
|
+
}
|
|
3283
|
+
else {
|
|
3284
|
+
const rc = vAdapters(t);
|
|
3285
|
+
emitter.line(`scr_throw_ref(${a.name}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(t)});${emitter.srcComment(e.loc)}`);
|
|
3286
|
+
}
|
|
3287
|
+
call = `scr_async_gen_throw(${g.name})`;
|
|
3288
|
+
}
|
|
3289
|
+
return emitter.newTemp(e.type, call);
|
|
3290
|
+
}
|
|
3117
3291
|
if (e.mode === "next") {
|
|
3118
3292
|
if (e.arg === null) {
|
|
3119
3293
|
// Valueless resume: dyn channels read JS's undefined; unit
|
|
@@ -3178,7 +3352,7 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3178
3352
|
}
|
|
3179
3353
|
emitter.line(`scr_gen_resume_throw(${g.name});`);
|
|
3180
3354
|
}
|
|
3181
|
-
const helper = genResultThunkFor(emitter, genT,
|
|
3355
|
+
const helper = genResultThunkFor(emitter, genT, resultT);
|
|
3182
3356
|
// The record builds before the check so an unwind (a propagated
|
|
3183
3357
|
// body exception) releases it as the frame's never-read dummy.
|
|
3184
3358
|
return emitter.fallibleTemp(e.type, `${helper}(${g.name})`);
|
|
@@ -6747,6 +6921,38 @@ function emitProcessLibCall(state) {
|
|
|
6747
6921
|
return finish(`scr_process_getuid()`);
|
|
6748
6922
|
case "process.uptime":
|
|
6749
6923
|
return finish(`scr_process_uptime()`);
|
|
6924
|
+
case "module.registryInit":
|
|
6925
|
+
return finish(`scr_module_registry_init(${arg(0)})`);
|
|
6926
|
+
case "module.define":
|
|
6927
|
+
return finish(`scr_module_define(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
|
|
6928
|
+
case "module.enter":
|
|
6929
|
+
return finish(`scr_module_enter(${arg(0)})`);
|
|
6930
|
+
case "module.link":
|
|
6931
|
+
return finish(`scr_module_link(${arg(0)}, ${arg(1)})`);
|
|
6932
|
+
case "module.finish":
|
|
6933
|
+
return finish(`scr_module_finish(${arg(0)})`);
|
|
6934
|
+
case "module.fail":
|
|
6935
|
+
return finish(`scr_module_fail(${arg(0)})`);
|
|
6936
|
+
case "module.filename":
|
|
6937
|
+
return finish(`scr_module_filename(${arg(0)})`);
|
|
6938
|
+
case "module.id":
|
|
6939
|
+
return finish(`scr_module_id(${arg(0)})`);
|
|
6940
|
+
case "module.path":
|
|
6941
|
+
return finish(`scr_module_path(${arg(0)})`);
|
|
6942
|
+
case "module.paths":
|
|
6943
|
+
return finish(`scr_module_paths(${arg(0)})`);
|
|
6944
|
+
case "module.children":
|
|
6945
|
+
return finish(`scr_module_children(${arg(0)})`);
|
|
6946
|
+
case "module.parent":
|
|
6947
|
+
return finish(`scr_module_parent(${arg(0)})`);
|
|
6948
|
+
case "module.loaded":
|
|
6949
|
+
return finish(`scr_module_loaded(${arg(0)})`);
|
|
6950
|
+
case "module.cacheGet":
|
|
6951
|
+
return finish(`scr_module_cache_get(${arg(0)})`);
|
|
6952
|
+
case "module.cacheHas":
|
|
6953
|
+
return finish(`scr_module_cache_has(${arg(0)})`);
|
|
6954
|
+
case "module.cacheKeys":
|
|
6955
|
+
return finish(`scr_module_cache_keys()`);
|
|
6750
6956
|
case "process.availableMemory":
|
|
6751
6957
|
return finish(`scr_available_memory()`);
|
|
6752
6958
|
case "process.constrainedMemory":
|
|
@@ -7492,6 +7698,9 @@ function emitStreamLibCall(state) {
|
|
|
7492
7698
|
case "stream.destroyErr":
|
|
7493
7699
|
emitter.usesTimers = true;
|
|
7494
7700
|
return finish(`(${cType(e.type).trim()})scr_stream_destroy((ScrStream *)${arg(0)}, ${arg(1)})`);
|
|
7701
|
+
case "stream.iteratorClose":
|
|
7702
|
+
emitter.usesTimers = true;
|
|
7703
|
+
return finish(`(${cType(e.type).trim()})scr_stream_iterator_close((ScrStream *)${arg(0)})`);
|
|
7495
7704
|
case "stream.prop": {
|
|
7496
7705
|
// The property NAME is a compile-time literal; args[1]'s
|
|
7497
7706
|
// emitted temp is unused (released with the statement's frame).
|
|
@@ -7791,6 +8000,7 @@ function emitLibCallExpr(emitter, e) {
|
|
|
7791
8000
|
return emitAsyncContextLibCall(state);
|
|
7792
8001
|
case "process":
|
|
7793
8002
|
case "stdin":
|
|
8003
|
+
case "module":
|
|
7794
8004
|
return emitProcessLibCall(state);
|
|
7795
8005
|
case "error":
|
|
7796
8006
|
case "regex":
|