gofront 1.6.1 → 1.8.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.
Files changed (132) hide show
  1. package/README.md +45 -49
  2. package/package.json +12 -8
  3. package/src/backend/js/expressions.js +1627 -148
  4. package/src/backend/js/fmt-runtime.js +573 -0
  5. package/src/backend/js/index.js +508 -102
  6. package/src/backend/js/runtime.js +1997 -106
  7. package/src/backend/js/statements.js +931 -87
  8. package/src/backend/js/stdlib/bits.js +87 -14
  9. package/src/backend/js/stdlib/builder.js +41 -6
  10. package/src/backend/js/stdlib/bytes.js +253 -7
  11. package/src/backend/js/stdlib/errors.js +7 -1
  12. package/src/backend/js/stdlib/fmt.js +349 -10
  13. package/src/backend/js/stdlib/index.js +19 -2
  14. package/src/backend/js/stdlib/json.js +1167 -0
  15. package/src/backend/js/stdlib/maps.js +0 -8
  16. package/src/backend/js/stdlib/math.js +17 -1
  17. package/src/backend/js/stdlib/simd.js +34 -0
  18. package/src/backend/js/stdlib/slices.js +36 -6
  19. package/src/backend/js/stdlib/strconv.js +10 -5
  20. package/src/backend/js/stdlib/strings.js +83 -4
  21. package/src/backend/js/stdlib/testing.js +7 -0
  22. package/src/backend/js/stdlib/time.js +79 -55
  23. package/src/backend/js/stdlib/unicode.js +1 -1
  24. package/src/backend/js/stdlib/utf8.js +1 -1
  25. package/src/backend/js/templ.js +38 -76
  26. package/src/backend/js/type-info.js +272 -0
  27. package/src/backend/shared/fmt-types.js +188 -0
  28. package/src/backend/wasm/boundary.js +446 -72
  29. package/src/backend/wasm/emit-builtins.js +320 -13
  30. package/src/backend/wasm/emit-exprs.js +1404 -199
  31. package/src/backend/wasm/emit-maps.js +61 -13
  32. package/src/backend/wasm/emit-stmts.js +1359 -164
  33. package/src/backend/wasm/emit.js +518 -74
  34. package/src/backend/wasm/encode.js +128 -13
  35. package/src/backend/wasm/globals.js +452 -0
  36. package/src/backend/wasm/index.js +194 -2489
  37. package/src/backend/wasm/method-expr.js +381 -0
  38. package/src/backend/wasm/module-emitter.js +2240 -0
  39. package/src/backend/wasm/monomorph.js +62 -4
  40. package/src/backend/wasm/optimize.js +4 -2
  41. package/src/backend/wasm/prescan.js +397 -0
  42. package/src/backend/wasm/stdlib/bytes.js +1804 -127
  43. package/src/backend/wasm/stdlib/core.js +1574 -199
  44. package/src/backend/wasm/stdlib/index.js +3 -5
  45. package/src/backend/wasm/stdlib/io.js +1567 -150
  46. package/src/backend/wasm/stdlib/packages.js +2 -0
  47. package/src/backend/wasm/stdlib/simd.js +499 -0
  48. package/src/backend/wasm/stdlib/time.js +1041 -12
  49. package/src/backend/wasm/types.js +221 -15
  50. package/src/backend/wasm/variadic.js +93 -0
  51. package/src/backend/wasm/wat.js +84 -20
  52. package/src/{cli-core.js → cli/cli-core.js} +236 -10
  53. package/src/{test-runner.js → cli/test-runner.js} +332 -39
  54. package/src/{vendor.js → cli/vendor.js} +89 -15
  55. package/src/compiler.js +107 -269
  56. package/src/dts-parser.js +71 -14
  57. package/src/index.js +15 -169
  58. package/src/{lexer.js → lexer/lexer.js} +102 -55
  59. package/src/{tokens.js → lexer/tokens.js} +1 -0
  60. package/src/link/sourcemap.js +97 -0
  61. package/src/link/stdlib.js +515 -0
  62. package/src/link/wasm.js +294 -0
  63. package/src/lower/bounds.js +394 -0
  64. package/src/lower/boxing.js +1 -6
  65. package/src/lower/captures.js +176 -32
  66. package/src/lower/embedding.js +2 -1
  67. package/src/lower/index.js +26 -18
  68. package/src/lower/json-codecs.js +1398 -0
  69. package/src/lower/ownership.js +22 -1
  70. package/src/lower/range.js +86 -1
  71. package/src/lower/reachability.js +132 -0
  72. package/src/parser/declarations.js +58 -13
  73. package/src/parser/expressions.js +29 -7
  74. package/src/parser/index.js +2 -1
  75. package/src/parser/statements.js +37 -22
  76. package/src/parser/struct-tag.js +144 -0
  77. package/src/{templ-parser.js → parser/templ.js} +138 -15
  78. package/src/parser/types.js +130 -13
  79. package/src/resolver.js +22 -1
  80. package/src/typechecker/assignability.js +215 -11
  81. package/src/typechecker/const-fold.js +356 -0
  82. package/src/typechecker/constants.js +256 -0
  83. package/src/typechecker/expressions.js +960 -99
  84. package/src/typechecker/index.js +491 -72
  85. package/src/typechecker/init-order.js +330 -0
  86. package/src/typechecker/resolve.js +596 -52
  87. package/src/typechecker/statements.js +157 -17
  88. package/src/typechecker/stdlib/core.js +333 -55
  89. package/src/typechecker/stdlib/excluded.js +898 -0
  90. package/src/typechecker/stdlib/extended.js +359 -26
  91. package/src/typechecker/{stdlib.js → stdlib/index.js} +6 -4
  92. package/src/typechecker/stdlib/simd.js +123 -0
  93. package/src/typechecker/termination.js +1 -1
  94. package/src/typechecker/types.js +165 -26
  95. package/stdlib/bytes/iter.go +192 -0
  96. package/stdlib/bytes/search.go +240 -0
  97. package/stdlib/bytes/split.go +218 -0
  98. package/stdlib/cmp/cmp.go +65 -0
  99. package/stdlib/encoding/json/errors.go +31 -0
  100. package/stdlib/encoding/json/indent.go +71 -0
  101. package/stdlib/encoding/json/number.go +12 -0
  102. package/stdlib/encoding/json/stream.go +173 -0
  103. package/stdlib/errors/overlay.go +12 -0
  104. package/stdlib/hash/hash.go +53 -0
  105. package/stdlib/internal/jsonrt/dec.go +738 -0
  106. package/stdlib/internal/jsonrt/enc.go +366 -0
  107. package/stdlib/internal/jsonrt/indent.go +135 -0
  108. package/stdlib/internal/jsonrt/number.go +27 -0
  109. package/stdlib/internal/jsonrt/reader.go +73 -0
  110. package/stdlib/internal/jsonrt/scanner.go +649 -0
  111. package/stdlib/io/io.go +346 -0
  112. package/stdlib/iter/iter.go +18 -0
  113. package/stdlib/maps/iter.go +65 -0
  114. package/stdlib/math/extra.go +270 -0
  115. package/stdlib/slices/extra.go +73 -0
  116. package/stdlib/slices/iter.go +113 -0
  117. package/stdlib/sort/sort.go +561 -0
  118. package/stdlib/strconv/quote.go +341 -0
  119. package/stdlib/strings/extra.go +35 -0
  120. package/stdlib/strings/iter.go +122 -0
  121. package/stdlib/sync/extra.go +105 -0
  122. package/stdlib/unicode/unicode.go +112 -0
  123. package/stdlib/unicode/utf8/bytes.go +239 -0
  124. package/src/backend/wasm/const-fold.js +0 -205
  125. package/src/backend/wasm/emit-stdlib.js +0 -13
  126. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  127. /package/src/{colors.js → cli/colors.js} +0 -0
  128. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  129. /package/src/{minifier.js → cli/minifier.js} +0 -0
  130. /package/src/{project-config.js → cli/project-config.js} +0 -0
  131. /package/src/{pwa.js → cli/pwa.js} +0 -0
  132. /package/src/{templ-lexer.js → lexer/templ-lexer.js} +0 -0
@@ -2,6 +2,45 @@
2
2
  // FunctionEmitter mixin: bytes package functions and bytes.Buffer methods.
3
3
 
