@scriptc/compiler 0.0.36 → 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 +52 -22
- package/ambient/scriptc-overrides.d.ts +0 -7
- package/ambient/scriptc.d.ts +3 -2
- 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 +289 -55
- 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 +3 -0
- 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 +76 -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 +36 -12
- package/dist/backend/c/walkers.js.map +1 -1
- package/dist/backend/external-c.d.ts +33 -0
- package/dist/backend/external-c.js +51 -0
- package/dist/backend/external-c.js.map +1 -0
- package/dist/backend/link-plan.d.ts +37 -0
- package/dist/backend/link-plan.js +26 -0
- package/dist/backend/link-plan.js.map +1 -0
- package/dist/backend/linker.d.ts +22 -0
- package/dist/backend/linker.js +236 -0
- package/dist/backend/linker.js.map +1 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/dyn.js +63 -3
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +132 -26
- 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 +68 -54
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +2 -1
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +2 -0
- 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.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +20 -0
- 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 +245 -10
- 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 +31 -4
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +8 -1
- package/dist/backend/native-codegen.js +39 -25
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +44 -4
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info.d.ts +1 -1
- package/dist/backend/native-link-info.js +42 -18
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +5 -1
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.d.ts +1 -0
- package/dist/backend/runtime-pack-targets.test.js +54 -0
- package/dist/backend/runtime-pack-targets.test.js.map +1 -0
- package/dist/backend/runtime-pack.d.ts +5 -30
- package/dist/backend/runtime-pack.js +46 -141
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +49 -14
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/targets.d.ts +63 -17
- package/dist/backend/targets.js +251 -35
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +27 -5
- package/dist/backend/targets.test.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 +22 -1
- 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 +12 -0
- package/dist/frontend/lowering/array-values.js +76 -0
- package/dist/frontend/lowering/array-values.js.map +1 -0
- 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-array-sort.d.ts +22 -0
- package/dist/frontend/lowering/lower-array-sort.js +619 -0
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -0
- 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 +379 -48
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +16 -8
- package/dist/frontend/lowering/lower-calls.js +667 -91
- 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 +779 -2038
- 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 +4 -78
- package/dist/frontend/lowering/lower-exprs.js +1128 -2409
- 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 +50 -36
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +11 -4
- package/dist/frontend/lowering/lower-island.js +47 -10
- 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 +11 -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 +811 -314
- 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 +109 -34
- package/dist/frontend/lowering/lowerer.js +1225 -62
- 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/lowering/surfaces.d.ts +10 -2
- package/dist/frontend/lowering/surfaces.js +15 -3
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- 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.d.ts +3 -3
- package/dist/index.js +50 -28
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/ir.d.ts +125 -41
- package/dist/ir/ir.js +82 -31
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/validate.js +127 -95
- 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/fence-eval.js +3 -1
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.js +12 -1
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/library-cache.test.js +5 -5
- 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.d.ts +9 -1
- package/dist/startup-cache.js +16 -1
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasi-paths.js.map +1 -1
- package/package.json +18 -5
- package/surface-manifest.json +64 -8
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";
|
|
@@ -17,7 +17,24 @@ function streamTypedRefCommitAdapter(emitter, t, snapshot, defs) {
|
|
|
17
17
|
if (t.kind === "array") {
|
|
18
18
|
const commit = `${snapshot}_commit`;
|
|
19
19
|
emitter.walkerProtos.push(`static void ${commit}(void *sc_p, const ScrDyn *sc_d); /* commit live stream element ${typeKey(t)} */`);
|
|
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;`, ` sc_target->len = sc_next->len;`, ` sc_target->cap = sc_next->cap;`, ` sc_target->data = sc_next->data;`, ` sc_next->len = sc_target_len;`, ` sc_next->cap = sc_target_cap;`, ` sc_next->data = sc_target_data;`, ` scr_arr_release(sc_next);`, `}`, ``);
|
|
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
|
+
return `&${commit}`;
|
|
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(`}`, ``);
|
|
21
38
|
return `&${commit}`;
|
|
22
39
|
}
|
|
23
40
|
if (t.kind !== "record")
|
|
@@ -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
|
}
|
|
@@ -1284,12 +1382,7 @@ function emitContainerExpr(emitter, e) {
|
|
|
1284
1382
|
e.elems.forEach((el, i) => {
|
|
1285
1383
|
const v = emitter.emitExpr(el);
|
|
1286
1384
|
if (spreadSet.has(i)) {
|
|
1287
|
-
|
|
1288
|
-
emitter.line(`for (size_t ${n} = 0, ${n}_len = (size_t)scr_arr_len(${v.name}); ${n} < ${n}_len; ${n}++) {`);
|
|
1289
|
-
emitter.indent++;
|
|
1290
|
-
emitter.line(`scr_arr_push_${acc}(${arr.name}, scr_arr_get_${acc}(${v.name}, (double)${n}));`);
|
|
1291
|
-
emitter.indent--;
|
|
1292
|
-
emitter.line(`}`);
|
|
1385
|
+
emitter.line(`scr_arr_push_spread(${arr.name}, ${v.name});`);
|
|
1293
1386
|
return;
|
|
1294
1387
|
}
|
|
1295
1388
|
if (acc === "ref")
|
|
@@ -1335,6 +1428,20 @@ function emitContainerExpr(emitter, e) {
|
|
|
1335
1428
|
const acc = elemAccess(e.arr.type.elem);
|
|
1336
1429
|
return emitter.newTemp(e.type, `scr_arr_get_${acc}(${arr.name}, ${idx.name})`);
|
|
1337
1430
|
}
|
|
1431
|
+
case "arrayHas": {
|
|
1432
|
+
const arr = emitter.emitExpr(e.arr);
|
|
1433
|
+
const idx = emitter.emitExpr(e.index);
|
|
1434
|
+
if (e.arr.type.kind !== "array")
|
|
1435
|
+
throw new InternalCompilerError("emitter bug: arrayHas on non-array");
|
|
1436
|
+
return emitter.newTemp(e.type, `scr_arr_has(${arr.name}, ${idx.name})`);
|
|
1437
|
+
}
|
|
1438
|
+
case "arrayState": {
|
|
1439
|
+
const arr = emitter.emitExpr(e.arr);
|
|
1440
|
+
const idx = emitter.emitExpr(e.index);
|
|
1441
|
+
if (e.arr.type.kind !== "array")
|
|
1442
|
+
throw new InternalCompilerError("emitter bug: arrayState on non-array");
|
|
1443
|
+
return emitter.newTemp(e.type, `scr_arr_state(${arr.name}, ${idx.name})`);
|
|
1444
|
+
}
|
|
1338
1445
|
case "arrIntrinsic": {
|
|
1339
1446
|
const r = emitter.emitExpr(e.receiver);
|
|
1340
1447
|
if (e.receiver.type.kind !== "array")
|
|
@@ -1344,6 +1451,10 @@ function emitContainerExpr(emitter, e) {
|
|
|
1344
1451
|
switch (method) {
|
|
1345
1452
|
case "length":
|
|
1346
1453
|
return emitter.newTemp(e.type, `scr_arr_len(${r.name})`);
|
|
1454
|
+
case "nextPresent": {
|
|
1455
|
+
const start = emitter.emitExpr(e.args[0]);
|
|
1456
|
+
return emitter.newTemp(e.type, `scr_arr_next_present(${r.name}, ${start.name})`);
|
|
1457
|
+
}
|
|
1347
1458
|
case "push": {
|
|
1348
1459
|
// Variadic like JS: every argument evaluates first (left to
|
|
1349
1460
|
// right — an argument reading the array sees the pre-push
|
|
@@ -1363,18 +1474,15 @@ function emitContainerExpr(emitter, e) {
|
|
|
1363
1474
|
: emitter.newTemp(e.type, `scr_arr_len(${r.name})`);
|
|
1364
1475
|
}
|
|
1365
1476
|
case "pushSpread": {
|
|
1366
|
-
// `a.push(...src)`: append src's
|
|
1367
|
-
//
|
|
1368
|
-
//
|
|
1369
|
-
// moves into _push_ref — RC-balanced. Result: the new length.
|
|
1477
|
+
// `a.push(...src)`: append src's indexed state in order while
|
|
1478
|
+
// preserving holes; the runtime snapshots self-spread and
|
|
1479
|
+
// retains copied refs. Result: the new length.
|
|
1370
1480
|
const src = emitter.emitExpr(e.args[0]);
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
emitter.
|
|
1375
|
-
emitter.
|
|
1376
|
-
emitter.line(`}`);
|
|
1377
|
-
return emitter.newTemp(e.type, `scr_arr_len(${r.name})`);
|
|
1481
|
+
return emitter.newTemp(e.type, `scr_arr_push_spread(${r.name}, ${src.name})`);
|
|
1482
|
+
}
|
|
1483
|
+
case "concatSpread": {
|
|
1484
|
+
const src = emitter.emitExpr(e.args[0]);
|
|
1485
|
+
return emitter.newTemp(e.type, `scr_arr_concat_copy(${r.name}, ${src.name})`);
|
|
1378
1486
|
}
|
|
1379
1487
|
case "unshift": {
|
|
1380
1488
|
// Like push, every argument evaluates before mutation. Apply
|
|
@@ -1396,9 +1504,39 @@ function emitContainerExpr(emitter, e) {
|
|
|
1396
1504
|
return emitter.newTemp(e.type, `scr_arr_unshift_spread(${r.name}, ${src.name})`);
|
|
1397
1505
|
}
|
|
1398
1506
|
case "pop":
|
|
1399
|
-
|
|
1400
|
-
//
|
|
1401
|
-
|
|
1507
|
+
case "shift": {
|
|
1508
|
+
// Move the slot once, preserving undefined and holes as values
|
|
1509
|
+
// while still applying the method's length/index mutation.
|
|
1510
|
+
if (e.type.kind !== "union")
|
|
1511
|
+
throw new InternalCompilerError("emitter bug: array removal result is not a union");
|
|
1512
|
+
const elemT = e.receiver.type.elem;
|
|
1513
|
+
const def = emitter.unionsById.get(e.type.unionId);
|
|
1514
|
+
const tag = def ? def.arms.findIndex((arm) => typeEquals(arm, elemT)) : -1;
|
|
1515
|
+
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
1516
|
+
const sameUnion = elemT.kind === "union" && typeEquals(elemT, e.type);
|
|
1517
|
+
if ((!sameUnion && tag < 0) || undefTag < 0)
|
|
1518
|
+
throw new InternalCompilerError("emitter bug: array removal union lacks its arms");
|
|
1519
|
+
const state = `sc_remove_state${emitter.tempCounter++}`;
|
|
1520
|
+
const slot = `sc_remove_slot${emitter.tempCounter++}`;
|
|
1521
|
+
emitter.line(`uint64_t ${slot} = 0;`);
|
|
1522
|
+
emitter.line(`uint8_t ${state} = scr_arr_${method}_state(${r.name}, &${slot});`);
|
|
1523
|
+
let present;
|
|
1524
|
+
if (elemT.kind === "f64") {
|
|
1525
|
+
const number = `sc_remove_number${emitter.tempCounter++}`;
|
|
1526
|
+
emitter.line(`double ${number}; memcpy(&${number}, &${slot}, sizeof ${number});`);
|
|
1527
|
+
present = `scr_union_new_f64(${tag}, ${number})`;
|
|
1528
|
+
}
|
|
1529
|
+
else if (elemT.kind === "bool") {
|
|
1530
|
+
present = `scr_union_new_bool(${tag}, ${slot} != 0)`;
|
|
1531
|
+
}
|
|
1532
|
+
else {
|
|
1533
|
+
const ref = `sc_remove_ref${emitter.tempCounter++}`;
|
|
1534
|
+
emitter.line(`void *${ref}; memcpy(&${ref}, &${slot}, sizeof ${ref});`);
|
|
1535
|
+
const rc = vAdapters(elemT);
|
|
1536
|
+
present = sameUnion ? `(ScrUnion *)${ref}` : `scr_union_new_ref(${tag}, ${ref}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(elemT)})`;
|
|
1537
|
+
}
|
|
1538
|
+
return emitter.newTemp(e.type, `${state} == SCR_ARR_VALUE ? ${present} : ${emitter.unitInstanceRef(e.type.unionId, undefTag)}`);
|
|
1539
|
+
}
|
|
1402
1540
|
case "indexOf": {
|
|
1403
1541
|
// The needle is BORROWED (released with this statement's frame);
|
|
1404
1542
|
// the ref variant dispatches on the array's element kind
|
|
@@ -1448,6 +1586,12 @@ function emitContainerExpr(emitter, e) {
|
|
|
1448
1586
|
emitter.emitPendingCheck();
|
|
1449
1587
|
return out;
|
|
1450
1588
|
}
|
|
1589
|
+
case "withUndefined": {
|
|
1590
|
+
const index = emitter.emitExpr(e.args[0]);
|
|
1591
|
+
const out = emitter.newTemp(e.type, `scr_arr_with_undefined(${r.name}, ${index.name})`);
|
|
1592
|
+
emitter.emitPendingCheck();
|
|
1593
|
+
return out;
|
|
1594
|
+
}
|
|
1451
1595
|
case "splice": {
|
|
1452
1596
|
// The removal splice: the removed elements come back as a
|
|
1453
1597
|
// fresh +1 array, their ownership MOVED out of the receiver
|
|
@@ -1457,30 +1601,6 @@ function emitContainerExpr(emitter, e) {
|
|
|
1457
1601
|
const cnt = e.args[1] ? emitter.emitExpr(e.args[1]).name : "INFINITY";
|
|
1458
1602
|
return emitter.newTemp(e.type, `scr_arr_splice(${r.name}, ${start.name}, ${cnt})`);
|
|
1459
1603
|
}
|
|
1460
|
-
case "shift": {
|
|
1461
|
-
// JS shift: undefined on an empty array, else the first
|
|
1462
|
-
// element out (ref ownership moves into the union box) with
|
|
1463
|
-
// the tail sliding down. Union construction is type-directed
|
|
1464
|
-
// here, the envGet convention.
|
|
1465
|
-
if (e.type.kind !== "union")
|
|
1466
|
-
throw new InternalCompilerError("emitter bug: shift result is not a union");
|
|
1467
|
-
const elemT = e.receiver.type.elem;
|
|
1468
|
-
const def = emitter.unionsById.get(e.type.unionId);
|
|
1469
|
-
const tag = def ? def.arms.findIndex((a) => typeEquals(a, elemT)) : -1;
|
|
1470
|
-
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
1471
|
-
if (tag < 0 || undefTag < 0)
|
|
1472
|
-
throw new InternalCompilerError("emitter bug: shift union lacks its arms");
|
|
1473
|
-
const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
|
|
1474
|
-
const present = elemT.kind === "f64"
|
|
1475
|
-
? `scr_union_new_f64(${tag}, scr_arr_shift_f64(${r.name}))`
|
|
1476
|
-
: elemT.kind === "bool"
|
|
1477
|
-
? `scr_union_new_bool(${tag}, scr_arr_shift_bool(${r.name}))`
|
|
1478
|
-
: (() => {
|
|
1479
|
-
const rc = vAdapters(elemT);
|
|
1480
|
-
return `scr_union_new_ref(${tag}, scr_arr_shift_ref(${r.name}), &${rc.retain}, &${rc.release}, ${emitter.traceArgC(elemT)})`;
|
|
1481
|
-
})();
|
|
1482
|
-
return emitter.newTemp(e.type, `scr_arr_len(${r.name}) ? ${present} : ${absent}`);
|
|
1483
|
-
}
|
|
1484
1604
|
default: {
|
|
1485
1605
|
const _exhaustive = method;
|
|
1486
1606
|
void _exhaustive;
|
|
@@ -2368,7 +2488,10 @@ function emitDynamicExpr(emitter, e) {
|
|
|
2368
2488
|
: "scr_dyn_new_null()");
|
|
2369
2489
|
}
|
|
2370
2490
|
const v = emitter.emitExpr(e.value);
|
|
2371
|
-
|
|
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) {
|
|
2372
2495
|
if (v.type.kind === "union") {
|
|
2373
2496
|
const adapter = liveDynUnionRefAdapter(emitter, v.type);
|
|
2374
2497
|
return emitter.newTemp(e.type, `${adapter}(${v.name})`);
|
|
@@ -3050,6 +3173,8 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3050
3173
|
throw new InternalCompilerError("emitter bug: yieldExpr with no operand (frontend fills undefined)");
|
|
3051
3174
|
const v = emitter.emitExpr(e.value);
|
|
3052
3175
|
const yt = e.value.type;
|
|
3176
|
+
if (e.awaited)
|
|
3177
|
+
emitter.line(`scr_async_gen_hop_done();`);
|
|
3053
3178
|
if (yt.kind === "f64" || yt.kind === "date") {
|
|
3054
3179
|
emitter.line(`scr_gen_yield_f64(${v.name});${emitter.srcComment(e.loc)}`);
|
|
3055
3180
|
}
|
|
@@ -3083,8 +3208,9 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3083
3208
|
const genT = e.gen.type;
|
|
3084
3209
|
if (genT.kind !== "generator")
|
|
3085
3210
|
throw new InternalCompilerError("emitter bug: genResume on a non-generator");
|
|
3086
|
-
|
|
3087
|
-
|
|
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");
|
|
3088
3214
|
const g = emitter.emitExpr(e.gen); // borrowed for the calls below
|
|
3089
3215
|
const sendArg = (store) => {
|
|
3090
3216
|
const a = emitter.emitExpr(e.arg);
|
|
@@ -3092,6 +3218,76 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3092
3218
|
emitter.moveTemp(a); // the slot takes ownership
|
|
3093
3219
|
emitter.line(store(a));
|
|
3094
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
|
+
}
|
|
3095
3291
|
if (e.mode === "next") {
|
|
3096
3292
|
if (e.arg === null) {
|
|
3097
3293
|
// Valueless resume: dyn channels read JS's undefined; unit
|
|
@@ -3156,7 +3352,7 @@ function emitAsyncExpr(emitter, e) {
|
|
|
3156
3352
|
}
|
|
3157
3353
|
emitter.line(`scr_gen_resume_throw(${g.name});`);
|
|
3158
3354
|
}
|
|
3159
|
-
const helper = genResultThunkFor(emitter, genT,
|
|
3355
|
+
const helper = genResultThunkFor(emitter, genT, resultT);
|
|
3160
3356
|
// The record builds before the check so an unwind (a propagated
|
|
3161
3357
|
// body exception) releases it as the frame's never-read dummy.
|
|
3162
3358
|
return emitter.fallibleTemp(e.type, `${helper}(${g.name})`);
|
|
@@ -6725,6 +6921,38 @@ function emitProcessLibCall(state) {
|
|
|
6725
6921
|
return finish(`scr_process_getuid()`);
|
|
6726
6922
|
case "process.uptime":
|
|
6727
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()`);
|
|
6728
6956
|
case "process.availableMemory":
|
|
6729
6957
|
return finish(`scr_available_memory()`);
|
|
6730
6958
|
case "process.constrainedMemory":
|
|
@@ -7470,6 +7698,9 @@ function emitStreamLibCall(state) {
|
|
|
7470
7698
|
case "stream.destroyErr":
|
|
7471
7699
|
emitter.usesTimers = true;
|
|
7472
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)})`);
|
|
7473
7704
|
case "stream.prop": {
|
|
7474
7705
|
// The property NAME is a compile-time literal; args[1]'s
|
|
7475
7706
|
// emitted temp is unused (released with the statement's frame).
|
|
@@ -7769,6 +8000,7 @@ function emitLibCallExpr(emitter, e) {
|
|
|
7769
8000
|
return emitAsyncContextLibCall(state);
|
|
7770
8001
|
case "process":
|
|
7771
8002
|
case "stdin":
|
|
8003
|
+
case "module":
|
|
7772
8004
|
return emitProcessLibCall(state);
|
|
7773
8005
|
case "error":
|
|
7774
8006
|
case "regex":
|
|
@@ -7832,6 +8064,8 @@ export function emitExpr(emitter, e) {
|
|
|
7832
8064
|
case "arrayLit":
|
|
7833
8065
|
case "arrayNewLen":
|
|
7834
8066
|
case "arrayGet":
|
|
8067
|
+
case "arrayHas":
|
|
8068
|
+
case "arrayState":
|
|
7835
8069
|
case "arrIntrinsic":
|
|
7836
8070
|
case "bytesNew":
|
|
7837
8071
|
case "bytesIntrinsic":
|