@scriptc/compiler 0.0.7 → 0.0.8
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/dist/backend/emission/emit-exprs.js +47 -1
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-island.js +9 -1
- package/dist/backend/emission/emit-island.js.map +1 -1
- package/dist/backend/emission/emit-stmts.js +3 -1
- package/dist/backend/emission/emit-stmts.js.map +1 -1
- package/dist/backend/emission/emit-walkers.js +22 -8
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.js +5 -1
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/emission/may-throw.js +4 -3
- package/dist/backend/emission/may-throw.js.map +1 -1
- package/dist/backend/llvm/emitter.js +94 -7
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +43 -1
- package/dist/diagnostics/diagnostic.js +103 -5
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lib-contract.d.ts +24 -6
- package/dist/frontend/lib-contract.js +125 -44
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.js +16 -1
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +47 -7
- package/dist/frontend/lowering/lower-calls.js +560 -36
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +14 -1
- package/dist/frontend/lowering/lower-classes.js +85 -15
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.js +43 -1
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.js +1 -1
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +26 -3
- package/dist/frontend/lowering/lower-exprs.js +455 -40
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +7 -0
- package/dist/frontend/lowering/lower-island.js +71 -10
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +1 -1
- package/dist/frontend/lowering/lower-mixins.js +1 -1
- package/dist/frontend/lowering/lower-modules.js +95 -4
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +421 -43
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +19 -3
- package/dist/frontend/lowering/lowerer.js +188 -11
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/types.d.ts +28 -1
- package/dist/frontend/types.js +300 -8
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +37 -7
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +28 -2
- package/dist/ir/nodes.js +35 -3
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +35 -6
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/profile.d.ts +17 -3
- package/dist/library/profile.js +38 -9
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar.js +162 -43
- package/dist/library/sidecar.js.map +1 -1
- package/dist/library/trap-teaching.d.ts +11 -0
- package/dist/library/trap-teaching.js +49 -0
- package/dist/library/trap-teaching.js.map +1 -0
- package/package.json +2 -2
- package/surface-manifest.json +37 -2
|
@@ -542,6 +542,8 @@ const LIB_FN_SYMS = {
|
|
|
542
542
|
// (option/DataClone/cycle errors), and new RegExp's eager compile
|
|
543
543
|
// (catchable SyntaxError) — all may-throw generics over the DOM.
|
|
544
544
|
"dyn.objKeys": "scr_dyn_obj_keys",
|
|
545
|
+
"dyn.hasOwn": "scr_dyn_has_own",
|
|
546
|
+
"dyn.assign": "scr_dyn_assign",
|
|
545
547
|
"dyn.objValues": "scr_dyn_obj_values",
|
|
546
548
|
"dyn.objEntries": "scr_dyn_obj_entries",
|
|
547
549
|
"dyn.structuredClone": "scr_structured_clone",
|
|
@@ -1023,7 +1025,7 @@ class LlEmitter {
|
|
|
1023
1025
|
this.declare(`declare ptr @scr_library_str_in(ptr, i64)`);
|
|
1024
1026
|
}
|
|
1025
1027
|
if (this.mod.lib.exports.some((e) => e.params.includes("bytes"))) {
|
|
1026
|
-
this.declare(`declare ptr @scr_library_bytes_in(ptr, i64)`);
|
|
1028
|
+
this.declare(`declare ptr @scr_library_bytes_in(ptr, i64, ptr)`);
|
|
1027
1029
|
}
|
|
1028
1030
|
if (this.mod.lib.exports.some((e) => e.returns === "string")) {
|
|
1029
1031
|
this.declare(`declare void @scr_library_str_out(ptr, ptr, ptr)`);
|
|
@@ -1286,6 +1288,14 @@ class LlEmitter {
|
|
|
1286
1288
|
const params = [];
|
|
1287
1289
|
const body = [` call void @scr_library_entry(i1 zeroext ${autoReset ? "true" : "false"})`];
|
|
1288
1290
|
const args = [];
|
|
1291
|
+
if (e.inboundBytesTrap !== undefined) {
|
|
1292
|
+
// The bytes-in helper's trap message: the compiler-assembled
|
|
1293
|
+
// structured trap-teaching form (0x01 text 0x1F SC4012 0x1F symbol
|
|
1294
|
+
// [0x1F remediation]) — the same bytes the C emission passes, so
|
|
1295
|
+
// the sink message is emission-invariant by construction.
|
|
1296
|
+
const trapBytes = Buffer.byteLength(e.inboundBytesTrap, "utf8");
|
|
1297
|
+
out.push(`@sc_lib_bytes_trap_${e.symbol} = internal constant [${trapBytes + 1} x i8] c"${llStrBytes(e.inboundBytesTrap)}"`, ``);
|
|
1298
|
+
}
|
|
1289
1299
|
e.params.forEach((cls, i) => {
|
|
1290
1300
|
switch (cls) {
|
|
1291
1301
|
case "f64":
|
|
@@ -1319,7 +1329,7 @@ class LlEmitter {
|
|
|
1319
1329
|
break;
|
|
1320
1330
|
case "bytes":
|
|
1321
1331
|
params.push(`ptr %a${i}_ptr`, `i64 %a${i}_len`);
|
|
1322
|
-
body.push(` %c${i} = call ptr @scr_library_bytes_in(ptr %a${i}_ptr, i64 %a${i}_len)`);
|
|
1332
|
+
body.push(` %c${i} = call ptr @scr_library_bytes_in(ptr %a${i}_ptr, i64 %a${i}_len, ptr @sc_lib_bytes_trap_${e.symbol})`);
|
|
1323
1333
|
args.push(`ptr %c${i}`);
|
|
1324
1334
|
break;
|
|
1325
1335
|
}
|
|
@@ -2558,9 +2568,13 @@ class LlEmitter {
|
|
|
2558
2568
|
if (isRefCounted(v.type))
|
|
2559
2569
|
this.moveTemp(v);
|
|
2560
2570
|
const shape = this.recordShape(s.shapeId);
|
|
2561
|
-
|
|
2571
|
+
// Signature-free shapes dispatch over their (one-typed) declared
|
|
2572
|
+
// fields and TRAP on a miss (scr_record_key_miss — JS would add
|
|
2573
|
+
// the property, which a monomorphic struct cannot); overflow
|
|
2574
|
+
// shapes keep the map insert tail.
|
|
2575
|
+
const iv = shape.indexValue ?? shape.fields[0]?.type;
|
|
2562
2576
|
if (!iv)
|
|
2563
|
-
throw new Error(`llvm emitter bug: keyed write on non-overflow shape ${s.shapeId}`);
|
|
2577
|
+
throw new Error(`llvm emitter bug: keyed write on field-free non-overflow shape ${s.shapeId}`);
|
|
2564
2578
|
const vAcc = iv.kind === "f64" ? "f64" : iv.kind === "bool" ? "bool" : "ref";
|
|
2565
2579
|
if (s.overflowOnly === true) {
|
|
2566
2580
|
// A LITERAL key naming no declared field: a plain overflow
|
|
@@ -2571,7 +2585,7 @@ class LlEmitter {
|
|
|
2571
2585
|
}
|
|
2572
2586
|
const join = B.newLabel("rks.j");
|
|
2573
2587
|
this.declare(`declare zeroext i1 @scr_str_eq(ptr, ptr)`);
|
|
2574
|
-
if (iv.kind === "dyn") {
|
|
2588
|
+
if (iv.kind === "dyn" && shape.indexValue) {
|
|
2575
2589
|
// A dyn-valued shape (the C recordKeySetHelper's dyn arm,
|
|
2576
2590
|
// inline): declared keys VALIDATE the dyn value against the
|
|
2577
2591
|
// field's type first (dynCheck — a mismatched write throws the
|
|
@@ -2656,6 +2670,19 @@ class LlEmitter {
|
|
|
2656
2670
|
B.br(join);
|
|
2657
2671
|
B.startBlock(ln);
|
|
2658
2672
|
}
|
|
2673
|
+
if (!shape.indexValue) {
|
|
2674
|
+
// The MISS on a fixed shape: release the moved-in value, throw
|
|
2675
|
+
// the catchable TypeError naming the key (scr_record_key_miss —
|
|
2676
|
+
// JS would add the property, the documented divergence).
|
|
2677
|
+
if (isRefCounted(iv))
|
|
2678
|
+
this.releaseValue(v.name, iv);
|
|
2679
|
+
this.declare(`declare void @scr_record_key_miss(ptr)`);
|
|
2680
|
+
B.line(`call void @scr_record_key_miss(ptr ${key.name})`);
|
|
2681
|
+
B.br(join);
|
|
2682
|
+
B.startBlock(join);
|
|
2683
|
+
this.emitPendingCheck();
|
|
2684
|
+
break;
|
|
2685
|
+
}
|
|
2659
2686
|
const ovf = this.recordOvfPtr(obj.name, s.shapeId);
|
|
2660
2687
|
this.mapSet(ovf, "str", vAcc, key.name, v.name);
|
|
2661
2688
|
B.br(join);
|
|
@@ -4051,6 +4078,31 @@ class LlEmitter {
|
|
|
4051
4078
|
// TAG against its unit arms as the test. Pass-through shape: the
|
|
4052
4079
|
// result IS the left box. Narrowed shape: the single non-unit
|
|
4053
4080
|
// arm's payload extracts (+1 for ref kinds) and the box releases.
|
|
4081
|
+
if (e.left.type.kind === "jsval") {
|
|
4082
|
+
// The island form: engine nullish test, lazy right (jsval).
|
|
4083
|
+
const l = this.emitExpr(e.left);
|
|
4084
|
+
this.moveTemp(l);
|
|
4085
|
+
this.declare(`declare zeroext i1 @scr_jsval_is_nullish(ptr)`);
|
|
4086
|
+
const slot = B.slot();
|
|
4087
|
+
B.entryAllocas.push(`${slot} = alloca ptr`);
|
|
4088
|
+
const isN = B.tmp();
|
|
4089
|
+
B.line(`${isN} = call zeroext i1 @scr_jsval_is_nullish(ptr ${l.name})`);
|
|
4090
|
+
const lu = B.newLabel("nulj.u");
|
|
4091
|
+
const lv = B.newLabel("nulj.v");
|
|
4092
|
+
const lj = B.newLabel("nulj.j");
|
|
4093
|
+
B.condBr(isN, lu, lv);
|
|
4094
|
+
B.startBlock(lu);
|
|
4095
|
+
this.releaseValue(l.name, e.left.type);
|
|
4096
|
+
this.emitBranchInto(slot, e.right);
|
|
4097
|
+
B.br(lj);
|
|
4098
|
+
B.startBlock(lv);
|
|
4099
|
+
B.line(`store ptr ${l.name}, ptr ${slot}`);
|
|
4100
|
+
B.br(lj);
|
|
4101
|
+
B.startBlock(lj);
|
|
4102
|
+
const t = B.tmp();
|
|
4103
|
+
B.line(`${t} = load ptr, ptr ${slot}`);
|
|
4104
|
+
return this.own({ name: t, type: e.type });
|
|
4105
|
+
}
|
|
4054
4106
|
if (e.left.type.kind !== "union")
|
|
4055
4107
|
throw new Error("llvm emitter bug: nullish left is not a union");
|
|
4056
4108
|
const def = this.unionsById.get(e.left.type.unionId);
|
|
@@ -5797,8 +5849,12 @@ class LlEmitter {
|
|
|
5797
5849
|
? this.islandAdapter(fn.params.length, fn.ret.kind)
|
|
5798
5850
|
: this.islandTypedAdapter(fn);
|
|
5799
5851
|
this.declare(`declare ptr @scr_jsval_from_closure(ptr, i32, ptr)`);
|
|
5852
|
+
// ISLAND-REST closures encode a NEGATIVE arity (the C emitter's
|
|
5853
|
+
// rule): the wrapper hands the trailing slot the engine array of
|
|
5854
|
+
// the surplus arguments.
|
|
5855
|
+
const arity = fn.rest === true && fn.restAbi === "jsval" ? -fn.params.length : fn.params.length;
|
|
5800
5856
|
const t = B.tmp();
|
|
5801
|
-
B.line(`${t} = call ptr @scr_jsval_from_closure(ptr ${v.name}, i32 ${
|
|
5857
|
+
B.line(`${t} = call ptr @scr_jsval_from_closure(ptr ${v.name}, i32 ${arity}, ptr @${adapter})`);
|
|
5802
5858
|
return this.own({ name: t, type: e.type });
|
|
5803
5859
|
}
|
|
5804
5860
|
default: {
|
|
@@ -5997,6 +6053,30 @@ class LlEmitter {
|
|
|
5997
6053
|
B.line(`${t} = call ptr @scr_jsval_obj_lit(i32 ${args.length / 2}, ptr ${pack})`);
|
|
5998
6054
|
return this.own({ name: t, type: e.type });
|
|
5999
6055
|
}
|
|
6056
|
+
case "tplStrings": {
|
|
6057
|
+
const pack = argPack(args.map((x) => x.name));
|
|
6058
|
+
this.declare(`declare ptr @scr_jsval_tpl_strings(i32, ptr)`);
|
|
6059
|
+
const t = B.tmp();
|
|
6060
|
+
B.line(`${t} = call ptr @scr_jsval_tpl_strings(i32 ${args.length / 2}, ptr ${pack})`);
|
|
6061
|
+
return this.own({ name: t, type: e.type });
|
|
6062
|
+
}
|
|
6063
|
+
case "objSpread": {
|
|
6064
|
+
this.declare(`declare ptr @scr_jsval_obj_spread(ptr, ptr)`);
|
|
6065
|
+
return fallible(() => {
|
|
6066
|
+
const t = B.tmp();
|
|
6067
|
+
B.line(`${t} = call ptr @scr_jsval_obj_spread(ptr ${a(0)}, ptr ${a(1)})`);
|
|
6068
|
+
return t;
|
|
6069
|
+
});
|
|
6070
|
+
}
|
|
6071
|
+
case "defineGetter": {
|
|
6072
|
+
// Getter completion for an island literal (the C emitter's
|
|
6073
|
+
// scr_jsval_define_getter shape): defines key a(1) on obj a(0)
|
|
6074
|
+
// as an engine getter invoking a(2); answers the object (+1).
|
|
6075
|
+
this.declare(`declare ptr @scr_jsval_define_getter(ptr, ptr, ptr)`);
|
|
6076
|
+
const t = B.tmp();
|
|
6077
|
+
B.line(`${t} = call ptr @scr_jsval_define_getter(ptr ${a(0)}, ptr ${a(1)}, ptr ${a(2)})`);
|
|
6078
|
+
return this.own({ name: t, type: e.type });
|
|
6079
|
+
}
|
|
6000
6080
|
case "arrLit": {
|
|
6001
6081
|
const pack = argPack(args.map((x) => x.name));
|
|
6002
6082
|
this.declare(`declare ptr @scr_jsval_arr_lit(i32, ptr)`);
|
|
@@ -6306,7 +6386,7 @@ class LlEmitter {
|
|
|
6306
6386
|
d.push(` %fnp = getelementptr inbounds %ScrClosure, ptr %c, i64 0, i32 1`, ` %fn = load ptr, ptr %fnp`);
|
|
6307
6387
|
if (ret.async) {
|
|
6308
6388
|
// The closure returns a +1 ScrPromise; from_promise takes ownership.
|
|
6309
|
-
const tagN = { void: 0, f64: 1, bool: 2, string: 3, jsval: 4, json: 0 }[ret.tag];
|
|
6389
|
+
const tagN = { void: 0, f64: 1, bool: 2, string: 3, jsval: 4, json: 0, dyn: 0 }[ret.tag];
|
|
6310
6390
|
this.declare(`declare ptr @scr_jsval_from_promise(ptr, i32)`);
|
|
6311
6391
|
d.push(` %pr = call ptr %fn(${passed.join(", ")})`, ` %prn = icmp eq ptr %pr, null`, ` br i1 %prn, label %pnull, label %pok`, `pnull:`, ` ret ptr null`, `pok:`, ` %pj = call ptr @scr_jsval_from_promise(ptr %pr, i32 ${tagN})`, ` ret ptr %pj`);
|
|
6312
6392
|
}
|
|
@@ -6331,6 +6411,13 @@ class LlEmitter {
|
|
|
6331
6411
|
this.declare(`declare void @scr_str_release(ptr)`);
|
|
6332
6412
|
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`);
|
|
6333
6413
|
break;
|
|
6414
|
+
case "dyn":
|
|
6415
|
+
// A checked-dynamic (+1 DOM) result: deep copy into the engine
|
|
6416
|
+
// (the jsMarshal dyn rule); NULL is the throw-path dummy.
|
|
6417
|
+
this.declare(`declare ptr @scr_jsval_from_dyn(ptr)`);
|
|
6418
|
+
this.declare(`declare void @scr_dyn_release(ptr)`);
|
|
6419
|
+
d.push(` %r = call ptr %fn(${passed.join(", ")})`, ` %rn = icmp eq ptr %r, null`, ` br i1 %rn, label %dnull, label %dok`, `dnull:`, ` ret ptr null`, `dok:`, ` %j = call ptr @scr_jsval_from_dyn(ptr %r)`, ` call void @scr_dyn_release(ptr %r)`, ` ret ptr %j`);
|
|
6420
|
+
break;
|
|
6334
6421
|
case "json": {
|
|
6335
6422
|
// A JSON-safe composite return: the jsMarshal path — the type-
|
|
6336
6423
|
// directed serializer, then the engine's JSON parser (deep
|