gofront 1.6.0 → 1.7.0
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/README.md +35 -39
- package/package.json +37 -4
- package/src/backend/js/expressions.js +559 -144
- package/src/backend/js/index.js +174 -49
- package/src/backend/js/runtime.js +1518 -54
- package/src/backend/js/statements.js +91 -73
- package/src/backend/js/stdlib/base64.js +12 -0
- package/src/backend/js/stdlib/binary.js +102 -0
- package/src/backend/js/stdlib/bits.js +15 -1
- package/src/backend/js/stdlib/builder.js +28 -9
- package/src/backend/js/stdlib/bytes.js +75 -18
- package/src/backend/js/stdlib/errors.js +25 -1
- package/src/backend/js/stdlib/fmt.js +70 -13
- package/src/backend/js/stdlib/hex.js +17 -0
- package/src/backend/js/stdlib/html.js +1 -1
- package/src/backend/js/stdlib/index.js +28 -0
- package/src/backend/js/stdlib/io.js +105 -3
- package/src/backend/js/stdlib/json.js +972 -0
- package/src/backend/js/stdlib/math.js +13 -1
- package/src/backend/js/stdlib/path.js +18 -4
- package/src/backend/js/stdlib/rand.js +10 -5
- package/src/backend/js/stdlib/sha256.js +12 -0
- package/src/backend/js/stdlib/simd.js +24 -0
- package/src/backend/js/stdlib/slices.js +52 -26
- package/src/backend/js/stdlib/strconv.js +21 -5
- package/src/backend/js/stdlib/strings.js +148 -15
- package/src/backend/js/stdlib/sync.js +13 -0
- package/src/backend/js/stdlib/time.js +90 -19
- package/src/backend/js/stdlib/unicode.js +2 -2
- package/src/backend/wasm/boundary.js +1225 -41
- package/src/backend/wasm/const-fold.js +205 -0
- package/src/backend/wasm/emit-builtins.js +220 -76
- package/src/backend/wasm/emit-exprs.js +475 -276
- package/src/backend/wasm/emit-maps.js +144 -8
- package/src/backend/wasm/emit-stdlib.js +12 -3005
- package/src/backend/wasm/emit-stmts.js +264 -270
- package/src/backend/wasm/emit.js +124 -87
- package/src/backend/wasm/encode.js +140 -29
- package/src/backend/wasm/index.js +1001 -32
- package/src/backend/wasm/optimize.js +17 -6
- package/src/backend/wasm/stdlib/bytes.js +5039 -0
- package/src/backend/wasm/stdlib/core.js +8903 -0
- package/src/backend/wasm/stdlib/index.js +43 -0
- package/src/backend/wasm/stdlib/io.js +2161 -0
- package/src/backend/wasm/stdlib/packages.js +2400 -0
- package/src/backend/wasm/stdlib/pure.js +720 -0
- package/src/backend/wasm/stdlib/simd.js +234 -0
- package/src/backend/wasm/stdlib/time.js +1200 -0
- package/src/backend/wasm/types.js +174 -1
- package/src/backend/wasm/wat.js +37 -0
- package/src/cli-core.js +1 -1
- package/src/compiler.js +18 -4
- package/src/dts-parser.js +150 -140
- package/src/index.js +2 -6
- package/src/lexer.js +80 -29
- package/src/lower/boxing.js +1 -7
- package/src/lower/captures.js +2 -6
- package/src/lower/embedding.js +2 -1
- package/src/lower/ownership.js +30 -9
- package/src/minifier.js +20 -68
- package/src/parser/declarations.js +3 -6
- package/src/parser/expressions.js +3 -8
- package/src/parser/index.js +18 -3
- package/src/parser/statements.js +25 -38
- package/src/parser/struct-tag.js +144 -0
- package/src/parser/types.js +64 -8
- package/src/resolver.js +2 -27
- package/src/templ-lexer.js +29 -63
- package/src/templ-parser.js +22 -45
- package/src/typechecker/assignability.js +126 -13
- package/src/typechecker/expressions.js +168 -16
- package/src/typechecker/index.js +35 -8
- package/src/typechecker/resolve.js +187 -8
- package/src/typechecker/statements.js +68 -9
- package/src/typechecker/stdlib/core.js +280 -89
- package/src/typechecker/stdlib/extended.js +490 -1
- package/src/typechecker/stdlib/simd.js +73 -0
- package/src/typechecker/stdlib.js +2 -0
- package/src/typechecker/types.js +362 -9
- package/src/vendor.js +86 -11
|
@@ -205,6 +205,31 @@ export class StmtsEmitter {
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
_emitAssignToTarget(target, wasmType, goType, emitValue) {
|
|
209
|
+
const tempName = `__assign_tmp_${this.tempCounter++}`;
|
|
210
|
+
const effectiveGoType = goType ??
|
|
211
|
+
target._type ?? {
|
|
212
|
+
kind: "basic",
|
|
213
|
+
name: wasmType === "i64" ? "int64" : "int",
|
|
214
|
+
};
|
|
215
|
+
const effectiveWasmType = wasmType ?? this.toWasmType(effectiveGoType);
|
|
216
|
+
const tempIdx = this.allocLocal(
|
|
217
|
+
tempName,
|
|
218
|
+
effectiveWasmType,
|
|
219
|
+
effectiveGoType,
|
|
220
|
+
true,
|
|
221
|
+
);
|
|
222
|
+
emitValue();
|
|
223
|
+
this.pushInstruction({ op: "local.set", index: tempIdx });
|
|
224
|
+
const rNode = {
|
|
225
|
+
kind: "Ident",
|
|
226
|
+
name: tempName,
|
|
227
|
+
_type: effectiveGoType,
|
|
228
|
+
};
|
|
229
|
+
this._emitAssignSingle(target, rNode, "=");
|
|
230
|
+
this.locals.delete(tempName);
|
|
231
|
+
}
|
|
232
|
+
|
|
208
233
|
_emitAssignSingle(l, r, op) {
|
|
209
234
|
if (!r) return;
|
|
210
235
|
if (l.kind === "Ident") {
|
|
@@ -261,7 +286,11 @@ export class StmtsEmitter {
|
|
|
261
286
|
);
|
|
262
287
|
}
|
|
263
288
|
const lastStep = path[path.length - 1];
|
|
264
|
-
const
|
|
289
|
+
const exprGoType =
|
|
290
|
+
l.expr._type ??
|
|
291
|
+
this.resolveLocal(l.expr.name)?.goType ??
|
|
292
|
+
this._resolveExprGoType(l.expr);
|
|
293
|
+
const baseWType = this.toWasmType(exprGoType);
|
|
265
294
|
|
|
266
295
|
this.emitExpr(l.expr, baseWType);
|
|
267
296
|
for (let i = 0; i < path.length - 1; i++) {
|
|
@@ -314,7 +343,13 @@ export class StmtsEmitter {
|
|
|
314
343
|
this.releaseTemp(tmpL, baseWType);
|
|
315
344
|
return;
|
|
316
345
|
}
|
|
317
|
-
const
|
|
346
|
+
const operandGoType =
|
|
347
|
+
l.operand._type ??
|
|
348
|
+
(l.operand.kind === "Ident"
|
|
349
|
+
? this.resolveLocal(l.operand.name)?.goType
|
|
350
|
+
: null) ??
|
|
351
|
+
this._resolveExprGoType(l.operand);
|
|
352
|
+
const box = this.mod.getBoxType(operandGoType?.base ?? operandGoType);
|
|
318
353
|
const baseWType = {
|
|
319
354
|
kind: "ref",
|
|
320
355
|
nullable: true,
|
|
@@ -455,43 +490,59 @@ export class StmtsEmitter {
|
|
|
455
490
|
|
|
456
491
|
this.releaseTemp(anyTmp, "anyref");
|
|
457
492
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
493
|
+
this._emitStoreLhsFromTemp(
|
|
494
|
+
valLhs,
|
|
495
|
+
valTmp,
|
|
496
|
+
targetWType,
|
|
497
|
+
targetGoType,
|
|
498
|
+
isDefine,
|
|
499
|
+
);
|
|
500
|
+
this._emitStoreLhsFromTemp(
|
|
501
|
+
okLhs,
|
|
502
|
+
okTmp,
|
|
503
|
+
"i32",
|
|
504
|
+
{ kind: "basic", name: "bool" },
|
|
505
|
+
isDefine,
|
|
506
|
+
);
|
|
473
507
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
508
|
+
this.releaseTemp(valTmp, targetWType);
|
|
509
|
+
this.releaseTemp(okTmp, "i32");
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
_emitStoreLhsFromTemp(lhsNode, tempIdx, wType, goType, isDefine) {
|
|
513
|
+
if (lhsNode.kind !== "Ident" || lhsNode.name === "_") return;
|
|
514
|
+
if (isDefine) {
|
|
515
|
+
const idx = this.allocLocal(lhsNode.name, wType, goType);
|
|
516
|
+
const local = this.locals.get(lhsNode.name);
|
|
517
|
+
this.pushInstruction({ op: "local.get", index: tempIdx });
|
|
518
|
+
if (local?.isBoxed) {
|
|
519
|
+
this.pushInstruction({
|
|
520
|
+
op: "struct.new",
|
|
521
|
+
typeIndex: local.boxInfo.typeIndex,
|
|
522
|
+
});
|
|
523
|
+
}
|
|
481
524
|
this.pushInstruction({ op: "local.set", index: idx });
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
const local = this.resolveLocal(lhsNode.name);
|
|
528
|
+
if (local) {
|
|
529
|
+
if (local.isBoxed) {
|
|
530
|
+
this.pushInstruction({ op: "local.get", index: local.index });
|
|
531
|
+
this.pushInstruction({ op: "local.get", index: tempIdx });
|
|
532
|
+
this.pushInstruction({
|
|
533
|
+
op: "struct.set",
|
|
534
|
+
typeIndex: local.boxInfo.typeIndex,
|
|
535
|
+
fieldIndex: 0,
|
|
536
|
+
});
|
|
487
537
|
} else {
|
|
488
|
-
|
|
489
|
-
this.pushInstruction({ op: "
|
|
538
|
+
this.pushInstruction({ op: "local.get", index: tempIdx });
|
|
539
|
+
this.pushInstruction({ op: "local.set", index: local.index });
|
|
490
540
|
}
|
|
541
|
+
} else {
|
|
542
|
+
const global = this.mod.resolveGlobal(lhsNode.name);
|
|
543
|
+
this.pushInstruction({ op: "local.get", index: tempIdx });
|
|
544
|
+
this.pushInstruction({ op: "global.set", index: global.index });
|
|
491
545
|
}
|
|
492
|
-
|
|
493
|
-
this.releaseTemp(valTmp, targetWType);
|
|
494
|
-
this.releaseTemp(okTmp, "i32");
|
|
495
546
|
}
|
|
496
547
|
|
|
497
548
|
_emitCommaOkMapIndex(valLhs, okLhs, indexExpr, isDefine) {
|
|
@@ -512,82 +563,20 @@ export class StmtsEmitter {
|
|
|
512
563
|
this.pushInstruction({ op: "local.set", index: okTmp });
|
|
513
564
|
this.pushInstruction({ op: "local.set", index: valTmp });
|
|
514
565
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
}
|
|
530
|
-
} else if (valLhs.kind === "Ident" && valLhs.name !== "_") {
|
|
531
|
-
const local = this.resolveLocal(valLhs.name);
|
|
532
|
-
if (local) {
|
|
533
|
-
if (local.isBoxed) {
|
|
534
|
-
this.pushInstruction({ op: "local.get", index: local.index });
|
|
535
|
-
this.pushInstruction({ op: "local.get", index: valTmp });
|
|
536
|
-
this.pushInstruction({
|
|
537
|
-
op: "struct.set",
|
|
538
|
-
typeIndex: local.boxInfo.typeIndex,
|
|
539
|
-
fieldIndex: 0,
|
|
540
|
-
});
|
|
541
|
-
} else {
|
|
542
|
-
this.pushInstruction({ op: "local.get", index: valTmp });
|
|
543
|
-
this.pushInstruction({ op: "local.set", index: local.index });
|
|
544
|
-
}
|
|
545
|
-
} else {
|
|
546
|
-
const global = this.mod.resolveGlobal(valLhs.name);
|
|
547
|
-
this.pushInstruction({ op: "local.get", index: valTmp });
|
|
548
|
-
this.pushInstruction({ op: "global.set", index: global.index });
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// Assign ok to okLhs
|
|
553
|
-
if (isDefine && okLhs.kind === "Ident" && okLhs.name !== "_") {
|
|
554
|
-
const idx = this.allocLocal(okLhs.name, "i32", {
|
|
555
|
-
kind: "basic",
|
|
556
|
-
name: "bool",
|
|
557
|
-
});
|
|
558
|
-
const local = this.locals.get(okLhs.name);
|
|
559
|
-
if (local?.isBoxed) {
|
|
560
|
-
this.pushInstruction({ op: "local.get", index: okTmp });
|
|
561
|
-
this.pushInstruction({
|
|
562
|
-
op: "struct.new",
|
|
563
|
-
typeIndex: local.boxInfo.typeIndex,
|
|
564
|
-
});
|
|
565
|
-
this.pushInstruction({ op: "local.set", index: idx });
|
|
566
|
-
} else {
|
|
567
|
-
this.pushInstruction({ op: "local.get", index: okTmp });
|
|
568
|
-
this.pushInstruction({ op: "local.set", index: idx });
|
|
569
|
-
}
|
|
570
|
-
} else if (okLhs.kind === "Ident" && okLhs.name !== "_") {
|
|
571
|
-
const local = this.resolveLocal(okLhs.name);
|
|
572
|
-
if (local) {
|
|
573
|
-
if (local.isBoxed) {
|
|
574
|
-
this.pushInstruction({ op: "local.get", index: local.index });
|
|
575
|
-
this.pushInstruction({ op: "local.get", index: okTmp });
|
|
576
|
-
this.pushInstruction({
|
|
577
|
-
op: "struct.set",
|
|
578
|
-
typeIndex: local.boxInfo.typeIndex,
|
|
579
|
-
fieldIndex: 0,
|
|
580
|
-
});
|
|
581
|
-
} else {
|
|
582
|
-
this.pushInstruction({ op: "local.get", index: okTmp });
|
|
583
|
-
this.pushInstruction({ op: "local.set", index: local.index });
|
|
584
|
-
}
|
|
585
|
-
} else {
|
|
586
|
-
const global = this.mod.resolveGlobal(okLhs.name);
|
|
587
|
-
this.pushInstruction({ op: "local.get", index: okTmp });
|
|
588
|
-
this.pushInstruction({ op: "global.set", index: global.index });
|
|
589
|
-
}
|
|
590
|
-
}
|
|
566
|
+
this._emitStoreLhsFromTemp(
|
|
567
|
+
valLhs,
|
|
568
|
+
valTmp,
|
|
569
|
+
mapInfo.valWType,
|
|
570
|
+
valType,
|
|
571
|
+
isDefine,
|
|
572
|
+
);
|
|
573
|
+
this._emitStoreLhsFromTemp(
|
|
574
|
+
okLhs,
|
|
575
|
+
okTmp,
|
|
576
|
+
"i32",
|
|
577
|
+
{ kind: "basic", name: "bool" },
|
|
578
|
+
isDefine,
|
|
579
|
+
);
|
|
591
580
|
|
|
592
581
|
this.releaseTemp(valTmp, mapInfo.valWType);
|
|
593
582
|
this.releaseTemp(okTmp, "i32");
|
|
@@ -693,7 +682,7 @@ export class StmtsEmitter {
|
|
|
693
682
|
}
|
|
694
683
|
|
|
695
684
|
// Scalar types
|
|
696
|
-
const box = this.mod.
|
|
685
|
+
const box = this.mod.getIfaceBoxType(targetGoType);
|
|
697
686
|
if (box) {
|
|
698
687
|
this.pushInstruction({ op: "ref.test", typeIndex: box.typeIndex });
|
|
699
688
|
return;
|
|
@@ -734,17 +723,9 @@ export class StmtsEmitter {
|
|
|
734
723
|
}
|
|
735
724
|
if (isStructType(targetGoType, this.mod.checker, this.mod)) {
|
|
736
725
|
const sInfo = this.mod.getStructType(this._structNameOf(targetGoType));
|
|
737
|
-
const box = this.mod.
|
|
726
|
+
const box = this.mod.getIfaceBoxType(targetGoType);
|
|
738
727
|
if (sInfo && box) {
|
|
739
|
-
this.
|
|
740
|
-
op: "ref.cast_null",
|
|
741
|
-
typeIndex: box.typeIndex,
|
|
742
|
-
});
|
|
743
|
-
this.pushInstruction({
|
|
744
|
-
op: "struct.get",
|
|
745
|
-
typeIndex: box.typeIndex,
|
|
746
|
-
fieldIndex: 0,
|
|
747
|
-
});
|
|
728
|
+
this._emitUnbox(box);
|
|
748
729
|
this.emitCloneStruct(sInfo, targetWType);
|
|
749
730
|
return;
|
|
750
731
|
}
|
|
@@ -775,21 +756,25 @@ export class StmtsEmitter {
|
|
|
775
756
|
}
|
|
776
757
|
|
|
777
758
|
// Scalar types
|
|
778
|
-
const box = this.mod.
|
|
759
|
+
const box = this.mod.getIfaceBoxType(targetGoType);
|
|
779
760
|
if (box) {
|
|
780
|
-
this.
|
|
781
|
-
op: "ref.cast_null",
|
|
782
|
-
typeIndex: box.typeIndex,
|
|
783
|
-
});
|
|
784
|
-
this.pushInstruction({
|
|
785
|
-
op: "struct.get",
|
|
786
|
-
typeIndex: box.typeIndex,
|
|
787
|
-
fieldIndex: 0,
|
|
788
|
-
});
|
|
761
|
+
this._emitUnbox(box);
|
|
789
762
|
return;
|
|
790
763
|
}
|
|
791
764
|
}
|
|
792
765
|
|
|
766
|
+
_emitUnbox(box) {
|
|
767
|
+
this.pushInstruction({
|
|
768
|
+
op: "ref.cast_null",
|
|
769
|
+
typeIndex: box.typeIndex,
|
|
770
|
+
});
|
|
771
|
+
this.pushInstruction({
|
|
772
|
+
op: "struct.get",
|
|
773
|
+
typeIndex: box.typeIndex,
|
|
774
|
+
fieldIndex: 0,
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
|
|
793
778
|
_emitCompoundAssign(lhs, rhs, op) {
|
|
794
779
|
const baseOp = op.slice(0, -1);
|
|
795
780
|
const l = Array.isArray(lhs) ? lhs[0] : lhs;
|
|
@@ -938,6 +923,38 @@ export class StmtsEmitter {
|
|
|
938
923
|
return;
|
|
939
924
|
}
|
|
940
925
|
|
|
926
|
+
if ((l.kind === "UnaryExpr" && l.op === "*") || l.kind === "StarExpr") {
|
|
927
|
+
const operand = l.operand ?? l.expr;
|
|
928
|
+
const box = this.mod.getBoxType(operand._type?.base ?? operand._type);
|
|
929
|
+
if (box) {
|
|
930
|
+
const baseWType = {
|
|
931
|
+
kind: "ref",
|
|
932
|
+
nullable: true,
|
|
933
|
+
typeIndex: box.typeIndex,
|
|
934
|
+
};
|
|
935
|
+
const boxTmp = this.acquireTemp(baseWType);
|
|
936
|
+
this.emitExpr(operand, baseWType);
|
|
937
|
+
this.pushInstruction({ op: "local.set", index: boxTmp });
|
|
938
|
+
this.pushInstruction({ op: "local.get", index: boxTmp });
|
|
939
|
+
this.pushInstruction({ op: "local.get", index: boxTmp });
|
|
940
|
+
this.pushInstruction({
|
|
941
|
+
op: "struct.get",
|
|
942
|
+
typeIndex: box.typeIndex,
|
|
943
|
+
fieldIndex: 0,
|
|
944
|
+
});
|
|
945
|
+
const targetType = box.wType;
|
|
946
|
+
this.emitExpr(r, targetType);
|
|
947
|
+
this.emitBinaryOp(baseOp, targetType, l._type ?? operand._type?.base);
|
|
948
|
+
this.pushInstruction({
|
|
949
|
+
op: "struct.set",
|
|
950
|
+
typeIndex: box.typeIndex,
|
|
951
|
+
fieldIndex: 0,
|
|
952
|
+
});
|
|
953
|
+
this.releaseTemp(boxTmp, baseWType);
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
941
958
|
if (l.kind !== "Ident") return;
|
|
942
959
|
|
|
943
960
|
const localInfo = this.resolveLocal(l.name);
|
|
@@ -1016,6 +1033,46 @@ export class StmtsEmitter {
|
|
|
1016
1033
|
emitIncDecStmt(stmt) {
|
|
1017
1034
|
const { expr, op } = stmt;
|
|
1018
1035
|
|
|
1036
|
+
if (
|
|
1037
|
+
(expr.kind === "UnaryExpr" && expr.op === "*") ||
|
|
1038
|
+
expr.kind === "StarExpr"
|
|
1039
|
+
) {
|
|
1040
|
+
const operand = expr.operand ?? expr.expr;
|
|
1041
|
+
const structInfo = this._resolveStructInfo(operand);
|
|
1042
|
+
if (!structInfo) {
|
|
1043
|
+
const box = this.mod.getBoxType(operand._type?.base ?? operand._type);
|
|
1044
|
+
if (box) {
|
|
1045
|
+
const baseWType = {
|
|
1046
|
+
kind: "ref",
|
|
1047
|
+
nullable: true,
|
|
1048
|
+
typeIndex: box.typeIndex,
|
|
1049
|
+
};
|
|
1050
|
+
const boxTmp = this.acquireTemp(baseWType);
|
|
1051
|
+
this.emitExpr(operand, baseWType);
|
|
1052
|
+
this.pushInstruction({ op: "local.set", index: boxTmp });
|
|
1053
|
+
this.pushInstruction({ op: "local.get", index: boxTmp });
|
|
1054
|
+
this.pushInstruction({ op: "local.get", index: boxTmp });
|
|
1055
|
+
this.pushInstruction({
|
|
1056
|
+
op: "struct.get",
|
|
1057
|
+
typeIndex: box.typeIndex,
|
|
1058
|
+
fieldIndex: 0,
|
|
1059
|
+
});
|
|
1060
|
+
this._emitIncDecStep(
|
|
1061
|
+
op,
|
|
1062
|
+
box.wType,
|
|
1063
|
+
operand._type?.base ?? operand._type,
|
|
1064
|
+
);
|
|
1065
|
+
this.pushInstruction({
|
|
1066
|
+
op: "struct.set",
|
|
1067
|
+
typeIndex: box.typeIndex,
|
|
1068
|
+
fieldIndex: 0,
|
|
1069
|
+
});
|
|
1070
|
+
this.releaseTemp(boxTmp, baseWType);
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1019
1076
|
if (expr.kind === "SelectorExpr") {
|
|
1020
1077
|
const structInfo = this._resolveStructInfo(expr.expr);
|
|
1021
1078
|
if (!structInfo) return;
|
|
@@ -1046,20 +1103,7 @@ export class StmtsEmitter {
|
|
|
1046
1103
|
fieldIndex: lastStep.fieldIndex,
|
|
1047
1104
|
});
|
|
1048
1105
|
|
|
1049
|
-
|
|
1050
|
-
this.pushInstruction({ op: "i64.const", value: 1n });
|
|
1051
|
-
this.pushInstruction(op === "++" ? "i64.add" : "i64.sub");
|
|
1052
|
-
} else if (targetType === "f32") {
|
|
1053
|
-
this.pushInstruction({ op: "f32.const", value: 1.0 });
|
|
1054
|
-
this.pushInstruction(op === "++" ? "f32.add" : "f32.sub");
|
|
1055
|
-
} else if (targetType === "f64") {
|
|
1056
|
-
this.pushInstruction({ op: "f64.const", value: 1.0 });
|
|
1057
|
-
this.pushInstruction(op === "++" ? "f64.add" : "f64.sub");
|
|
1058
|
-
} else {
|
|
1059
|
-
this.pushInstruction({ op: "i32.const", value: 1 });
|
|
1060
|
-
this.pushInstruction(op === "++" ? "i32.add" : "i32.sub");
|
|
1061
|
-
this.emitNarrowIntWrap(expr._type);
|
|
1062
|
-
}
|
|
1106
|
+
this._emitIncDecStep(op, targetType, expr._type);
|
|
1063
1107
|
|
|
1064
1108
|
this.pushInstruction({
|
|
1065
1109
|
op: "struct.set",
|
|
@@ -1096,20 +1140,7 @@ export class StmtsEmitter {
|
|
|
1096
1140
|
funcIndex: this.mod.resolveFuncIndex(mapInfo.getFuncName),
|
|
1097
1141
|
});
|
|
1098
1142
|
|
|
1099
|
-
|
|
1100
|
-
this.pushInstruction({ op: "i64.const", value: 1n });
|
|
1101
|
-
this.pushInstruction(op === "++" ? "i64.add" : "i64.sub");
|
|
1102
|
-
} else if (mapInfo.valWType === "f32") {
|
|
1103
|
-
this.pushInstruction({ op: "f32.const", value: 1.0 });
|
|
1104
|
-
this.pushInstruction(op === "++" ? "f32.add" : "f32.sub");
|
|
1105
|
-
} else if (mapInfo.valWType === "f64") {
|
|
1106
|
-
this.pushInstruction({ op: "f64.const", value: 1.0 });
|
|
1107
|
-
this.pushInstruction(op === "++" ? "f64.add" : "f64.sub");
|
|
1108
|
-
} else {
|
|
1109
|
-
this.pushInstruction({ op: "i32.const", value: 1 });
|
|
1110
|
-
this.pushInstruction(op === "++" ? "i32.add" : "i32.sub");
|
|
1111
|
-
this.emitNarrowIntWrap(valType);
|
|
1112
|
-
}
|
|
1143
|
+
this._emitIncDecStep(op, mapInfo.valWType, valType);
|
|
1113
1144
|
|
|
1114
1145
|
this.pushInstruction({
|
|
1115
1146
|
op: "call",
|
|
@@ -1167,20 +1198,7 @@ export class StmtsEmitter {
|
|
|
1167
1198
|
typeIndex: arrInfo.typeIndex,
|
|
1168
1199
|
});
|
|
1169
1200
|
|
|
1170
|
-
|
|
1171
|
-
this.pushInstruction({ op: "i64.const", value: 1n });
|
|
1172
|
-
this.pushInstruction(op === "++" ? "i64.add" : "i64.sub");
|
|
1173
|
-
} else if (targetType === "f32") {
|
|
1174
|
-
this.pushInstruction({ op: "f32.const", value: 1.0 });
|
|
1175
|
-
this.pushInstruction(op === "++" ? "f32.add" : "f32.sub");
|
|
1176
|
-
} else if (targetType === "f64") {
|
|
1177
|
-
this.pushInstruction({ op: "f64.const", value: 1.0 });
|
|
1178
|
-
this.pushInstruction(op === "++" ? "f64.add" : "f64.sub");
|
|
1179
|
-
} else {
|
|
1180
|
-
this.pushInstruction({ op: "i32.const", value: 1 });
|
|
1181
|
-
this.pushInstruction(op === "++" ? "i32.add" : "i32.sub");
|
|
1182
|
-
this.emitNarrowIntWrap(elemGoType);
|
|
1183
|
-
}
|
|
1201
|
+
this._emitIncDecStep(op, targetType, elemGoType);
|
|
1184
1202
|
|
|
1185
1203
|
this.pushInstruction({
|
|
1186
1204
|
op: "array.set",
|
|
@@ -1199,7 +1217,6 @@ export class StmtsEmitter {
|
|
|
1199
1217
|
|
|
1200
1218
|
if (localInfo?.isBoxed) {
|
|
1201
1219
|
const boxInfo = localInfo.boxInfo;
|
|
1202
|
-
const innerWType = boxInfo.wType;
|
|
1203
1220
|
this.pushInstruction({ op: "local.get", index: localInfo.index });
|
|
1204
1221
|
this.pushInstruction({ op: "local.get", index: localInfo.index });
|
|
1205
1222
|
this.pushInstruction({
|
|
@@ -1207,20 +1224,7 @@ export class StmtsEmitter {
|
|
|
1207
1224
|
typeIndex: boxInfo.typeIndex,
|
|
1208
1225
|
fieldIndex: 0,
|
|
1209
1226
|
});
|
|
1210
|
-
|
|
1211
|
-
this.pushInstruction({ op: "i64.const", value: 1n });
|
|
1212
|
-
this.pushInstruction(op === "++" ? "i64.add" : "i64.sub");
|
|
1213
|
-
} else if (innerWType === "f32") {
|
|
1214
|
-
this.pushInstruction({ op: "f32.const", value: 1.0 });
|
|
1215
|
-
this.pushInstruction(op === "++" ? "f32.add" : "f32.sub");
|
|
1216
|
-
} else if (innerWType === "f64") {
|
|
1217
|
-
this.pushInstruction({ op: "f64.const", value: 1.0 });
|
|
1218
|
-
this.pushInstruction(op === "++" ? "f64.add" : "f64.sub");
|
|
1219
|
-
} else {
|
|
1220
|
-
this.pushInstruction({ op: "i32.const", value: 1 });
|
|
1221
|
-
this.pushInstruction(op === "++" ? "i32.add" : "i32.sub");
|
|
1222
|
-
this.emitNarrowIntWrap(localInfo.goType);
|
|
1223
|
-
}
|
|
1227
|
+
this._emitIncDecStep(op, boxInfo.wType, localInfo.goType);
|
|
1224
1228
|
this.pushInstruction({
|
|
1225
1229
|
op: "struct.set",
|
|
1226
1230
|
typeIndex: boxInfo.typeIndex,
|
|
@@ -1237,20 +1241,7 @@ export class StmtsEmitter {
|
|
|
1237
1241
|
this.pushInstruction({ op: "global.get", index: globalInfo.index });
|
|
1238
1242
|
}
|
|
1239
1243
|
|
|
1240
|
-
|
|
1241
|
-
this.pushInstruction({ op: "i64.const", value: 1n });
|
|
1242
|
-
this.pushInstruction(op === "++" ? "i64.add" : "i64.sub");
|
|
1243
|
-
} else if (targetType === "f32") {
|
|
1244
|
-
this.pushInstruction({ op: "f32.const", value: 1.0 });
|
|
1245
|
-
this.pushInstruction(op === "++" ? "f32.add" : "f32.sub");
|
|
1246
|
-
} else if (targetType === "f64") {
|
|
1247
|
-
this.pushInstruction({ op: "f64.const", value: 1.0 });
|
|
1248
|
-
this.pushInstruction(op === "++" ? "f64.add" : "f64.sub");
|
|
1249
|
-
} else {
|
|
1250
|
-
this.pushInstruction({ op: "i32.const", value: 1 });
|
|
1251
|
-
this.pushInstruction(op === "++" ? "i32.add" : "i32.sub");
|
|
1252
|
-
this.emitNarrowIntWrap(expr._type);
|
|
1253
|
-
}
|
|
1244
|
+
this._emitIncDecStep(op, targetType, expr._type);
|
|
1254
1245
|
|
|
1255
1246
|
if (localInfo) {
|
|
1256
1247
|
this.pushInstruction({ op: "local.set", index: localInfo.index });
|
|
@@ -1260,6 +1251,21 @@ export class StmtsEmitter {
|
|
|
1260
1251
|
}
|
|
1261
1252
|
}
|
|
1262
1253
|
|
|
1254
|
+
_emitIncDecStep(op, targetType, goType) {
|
|
1255
|
+
const isAdd = op === "++";
|
|
1256
|
+
if (targetType === "i64") {
|
|
1257
|
+
this.pushInstruction({ op: "i64.const", value: 1n });
|
|
1258
|
+
this.pushInstruction(isAdd ? "i64.add" : "i64.sub");
|
|
1259
|
+
} else if (targetType === "f32" || targetType === "f64") {
|
|
1260
|
+
this.pushInstruction({ op: `${targetType}.const`, value: 1.0 });
|
|
1261
|
+
this.pushInstruction(`${targetType}.${isAdd ? "add" : "sub"}`);
|
|
1262
|
+
} else {
|
|
1263
|
+
this.pushInstruction({ op: "i32.const", value: 1 });
|
|
1264
|
+
this.pushInstruction(isAdd ? "i32.add" : "i32.sub");
|
|
1265
|
+
this.emitNarrowIntWrap(goType);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1263
1269
|
emitIfStmt(stmt) {
|
|
1264
1270
|
if (stmt.init) this.emitStmt(stmt.init);
|
|
1265
1271
|
|
|
@@ -1775,8 +1781,9 @@ export class StmtsEmitter {
|
|
|
1775
1781
|
nullable: true,
|
|
1776
1782
|
typeIndex: arrInfo.typeIndex,
|
|
1777
1783
|
};
|
|
1778
|
-
const
|
|
1779
|
-
const
|
|
1784
|
+
const hasVal = Boolean(lhs[1] && lhs[1].name !== "_");
|
|
1785
|
+
const arrTmp = hasVal ? this.acquireTemp(arrWType) : null;
|
|
1786
|
+
const offTmp = hasVal ? this.acquireTemp("i32") : null;
|
|
1780
1787
|
const lenTmp = this.acquireTemp("i32");
|
|
1781
1788
|
|
|
1782
1789
|
if (isSlice) {
|
|
@@ -1789,18 +1796,26 @@ export class StmtsEmitter {
|
|
|
1789
1796
|
this.emitExpr(iterExpr, sliceWType);
|
|
1790
1797
|
this.pushInstruction({ op: "local.set", index: sliceTmp });
|
|
1791
1798
|
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1799
|
+
if (hasVal) {
|
|
1800
|
+
this._emitSliceUnpack(sliceTmp, sliceInfo, {
|
|
1801
|
+
arr: arrTmp,
|
|
1802
|
+
off: offTmp,
|
|
1803
|
+
len: lenTmp,
|
|
1804
|
+
});
|
|
1805
|
+
} else {
|
|
1806
|
+
this._emitSliceUnpack(sliceTmp, sliceInfo, {
|
|
1807
|
+
len: lenTmp,
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1797
1810
|
this.releaseTemp(sliceTmp, sliceWType);
|
|
1798
1811
|
} else {
|
|
1799
1812
|
this.emitExpr(iterExpr, arrWType);
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1813
|
+
if (hasVal) {
|
|
1814
|
+
this.pushInstruction({ op: "local.set", index: arrTmp });
|
|
1815
|
+
this.pushInstruction({ op: "i32.const", value: 0 });
|
|
1816
|
+
this.pushInstruction({ op: "local.set", index: offTmp });
|
|
1817
|
+
this.pushInstruction({ op: "local.get", index: arrTmp });
|
|
1818
|
+
}
|
|
1804
1819
|
this.pushInstruction("array.len");
|
|
1805
1820
|
this.pushInstruction({ op: "local.set", index: lenTmp });
|
|
1806
1821
|
}
|
|
@@ -1934,8 +1949,8 @@ export class StmtsEmitter {
|
|
|
1934
1949
|
|
|
1935
1950
|
this.releaseTemp(idxTmp, "i32");
|
|
1936
1951
|
this.releaseTemp(lenTmp, "i32");
|
|
1937
|
-
this.releaseTemp(offTmp, "i32");
|
|
1938
|
-
this.releaseTemp(arrTmp, arrWType);
|
|
1952
|
+
if (offTmp !== null) this.releaseTemp(offTmp, "i32");
|
|
1953
|
+
if (arrTmp !== null) this.releaseTemp(arrTmp, arrWType);
|
|
1939
1954
|
|
|
1940
1955
|
restoreShadowed();
|
|
1941
1956
|
}
|
|
@@ -2185,74 +2200,53 @@ export class StmtsEmitter {
|
|
|
2185
2200
|
if (stmt.init) this.emitStmt(stmt.init);
|
|
2186
2201
|
|
|
2187
2202
|
const getCaseVals = (c) => c.list ?? c.values ?? [];
|
|
2203
|
+
const nonDefaultCases = (stmt.cases ?? []).filter(
|
|
2204
|
+
(c) => getCaseVals(c).length > 0,
|
|
2205
|
+
);
|
|
2206
|
+
const defaultCase = (stmt.cases ?? []).find(
|
|
2207
|
+
(c) => getCaseVals(c).length === 0,
|
|
2208
|
+
);
|
|
2188
2209
|
|
|
2210
|
+
let tagGoType = null;
|
|
2211
|
+
let tagWType = null;
|
|
2212
|
+
let tagTmp = -1;
|
|
2189
2213
|
if (stmt.tag) {
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2214
|
+
tagGoType = stmt.tag._type ?? this._resolveExprGoType(stmt.tag);
|
|
2215
|
+
tagWType = this.toWasmType(tagGoType);
|
|
2216
|
+
tagTmp = this.acquireTemp(tagWType);
|
|
2193
2217
|
this.emitExpr(stmt.tag, tagWType);
|
|
2194
2218
|
this.pushInstruction({ op: "local.set", index: tagTmp });
|
|
2219
|
+
}
|
|
2195
2220
|
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
);
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
);
|
|
2202
|
-
|
|
2203
|
-
let ifCount = 0;
|
|
2204
|
-
for (const c of nonDefaultCases) {
|
|
2205
|
-
const vals = getCaseVals(c);
|
|
2206
|
-
for (let i = 0; i < vals.length; i++) {
|
|
2221
|
+
let ifCount = 0;
|
|
2222
|
+
for (const c of nonDefaultCases) {
|
|
2223
|
+
const vals = getCaseVals(c);
|
|
2224
|
+
for (let i = 0; i < vals.length; i++) {
|
|
2225
|
+
if (stmt.tag) {
|
|
2207
2226
|
this.pushInstruction({ op: "local.get", index: tagTmp });
|
|
2208
2227
|
this.emitExpr(vals[i], tagWType);
|
|
2209
2228
|
this.emitBinaryOp("==", tagWType, tagGoType);
|
|
2210
|
-
|
|
2211
|
-
}
|
|
2212
|
-
this.pushInstruction({ op: "if", blockType: "void" });
|
|
2213
|
-
ifCount++;
|
|
2214
|
-
|
|
2215
|
-
for (const s of c.stmts ?? []) this.emitStmt(s);
|
|
2216
|
-
this.pushInstruction("else");
|
|
2217
|
-
}
|
|
2218
|
-
|
|
2219
|
-
if (defaultCase) {
|
|
2220
|
-
for (const s of defaultCase.stmts ?? []) this.emitStmt(s);
|
|
2221
|
-
}
|
|
2222
|
-
|
|
2223
|
-
for (let i = 0; i < ifCount; i++) {
|
|
2224
|
-
this.pushInstruction("end");
|
|
2225
|
-
}
|
|
2226
|
-
this.releaseTemp(tagTmp, tagWType);
|
|
2227
|
-
} else {
|
|
2228
|
-
const nonDefaultCases = (stmt.cases ?? []).filter(
|
|
2229
|
-
(c) => getCaseVals(c).length > 0,
|
|
2230
|
-
);
|
|
2231
|
-
const defaultCase = (stmt.cases ?? []).find(
|
|
2232
|
-
(c) => getCaseVals(c).length === 0,
|
|
2233
|
-
);
|
|
2234
|
-
|
|
2235
|
-
let ifCount = 0;
|
|
2236
|
-
for (const c of nonDefaultCases) {
|
|
2237
|
-
const vals = getCaseVals(c);
|
|
2238
|
-
for (let i = 0; i < vals.length; i++) {
|
|
2229
|
+
} else {
|
|
2239
2230
|
this.emitExpr(vals[i], "i32");
|
|
2240
|
-
if (i > 0) this.pushInstruction("i32.or");
|
|
2241
2231
|
}
|
|
2242
|
-
this.pushInstruction(
|
|
2243
|
-
ifCount++;
|
|
2244
|
-
|
|
2245
|
-
for (const s of c.stmts ?? []) this.emitStmt(s);
|
|
2246
|
-
this.pushInstruction("else");
|
|
2232
|
+
if (i > 0) this.pushInstruction("i32.or");
|
|
2247
2233
|
}
|
|
2234
|
+
this.pushInstruction({ op: "if", blockType: "void" });
|
|
2235
|
+
ifCount++;
|
|
2248
2236
|
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2237
|
+
for (const s of c.stmts ?? []) this.emitStmt(s);
|
|
2238
|
+
this.pushInstruction("else");
|
|
2239
|
+
}
|
|
2252
2240
|
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2241
|
+
if (defaultCase) {
|
|
2242
|
+
for (const s of defaultCase.stmts ?? []) this.emitStmt(s);
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
for (let i = 0; i < ifCount; i++) {
|
|
2246
|
+
this.pushInstruction("end");
|
|
2247
|
+
}
|
|
2248
|
+
if (stmt.tag) {
|
|
2249
|
+
this.releaseTemp(tagTmp, tagWType);
|
|
2256
2250
|
}
|
|
2257
2251
|
|
|
2258
2252
|
this.pushInstruction("end");
|