4
4
  export class BytesEmitter {
5
+ emitBytesNewBuffer(call, _targetWasmType) {
6
+ const structInfo = this.mod.getStructType("bytes.Buffer");
7
+ const byteElemGo = { kind: "basic", name: "byte" };
8
+ const sliceInfo = this.mod.getSliceType(byteElemGo);
9
+ const sliceW = {
10
+ kind: "ref",
11
+ nullable: true,
12
+ typeIndex: sliceInfo.typeIndex,
13
+ };
14
+ this.emitExpr(call.args[0], sliceW);
15
+ if (structInfo.fields.length > 1) {
16
+ this.pushInstruction({ op: "i64.const", value: 0n });
17
+ this.pushInstruction({ op: "i64.const", value: 0n });
18
+ }
19
+ this.pushInstruction({
20
+ op: "struct.new",
21
+ typeIndex: structInfo.typeIndex,
22
+ });
23
+ }
24
+
25
+ emitBytesNewBufferString(call, _targetWasmType) {
26
+ const structInfo = this.mod.getStructType("bytes.Buffer");
27
+ const sTmp = this.acquireTemp("externref");
28
+ this.emitExpr(call.args[0], "externref");
29
+ this.pushInstruction({ op: "local.set", index: sTmp });
30
+
31
+ this.pushInstruction({ op: "local.get", index: sTmp });
32
+ this._emitStringToByteSlice({ elem: { kind: "basic", name: "byte" } });
33
+ this.releaseTemp(sTmp, "externref");
34
+ if (structInfo.fields.length > 1) {
35
+ this.pushInstruction({ op: "i64.const", value: 0n });
36
+ this.pushInstruction({ op: "i64.const", value: 0n });
37
+ }
38
+ this.pushInstruction({
39
+ op: "struct.new",
40
+ typeIndex: structInfo.typeIndex,
41
+ });
42
+ }
43
+
5
44
  emitBytesBufferMethodCall(method, recvExpr, args, targetWasmType) {
6
45
  const structInfo = this.mod.getStructType("bytes.Buffer");
7
46
  const bufW = {
@@ -44,6 +83,30 @@ export class BytesEmitter {
44
83
  return sTmp;
45
84
  };
46
85
 
86
+ const setLastOp = (opVal) => {
87
+ if (structInfo.fields.length > 1) {
88
+ this.pushInstruction({ op: "local.get", index: bTmp });
89
+ this.pushInstruction({ op: "i64.const", value: BigInt(opVal) });
90
+ this.pushInstruction({
91
+ op: "struct.set",
92
+ typeIndex: structInfo.typeIndex,
93
+ fieldIndex: 1,
94
+ });
95
+ }
96
+ };
97
+ const setLastRuneLen = (lenLocal) => {
98
+ if (structInfo.fields.length > 2) {
99
+ this.pushInstruction({ op: "local.get", index: bTmp });
100
+ this.pushInstruction({ op: "local.get", index: lenLocal });
101
+ this.pushInstruction("i64.extend_i32_u");
102
+ this.pushInstruction({
103
+ op: "struct.set",
104
+ typeIndex: structInfo.typeIndex,
105
+ fieldIndex: 2,
106
+ });
107
+ }
108
+ };
109
+
47
110
  switch (method) {
48
111
  case "Len": {
49
112
  const sTmp = getBufSlice();
@@ -86,6 +149,7 @@ export class BytesEmitter {
86
149
  typeIndex: structInfo.typeIndex,
87
150
  fieldIndex: 0,
88
151
  });
152
+ setLastOp(0);
89
153
  this.releaseTemp(bTmp, bufW);
90
154
  return;
91
155
  }
@@ -221,6 +285,7 @@ export class BytesEmitter {
221
285
  });
222
286
 
223
287
  this.pushInstruction({ op: "ref.null", heapType: "any" });
288
+ setLastOp(0);
224
289
 
225
290
  this.releaseTemp(newCapTmp, "i32");
226
291
  this.releaseTemp(newOffTmp, "i32");
@@ -316,6 +381,7 @@ export class BytesEmitter {
316
381
  this.pushInstruction({ op: "local.get", index: pLenTmp });
317
382
  this.pushInstruction("i64.extend_i32_u");
318
383
  this.pushInstruction({ op: "ref.null", heapType: "any" });
384
+ setLastOp(0);
319
385
 
320
386
  this.releaseTemp(newCapTmp, "i32");
321
387
  this.releaseTemp(newOffTmp, "i32");
@@ -640,117 +706,1105 @@ export class BytesEmitter {
640
706
  this.pushInstruction({ op: "local.get", index: newLenTmp });
641
707
  this.pushInstruction({ op: "local.get", index: newCapTmp });
642
708
  this.pushInstruction({
643
- op: "struct.new",
709
+ op: "struct.new",
710
+ typeIndex: sliceInfo.typeIndex,
711
+ });
712
+ this.pushInstruction({
713
+ op: "struct.set",
714
+ typeIndex: structInfo.typeIndex,
715
+ fieldIndex: 0,
716
+ });
717
+
718
+ this.pushInstruction({ op: "local.get", index: rLenTmp });
719
+ this.pushInstruction("i64.extend_i32_u");
720
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
721
+ setLastOp(0);
722
+
723
+ this.releaseTemp(newCapTmp, "i32");
724
+ this.releaseTemp(newOffTmp, "i32");
725
+ this.releaseTemp(newArrTmp, arrW);
726
+ this.releaseTemp(newLenTmp, "i32");
727
+ this.releaseTemp(oldCapTmp, "i32");
728
+ this.releaseTemp(oldLenTmp, "i32");
729
+ this.releaseTemp(oldOffTmp, "i32");
730
+ this.releaseTemp(oldArrTmp, arrW);
731
+ this.releaseTemp(rLenTmp, "i32");
732
+ this.releaseTemp(rTmp, "i32");
733
+ this.releaseTemp(bTmp, bufW);
734
+ return;
735
+ }
736
+ case "Grow": {
737
+ const nTmp = this.acquireTemp("i32");
738
+ this._emitI32Arg(args[0]);
739
+ this.pushInstruction({ op: "local.set", index: nTmp });
740
+
741
+ this.pushInstruction({ op: "local.get", index: nTmp });
742
+ this.pushInstruction({ op: "i32.const", value: 0 });
743
+ this.pushInstruction("i32.lt_s");
744
+ this.pushInstruction({ op: "if", blockType: "void" });
745
+ this.emitPanic("bytes.Buffer.Grow: negative count");
746
+ this.pushInstruction("end");
747
+
748
+ this.pushInstruction({ op: "local.get", index: nTmp });
749
+ this.pushInstruction({ op: "i32.const", value: 0 });
750
+ this.pushInstruction("i32.gt_s");
751
+ this.pushInstruction({ op: "if", blockType: "void" });
752
+
753
+ const sTmp = getBufSlice();
754
+ const oldArrTmp = this.acquireTemp(arrW);
755
+ const oldOffTmp = this.acquireTemp("i32");
756
+ const oldLenTmp = this.acquireTemp("i32");
757
+ const oldCapTmp = this.acquireTemp("i32");
758
+ this._emitSliceUnpack(sTmp, sliceInfo, {
759
+ arr: oldArrTmp,
760
+ off: oldOffTmp,
761
+ len: oldLenTmp,
762
+ cap: oldCapTmp,
763
+ });
764
+ this.releaseTemp(sTmp, sliceW);
765
+
766
+ const targetCapTmp = this.acquireTemp("i32");
767
+ this.pushInstruction({ op: "local.get", index: oldLenTmp });
768
+ this.pushInstruction({ op: "local.get", index: nTmp });
769
+ this.pushInstruction("i32.add");
770
+ this.pushInstruction({ op: "local.set", index: targetCapTmp });
771
+
772
+ this.pushInstruction({ op: "local.get", index: targetCapTmp });
773
+ this.pushInstruction({ op: "local.get", index: oldCapTmp });
774
+ this.pushInstruction("i32.gt_u");
775
+ this.pushInstruction({ op: "if", blockType: "void" });
776
+
777
+ const newArrTmp = this.acquireTemp(arrW);
778
+ const newOffTmp = this.acquireTemp("i32");
779
+ const newCapTmp = this.acquireTemp("i32");
780
+
781
+ this._emitGrowSlice({
782
+ arrInfo,
783
+ elemGoType: byteGo,
784
+ oldArrTmp,
785
+ oldOffTmp,
786
+ oldLenTmp,
787
+ oldCapTmp,
788
+ newArrTmp,
789
+ newOffTmp,
790
+ newLenTmp: targetCapTmp,
791
+ newCapTmp,
792
+ });
793
+
794
+ this.pushInstruction({ op: "local.get", index: bTmp });
795
+ this.pushInstruction({ op: "local.get", index: newArrTmp });
796
+ this.pushInstruction({ op: "local.get", index: newOffTmp });
797
+ this.pushInstruction({ op: "local.get", index: oldLenTmp });
798
+ this.pushInstruction({ op: "local.get", index: newCapTmp });
799
+ this.pushInstruction({
800
+ op: "struct.new",
801
+ typeIndex: sliceInfo.typeIndex,
802
+ });
803
+ this.pushInstruction({
804
+ op: "struct.set",
805
+ typeIndex: structInfo.typeIndex,
806
+ fieldIndex: 0,
807
+ });
808
+
809
+ this.releaseTemp(newCapTmp, "i32");
810
+ this.releaseTemp(newOffTmp, "i32");
811
+ this.releaseTemp(newArrTmp, arrW);
812
+ this.pushInstruction("end");
813
+
814
+ this.releaseTemp(targetCapTmp, "i32");
815
+ this.releaseTemp(oldCapTmp, "i32");
816
+ this.releaseTemp(oldLenTmp, "i32");
817
+ this.releaseTemp(oldOffTmp, "i32");
818
+ this.releaseTemp(oldArrTmp, arrW);
819
+ this.pushInstruction("end");
820
+
821
+ setLastOp(0);
822
+ this.releaseTemp(nTmp, "i32");
823
+ this.releaseTemp(bTmp, bufW);
824
+ return;
825
+ }
826
+ case "Read": {
827
+ const pTmp = this.acquireTemp(sliceW);
828
+ this.emitExpr(args[0], sliceW);
829
+ this.pushInstruction({ op: "local.set", index: pTmp });
830
+
831
+ this._emitBufferReadCore(bTmp, pTmp);
832
+ this.releaseTemp(pTmp, sliceW);
833
+ this.releaseTemp(bTmp, bufW);
834
+ return;
835
+ }
836
+ case "ReadByte": {
837
+ const sTmp = getBufSlice();
838
+ const arrTmp = this.acquireTemp(arrW);
839
+ const offTmp = this.acquireTemp("i32");
840
+ const lenTmp = this.acquireTemp("i32");
841
+ const capTmp = this.acquireTemp("i32");
842
+ this._emitSliceUnpack(sTmp, sliceInfo, {
843
+ arr: arrTmp,
844
+ off: offTmp,
845
+ len: lenTmp,
846
+ cap: capTmp,
847
+ });
848
+ this.releaseTemp(sTmp, sliceW);
849
+
850
+ const resByteTmp = this.acquireTemp("i32");
851
+ const resErrTmp = this.acquireTemp("anyref");
852
+
853
+ this.pushInstruction({ op: "local.get", index: lenTmp });
854
+ this.pushInstruction("i32.eqz");
855
+ this.pushInstruction({ op: "if", blockType: "void" });
856
+ this.pushInstruction({ op: "i32.const", value: 0 });
857
+ this.pushInstruction({ op: "local.set", index: resByteTmp });
858
+ this.emitIoConst("EOF", "anyref");
859
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
860
+ setLastOp(0);
861
+ this.pushInstruction("else");
862
+
863
+ this.pushInstruction({ op: "local.get", index: arrTmp });
864
+ this.pushInstruction({ op: "local.get", index: offTmp });
865
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
866
+ this.pushInstruction({ op: "local.set", index: resByteTmp });
867
+
868
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
869
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
870
+
871
+ // update b.buf: (arrTmp, offTmp + 1, lenTmp - 1, capTmp - 1)
872
+ this.pushInstruction({ op: "local.get", index: bTmp });
873
+ this.pushInstruction({ op: "local.get", index: arrTmp });
874
+ this.pushInstruction({ op: "local.get", index: offTmp });
875
+ this.pushInstruction({ op: "i32.const", value: 1 });
876
+ this.pushInstruction("i32.add");
877
+ this.pushInstruction({ op: "local.get", index: lenTmp });
878
+ this.pushInstruction({ op: "i32.const", value: 1 });
879
+ this.pushInstruction("i32.sub");
880
+ this.pushInstruction({ op: "local.get", index: capTmp });
881
+ this.pushInstruction({ op: "i32.const", value: 1 });
882
+ this.pushInstruction("i32.sub");
883
+ this.pushInstruction({
884
+ op: "struct.new",
885
+ typeIndex: sliceInfo.typeIndex,
886
+ });
887
+ this.pushInstruction({
888
+ op: "struct.set",
889
+ typeIndex: structInfo.typeIndex,
890
+ fieldIndex: 0,
891
+ });
892
+ setLastOp(1);
893
+ this.pushInstruction("end");
894
+
895
+ this.pushInstruction({ op: "local.get", index: resByteTmp });
896
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
897
+
898
+ this.releaseTemp(resErrTmp, "anyref");
899
+ this.releaseTemp(resByteTmp, "i32");
900
+ this.releaseTemp(capTmp, "i32");
901
+ this.releaseTemp(lenTmp, "i32");
902
+ this.releaseTemp(offTmp, "i32");
903
+ this.releaseTemp(arrTmp, arrW);
904
+ this.releaseTemp(bTmp, bufW);
905
+ return;
906
+ }
907
+ case "UnreadByte": {
908
+ const resErrTmp = this.acquireTemp("anyref");
909
+ if (structInfo.fields.length > 1) {
910
+ this.pushInstruction({ op: "local.get", index: bTmp });
911
+ this.pushInstruction({
912
+ op: "struct.get",
913
+ typeIndex: structInfo.typeIndex,
914
+ fieldIndex: 1,
915
+ });
916
+ this.pushInstruction({ op: "i64.const", value: 1n });
917
+ this.pushInstruction("i64.ne");
918
+ this.pushInstruction({ op: "if", blockType: "void" });
919
+ this._emitNewError(
920
+ "bytes.Buffer: UnreadByte: previous operation was not a successful read",
921
+ );
922
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
923
+ this.pushInstruction("else");
924
+
925
+ const sTmp = getBufSlice();
926
+ const arrTmp = this.acquireTemp(arrW);
927
+ const offTmp = this.acquireTemp("i32");
928
+ const lenTmp = this.acquireTemp("i32");
929
+ const capTmp = this.acquireTemp("i32");
930
+ this._emitSliceUnpack(sTmp, sliceInfo, {
931
+ arr: arrTmp,
932
+ off: offTmp,
933
+ len: lenTmp,
934
+ cap: capTmp,
935
+ });
936
+ this.releaseTemp(sTmp, sliceW);
937
+
938
+ // update b.buf: (arrTmp, offTmp - 1, lenTmp + 1, capTmp + 1)
939
+ this.pushInstruction({ op: "local.get", index: bTmp });
940
+ this.pushInstruction({ op: "local.get", index: arrTmp });
941
+ this.pushInstruction({ op: "local.get", index: offTmp });
942
+ this.pushInstruction({ op: "i32.const", value: 1 });
943
+ this.pushInstruction("i32.sub");
944
+ this.pushInstruction({ op: "local.get", index: lenTmp });
945
+ this.pushInstruction({ op: "i32.const", value: 1 });
946
+ this.pushInstruction("i32.add");
947
+ this.pushInstruction({ op: "local.get", index: capTmp });
948
+ this.pushInstruction({ op: "i32.const", value: 1 });
949
+ this.pushInstruction("i32.add");
950
+ this.pushInstruction({
951
+ op: "struct.new",
952
+ typeIndex: sliceInfo.typeIndex,
953
+ });
954
+ this.pushInstruction({
955
+ op: "struct.set",
956
+ typeIndex: structInfo.typeIndex,
957
+ fieldIndex: 0,
958
+ });
959
+ setLastOp(0);
960
+
961
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
962
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
963
+
964
+ this.releaseTemp(capTmp, "i32");
965
+ this.releaseTemp(lenTmp, "i32");
966
+ this.releaseTemp(offTmp, "i32");
967
+ this.releaseTemp(arrTmp, arrW);
968
+ this.pushInstruction("end");
969
+ } else {
970
+ this._emitNewError(
971
+ "bytes.Buffer: UnreadByte: previous operation was not a successful read",
972
+ );
973
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
974
+ }
975
+
976
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
977
+ this.releaseTemp(resErrTmp, "anyref");
978
+ this.releaseTemp(bTmp, bufW);
979
+ return;
980
+ }
981
+ case "ReadRune": {
982
+ const sTmp = getBufSlice();
983
+ const arrTmp = this.acquireTemp(arrW);
984
+ const offTmp = this.acquireTemp("i32");
985
+ const lenTmp = this.acquireTemp("i32");
986
+ const capTmp = this.acquireTemp("i32");
987
+ this._emitSliceUnpack(sTmp, sliceInfo, {
988
+ arr: arrTmp,
989
+ off: offTmp,
990
+ len: lenTmp,
991
+ cap: capTmp,
992
+ });
993
+ this.releaseTemp(sTmp, sliceW);
994
+
995
+ const resRuneTmp = this.acquireTemp("i32");
996
+ const resSizeTmp = this.acquireTemp("i64");
997
+ const resErrTmp = this.acquireTemp("anyref");
998
+
999
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1000
+ this.pushInstruction("i32.eqz");
1001
+ this.pushInstruction({ op: "if", blockType: "void" });
1002
+ this.pushInstruction({ op: "i32.const", value: 0 });
1003
+ this.pushInstruction({ op: "local.set", index: resRuneTmp });
1004
+ this.pushInstruction({ op: "i64.const", value: 0n });
1005
+ this.pushInstruction({ op: "local.set", index: resSizeTmp });
1006
+ this.emitIoConst("EOF", "anyref");
1007
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1008
+ setLastOp(0);
1009
+ this.pushInstruction("else");
1010
+
1011
+ const cpTmp = this.acquireTemp("i32");
1012
+ const runeLenTmp = this.acquireTemp("i32");
1013
+ const zeroTmp = this.acquireTemp("i32");
1014
+ this.pushInstruction({ op: "i32.const", value: 0 });
1015
+ this.pushInstruction({ op: "local.set", index: zeroTmp });
1016
+
1017
+ this._emitDecodeUtf8Rune({
1018
+ arrTmp,
1019
+ offTmp,
1020
+ idxTmp: zeroTmp,
1021
+ lenTmp,
1022
+ outRuneTmp: cpTmp,
1023
+ outLenTmp: runeLenTmp,
1024
+ arrTypeIndex: arrInfo.typeIndex,
1025
+ });
1026
+ this.releaseTemp(zeroTmp, "i32");
1027
+
1028
+ // update b.buf: (arrTmp, offTmp + runeLenTmp, lenTmp - runeLenTmp, capTmp - runeLenTmp)
1029
+ this.pushInstruction({ op: "local.get", index: bTmp });
1030
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1031
+ this.pushInstruction({ op: "local.get", index: offTmp });
1032
+ this.pushInstruction({ op: "local.get", index: runeLenTmp });
1033
+ this.pushInstruction("i32.add");
1034
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1035
+ this.pushInstruction({ op: "local.get", index: runeLenTmp });
1036
+ this.pushInstruction("i32.sub");
1037
+ this.pushInstruction({ op: "local.get", index: capTmp });
1038
+ this.pushInstruction({ op: "local.get", index: runeLenTmp });
1039
+ this.pushInstruction("i32.sub");
1040
+ this.pushInstruction({
1041
+ op: "struct.new",
1042
+ typeIndex: sliceInfo.typeIndex,
1043
+ });
1044
+ this.pushInstruction({
1045
+ op: "struct.set",
1046
+ typeIndex: structInfo.typeIndex,
1047
+ fieldIndex: 0,
1048
+ });
1049
+
1050
+ setLastOp(2);
1051
+ setLastRuneLen(runeLenTmp);
1052
+
1053
+ this.pushInstruction({ op: "local.get", index: cpTmp });
1054
+ this.pushInstruction({ op: "local.set", index: resRuneTmp });
1055
+ this.pushInstruction({ op: "local.get", index: runeLenTmp });
1056
+ this.pushInstruction("i64.extend_i32_u");
1057
+ this.pushInstruction({ op: "local.set", index: resSizeTmp });
1058
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1059
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1060
+
1061
+ this.releaseTemp(runeLenTmp, "i32");
1062
+ this.releaseTemp(cpTmp, "i32");
1063
+ this.pushInstruction("end");
1064
+
1065
+ this.pushInstruction({ op: "local.get", index: resRuneTmp });
1066
+ this.pushInstruction({ op: "local.get", index: resSizeTmp });
1067
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
1068
+
1069
+ this.releaseTemp(resErrTmp, "anyref");
1070
+ this.releaseTemp(resSizeTmp, "i64");
1071
+ this.releaseTemp(resRuneTmp, "i32");
1072
+ this.releaseTemp(capTmp, "i32");
1073
+ this.releaseTemp(lenTmp, "i32");
1074
+ this.releaseTemp(offTmp, "i32");
1075
+ this.releaseTemp(arrTmp, arrW);
1076
+ this.releaseTemp(bTmp, bufW);
1077
+ return;
1078
+ }
1079
+ case "UnreadRune": {
1080
+ const resErrTmp = this.acquireTemp("anyref");
1081
+ if (structInfo.fields.length > 2) {
1082
+ this.pushInstruction({ op: "local.get", index: bTmp });
1083
+ this.pushInstruction({
1084
+ op: "struct.get",
1085
+ typeIndex: structInfo.typeIndex,
1086
+ fieldIndex: 1,
1087
+ });
1088
+ this.pushInstruction({ op: "i64.const", value: 2n });
1089
+ this.pushInstruction("i64.ne");
1090
+ this.pushInstruction({ op: "if", blockType: "void" });
1091
+ this._emitNewError(
1092
+ "bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune",
1093
+ );
1094
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1095
+ this.pushInstruction("else");
1096
+
1097
+ const lastRuneLenTmp = this.acquireTemp("i32");
1098
+ this.pushInstruction({ op: "local.get", index: bTmp });
1099
+ this.pushInstruction({
1100
+ op: "struct.get",
1101
+ typeIndex: structInfo.typeIndex,
1102
+ fieldIndex: 2,
1103
+ });
1104
+ this.pushInstruction("i32.wrap_i64");
1105
+ this.pushInstruction({ op: "local.set", index: lastRuneLenTmp });
1106
+
1107
+ const sTmp = getBufSlice();
1108
+ const arrTmp = this.acquireTemp(arrW);
1109
+ const offTmp = this.acquireTemp("i32");
1110
+ const lenTmp = this.acquireTemp("i32");
1111
+ const capTmp = this.acquireTemp("i32");
1112
+ this._emitSliceUnpack(sTmp, sliceInfo, {
1113
+ arr: arrTmp,
1114
+ off: offTmp,
1115
+ len: lenTmp,
1116
+ cap: capTmp,
1117
+ });
1118
+ this.releaseTemp(sTmp, sliceW);
1119
+
1120
+ // update b.buf: (arrTmp, offTmp - lastRuneLenTmp, lenTmp + lastRuneLenTmp, capTmp + lastRuneLenTmp)
1121
+ this.pushInstruction({ op: "local.get", index: bTmp });
1122
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1123
+ this.pushInstruction({ op: "local.get", index: offTmp });
1124
+ this.pushInstruction({ op: "local.get", index: lastRuneLenTmp });
1125
+ this.pushInstruction("i32.sub");
1126
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1127
+ this.pushInstruction({ op: "local.get", index: lastRuneLenTmp });
1128
+ this.pushInstruction("i32.add");
1129
+ this.pushInstruction({ op: "local.get", index: capTmp });
1130
+ this.pushInstruction({ op: "local.get", index: lastRuneLenTmp });
1131
+ this.pushInstruction("i32.add");
1132
+ this.pushInstruction({
1133
+ op: "struct.new",
1134
+ typeIndex: sliceInfo.typeIndex,
1135
+ });
1136
+ this.pushInstruction({
1137
+ op: "struct.set",
1138
+ typeIndex: structInfo.typeIndex,
1139
+ fieldIndex: 0,
1140
+ });
1141
+ setLastOp(0);
1142
+
1143
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1144
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1145
+
1146
+ this.releaseTemp(capTmp, "i32");
1147
+ this.releaseTemp(lenTmp, "i32");
1148
+ this.releaseTemp(offTmp, "i32");
1149
+ this.releaseTemp(arrTmp, arrW);
1150
+ this.releaseTemp(lastRuneLenTmp, "i32");
1151
+ this.pushInstruction("end");
1152
+ } else {
1153
+ this._emitNewError(
1154
+ "bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune",
1155
+ );
1156
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1157
+ }
1158
+
1159
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
1160
+ this.releaseTemp(resErrTmp, "anyref");
1161
+ this.releaseTemp(bTmp, bufW);
1162
+ return;
1163
+ }
1164
+ case "ReadBytes":
1165
+ case "ReadString": {
1166
+ const isStr = method === "ReadString";
1167
+ const delimTmp = this.acquireTemp("i32");
1168
+ this._emitI32Arg(args[0]);
1169
+ this.pushInstruction({ op: "local.set", index: delimTmp });
1170
+
1171
+ const sTmp = getBufSlice();
1172
+ const arrTmp = this.acquireTemp(arrW);
1173
+ const offTmp = this.acquireTemp("i32");
1174
+ const lenTmp = this.acquireTemp("i32");
1175
+ const capTmp = this.acquireTemp("i32");
1176
+ this._emitSliceUnpack(sTmp, sliceInfo, {
1177
+ arr: arrTmp,
1178
+ off: offTmp,
1179
+ len: lenTmp,
1180
+ cap: capTmp,
1181
+ });
1182
+ this.releaseTemp(sTmp, sliceW);
1183
+
1184
+ // Find delim
1185
+ const kTmp = this.acquireTemp("i32");
1186
+ const matchTmp = this.acquireTemp("i32");
1187
+ this.pushInstruction({ op: "i32.const", value: 0 });
1188
+ this.pushInstruction({ op: "local.set", index: kTmp });
1189
+ this.pushInstruction({ op: "i32.const", value: -1 });
1190
+ this.pushInstruction({ op: "local.set", index: matchTmp });
1191
+
1192
+ this.pushInstruction({ op: "block", blockType: "void" });
1193
+ this.pushInstruction({ op: "loop", blockType: "void" });
1194
+ this.pushInstruction({ op: "local.get", index: kTmp });
1195
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1196
+ this.pushInstruction("i32.ge_s");
1197
+ this.pushInstruction({ op: "br_if", depth: 1 });
1198
+
1199
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1200
+ this.pushInstruction({ op: "local.get", index: offTmp });
1201
+ this.pushInstruction({ op: "local.get", index: kTmp });
1202
+ this.pushInstruction("i32.add");
1203
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
1204
+ this.pushInstruction({ op: "local.get", index: delimTmp });
1205
+ this.pushInstruction("i32.eq");
1206
+ this.pushInstruction({ op: "if", blockType: "void" });
1207
+ this.pushInstruction({ op: "local.get", index: kTmp });
1208
+ this.pushInstruction({ op: "local.set", index: matchTmp });
1209
+ this.pushInstruction({ op: "br", depth: 2 });
1210
+ this.pushInstruction("end");
1211
+
1212
+ this.pushInstruction({ op: "local.get", index: kTmp });
1213
+ this.pushInstruction({ op: "i32.const", value: 1 });
1214
+ this.pushInstruction("i32.add");
1215
+ this.pushInstruction({ op: "local.set", index: kTmp });
1216
+ this.pushInstruction({ op: "br", depth: 0 });
1217
+ this.pushInstruction("end");
1218
+ this.pushInstruction("end");
1219
+ this.releaseTemp(kTmp, "i32");
1220
+ this.releaseTemp(delimTmp, "i32");
1221
+
1222
+ const resLineTmp = isStr ? null : this.acquireTemp(sliceW);
1223
+ const resStrTmp = isStr ? this.acquireTemp("externref") : null;
1224
+ const resErrTmp = this.acquireTemp("anyref");
1225
+
1226
+ this.pushInstruction({ op: "local.get", index: matchTmp });
1227
+ this.pushInstruction({ op: "i32.const", value: 0 });
1228
+ this.pushInstruction("i32.ge_s");
1229
+ this.pushInstruction({ op: "if", blockType: "void" });
1230
+
1231
+ const lineLenTmp = this.acquireTemp("i32");
1232
+ this.pushInstruction({ op: "local.get", index: matchTmp });
1233
+ this.pushInstruction({ op: "i32.const", value: 1 });
1234
+ this.pushInstruction("i32.add");
1235
+ this.pushInstruction({ op: "local.set", index: lineLenTmp });
1236
+
1237
+ if (isStr) {
1238
+ this._emitBytesSliceToString(
1239
+ arrTmp,
1240
+ offTmp,
1241
+ lineLenTmp,
1242
+ arrInfo.typeIndex,
1243
+ );
1244
+ this.pushInstruction({ op: "local.set", index: resStrTmp });
1245
+ } else {
1246
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1247
+ this.pushInstruction({ op: "local.get", index: offTmp });
1248
+ this.pushInstruction({ op: "local.get", index: lineLenTmp });
1249
+ this.pushInstruction({ op: "local.get", index: lineLenTmp });
1250
+ this.pushInstruction({
1251
+ op: "struct.new",
1252
+ typeIndex: sliceInfo.typeIndex,
1253
+ });
1254
+ this.pushInstruction({ op: "local.set", index: resLineTmp });
1255
+ }
1256
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1257
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1258
+
1259
+ // update b.buf: (arrTmp, offTmp + lineLenTmp, lenTmp - lineLenTmp, capTmp - lineLenTmp)
1260
+ this.pushInstruction({ op: "local.get", index: bTmp });
1261
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1262
+ this.pushInstruction({ op: "local.get", index: offTmp });
1263
+ this.pushInstruction({ op: "local.get", index: lineLenTmp });
1264
+ this.pushInstruction("i32.add");
1265
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1266
+ this.pushInstruction({ op: "local.get", index: lineLenTmp });
1267
+ this.pushInstruction("i32.sub");
1268
+ this.pushInstruction({ op: "local.get", index: capTmp });
1269
+ this.pushInstruction({ op: "local.get", index: lineLenTmp });
1270
+ this.pushInstruction("i32.sub");
1271
+ this.pushInstruction({
1272
+ op: "struct.new",
1273
+ typeIndex: sliceInfo.typeIndex,
1274
+ });
1275
+ this.pushInstruction({
1276
+ op: "struct.set",
1277
+ typeIndex: structInfo.typeIndex,
1278
+ fieldIndex: 0,
1279
+ });
1280
+ setLastOp(1);
1281
+ this.releaseTemp(lineLenTmp, "i32");
1282
+
1283
+ this.pushInstruction("else");
1284
+
1285
+ // Not found
1286
+ if (isStr) {
1287
+ this._emitBytesSliceToString(
1288
+ arrTmp,
1289
+ offTmp,
1290
+ lenTmp,
1291
+ arrInfo.typeIndex,
1292
+ );
1293
+ this.pushInstruction({ op: "local.set", index: resStrTmp });
1294
+ } else {
1295
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1296
+ this.pushInstruction({ op: "local.get", index: offTmp });
1297
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1298
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1299
+ this.pushInstruction({
1300
+ op: "struct.new",
1301
+ typeIndex: sliceInfo.typeIndex,
1302
+ });
1303
+ this.pushInstruction({ op: "local.set", index: resLineTmp });
1304
+ }
1305
+ this.emitIoConst("EOF", "anyref");
1306
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1307
+
1308
+ this.pushInstruction({ op: "local.get", index: bTmp });
1309
+ this.pushInstruction({
1310
+ op: "global.get",
1311
+ index: sliceInfo.emptyGlobalIndex,
1312
+ });
1313
+ this.pushInstruction({
1314
+ op: "struct.set",
1315
+ typeIndex: structInfo.typeIndex,
1316
+ fieldIndex: 0,
1317
+ });
1318
+ setLastOp(0);
1319
+ this.pushInstruction("end");
1320
+
1321
+ if (isStr) {
1322
+ this.pushInstruction({ op: "local.get", index: resStrTmp });
1323
+ this.releaseTemp(resStrTmp, "externref");
1324
+ } else {
1325
+ this.pushInstruction({ op: "local.get", index: resLineTmp });
1326
+ this.releaseTemp(resLineTmp, sliceW);
1327
+ }
1328
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
1329
+
1330
+ this.releaseTemp(resErrTmp, "anyref");
1331
+ this.releaseTemp(matchTmp, "i32");
1332
+ this.releaseTemp(capTmp, "i32");
1333
+ this.releaseTemp(lenTmp, "i32");
1334
+ this.releaseTemp(offTmp, "i32");
1335
+ this.releaseTemp(arrTmp, arrW);
1336
+ this.releaseTemp(bTmp, bufW);
1337
+ return;
1338
+ }
1339
+ case "ReadFrom": {
1340
+ const rTmp = this.acquireTemp("anyref");
1341
+ this.emitExpr(args[0], "anyref");
1342
+ this.pushInstruction({ op: "local.set", index: rTmp });
1343
+
1344
+ const chunkLen = 4096;
1345
+ const chunkArrTmp = this.acquireTemp(arrW);
1346
+ this.pushInstruction({ op: "i32.const", value: chunkLen });
1347
+ this.pushInstruction({
1348
+ op: "array.new_default",
1349
+ typeIndex: arrInfo.typeIndex,
1350
+ });
1351
+ this.pushInstruction({ op: "local.set", index: chunkArrTmp });
1352
+
1353
+ const chunkSliceTmp = this.acquireTemp(sliceW);
1354
+ this.pushInstruction({ op: "local.get", index: chunkArrTmp });
1355
+ this.pushInstruction({ op: "i32.const", value: 0 });
1356
+ this.pushInstruction({ op: "i32.const", value: chunkLen });
1357
+ this.pushInstruction({ op: "i32.const", value: chunkLen });
1358
+ this.pushInstruction({
1359
+ op: "struct.new",
1360
+ typeIndex: sliceInfo.typeIndex,
1361
+ });
1362
+ this.pushInstruction({ op: "local.set", index: chunkSliceTmp });
1363
+
1364
+ const totalTmp = this.acquireTemp("i64");
1365
+ this.pushInstruction({ op: "i64.const", value: 0n });
1366
+ this.pushInstruction({ op: "local.set", index: totalTmp });
1367
+
1368
+ const errTmp = this.acquireTemp("anyref");
1369
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1370
+ this.pushInstruction({ op: "local.set", index: errTmp });
1371
+
1372
+ const readErrTmp = this.acquireTemp("anyref");
1373
+ const nrTmp = this.acquireTemp("i32");
1374
+ const subsliceTmp = this.acquireTemp(sliceW);
1375
+
1376
+ const dispatchReadIdx = this.mod.resolveFuncIndex(
1377
+ "__dispatch_io.Reader_Read",
1378
+ );
1379
+
1380
+ this.pushInstruction({ op: "block", blockType: "void" });
1381
+ this.pushInstruction({ op: "loop", blockType: "void" });
1382
+
1383
+ this.pushInstruction({ op: "local.get", index: rTmp });
1384
+ this.pushInstruction({ op: "local.get", index: chunkSliceTmp });
1385
+ if (dispatchReadIdx !== null) {
1386
+ this.pushInstruction({ op: "call", funcIndex: dispatchReadIdx });
1387
+ } else {
1388
+ this.pushInstruction({ op: "i64.const", value: 0n });
1389
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1390
+ }
1391
+ this.pushInstruction({ op: "local.set", index: readErrTmp });
1392
+ this.pushInstruction("i32.wrap_i64");
1393
+ this.pushInstruction({ op: "local.set", index: nrTmp });
1394
+
1395
+ this.pushInstruction({ op: "local.get", index: nrTmp });
1396
+ this.pushInstruction({ op: "i32.const", value: 0 });
1397
+ this.pushInstruction("i32.gt_s");
1398
+ this.pushInstruction({ op: "if", blockType: "void" });
1399
+
1400
+ this.pushInstruction({ op: "local.get", index: chunkArrTmp });
1401
+ this.pushInstruction({ op: "i32.const", value: 0 });
1402
+ this.pushInstruction({ op: "local.get", index: nrTmp });
1403
+ this.pushInstruction({ op: "local.get", index: nrTmp });
1404
+ this.pushInstruction({
1405
+ op: "struct.new",
1406
+ typeIndex: sliceInfo.typeIndex,
1407
+ });
1408
+ this.pushInstruction({ op: "local.set", index: subsliceTmp });
1409
+
1410
+ this._emitBufferWriteCore(bTmp, subsliceTmp);
1411
+ this.pushInstruction("drop");
1412
+ this.pushInstruction("drop");
1413
+
1414
+ this.pushInstruction({ op: "local.get", index: totalTmp });
1415
+ this.pushInstruction({ op: "local.get", index: nrTmp });
1416
+ this.pushInstruction("i64.extend_i32_u");
1417
+ this.pushInstruction("i64.add");
1418
+ this.pushInstruction({ op: "local.set", index: totalTmp });
1419
+ this.pushInstruction("end");
1420
+
1421
+ this.pushInstruction({ op: "local.get", index: readErrTmp });
1422
+ this.pushInstruction("ref.is_null");
1423
+ this.pushInstruction("i32.eqz");
1424
+ this.pushInstruction({ op: "if", blockType: "void" });
1425
+ this.pushInstruction({ op: "local.get", index: readErrTmp });
1426
+ this.emitIoConst("EOF", "anyref");
1427
+ this.pushInstruction({
1428
+ op: "call",
1429
+ funcIndex: this.mod.resolveFuncIndex("__errors_is"),
1430
+ });
1431
+ this.pushInstruction({ op: "if", blockType: "void" });
1432
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1433
+ this.pushInstruction({ op: "local.set", index: errTmp });
1434
+ this.pushInstruction("else");
1435
+ this.pushInstruction({ op: "local.get", index: readErrTmp });
1436
+ this.pushInstruction({ op: "local.set", index: errTmp });
1437
+ this.pushInstruction("end");
1438
+ this.pushInstruction({ op: "br", depth: 2 });
1439
+ this.pushInstruction("end");
1440
+
1441
+ this.pushInstruction({ op: "br", depth: 0 });
1442
+ this.pushInstruction("end");
1443
+ this.pushInstruction("end");
1444
+
1445
+ setLastOp(0);
1446
+
1447
+ this.pushInstruction({ op: "local.get", index: totalTmp });
1448
+ this.pushInstruction({ op: "local.get", index: errTmp });
1449
+
1450
+ this.releaseTemp(subsliceTmp, sliceW);
1451
+ this.releaseTemp(nrTmp, "i32");
1452
+ this.releaseTemp(readErrTmp, "anyref");
1453
+ this.releaseTemp(errTmp, "anyref");
1454
+ this.releaseTemp(totalTmp, "i64");
1455
+ this.releaseTemp(chunkSliceTmp, sliceW);
1456
+ this.releaseTemp(chunkArrTmp, arrW);
1457
+ this.releaseTemp(rTmp, "anyref");
1458
+ this.releaseTemp(bTmp, bufW);
1459
+ return;
1460
+ }
1461
+ case "WriteTo": {
1462
+ const wTmp = this.acquireTemp("anyref");
1463
+ this.emitExpr(args[0], "anyref");
1464
+ this.pushInstruction({ op: "local.set", index: wTmp });
1465
+
1466
+ const sTmp = getBufSlice();
1467
+ const arrTmp = this.acquireTemp(arrW);
1468
+ const offTmp = this.acquireTemp("i32");
1469
+ const lenTmp = this.acquireTemp("i32");
1470
+ const capTmp = this.acquireTemp("i32");
1471
+ this._emitSliceUnpack(sTmp, sliceInfo, {
1472
+ arr: arrTmp,
1473
+ off: offTmp,
1474
+ len: lenTmp,
1475
+ cap: capTmp,
1476
+ });
1477
+
1478
+ const resNTmp = this.acquireTemp("i64");
1479
+ const resErrTmp = this.acquireTemp("anyref");
1480
+
1481
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1482
+ this.pushInstruction("i32.eqz");
1483
+ this.pushInstruction({ op: "if", blockType: "void" });
1484
+ this.pushInstruction({ op: "i64.const", value: 0n });
1485
+ this.pushInstruction({ op: "local.set", index: resNTmp });
1486
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1487
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1488
+ this.pushInstruction("else");
1489
+
1490
+ const dispatchWriteIdx = this.mod.resolveFuncIndex(
1491
+ "__dispatch_io.Writer_Write",
1492
+ );
1493
+ this.pushInstruction({ op: "local.get", index: wTmp });
1494
+ this.pushInstruction({ op: "local.get", index: sTmp });
1495
+ if (dispatchWriteIdx !== null) {
1496
+ this.pushInstruction({ op: "call", funcIndex: dispatchWriteIdx });
1497
+ } else {
1498
+ this.pushInstruction({ op: "i64.const", value: 0n });
1499
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1500
+ }
1501
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1502
+ this.pushInstruction({ op: "local.set", index: resNTmp });
1503
+
1504
+ const nwI32Tmp = this.acquireTemp("i32");
1505
+ this.pushInstruction({ op: "local.get", index: resNTmp });
1506
+ this.pushInstruction("i32.wrap_i64");
1507
+ this.pushInstruction({ op: "local.set", index: nwI32Tmp });
1508
+
1509
+ this.pushInstruction({ op: "local.get", index: bTmp });
1510
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1511
+ this.pushInstruction({ op: "local.get", index: offTmp });
1512
+ this.pushInstruction({ op: "local.get", index: nwI32Tmp });
1513
+ this.pushInstruction("i32.add");
1514
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1515
+ this.pushInstruction({ op: "local.get", index: nwI32Tmp });
1516
+ this.pushInstruction("i32.sub");
1517
+ this.pushInstruction({ op: "local.get", index: capTmp });
1518
+ this.pushInstruction({ op: "local.get", index: nwI32Tmp });
1519
+ this.pushInstruction("i32.sub");
1520
+ this.pushInstruction({
1521
+ op: "struct.new",
1522
+ typeIndex: sliceInfo.typeIndex,
1523
+ });
1524
+ this.pushInstruction({
1525
+ op: "struct.set",
1526
+ typeIndex: structInfo.typeIndex,
1527
+ fieldIndex: 0,
1528
+ });
1529
+ setLastOp(0);
1530
+ this.releaseTemp(nwI32Tmp, "i32");
1531
+ this.pushInstruction("end");
1532
+
1533
+ this.releaseTemp(sTmp, sliceW);
1534
+ this.releaseTemp(capTmp, "i32");
1535
+ this.releaseTemp(lenTmp, "i32");
1536
+ this.releaseTemp(offTmp, "i32");
1537
+ this.releaseTemp(arrTmp, arrW);
1538
+
1539
+ this.pushInstruction({ op: "local.get", index: resNTmp });
1540
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
1541
+
1542
+ this.releaseTemp(resErrTmp, "anyref");
1543
+ this.releaseTemp(resNTmp, "i64");
1544
+ this.releaseTemp(wTmp, "anyref");
1545
+ this.releaseTemp(bTmp, bufW);
1546
+ return;
1547
+ }
1548
+ case "Next": {
1549
+ const nTmp = this.acquireTemp("i32");
1550
+ this._emitI32Arg(args[0]);
1551
+ this.pushInstruction({ op: "local.set", index: nTmp });
1552
+
1553
+ const sTmp = getBufSlice();
1554
+ const arrTmp = this.acquireTemp(arrW);
1555
+ const offTmp = this.acquireTemp("i32");
1556
+ const lenTmp = this.acquireTemp("i32");
1557
+ const capTmp = this.acquireTemp("i32");
1558
+ this._emitSliceUnpack(sTmp, sliceInfo, {
1559
+ arr: arrTmp,
1560
+ off: offTmp,
1561
+ len: lenTmp,
1562
+ cap: capTmp,
1563
+ });
1564
+ this.releaseTemp(sTmp, sliceW);
1565
+
1566
+ const cntTmp = this.acquireTemp("i32");
1567
+ this.pushInstruction({ op: "local.get", index: nTmp });
1568
+ this.pushInstruction({ op: "i32.const", value: 0 });
1569
+ this.pushInstruction("i32.lt_s");
1570
+ this.pushInstruction({ op: "if", blockType: "i32" });
1571
+ this.pushInstruction({ op: "i32.const", value: 0 });
1572
+ this.pushInstruction("else");
1573
+ this.pushInstruction({ op: "local.get", index: nTmp });
1574
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1575
+ this.pushInstruction("i32.gt_s");
1576
+ this.pushInstruction({ op: "if", blockType: "i32" });
1577
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1578
+ this.pushInstruction("else");
1579
+ this.pushInstruction({ op: "local.get", index: nTmp });
1580
+ this.pushInstruction("end");
1581
+ this.pushInstruction("end");
1582
+ this.pushInstruction({ op: "local.set", index: cntTmp });
1583
+ this.releaseTemp(nTmp, "i32");
1584
+
1585
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1586
+ this.pushInstruction({ op: "local.get", index: offTmp });
1587
+ this.pushInstruction({ op: "local.get", index: cntTmp });
1588
+ this.pushInstruction({ op: "local.get", index: cntTmp });
1589
+ this.pushInstruction({
1590
+ op: "struct.new",
1591
+ typeIndex: sliceInfo.typeIndex,
1592
+ });
1593
+
1594
+ this.pushInstruction({ op: "local.get", index: bTmp });
1595
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1596
+ this.pushInstruction({ op: "local.get", index: offTmp });
1597
+ this.pushInstruction({ op: "local.get", index: cntTmp });
1598
+ this.pushInstruction("i32.add");
1599
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1600
+ this.pushInstruction({ op: "local.get", index: cntTmp });
1601
+ this.pushInstruction("i32.sub");
1602
+ this.pushInstruction({ op: "local.get", index: capTmp });
1603
+ this.pushInstruction({ op: "local.get", index: cntTmp });
1604
+ this.pushInstruction("i32.sub");
1605
+ this.pushInstruction({
1606
+ op: "struct.new",
1607
+ typeIndex: sliceInfo.typeIndex,
1608
+ });
1609
+ this.pushInstruction({
1610
+ op: "struct.set",
1611
+ typeIndex: structInfo.typeIndex,
1612
+ fieldIndex: 0,
1613
+ });
1614
+ setLastOp(0);
1615
+
1616
+ this.releaseTemp(cntTmp, "i32");
1617
+ this.releaseTemp(capTmp, "i32");
1618
+ this.releaseTemp(lenTmp, "i32");
1619
+ this.releaseTemp(offTmp, "i32");
1620
+ this.releaseTemp(arrTmp, arrW);
1621
+ this.releaseTemp(bTmp, bufW);
1622
+ return;
1623
+ }
1624
+ case "Truncate": {
1625
+ const nTmp = this.acquireTemp("i32");
1626
+ this._emitI32Arg(args[0]);
1627
+ this.pushInstruction({ op: "local.set", index: nTmp });
1628
+
1629
+ const sTmp = getBufSlice();
1630
+ const arrTmp = this.acquireTemp(arrW);
1631
+ const offTmp = this.acquireTemp("i32");
1632
+ const lenTmp = this.acquireTemp("i32");
1633
+ const capTmp = this.acquireTemp("i32");
1634
+ this._emitSliceUnpack(sTmp, sliceInfo, {
1635
+ arr: arrTmp,
1636
+ off: offTmp,
1637
+ len: lenTmp,
1638
+ cap: capTmp,
1639
+ });
1640
+ this.releaseTemp(sTmp, sliceW);
1641
+
1642
+ this.pushInstruction({ op: "local.get", index: nTmp });
1643
+ this.pushInstruction({ op: "i32.const", value: 0 });
1644
+ this.pushInstruction("i32.lt_s");
1645
+ this.pushInstruction({ op: "local.get", index: nTmp });
1646
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1647
+ this.pushInstruction("i32.gt_s");
1648
+ this.pushInstruction("i32.or");
1649
+ this.pushInstruction({ op: "if", blockType: "void" });
1650
+ this.emitPanic("bytes.Buffer: truncation out of range");
1651
+ this.pushInstruction("end");
1652
+
1653
+ this.pushInstruction({ op: "local.get", index: bTmp });
1654
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1655
+ this.pushInstruction({ op: "local.get", index: offTmp });
1656
+ this.pushInstruction({ op: "local.get", index: nTmp });
1657
+ this.pushInstruction({ op: "local.get", index: capTmp });
1658
+ this.pushInstruction({
1659
+ op: "struct.new",
1660
+ typeIndex: sliceInfo.typeIndex,
1661
+ });
1662
+ this.pushInstruction({
1663
+ op: "struct.set",
1664
+ typeIndex: structInfo.typeIndex,
1665
+ fieldIndex: 0,
1666
+ });
1667
+ setLastOp(0);
1668
+
1669
+ this.releaseTemp(nTmp, "i32");
1670
+ this.releaseTemp(capTmp, "i32");
1671
+ this.releaseTemp(lenTmp, "i32");
1672
+ this.releaseTemp(offTmp, "i32");
1673
+ this.releaseTemp(arrTmp, arrW);
1674
+ this.releaseTemp(bTmp, bufW);
1675
+ return;
1676
+ }
1677
+ case "Available": {
1678
+ const sTmp = getBufSlice();
1679
+ const lenTmp = this.acquireTemp("i32");
1680
+ const capTmp = this.acquireTemp("i32");
1681
+ this.pushInstruction({ op: "local.get", index: sTmp });
1682
+ this.pushInstruction({
1683
+ op: "struct.get",
644
1684
  typeIndex: sliceInfo.typeIndex,
1685
+ fieldIndex: 2,
645
1686
  });
1687
+ this.pushInstruction({ op: "local.set", index: lenTmp });
1688
+ this.pushInstruction({ op: "local.get", index: sTmp });
646
1689
  this.pushInstruction({
647
- op: "struct.set",
648
- typeIndex: structInfo.typeIndex,
649
- fieldIndex: 0,
1690
+ op: "struct.get",
1691
+ typeIndex: sliceInfo.typeIndex,
1692
+ fieldIndex: 3,
650
1693
  });
1694
+ this.pushInstruction({ op: "local.set", index: capTmp });
1695
+ this.releaseTemp(sTmp, sliceW);
651
1696
 
652
- this.pushInstruction({ op: "local.get", index: rLenTmp });
653
- this.pushInstruction("i64.extend_i32_u");
654
- this.pushInstruction({ op: "ref.null", heapType: "any" });
1697
+ this.pushInstruction({ op: "local.get", index: capTmp });
1698
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1699
+ this.pushInstruction("i32.sub");
1700
+ if ((targetWasmType ?? "i64") === "i64") {
1701
+ this.pushInstruction("i64.extend_i32_u");
1702
+ }
1703
+ this.releaseTemp(capTmp, "i32");
1704
+ this.releaseTemp(lenTmp, "i32");
1705
+ this.releaseTemp(bTmp, bufW);
1706
+ return;
1707
+ }
1708
+ case "AvailableBuffer": {
1709
+ const sTmp = getBufSlice();
1710
+ const arrTmp = this.acquireTemp(arrW);
1711
+ const offTmp = this.acquireTemp("i32");
1712
+ const lenTmp = this.acquireTemp("i32");
1713
+ const capTmp = this.acquireTemp("i32");
1714
+ this._emitSliceUnpack(sTmp, sliceInfo, {
1715
+ arr: arrTmp,
1716
+ off: offTmp,
1717
+ len: lenTmp,
1718
+ cap: capTmp,
1719
+ });
1720
+ this.releaseTemp(sTmp, sliceW);
655
1721
 
656
- this.releaseTemp(newCapTmp, "i32");
657
- this.releaseTemp(newOffTmp, "i32");
658
- this.releaseTemp(newArrTmp, arrW);
659
- this.releaseTemp(newLenTmp, "i32");
660
- this.releaseTemp(oldCapTmp, "i32");
661
- this.releaseTemp(oldLenTmp, "i32");
662
- this.releaseTemp(oldOffTmp, "i32");
663
- this.releaseTemp(oldArrTmp, arrW);
664
- this.releaseTemp(rLenTmp, "i32");
665
- this.releaseTemp(rTmp, "i32");
1722
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1723
+ this.pushInstruction({ op: "local.get", index: offTmp });
1724
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1725
+ this.pushInstruction("i32.add");
1726
+ this.pushInstruction({ op: "i32.const", value: 0 });
1727
+ this.pushInstruction({ op: "local.get", index: capTmp });
1728
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1729
+ this.pushInstruction("i32.sub");
1730
+ this.pushInstruction({
1731
+ op: "struct.new",
1732
+ typeIndex: sliceInfo.typeIndex,
1733
+ });
1734
+
1735
+ this.releaseTemp(capTmp, "i32");
1736
+ this.releaseTemp(lenTmp, "i32");
1737
+ this.releaseTemp(offTmp, "i32");
1738
+ this.releaseTemp(arrTmp, arrW);
666
1739
  this.releaseTemp(bTmp, bufW);
667
1740
  return;
668
1741
  }
669
- case "Grow": {
1742
+ case "Peek": {
670
1743
  const nTmp = this.acquireTemp("i32");
671
1744
  this._emitI32Arg(args[0]);
672
1745
  this.pushInstruction({ op: "local.set", index: nTmp });
673
1746
 
674
- this.pushInstruction({ op: "local.get", index: nTmp });
675
- this.pushInstruction({ op: "i32.const", value: 0 });
676
- this.pushInstruction("i32.lt_s");
677
- this.pushInstruction({ op: "if", blockType: "void" });
678
- this.emitPanic("bytes.Buffer.Grow: negative count");
679
- this.pushInstruction("end");
680
-
681
- this.pushInstruction({ op: "local.get", index: nTmp });
682
- this.pushInstruction({ op: "i32.const", value: 0 });
683
- this.pushInstruction("i32.gt_s");
684
- this.pushInstruction({ op: "if", blockType: "void" });
685
-
686
1747
  const sTmp = getBufSlice();
687
- const oldArrTmp = this.acquireTemp(arrW);
688
- const oldOffTmp = this.acquireTemp("i32");
689
- const oldLenTmp = this.acquireTemp("i32");
690
- const oldCapTmp = this.acquireTemp("i32");
1748
+ const arrTmp = this.acquireTemp(arrW);
1749
+ const offTmp = this.acquireTemp("i32");
1750
+ const lenTmp = this.acquireTemp("i32");
1751
+ const capTmp = this.acquireTemp("i32");
691
1752
  this._emitSliceUnpack(sTmp, sliceInfo, {
692
- arr: oldArrTmp,
693
- off: oldOffTmp,
694
- len: oldLenTmp,
695
- cap: oldCapTmp,
1753
+ arr: arrTmp,
1754
+ off: offTmp,
1755
+ len: lenTmp,
1756
+ cap: capTmp,
696
1757
  });
697
1758
  this.releaseTemp(sTmp, sliceW);
698
1759
 
699
- const targetCapTmp = this.acquireTemp("i32");
700
- this.pushInstruction({ op: "local.get", index: oldLenTmp });
701
1760
  this.pushInstruction({ op: "local.get", index: nTmp });
702
- this.pushInstruction("i32.add");
703
- this.pushInstruction({ op: "local.set", index: targetCapTmp });
704
-
705
- this.pushInstruction({ op: "local.get", index: targetCapTmp });
706
- this.pushInstruction({ op: "local.get", index: oldCapTmp });
707
- this.pushInstruction("i32.gt_u");
1761
+ this.pushInstruction({ op: "i32.const", value: 0 });
1762
+ this.pushInstruction("i32.lt_s");
708
1763
  this.pushInstruction({ op: "if", blockType: "void" });
1764
+ this.emitPanic("runtime error: slice bounds out of range");
1765
+ this.pushInstruction("end");
709
1766
 
710
- const newArrTmp = this.acquireTemp(arrW);
711
- const newOffTmp = this.acquireTemp("i32");
712
- const newCapTmp = this.acquireTemp("i32");
713
-
714
- this._emitGrowSlice({
715
- arrInfo,
716
- elemGoType: byteGo,
717
- oldArrTmp,
718
- oldOffTmp,
719
- oldLenTmp,
720
- oldCapTmp,
721
- newArrTmp,
722
- newOffTmp,
723
- newLenTmp: targetCapTmp,
724
- newCapTmp,
725
- });
1767
+ const resSliceTmp = this.acquireTemp(sliceW);
1768
+ const resErrTmp = this.acquireTemp("anyref");
726
1769
 
727
- this.pushInstruction({ op: "local.get", index: bTmp });
728
- this.pushInstruction({ op: "local.get", index: newArrTmp });
729
- this.pushInstruction({ op: "local.get", index: newOffTmp });
730
- this.pushInstruction({ op: "local.get", index: oldLenTmp });
731
- this.pushInstruction({ op: "local.get", index: newCapTmp });
1770
+ this.pushInstruction({ op: "local.get", index: nTmp });
1771
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1772
+ this.pushInstruction("i32.gt_s");
1773
+ this.pushInstruction({ op: "if", blockType: "void" });
1774
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1775
+ this.pushInstruction({ op: "local.get", index: offTmp });
1776
+ this.pushInstruction({ op: "local.get", index: lenTmp });
1777
+ this.pushInstruction({ op: "local.get", index: lenTmp });
732
1778
  this.pushInstruction({
733
1779
  op: "struct.new",
734
1780
  typeIndex: sliceInfo.typeIndex,
735
1781
  });
1782
+ this.pushInstruction({ op: "local.set", index: resSliceTmp });
1783
+ this.emitIoConst("EOF", "anyref");
1784
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1785
+ this.pushInstruction("else");
1786
+ this.pushInstruction({ op: "local.get", index: arrTmp });
1787
+ this.pushInstruction({ op: "local.get", index: offTmp });
1788
+ this.pushInstruction({ op: "local.get", index: nTmp });
1789
+ this.pushInstruction({ op: "local.get", index: nTmp });
736
1790
  this.pushInstruction({
737
- op: "struct.set",
738
- typeIndex: structInfo.typeIndex,
739
- fieldIndex: 0,
1791
+ op: "struct.new",
1792
+ typeIndex: sliceInfo.typeIndex,
740
1793
  });
741
-
742
- this.releaseTemp(newCapTmp, "i32");
743
- this.releaseTemp(newOffTmp, "i32");
744
- this.releaseTemp(newArrTmp, arrW);
1794
+ this.pushInstruction({ op: "local.set", index: resSliceTmp });
1795
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1796
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
745
1797
  this.pushInstruction("end");
746
1798
 
747
- this.releaseTemp(targetCapTmp, "i32");
748
- this.releaseTemp(oldCapTmp, "i32");
749
- this.releaseTemp(oldLenTmp, "i32");
750
- this.releaseTemp(oldOffTmp, "i32");
751
- this.releaseTemp(oldArrTmp, arrW);
752
- this.pushInstruction("end");
1799
+ this.pushInstruction({ op: "local.get", index: resSliceTmp });
1800
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
753
1801
 
1802
+ this.releaseTemp(resErrTmp, "anyref");
1803
+ this.releaseTemp(resSliceTmp, sliceW);
1804
+ this.releaseTemp(capTmp, "i32");
1805
+ this.releaseTemp(lenTmp, "i32");
1806
+ this.releaseTemp(offTmp, "i32");
1807
+ this.releaseTemp(arrTmp, arrW);
754
1808
  this.releaseTemp(nTmp, "i32");
755
1809
  this.releaseTemp(bTmp, bufW);
756
1810
  return;
@@ -808,6 +1862,8 @@ export class BytesEmitter {
808
1862
  return this.emitSlicesClone(args);
809
1863
  case "Join":
810
1864
  return this._emitBytesJoin(name, args, targetWasmType);
1865
+ case "ToValidUTF8":
1866
+ return this._emitBytesToValidUTF8(args, targetWasmType);
811
1867
  default:
812
1868
  throw new Error(`Unsupported bytes function: bytes.${name}`);
813
1869
  }
@@ -4013,6 +5069,174 @@ export class BytesEmitter {
4013
5069
  this.releaseTemp(bArr, arrW);
4014
5070
  }
4015
5071
 
5072
+ _emitIsSpaceAt(arr, off, idx, len, outWidth, arrInfo) {
5073
+ this.pushInstruction({ op: "i32.const", value: 0 });
5074
+ this.pushInstruction({ op: "local.set", index: outWidth });
5075
+
5076
+ const cTmp = this.acquireTemp("i32");
5077
+ this.pushInstruction({ op: "local.get", index: arr });
5078
+ this.pushInstruction({ op: "local.get", index: off });
5079
+ this.pushInstruction({ op: "local.get", index: idx });
5080
+ this.pushInstruction("i32.add");
5081
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
5082
+ this.pushInstruction({ op: "local.set", index: cTmp });
5083
+
5084
+ // if c == 32 || (c >= 9 && c <= 13) -> 1
5085
+ this.pushInstruction({ op: "local.get", index: cTmp });
5086
+ this.pushInstruction({ op: "i32.const", value: 32 });
5087
+ this.pushInstruction("i32.eq");
5088
+ this.pushInstruction({ op: "local.get", index: cTmp });
5089
+ this.pushInstruction({ op: "i32.const", value: 9 });
5090
+ this.pushInstruction("i32.sub");
5091
+ this.pushInstruction({ op: "i32.const", value: 4 });
5092
+ this.pushInstruction("i32.le_u");
5093
+ this.pushInstruction("i32.or");
5094
+ this.pushInstruction({ op: "if", blockType: "void" });
5095
+ this.pushInstruction({ op: "i32.const", value: 1 });
5096
+ this.pushInstruction({ op: "local.set", index: outWidth });
5097
+ this.pushInstruction({ op: "else" });
5098
+
5099
+ // if c == 0xC2 && idx + 1 < len
5100
+ this.pushInstruction({ op: "local.get", index: cTmp });
5101
+ this.pushInstruction({ op: "i32.const", value: 0xc2 });
5102
+ this.pushInstruction("i32.eq");
5103
+ this.pushInstruction({ op: "local.get", index: idx });
5104
+ this.pushInstruction({ op: "i32.const", value: 1 });
5105
+ this.pushInstruction("i32.add");
5106
+ this.pushInstruction({ op: "local.get", index: len });
5107
+ this.pushInstruction("i32.lt_s");
5108
+ this.pushInstruction("i32.and");
5109
+ this.pushInstruction({ op: "if", blockType: "void" });
5110
+ // c1 = arr[off + idx + 1]
5111
+ this.pushInstruction({ op: "local.get", index: arr });
5112
+ this.pushInstruction({ op: "local.get", index: off });
5113
+ this.pushInstruction({ op: "local.get", index: idx });
5114
+ this.pushInstruction("i32.add");
5115
+ this.pushInstruction({ op: "i32.const", value: 1 });
5116
+ this.pushInstruction("i32.add");
5117
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
5118
+ this.pushInstruction({ op: "local.tee", index: cTmp });
5119
+ this.pushInstruction({ op: "i32.const", value: 0x85 });
5120
+ this.pushInstruction("i32.eq");
5121
+ this.pushInstruction({ op: "local.get", index: cTmp });
5122
+ this.pushInstruction({ op: "i32.const", value: 0xa0 });
5123
+ this.pushInstruction("i32.eq");
5124
+ this.pushInstruction("i32.or");
5125
+ this.pushInstruction({ op: "if", blockType: "void" });
5126
+ this.pushInstruction({ op: "i32.const", value: 2 });
5127
+ this.pushInstruction({ op: "local.set", index: outWidth });
5128
+ this.pushInstruction("end");
5129
+ this.pushInstruction({ op: "else" });
5130
+
5131
+ // idx + 2 < len
5132
+ this.pushInstruction({ op: "local.get", index: idx });
5133
+ this.pushInstruction({ op: "i32.const", value: 2 });
5134
+ this.pushInstruction("i32.add");
5135
+ this.pushInstruction({ op: "local.get", index: len });
5136
+ this.pushInstruction("i32.lt_s");
5137
+ this.pushInstruction({ op: "if", blockType: "void" });
5138
+ const c1Tmp = this.acquireTemp("i32");
5139
+ const c2Tmp = this.acquireTemp("i32");
5140
+ this.pushInstruction({ op: "local.get", index: arr });
5141
+ this.pushInstruction({ op: "local.get", index: off });
5142
+ this.pushInstruction({ op: "local.get", index: idx });
5143
+ this.pushInstruction("i32.add");
5144
+ this.pushInstruction({ op: "i32.const", value: 1 });
5145
+ this.pushInstruction("i32.add");
5146
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
5147
+ this.pushInstruction({ op: "local.set", index: c1Tmp });
5148
+
5149
+ this.pushInstruction({ op: "local.get", index: arr });
5150
+ this.pushInstruction({ op: "local.get", index: off });
5151
+ this.pushInstruction({ op: "local.get", index: idx });
5152
+ this.pushInstruction("i32.add");
5153
+ this.pushInstruction({ op: "i32.const", value: 2 });
5154
+ this.pushInstruction("i32.add");
5155
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
5156
+ this.pushInstruction({ op: "local.set", index: c2Tmp });
5157
+
5158
+ // if c == 0xE1 && c1 == 0x9A && c2 == 0x80 -> 3
5159
+ this.pushInstruction({ op: "local.get", index: cTmp });
5160
+ this.pushInstruction({ op: "i32.const", value: 0xe1 });
5161
+ this.pushInstruction("i32.eq");
5162
+ this.pushInstruction({ op: "local.get", index: c1Tmp });
5163
+ this.pushInstruction({ op: "i32.const", value: 0x9a });
5164
+ this.pushInstruction("i32.eq");
5165
+ this.pushInstruction("i32.and");
5166
+ this.pushInstruction({ op: "local.get", index: c2Tmp });
5167
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
5168
+ this.pushInstruction("i32.eq");
5169
+ this.pushInstruction("i32.and");
5170
+ this.pushInstruction({ op: "if", blockType: "void" });
5171
+ this.pushInstruction({ op: "i32.const", value: 3 });
5172
+ this.pushInstruction({ op: "local.set", index: outWidth });
5173
+ this.pushInstruction("end");
5174
+
5175
+ // if c == 0xE2:
5176
+ this.pushInstruction({ op: "local.get", index: cTmp });
5177
+ this.pushInstruction({ op: "i32.const", value: 0xe2 });
5178
+ this.pushInstruction("i32.eq");
5179
+ this.pushInstruction({ op: "if", blockType: "void" });
5180
+ // condition 1: (c1 == 0x80 && (c2 <= 0x8A || c2 == 0xA8 || c2 == 0xA9 || c2 == 0xAF))
5181
+ this.pushInstruction({ op: "local.get", index: c1Tmp });
5182
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
5183
+ this.pushInstruction("i32.eq");
5184
+ this.pushInstruction({ op: "local.get", index: c2Tmp });
5185
+ this.pushInstruction({ op: "i32.const", value: 0x8a });
5186
+ this.pushInstruction("i32.le_u");
5187
+ this.pushInstruction({ op: "local.get", index: c2Tmp });
5188
+ this.pushInstruction({ op: "i32.const", value: 0xa8 });
5189
+ this.pushInstruction("i32.eq");
5190
+ this.pushInstruction("i32.or");
5191
+ this.pushInstruction({ op: "local.get", index: c2Tmp });
5192
+ this.pushInstruction({ op: "i32.const", value: 0xa9 });
5193
+ this.pushInstruction("i32.eq");
5194
+ this.pushInstruction("i32.or");
5195
+ this.pushInstruction({ op: "local.get", index: c2Tmp });
5196
+ this.pushInstruction({ op: "i32.const", value: 0xaf });
5197
+ this.pushInstruction("i32.eq");
5198
+ this.pushInstruction("i32.or");
5199
+ this.pushInstruction("i32.and");
5200
+ // condition 2: (c1 == 0x81 && c2 == 0x9F)
5201
+ this.pushInstruction({ op: "local.get", index: c1Tmp });
5202
+ this.pushInstruction({ op: "i32.const", value: 0x81 });
5203
+ this.pushInstruction("i32.eq");
5204
+ this.pushInstruction({ op: "local.get", index: c2Tmp });
5205
+ this.pushInstruction({ op: "i32.const", value: 0x9f });
5206
+ this.pushInstruction("i32.eq");
5207
+ this.pushInstruction("i32.and");
5208
+ this.pushInstruction("i32.or");
5209
+ this.pushInstruction({ op: "if", blockType: "void" });
5210
+ this.pushInstruction({ op: "i32.const", value: 3 });
5211
+ this.pushInstruction({ op: "local.set", index: outWidth });
5212
+ this.pushInstruction("end");
5213
+ this.pushInstruction("end");
5214
+
5215
+ // if c == 0xE3 && c1 == 0x80 && c2 == 0x80 -> 3
5216
+ this.pushInstruction({ op: "local.get", index: cTmp });
5217
+ this.pushInstruction({ op: "i32.const", value: 0xe3 });
5218
+ this.pushInstruction("i32.eq");
5219
+ this.pushInstruction({ op: "local.get", index: c1Tmp });
5220
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
5221
+ this.pushInstruction("i32.eq");
5222
+ this.pushInstruction("i32.and");
5223
+ this.pushInstruction({ op: "local.get", index: c2Tmp });
5224
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
5225
+ this.pushInstruction("i32.eq");
5226
+ this.pushInstruction("i32.and");
5227
+ this.pushInstruction({ op: "if", blockType: "void" });
5228
+ this.pushInstruction({ op: "i32.const", value: 3 });
5229
+ this.pushInstruction({ op: "local.set", index: outWidth });
5230
+ this.pushInstruction("end");
5231
+
5232
+ this.releaseTemp(c2Tmp, "i32");
5233
+ this.releaseTemp(c1Tmp, "i32");
5234
+ this.pushInstruction("end"); // idx + 2 < len
5235
+ this.pushInstruction("end"); // c == 0xC2 else
5236
+ this.pushInstruction("end"); // c == 32 else
5237
+ this.releaseTemp(cTmp, "i32");
5238
+ }
5239
+
4016
5240
  _emitInternalBytesFields(bTmp) {
4017
5241
  const byteGo = { kind: "basic", name: "byte" };
4018
5242
  const sliceInfo = this.mod.getSliceType(byteGo);
@@ -4062,31 +5286,17 @@ export class BytesEmitter {
4062
5286
  this.pushInstruction("i32.ge_s");
4063
5287
  this.pushInstruction({ op: "br_if", depth: 1 });
4064
5288
 
4065
- const cTmp = this.acquireTemp("i32");
4066
- this.pushInstruction({ op: "local.get", index: bArr });
4067
- this.pushInstruction({ op: "local.get", index: bOff });
4068
- this.pushInstruction({ op: "local.get", index: iTmp });
4069
- this.pushInstruction("i32.add");
4070
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
4071
- this.pushInstruction({ op: "local.set", index: cTmp });
4072
-
4073
- // isSp: c == 32 || (c >= 9 && c <= 13)
4074
5289
  const isSpTmp = this.acquireTemp("i32");
4075
- this.pushInstruction({ op: "local.get", index: cTmp });
4076
- this.pushInstruction({ op: "i32.const", value: 32 });
4077
- this.pushInstruction("i32.eq");
4078
- this.pushInstruction({ op: "local.get", index: cTmp });
4079
- this.pushInstruction({ op: "i32.const", value: 9 });
4080
- this.pushInstruction("i32.sub");
4081
- this.pushInstruction({ op: "i32.const", value: 4 });
4082
- this.pushInstruction("i32.le_u");
4083
- this.pushInstruction("i32.or");
4084
- this.pushInstruction({ op: "local.set", index: isSpTmp });
5290
+ this._emitIsSpaceAt(bArr, bOff, iTmp, bLen, isSpTmp, arrInfo);
4085
5291
 
4086
5292
  this.pushInstruction({ op: "local.get", index: isSpTmp });
4087
5293
  this.pushInstruction({ op: "if", blockType: "void" });
4088
5294
  this.pushInstruction({ op: "i32.const", value: 0 });
4089
5295
  this.pushInstruction({ op: "local.set", index: inWordTmp });
5296
+ this.pushInstruction({ op: "local.get", index: iTmp });
5297
+ this.pushInstruction({ op: "local.get", index: isSpTmp });
5298
+ this.pushInstruction("i32.add");
5299
+ this.pushInstruction({ op: "local.set", index: iTmp });
4090
5300
  this.pushInstruction("else");
4091
5301
  this.pushInstruction({ op: "local.get", index: inWordTmp });
4092
5302
  this.pushInstruction("i32.eqz");
@@ -4098,15 +5308,14 @@ export class BytesEmitter {
4098
5308
  this.pushInstruction({ op: "i32.const", value: 1 });
4099
5309
  this.pushInstruction({ op: "local.set", index: inWordTmp });
4100
5310
  this.pushInstruction("end");
4101
- this.pushInstruction("end");
4102
-
4103
- this.releaseTemp(isSpTmp, "i32");
4104
- this.releaseTemp(cTmp, "i32");
4105
-
4106
5311
  this.pushInstruction({ op: "local.get", index: iTmp });
4107
5312
  this.pushInstruction({ op: "i32.const", value: 1 });
4108
5313
  this.pushInstruction("i32.add");
4109
5314
  this.pushInstruction({ op: "local.set", index: iTmp });
5315
+ this.pushInstruction("end");
5316
+
5317
+ this.releaseTemp(isSpTmp, "i32");
5318
+
4110
5319
  this.pushInstruction({ op: "br", depth: 0 });
4111
5320
  this.pushInstruction("end");
4112
5321
  this.pushInstruction("end");
@@ -4152,25 +5361,8 @@ export class BytesEmitter {
4152
5361
  this.pushInstruction("i32.ge_s");
4153
5362
  this.pushInstruction({ op: "br_if", depth: 1 });
4154
5363
 
4155
- const c2Tmp = this.acquireTemp("i32");
4156
- this.pushInstruction({ op: "local.get", index: bArr });
4157
- this.pushInstruction({ op: "local.get", index: bOff });
4158
- this.pushInstruction({ op: "local.get", index: kTmp });
4159
- this.pushInstruction("i32.add");
4160
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
4161
- this.pushInstruction({ op: "local.set", index: c2Tmp });
4162
-
4163
5364
  const isSp2Tmp = this.acquireTemp("i32");
4164
- this.pushInstruction({ op: "local.get", index: c2Tmp });
4165
- this.pushInstruction({ op: "i32.const", value: 32 });
4166
- this.pushInstruction("i32.eq");
4167
- this.pushInstruction({ op: "local.get", index: c2Tmp });
4168
- this.pushInstruction({ op: "i32.const", value: 9 });
4169
- this.pushInstruction("i32.sub");
4170
- this.pushInstruction({ op: "i32.const", value: 4 });
4171
- this.pushInstruction("i32.le_u");
4172
- this.pushInstruction("i32.or");
4173
- this.pushInstruction({ op: "local.set", index: isSp2Tmp });
5365
+ this._emitIsSpaceAt(bArr, bOff, kTmp, bLen, isSp2Tmp, arrInfo);
4174
5366
 
4175
5367
  this.pushInstruction({ op: "local.get", index: isSp2Tmp });
4176
5368
  this.pushInstruction({ op: "if", blockType: "void" });
@@ -4204,6 +5396,10 @@ export class BytesEmitter {
4204
5396
  this.pushInstruction({ op: "i32.const", value: 0 });
4205
5397
  this.pushInstruction({ op: "local.set", index: inWordTmp });
4206
5398
  this.pushInstruction("end");
5399
+ this.pushInstruction({ op: "local.get", index: kTmp });
5400
+ this.pushInstruction({ op: "local.get", index: isSp2Tmp });
5401
+ this.pushInstruction("i32.add");
5402
+ this.pushInstruction({ op: "local.set", index: kTmp });
4207
5403
  this.pushInstruction("else");
4208
5404
  this.pushInstruction({ op: "local.get", index: inWordTmp });
4209
5405
  this.pushInstruction("i32.eqz");
@@ -4213,15 +5409,14 @@ export class BytesEmitter {
4213
5409
  this.pushInstruction({ op: "i32.const", value: 1 });
4214
5410
  this.pushInstruction({ op: "local.set", index: inWordTmp });
4215
5411
  this.pushInstruction("end");
4216
- this.pushInstruction("end");
4217
-
4218
- this.releaseTemp(isSp2Tmp, "i32");
4219
- this.releaseTemp(c2Tmp, "i32");
4220
-
4221
5412
  this.pushInstruction({ op: "local.get", index: kTmp });
4222
5413
  this.pushInstruction({ op: "i32.const", value: 1 });
4223
5414
  this.pushInstruction("i32.add");
4224
5415
  this.pushInstruction({ op: "local.set", index: kTmp });
5416
+ this.pushInstruction("end");
5417
+
5418
+ this.releaseTemp(isSp2Tmp, "i32");
5419
+
4225
5420
  this.pushInstruction({ op: "br", depth: 0 });
4226
5421
  this.pushInstruction("end");
4227
5422
  this.pushInstruction("end");
@@ -5036,4 +6231,486 @@ export class BytesEmitter {
5036
6231
  this.pushInstruction("end");
5037
6232
  this.releaseTemp(b0Tmp, "i32");
5038
6233
  }
6234
+
6235
+ _emitBytesToValidUTF8(args, _targetWasmType) {
6236
+ const byteGo = { kind: "basic", name: "byte" };
6237
+ const sliceInfo = this.mod.getSliceType(byteGo);
6238
+ const arrInfo = sliceInfo.arrInfo;
6239
+ const sliceW = {
6240
+ kind: "ref",
6241
+ nullable: true,
6242
+ typeIndex: sliceInfo.typeIndex,
6243
+ };
6244
+ const arrW = { kind: "ref", nullable: true, typeIndex: arrInfo.typeIndex };
6245
+
6246
+ const bTmp = this.acquireTemp(sliceW);
6247
+ const replTmp = this.acquireTemp(sliceW);
6248
+ this.emitExpr(args[0], sliceW);
6249
+ this.pushInstruction({ op: "local.set", index: bTmp });
6250
+ this.emitExpr(args[1], sliceW);
6251
+ this.pushInstruction({ op: "local.set", index: replTmp });
6252
+
6253
+ const bArr = this.acquireTemp(arrW),
6254
+ bOff = this.acquireTemp("i32"),
6255
+ bLen = this.acquireTemp("i32");
6256
+ const replArr = this.acquireTemp(arrW),
6257
+ replOff = this.acquireTemp("i32"),
6258
+ replLen = this.acquireTemp("i32");
6259
+
6260
+ this._emitSliceUnpack(bTmp, sliceInfo, {
6261
+ arr: bArr,
6262
+ off: bOff,
6263
+ len: bLen,
6264
+ });
6265
+ this._emitSliceUnpack(replTmp, sliceInfo, {
6266
+ arr: replArr,
6267
+ off: replOff,
6268
+ len: replLen,
6269
+ });
6270
+
6271
+ // Pass 1: compute outLen
6272
+ const outLenTmp = this.acquireTemp("i32");
6273
+ const inInvalidTmp = this.acquireTemp("i32");
6274
+ const iTmp = this.acquireTemp("i32");
6275
+ const b0Tmp = this.acquireTemp("i32");
6276
+ const szTmp = this.acquireTemp("i32");
6277
+ const validTmp = this.acquireTemp("i32");
6278
+ const b1Tmp = this.acquireTemp("i32");
6279
+ const b2Tmp = this.acquireTemp("i32");
6280
+ const b3Tmp = this.acquireTemp("i32");
6281
+ const rTmp = this.acquireTemp("i32");
6282
+
6283
+ this.pushInstruction({ op: "i32.const", value: 0 });
6284
+ this.pushInstruction({ op: "local.set", index: outLenTmp });
6285
+ this.pushInstruction({ op: "i32.const", value: 0 });
6286
+ this.pushInstruction({ op: "local.set", index: inInvalidTmp });
6287
+ this.pushInstruction({ op: "i32.const", value: 0 });
6288
+ this.pushInstruction({ op: "local.set", index: iTmp });
6289
+
6290
+ const emitValidateStep = () => {
6291
+ this.pushInstruction({ op: "i32.const", value: 0 });
6292
+ this.pushInstruction({ op: "local.set", index: szTmp });
6293
+ this.pushInstruction({ op: "i32.const", value: 0 });
6294
+ this.pushInstruction({ op: "local.set", index: validTmp });
6295
+
6296
+ this.pushInstruction({ op: "local.get", index: bArr });
6297
+ this.pushInstruction({ op: "local.get", index: bOff });
6298
+ this.pushInstruction({ op: "local.get", index: iTmp });
6299
+ this.pushInstruction("i32.add");
6300
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
6301
+ this.pushInstruction({ op: "local.set", index: b0Tmp });
6302
+
6303
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6304
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
6305
+ this.pushInstruction("i32.lt_u");
6306
+ this.pushInstruction({ op: "if", blockType: "void" });
6307
+ this.pushInstruction({ op: "i32.const", value: 1 });
6308
+ this.pushInstruction({ op: "local.set", index: szTmp });
6309
+ this.pushInstruction({ op: "i32.const", value: 1 });
6310
+ this.pushInstruction({ op: "local.set", index: validTmp });
6311
+ this.pushInstruction("else");
6312
+
6313
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6314
+ this.pushInstruction({ op: "i32.const", value: 0xc2 });
6315
+ this.pushInstruction("i32.ge_u");
6316
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6317
+ this.pushInstruction({ op: "i32.const", value: 0xdf });
6318
+ this.pushInstruction("i32.le_u");
6319
+ this.pushInstruction("i32.and");
6320
+ this.pushInstruction({ op: "if", blockType: "void" });
6321
+ this.pushInstruction({ op: "local.get", index: iTmp });
6322
+ this.pushInstruction({ op: "i32.const", value: 1 });
6323
+ this.pushInstruction("i32.add");
6324
+ this.pushInstruction({ op: "local.get", index: bLen });
6325
+ this.pushInstruction("i32.lt_s");
6326
+ this.pushInstruction({ op: "if", blockType: "void" });
6327
+ this.pushInstruction({ op: "local.get", index: bArr });
6328
+ this.pushInstruction({ op: "local.get", index: bOff });
6329
+ this.pushInstruction({ op: "local.get", index: iTmp });
6330
+ this.pushInstruction("i32.add");
6331
+ this.pushInstruction({ op: "i32.const", value: 1 });
6332
+ this.pushInstruction("i32.add");
6333
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
6334
+ this.pushInstruction({ op: "i32.const", value: 0xc0 });
6335
+ this.pushInstruction("i32.and");
6336
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
6337
+ this.pushInstruction("i32.eq");
6338
+ this.pushInstruction({ op: "if", blockType: "void" });
6339
+ this.pushInstruction({ op: "i32.const", value: 2 });
6340
+ this.pushInstruction({ op: "local.set", index: szTmp });
6341
+ this.pushInstruction({ op: "i32.const", value: 1 });
6342
+ this.pushInstruction({ op: "local.set", index: validTmp });
6343
+ this.pushInstruction("end");
6344
+ this.pushInstruction("end");
6345
+ this.pushInstruction("else");
6346
+
6347
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6348
+ this.pushInstruction({ op: "i32.const", value: 0xe0 });
6349
+ this.pushInstruction("i32.ge_u");
6350
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6351
+ this.pushInstruction({ op: "i32.const", value: 0xef });
6352
+ this.pushInstruction("i32.le_u");
6353
+ this.pushInstruction("i32.and");
6354
+ this.pushInstruction({ op: "if", blockType: "void" });
6355
+ this.pushInstruction({ op: "local.get", index: iTmp });
6356
+ this.pushInstruction({ op: "i32.const", value: 2 });
6357
+ this.pushInstruction("i32.add");
6358
+ this.pushInstruction({ op: "local.get", index: bLen });
6359
+ this.pushInstruction("i32.lt_s");
6360
+ this.pushInstruction({ op: "if", blockType: "void" });
6361
+ this.pushInstruction({ op: "local.get", index: bArr });
6362
+ this.pushInstruction({ op: "local.get", index: bOff });
6363
+ this.pushInstruction({ op: "local.get", index: iTmp });
6364
+ this.pushInstruction("i32.add");
6365
+ this.pushInstruction({ op: "i32.const", value: 1 });
6366
+ this.pushInstruction("i32.add");
6367
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
6368
+ this.pushInstruction({ op: "local.set", index: b1Tmp });
6369
+
6370
+ this.pushInstruction({ op: "local.get", index: bArr });
6371
+ this.pushInstruction({ op: "local.get", index: bOff });
6372
+ this.pushInstruction({ op: "local.get", index: iTmp });
6373
+ this.pushInstruction("i32.add");
6374
+ this.pushInstruction({ op: "i32.const", value: 2 });
6375
+ this.pushInstruction("i32.add");
6376
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
6377
+ this.pushInstruction({ op: "local.set", index: b2Tmp });
6378
+
6379
+ this.pushInstruction({ op: "local.get", index: b1Tmp });
6380
+ this.pushInstruction({ op: "i32.const", value: 0xc0 });
6381
+ this.pushInstruction("i32.and");
6382
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
6383
+ this.pushInstruction("i32.eq");
6384
+ this.pushInstruction({ op: "local.get", index: b2Tmp });
6385
+ this.pushInstruction({ op: "i32.const", value: 0xc0 });
6386
+ this.pushInstruction("i32.and");
6387
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
6388
+ this.pushInstruction("i32.eq");
6389
+ this.pushInstruction("i32.and");
6390
+ this.pushInstruction({ op: "if", blockType: "void" });
6391
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6392
+ this.pushInstruction({ op: "i32.const", value: 0x0f });
6393
+ this.pushInstruction("i32.and");
6394
+ this.pushInstruction({ op: "i32.const", value: 12 });
6395
+ this.pushInstruction("i32.shl");
6396
+ this.pushInstruction({ op: "local.get", index: b1Tmp });
6397
+ this.pushInstruction({ op: "i32.const", value: 0x3f });
6398
+ this.pushInstruction("i32.and");
6399
+ this.pushInstruction({ op: "i32.const", value: 6 });
6400
+ this.pushInstruction("i32.shl");
6401
+ this.pushInstruction("i32.or");
6402
+ this.pushInstruction({ op: "local.get", index: b2Tmp });
6403
+ this.pushInstruction({ op: "i32.const", value: 0x3f });
6404
+ this.pushInstruction("i32.and");
6405
+ this.pushInstruction("i32.or");
6406
+ this.pushInstruction({ op: "local.set", index: rTmp });
6407
+
6408
+ this.pushInstruction({ op: "local.get", index: rTmp });
6409
+ this.pushInstruction({ op: "i32.const", value: 0x800 });
6410
+ this.pushInstruction("i32.ge_u");
6411
+ this.pushInstruction({ op: "local.get", index: rTmp });
6412
+ this.pushInstruction({ op: "i32.const", value: 0xd800 });
6413
+ this.pushInstruction("i32.lt_u");
6414
+ this.pushInstruction({ op: "local.get", index: rTmp });
6415
+ this.pushInstruction({ op: "i32.const", value: 0xdfff });
6416
+ this.pushInstruction("i32.gt_u");
6417
+ this.pushInstruction("i32.or");
6418
+ this.pushInstruction("i32.and");
6419
+ this.pushInstruction({ op: "if", blockType: "void" });
6420
+ this.pushInstruction({ op: "i32.const", value: 3 });
6421
+ this.pushInstruction({ op: "local.set", index: szTmp });
6422
+ this.pushInstruction({ op: "i32.const", value: 1 });
6423
+ this.pushInstruction({ op: "local.set", index: validTmp });
6424
+ this.pushInstruction("end");
6425
+ this.pushInstruction("end");
6426
+ this.pushInstruction("end");
6427
+ this.pushInstruction("else");
6428
+
6429
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6430
+ this.pushInstruction({ op: "i32.const", value: 0xf0 });
6431
+ this.pushInstruction("i32.ge_u");
6432
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6433
+ this.pushInstruction({ op: "i32.const", value: 0xf4 });
6434
+ this.pushInstruction("i32.le_u");
6435
+ this.pushInstruction("i32.and");
6436
+ this.pushInstruction({ op: "if", blockType: "void" });
6437
+ this.pushInstruction({ op: "local.get", index: iTmp });
6438
+ this.pushInstruction({ op: "i32.const", value: 3 });
6439
+ this.pushInstruction("i32.add");
6440
+ this.pushInstruction({ op: "local.get", index: bLen });
6441
+ this.pushInstruction("i32.lt_s");
6442
+ this.pushInstruction({ op: "if", blockType: "void" });
6443
+ this.pushInstruction({ op: "local.get", index: bArr });
6444
+ this.pushInstruction({ op: "local.get", index: bOff });
6445
+ this.pushInstruction({ op: "local.get", index: iTmp });
6446
+ this.pushInstruction("i32.add");
6447
+ this.pushInstruction({ op: "i32.const", value: 1 });
6448
+ this.pushInstruction("i32.add");
6449
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
6450
+ this.pushInstruction({ op: "local.set", index: b1Tmp });
6451
+
6452
+ this.pushInstruction({ op: "local.get", index: bArr });
6453
+ this.pushInstruction({ op: "local.get", index: bOff });
6454
+ this.pushInstruction({ op: "local.get", index: iTmp });
6455
+ this.pushInstruction("i32.add");
6456
+ this.pushInstruction({ op: "i32.const", value: 2 });
6457
+ this.pushInstruction("i32.add");
6458
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
6459
+ this.pushInstruction({ op: "local.set", index: b2Tmp });
6460
+
6461
+ this.pushInstruction({ op: "local.get", index: bArr });
6462
+ this.pushInstruction({ op: "local.get", index: bOff });
6463
+ this.pushInstruction({ op: "local.get", index: iTmp });
6464
+ this.pushInstruction("i32.add");
6465
+ this.pushInstruction({ op: "i32.const", value: 3 });
6466
+ this.pushInstruction("i32.add");
6467
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
6468
+ this.pushInstruction({ op: "local.set", index: b3Tmp });
6469
+
6470
+ this.pushInstruction({ op: "local.get", index: b1Tmp });
6471
+ this.pushInstruction({ op: "i32.const", value: 0xc0 });
6472
+ this.pushInstruction("i32.and");
6473
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
6474
+ this.pushInstruction("i32.eq");
6475
+ this.pushInstruction({ op: "local.get", index: b2Tmp });
6476
+ this.pushInstruction({ op: "i32.const", value: 0xc0 });
6477
+ this.pushInstruction("i32.and");
6478
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
6479
+ this.pushInstruction("i32.eq");
6480
+ this.pushInstruction("i32.and");
6481
+ this.pushInstruction({ op: "local.get", index: b3Tmp });
6482
+ this.pushInstruction({ op: "i32.const", value: 0xc0 });
6483
+ this.pushInstruction("i32.and");
6484
+ this.pushInstruction({ op: "i32.const", value: 0x80 });
6485
+ this.pushInstruction("i32.eq");
6486
+ this.pushInstruction("i32.and");
6487
+ this.pushInstruction({ op: "if", blockType: "void" });
6488
+ this.pushInstruction({ op: "local.get", index: b0Tmp });
6489
+ this.pushInstruction({ op: "i32.const", value: 0x07 });
6490
+ this.pushInstruction("i32.and");
6491
+ this.pushInstruction({ op: "i32.const", value: 18 });
6492
+ this.pushInstruction("i32.shl");
6493
+ this.pushInstruction({ op: "local.get", index: b1Tmp });
6494
+ this.pushInstruction({ op: "i32.const", value: 0x3f });
6495
+ this.pushInstruction("i32.and");
6496
+ this.pushInstruction({ op: "i32.const", value: 12 });
6497
+ this.pushInstruction("i32.shl");
6498
+ this.pushInstruction("i32.or");
6499
+ this.pushInstruction({ op: "local.get", index: b2Tmp });
6500
+ this.pushInstruction({ op: "i32.const", value: 0x3f });
6501
+ this.pushInstruction("i32.and");
6502
+ this.pushInstruction({ op: "i32.const", value: 6 });
6503
+ this.pushInstruction("i32.shl");
6504
+ this.pushInstruction("i32.or");
6505
+ this.pushInstruction({ op: "local.get", index: b3Tmp });
6506
+ this.pushInstruction({ op: "i32.const", value: 0x3f });
6507
+ this.pushInstruction("i32.and");
6508
+ this.pushInstruction("i32.or");
6509
+ this.pushInstruction({ op: "local.set", index: rTmp });
6510
+
6511
+ this.pushInstruction({ op: "local.get", index: rTmp });
6512
+ this.pushInstruction({ op: "i32.const", value: 0x10000 });
6513
+ this.pushInstruction("i32.ge_u");
6514
+ this.pushInstruction({ op: "local.get", index: rTmp });
6515
+ this.pushInstruction({ op: "i32.const", value: 0x10ffff });
6516
+ this.pushInstruction("i32.le_u");
6517
+ this.pushInstruction("i32.and");
6518
+ this.pushInstruction({ op: "if", blockType: "void" });
6519
+ this.pushInstruction({ op: "i32.const", value: 4 });
6520
+ this.pushInstruction({ op: "local.set", index: szTmp });
6521
+ this.pushInstruction({ op: "i32.const", value: 1 });
6522
+ this.pushInstruction({ op: "local.set", index: validTmp });
6523
+ this.pushInstruction("end");
6524
+ this.pushInstruction("end");
6525
+ this.pushInstruction("end");
6526
+ this.pushInstruction("end");
6527
+ this.pushInstruction("end");
6528
+ this.pushInstruction("end");
6529
+ this.pushInstruction("end");
6530
+ };
6531
+
6532
+ this.pushInstruction({ op: "block", blockType: "void" });
6533
+ this.pushInstruction({ op: "loop", blockType: "void" });
6534
+ this.pushInstruction({ op: "local.get", index: iTmp });
6535
+ this.pushInstruction({ op: "local.get", index: bLen });
6536
+ this.pushInstruction("i32.ge_s");
6537
+ this.pushInstruction({ op: "br_if", depth: 1 });
6538
+
6539
+ emitValidateStep();
6540
+
6541
+ this.pushInstruction({ op: "local.get", index: validTmp });
6542
+ this.pushInstruction({ op: "if", blockType: "void" });
6543
+
6544
+ this.pushInstruction({ op: "local.get", index: inInvalidTmp });
6545
+ this.pushInstruction({ op: "if", blockType: "void" });
6546
+ this.pushInstruction({ op: "local.get", index: outLenTmp });
6547
+ this.pushInstruction({ op: "local.get", index: replLen });
6548
+ this.pushInstruction("i32.add");
6549
+ this.pushInstruction({ op: "local.set", index: outLenTmp });
6550
+ this.pushInstruction({ op: "i32.const", value: 0 });
6551
+ this.pushInstruction({ op: "local.set", index: inInvalidTmp });
6552
+ this.pushInstruction("end");
6553
+
6554
+ this.pushInstruction({ op: "local.get", index: outLenTmp });
6555
+ this.pushInstruction({ op: "local.get", index: szTmp });
6556
+ this.pushInstruction("i32.add");
6557
+ this.pushInstruction({ op: "local.set", index: outLenTmp });
6558
+
6559
+ this.pushInstruction({ op: "local.get", index: iTmp });
6560
+ this.pushInstruction({ op: "local.get", index: szTmp });
6561
+ this.pushInstruction("i32.add");
6562
+ this.pushInstruction({ op: "local.set", index: iTmp });
6563
+
6564
+ this.pushInstruction("else");
6565
+
6566
+ this.pushInstruction({ op: "i32.const", value: 1 });
6567
+ this.pushInstruction({ op: "local.set", index: inInvalidTmp });
6568
+ this.pushInstruction({ op: "local.get", index: iTmp });
6569
+ this.pushInstruction({ op: "i32.const", value: 1 });
6570
+ this.pushInstruction("i32.add");
6571
+ this.pushInstruction({ op: "local.set", index: iTmp });
6572
+
6573
+ this.pushInstruction("end");
6574
+
6575
+ this.pushInstruction({ op: "br", depth: 0 });
6576
+ this.pushInstruction("end");
6577
+ this.pushInstruction("end");
6578
+
6579
+ this.pushInstruction({ op: "local.get", index: inInvalidTmp });
6580
+ this.pushInstruction({ op: "if", blockType: "void" });
6581
+ this.pushInstruction({ op: "local.get", index: outLenTmp });
6582
+ this.pushInstruction({ op: "local.get", index: replLen });
6583
+ this.pushInstruction("i32.add");
6584
+ this.pushInstruction({ op: "local.set", index: outLenTmp });
6585
+ this.pushInstruction("end");
6586
+
6587
+ const resArrTmp = this.acquireTemp(arrW);
6588
+ this.pushInstruction({ op: "local.get", index: outLenTmp });
6589
+ this.pushInstruction({
6590
+ op: "array.new_default",
6591
+ typeIndex: arrInfo.typeIndex,
6592
+ });
6593
+ this.pushInstruction({ op: "local.set", index: resArrTmp });
6594
+
6595
+ const dstTmp = this.acquireTemp("i32");
6596
+ this.pushInstruction({ op: "i32.const", value: 0 });
6597
+ this.pushInstruction({ op: "local.set", index: dstTmp });
6598
+ this.pushInstruction({ op: "i32.const", value: 0 });
6599
+ this.pushInstruction({ op: "local.set", index: inInvalidTmp });
6600
+ this.pushInstruction({ op: "i32.const", value: 0 });
6601
+ this.pushInstruction({ op: "local.set", index: iTmp });
6602
+
6603
+ this.pushInstruction({ op: "block", blockType: "void" });
6604
+ this.pushInstruction({ op: "loop", blockType: "void" });
6605
+ this.pushInstruction({ op: "local.get", index: iTmp });
6606
+ this.pushInstruction({ op: "local.get", index: bLen });
6607
+ this.pushInstruction("i32.ge_s");
6608
+ this.pushInstruction({ op: "br_if", depth: 1 });
6609
+
6610
+ emitValidateStep();
6611
+
6612
+ this.pushInstruction({ op: "local.get", index: validTmp });
6613
+ this.pushInstruction({ op: "if", blockType: "void" });
6614
+
6615
+ this.pushInstruction({ op: "local.get", index: inInvalidTmp });
6616
+ this.pushInstruction({ op: "if", blockType: "void" });
6617
+ this.pushInstruction({ op: "local.get", index: replLen });
6618
+ this.pushInstruction({ op: "i32.const", value: 0 });
6619
+ this.pushInstruction("i32.gt_s");
6620
+ this.pushInstruction({ op: "if", blockType: "void" });
6621
+ this.pushInstruction({ op: "local.get", index: resArrTmp });
6622
+ this.pushInstruction({ op: "local.get", index: dstTmp });
6623
+ this.pushInstruction({ op: "local.get", index: replArr });
6624
+ this.pushInstruction({ op: "local.get", index: replOff });
6625
+ this.pushInstruction({ op: "local.get", index: replLen });
6626
+ this._emitArrayCopy(arrInfo, byteGo);
6627
+ this.pushInstruction("end");
6628
+ this.pushInstruction({ op: "local.get", index: dstTmp });
6629
+ this.pushInstruction({ op: "local.get", index: replLen });
6630
+ this.pushInstruction("i32.add");
6631
+ this.pushInstruction({ op: "local.set", index: dstTmp });
6632
+ this.pushInstruction({ op: "i32.const", value: 0 });
6633
+ this.pushInstruction({ op: "local.set", index: inInvalidTmp });
6634
+ this.pushInstruction("end");
6635
+
6636
+ this.pushInstruction({ op: "local.get", index: resArrTmp });
6637
+ this.pushInstruction({ op: "local.get", index: dstTmp });
6638
+ this.pushInstruction({ op: "local.get", index: bArr });
6639
+ this.pushInstruction({ op: "local.get", index: bOff });
6640
+ this.pushInstruction({ op: "local.get", index: iTmp });
6641
+ this.pushInstruction("i32.add");
6642
+ this.pushInstruction({ op: "local.get", index: szTmp });
6643
+ this._emitArrayCopy(arrInfo, byteGo);
6644
+
6645
+ this.pushInstruction({ op: "local.get", index: dstTmp });
6646
+ this.pushInstruction({ op: "local.get", index: szTmp });
6647
+ this.pushInstruction("i32.add");
6648
+ this.pushInstruction({ op: "local.set", index: dstTmp });
6649
+
6650
+ this.pushInstruction({ op: "local.get", index: iTmp });
6651
+ this.pushInstruction({ op: "local.get", index: szTmp });
6652
+ this.pushInstruction("i32.add");
6653
+ this.pushInstruction({ op: "local.set", index: iTmp });
6654
+
6655
+ this.pushInstruction("else");
6656
+
6657
+ this.pushInstruction({ op: "i32.const", value: 1 });
6658
+ this.pushInstruction({ op: "local.set", index: inInvalidTmp });
6659
+ this.pushInstruction({ op: "local.get", index: iTmp });
6660
+ this.pushInstruction({ op: "i32.const", value: 1 });
6661
+ this.pushInstruction("i32.add");
6662
+ this.pushInstruction({ op: "local.set", index: iTmp });
6663
+
6664
+ this.pushInstruction("end");
6665
+
6666
+ this.pushInstruction({ op: "br", depth: 0 });
6667
+ this.pushInstruction("end");
6668
+ this.pushInstruction("end");
6669
+
6670
+ this.pushInstruction({ op: "local.get", index: inInvalidTmp });
6671
+ this.pushInstruction({ op: "if", blockType: "void" });
6672
+ this.pushInstruction({ op: "local.get", index: replLen });
6673
+ this.pushInstruction({ op: "i32.const", value: 0 });
6674
+ this.pushInstruction("i32.gt_s");
6675
+ this.pushInstruction({ op: "if", blockType: "void" });
6676
+ this.pushInstruction({ op: "local.get", index: resArrTmp });
6677
+ this.pushInstruction({ op: "local.get", index: dstTmp });
6678
+ this.pushInstruction({ op: "local.get", index: replArr });
6679
+ this.pushInstruction({ op: "local.get", index: replOff });
6680
+ this.pushInstruction({ op: "local.get", index: replLen });
6681
+ this._emitArrayCopy(arrInfo, byteGo);
6682
+ this.pushInstruction("end");
6683
+ this.pushInstruction("end");
6684
+
6685
+ this.pushInstruction({ op: "local.get", index: resArrTmp });
6686
+ this.pushInstruction({ op: "i32.const", value: 0 });
6687
+ this.pushInstruction({ op: "local.get", index: outLenTmp });
6688
+ this.pushInstruction({ op: "local.get", index: outLenTmp });
6689
+ this.pushInstruction({
6690
+ op: "struct.new",
6691
+ typeIndex: sliceInfo.typeIndex,
6692
+ });
6693
+
6694
+ this.releaseTemp(dstTmp, "i32");
6695
+ this.releaseTemp(resArrTmp, arrW);
6696
+ this.releaseTemp(rTmp, "i32");
6697
+ this.releaseTemp(b3Tmp, "i32");
6698
+ this.releaseTemp(b2Tmp, "i32");
6699
+ this.releaseTemp(b1Tmp, "i32");
6700
+ this.releaseTemp(validTmp, "i32");
6701
+ this.releaseTemp(szTmp, "i32");
6702
+ this.releaseTemp(b0Tmp, "i32");
6703
+ this.releaseTemp(iTmp, "i32");
6704
+ this.releaseTemp(inInvalidTmp, "i32");
6705
+ this.releaseTemp(outLenTmp, "i32");
6706
+
6707
+ this.releaseTemp(replLen, "i32");
6708
+ this.releaseTemp(replOff, "i32");
6709
+ this.releaseTemp(replArr, arrW);
6710
+ this.releaseTemp(bLen, "i32");
6711
+ this.releaseTemp(bOff, "i32");
6712
+ this.releaseTemp(bArr, arrW);
6713
+ this.releaseTemp(replTmp, sliceW);
6714
+ this.releaseTemp(bTmp, sliceW);
6715
+ }
5039
6716
  }