gofront 1.7.0 → 1.9.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 (194) hide show
  1. package/README.md +14 -14
  2. package/package.json +10 -38
  3. package/src/backend/js/expressions.js +2060 -389
  4. package/src/backend/js/index.js +586 -174
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +936 -1644
  7. package/src/backend/js/statements.js +1349 -132
  8. package/src/backend/js/stdlib/index.js +51 -94
  9. package/src/backend/js/templ.js +67 -118
  10. package/src/backend/js/type-info.js +436 -0
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +80 -0
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +753 -872
  15. package/src/backend/wasm/emit-builtins.js +914 -237
  16. package/src/backend/wasm/emit-exprs.js +1456 -195
  17. package/src/backend/wasm/emit-maps.js +78 -380
  18. package/src/backend/wasm/emit-stmts.js +1659 -214
  19. package/src/backend/wasm/emit.js +614 -88
  20. package/src/backend/wasm/encode.js +43 -13
  21. package/src/backend/wasm/globals.js +491 -0
  22. package/src/backend/wasm/glue.js +2 -4
  23. package/src/backend/wasm/index.js +406 -3195
  24. package/src/backend/wasm/method-expr.js +392 -0
  25. package/src/backend/wasm/module-emitter.js +1615 -0
  26. package/src/backend/wasm/monomorph.js +164 -9
  27. package/src/backend/wasm/natives.js +596 -0
  28. package/src/backend/wasm/prescan.js +249 -0
  29. package/src/backend/wasm/prune-funcs.js +89 -0
  30. package/src/backend/wasm/stdlib/index.js +2 -37
  31. package/src/backend/wasm/stdlib/simd.js +293 -28
  32. package/src/backend/wasm/types.js +260 -27
  33. package/src/backend/wasm/variadic.js +93 -0
  34. package/src/backend/wasm/wat.js +47 -20
  35. package/src/{cli-core.js → cli/cli-core.js} +241 -11
  36. package/src/{test-runner.js → cli/test-runner.js} +188 -122
  37. package/src/{vendor.js → cli/vendor.js} +3 -4
  38. package/src/compiler.js +202 -386
  39. package/src/index.js +15 -169
  40. package/src/{lexer.js → lexer/lexer.js} +203 -62
  41. package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
  42. package/src/{tokens.js → lexer/tokens.js} +2 -0
  43. package/src/link/sourcemap.js +97 -0
  44. package/src/link/stdlib.js +737 -0
  45. package/src/link/type-names.js +148 -0
  46. package/src/link/wasm.js +318 -0
  47. package/src/lower/bounds.js +547 -0
  48. package/src/lower/boxing.js +1 -1
  49. package/src/lower/captures.js +267 -64
  50. package/src/lower/embedding.js +32 -3
  51. package/src/lower/errors-as.js +196 -0
  52. package/src/lower/fmt-formatters.js +905 -0
  53. package/src/lower/functions.js +2 -0
  54. package/src/lower/gen-types.js +274 -0
  55. package/src/lower/index.js +33 -19
  56. package/src/lower/json-codecs.js +1379 -0
  57. package/src/lower/ownership.js +47 -8
  58. package/src/lower/range.js +86 -1
  59. package/src/lower/reachability.js +150 -0
  60. package/src/lower/walk.js +12 -0
  61. package/src/parser/declarations.js +83 -15
  62. package/src/parser/expressions.js +110 -18
  63. package/src/parser/index.js +2 -1
  64. package/src/parser/statements.js +38 -22
  65. package/src/{templ-parser.js → parser/templ.js} +179 -17
  66. package/src/parser/types.js +70 -9
  67. package/src/resolver.js +21 -1
  68. package/src/typechecker/assignability.js +291 -19
  69. package/src/typechecker/const-fold.js +399 -0
  70. package/src/typechecker/constants.js +282 -0
  71. package/src/typechecker/expressions.js +1220 -183
  72. package/src/typechecker/index.js +659 -92
  73. package/src/typechecker/init-order.js +426 -0
  74. package/src/typechecker/operand-text.js +40 -0
  75. package/src/typechecker/resolve.js +613 -62
  76. package/src/typechecker/statements.js +212 -20
  77. package/src/typechecker/stdlib/excluded.js +902 -0
  78. package/src/typechecker/stdlib/index.js +38 -0
  79. package/src/typechecker/stdlib/simd.js +65 -15
  80. package/src/typechecker/termination.js +11 -2
  81. package/src/typechecker/types.js +268 -514
  82. package/stdlib/bytes/buffer.go +479 -0
  83. package/stdlib/bytes/bytes.go +1010 -0
  84. package/stdlib/bytes/reader.go +161 -0
  85. package/stdlib/cmp/cmp.go +65 -0
  86. package/stdlib/context/context.go +115 -0
  87. package/stdlib/crypto/rand/rand.go +34 -0
  88. package/stdlib/crypto/sha256/sha256.go +249 -0
  89. package/stdlib/encoding/base64/base64.go +331 -0
  90. package/stdlib/encoding/binary/binary.go +332 -0
  91. package/stdlib/encoding/hex/hex.go +140 -0
  92. package/stdlib/encoding/json/errors.go +31 -0
  93. package/stdlib/encoding/json/indent.go +71 -0
  94. package/stdlib/encoding/json/json.go +62 -0
  95. package/stdlib/encoding/json/number.go +12 -0
  96. package/stdlib/encoding/json/stream.go +173 -0
  97. package/stdlib/errors/errors.go +174 -0
  98. package/stdlib/fmt/errors.go +110 -0
  99. package/stdlib/fmt/format.go +732 -0
  100. package/stdlib/fmt/print.go +1232 -0
  101. package/stdlib/gom/gom.go +293 -0
  102. package/stdlib/hash/hash.go +53 -0
  103. package/stdlib/html/html.go +251 -0
  104. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  105. package/stdlib/internal/jsonrt/dec.go +871 -0
  106. package/stdlib/internal/jsonrt/enc.go +516 -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 +658 -0
  111. package/stdlib/io/io.go +502 -0
  112. package/stdlib/iter/iter.go +18 -0
  113. package/stdlib/maps/maps.go +131 -0
  114. package/stdlib/math/bits/bits.go +507 -0
  115. package/stdlib/math/extra.go +272 -0
  116. package/stdlib/math/math.go +439 -0
  117. package/stdlib/math/rand/rand.go +297 -0
  118. package/stdlib/os/os.go +93 -0
  119. package/stdlib/path/filepath/filepath.go +47 -0
  120. package/stdlib/path/path.go +394 -0
  121. package/stdlib/regexp/regexp.go +231 -0
  122. package/stdlib/slices/slices.go +526 -0
  123. package/stdlib/slices/sort.go +209 -0
  124. package/stdlib/slices/zsort_cmp.go +480 -0
  125. package/stdlib/slices/zsort_ordered.go +482 -0
  126. package/stdlib/sort/sort.go +500 -0
  127. package/stdlib/sort/zsort_func.go +480 -0
  128. package/stdlib/sort/zsort_iface.go +480 -0
  129. package/stdlib/strconv/float.go +1699 -0
  130. package/stdlib/strconv/isprint.go +752 -0
  131. package/stdlib/strconv/quote.go +526 -0
  132. package/stdlib/strconv/strconv.go +616 -0
  133. package/stdlib/strings/builder.go +95 -0
  134. package/stdlib/strings/reader.go +163 -0
  135. package/stdlib/strings/replacer.go +102 -0
  136. package/stdlib/strings/strings.go +807 -0
  137. package/stdlib/sync/sync.go +268 -0
  138. package/stdlib/testing/async_js.go +61 -0
  139. package/stdlib/testing/benchmark.go +297 -0
  140. package/stdlib/testing/testing.go +523 -0
  141. package/stdlib/time/duration.go +233 -0
  142. package/stdlib/time/format.go +745 -0
  143. package/stdlib/time/parse.go +790 -0
  144. package/stdlib/time/sleep_js.go +63 -0
  145. package/stdlib/time/time.go +834 -0
  146. package/stdlib/unicode/unicode.go +250 -0
  147. package/stdlib/unicode/utf8/utf8.go +464 -0
  148. package/src/backend/js/stdlib/base64.js +0 -12
  149. package/src/backend/js/stdlib/binary.js +0 -102
  150. package/src/backend/js/stdlib/bits.js +0 -46
  151. package/src/backend/js/stdlib/builder.js +0 -63
  152. package/src/backend/js/stdlib/bytes.js +0 -122
  153. package/src/backend/js/stdlib/errors.js +0 -44
  154. package/src/backend/js/stdlib/fmt.js +0 -178
  155. package/src/backend/js/stdlib/gom.js +0 -155
  156. package/src/backend/js/stdlib/hex.js +0 -17
  157. package/src/backend/js/stdlib/html.js +0 -20
  158. package/src/backend/js/stdlib/io.js +0 -137
  159. package/src/backend/js/stdlib/json.js +0 -972
  160. package/src/backend/js/stdlib/maps.js +0 -45
  161. package/src/backend/js/stdlib/math.js +0 -69
  162. package/src/backend/js/stdlib/os.js +0 -13
  163. package/src/backend/js/stdlib/path.js +0 -48
  164. package/src/backend/js/stdlib/rand.js +0 -32
  165. package/src/backend/js/stdlib/regexp.js +0 -54
  166. package/src/backend/js/stdlib/sha256.js +0 -12
  167. package/src/backend/js/stdlib/shared.js +0 -17
  168. package/src/backend/js/stdlib/simd.js +0 -24
  169. package/src/backend/js/stdlib/slices.js +0 -77
  170. package/src/backend/js/stdlib/sort.js +0 -30
  171. package/src/backend/js/stdlib/strconv.js +0 -74
  172. package/src/backend/js/stdlib/strings.js +0 -222
  173. package/src/backend/js/stdlib/sync.js +0 -13
  174. package/src/backend/js/stdlib/testing.js +0 -34
  175. package/src/backend/js/stdlib/time.js +0 -128
  176. package/src/backend/js/stdlib/unicode.js +0 -25
  177. package/src/backend/js/stdlib/utf8.js +0 -26
  178. package/src/backend/wasm/const-fold.js +0 -205
  179. package/src/backend/wasm/emit-stdlib.js +0 -13
  180. package/src/backend/wasm/stdlib/bytes.js +0 -5039
  181. package/src/backend/wasm/stdlib/core.js +0 -8903
  182. package/src/backend/wasm/stdlib/io.js +0 -2161
  183. package/src/backend/wasm/stdlib/packages.js +0 -2400
  184. package/src/backend/wasm/stdlib/pure.js +0 -720
  185. package/src/backend/wasm/stdlib/time.js +0 -1200
  186. package/src/typechecker/stdlib/core.js +0 -801
  187. package/src/typechecker/stdlib/extended.js +0 -914
  188. package/src/typechecker/stdlib.js +0 -22
  189. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  190. /package/src/{colors.js → cli/colors.js} +0 -0
  191. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  192. /package/src/{minifier.js → cli/minifier.js} +0 -0
  193. /package/src/{project-config.js → cli/project-config.js} +0 -0
  194. /package/src/{pwa.js → cli/pwa.js} +0 -0
@@ -1,2400 +0,0 @@
1
- // src/backend/wasm/stdlib/packages.js
2
- // FunctionEmitter mixin: sync, encoding/binary, crypto/sha256, encoding/hex, encoding/base64.
3
-
4
- import { isSliceType, toWasmType } from "../types.js";
5
-
6
- const EXT_PKG_CONSTS = {
7
- sha256: { Size: 32, BlockSize: 64 },
8
- base64: { StdPadding: 61, NoPadding: -1 },
9
- };
10
- const EXT_PKG_SPECIAL = new Set([
11
- "hex.ErrLength",
12
- "base64.StdEncoding",
13
- "base64.URLEncoding",
14
- "base64.RawStdEncoding",
15
- "base64.RawURLEncoding",
16
- "binary.LittleEndian",
17
- "binary.BigEndian",
18
- ]);
19
-
20
- export class ExtendedPackagesEmitter {
21
- _isExtendedPkgConst(expr) {
22
- if (!this._isPkgExpr(expr)) return false;
23
- const pkg = expr.expr.name;
24
- return (
25
- EXT_PKG_CONSTS[pkg]?.[expr.field] !== undefined ||
26
- EXT_PKG_SPECIAL.has(`${pkg}.${expr.field}`)
27
- );
28
- }
29
-
30
- emitExtendedPkgConst(expr, targetWasmType) {
31
- const pkg = expr.expr.name;
32
- const field = expr.field;
33
- const scalarVal = EXT_PKG_CONSTS[pkg]?.[field];
34
- if (scalarVal !== undefined) {
35
- if ((targetWasmType ?? "i64") === "i64") {
36
- this.pushInstruction({ op: "i64.const", value: BigInt(scalarVal) });
37
- } else {
38
- this.pushInstruction({ op: "i32.const", value: scalarVal });
39
- }
40
- return;
41
- }
42
- if (pkg === "hex" && field === "ErrLength") {
43
- const strIdx = this.mod.internString(
44
- "encoding/hex: odd length hex string",
45
- );
46
- this.pushInstruction({ op: "i32.const", value: strIdx });
47
- this.pushInstruction({
48
- op: "call",
49
- funcIndex: this.mod.getStringImportIndex(),
50
- });
51
- this.pushInstruction({ op: "ref.null", heapType: "any" });
52
- this.pushInstruction({
53
- op: "call",
54
- funcIndex: this.mod.resolveFuncIndex("__mk_error"),
55
- });
56
- return;
57
- }
58
- if (pkg === "base64") {
59
- const mode =
60
- field === "URLEncoding"
61
- ? 1
62
- : field === "RawStdEncoding"
63
- ? 2
64
- : field === "RawURLEncoding"
65
- ? 3
66
- : 0;
67
- const structInfo = this.mod.getStructType("base64.Encoding");
68
- this.pushInstruction({ op: "i32.const", value: mode });
69
- this.pushInstruction({
70
- op: "struct.new",
71
- typeIndex: structInfo.typeIndex,
72
- });
73
- return;
74
- }
75
- if (pkg === "binary") {
76
- const isBig = field === "BigEndian";
77
- const structInfo = this.mod.getStructType(
78
- isBig ? "binary.BigEndian" : "binary.LittleEndian",
79
- );
80
- this.pushInstruction({ op: "i32.const", value: isBig ? 1 : 0 });
81
- this.pushInstruction({
82
- op: "struct.new",
83
- typeIndex: structInfo.typeIndex,
84
- });
85
- return;
86
- }
87
- }
88
-
89
- emitSyncMutexMethodCall(method, recvExpr, _args, _targetWasmType) {
90
- const recvW = toWasmType(
91
- recvExpr._type ?? this._resolveExprGoType(recvExpr),
92
- this.mod.checker,
93
- this.mod,
94
- );
95
- this.emitExpr(recvExpr, recvW);
96
- this.pushInstruction("drop");
97
- if (method === "TryLock" || method === "TryRLock") {
98
- this.pushInstruction({ op: "i32.const", value: 1 });
99
- }
100
- }
101
-
102
- emitSyncOnceMethodCall(method, recvExpr, args, _targetWasmType) {
103
- if (method !== "Do") return;
104
- const structInfo = this.mod.getStructType("sync.Once");
105
- const onceW = {
106
- kind: "ref",
107
- nullable: true,
108
- typeIndex: structInfo.typeIndex,
109
- };
110
- const oTmp = this.acquireTemp(onceW);
111
- this.emitExpr(recvExpr, onceW);
112
- this.pushInstruction({ op: "local.set", index: oTmp });
113
-
114
- this.pushInstruction({ op: "local.get", index: oTmp });
115
- this.pushInstruction({
116
- op: "struct.get",
117
- typeIndex: structInfo.typeIndex,
118
- fieldIndex: 0,
119
- });
120
- this.pushInstruction("i32.eqz");
121
- this.pushInstruction({ op: "if", blockType: "void" });
122
-
123
- this.pushInstruction({ op: "local.get", index: oTmp });
124
- this.pushInstruction({ op: "i32.const", value: 1 });
125
- this.pushInstruction({
126
- op: "struct.set",
127
- typeIndex: structInfo.typeIndex,
128
- fieldIndex: 0,
129
- });
130
-
131
- const fnNode = args[0];
132
- const closureGoType = this._resolveExprGoType(fnNode);
133
- const closureInfo = this.mod.getClosureType(closureGoType);
134
- const closureW = {
135
- kind: "ref",
136
- nullable: true,
137
- typeIndex: closureInfo.typeIndex,
138
- };
139
- const clTmp = this.acquireTemp(closureW);
140
- this.emitExpr(fnNode, closureW);
141
- this.pushInstruction({ op: "local.set", index: clTmp });
142
-
143
- this.pushInstruction({ op: "local.get", index: clTmp });
144
- this.pushInstruction({
145
- op: "struct.get",
146
- typeIndex: closureInfo.typeIndex,
147
- fieldIndex: 1,
148
- });
149
- this.pushInstruction({ op: "local.get", index: clTmp });
150
- this.pushInstruction({
151
- op: "struct.get",
152
- typeIndex: closureInfo.typeIndex,
153
- fieldIndex: 0,
154
- });
155
- this.pushInstruction({
156
- op: "call_ref",
157
- typeIndex: closureInfo.funcTypeIndex,
158
- });
159
-
160
- this.releaseTemp(clTmp, closureW);
161
- this.pushInstruction("end");
162
- this.releaseTemp(oTmp, onceW);
163
- }
164
-
165
- emitSyncWaitGroupMethodCall(method, recvExpr, args, _targetWasmType) {
166
- const structInfo = this.mod.getStructType("sync.WaitGroup");
167
- const wgW = {
168
- kind: "ref",
169
- nullable: true,
170
- typeIndex: structInfo.typeIndex,
171
- };
172
- const wgTmp = this.acquireTemp(wgW);
173
- this.emitExpr(recvExpr, wgW);
174
- this.pushInstruction({ op: "local.set", index: wgTmp });
175
-
176
- if (method === "Add") {
177
- const deltaTmp = this.acquireTemp("i64");
178
- this.emitExpr(args[0], "i64");
179
- this.pushInstruction({ op: "local.set", index: deltaTmp });
180
-
181
- this.pushInstruction({ op: "local.get", index: wgTmp });
182
- this.pushInstruction({ op: "local.get", index: wgTmp });
183
- this.pushInstruction({
184
- op: "struct.get",
185
- typeIndex: structInfo.typeIndex,
186
- fieldIndex: 0,
187
- });
188
- this.pushInstruction({ op: "local.get", index: deltaTmp });
189
- this.pushInstruction("i64.add");
190
- this.pushInstruction({
191
- op: "struct.set",
192
- typeIndex: structInfo.typeIndex,
193
- fieldIndex: 0,
194
- });
195
- this.releaseTemp(deltaTmp, "i64");
196
- } else if (method === "Done") {
197
- this.pushInstruction({ op: "local.get", index: wgTmp });
198
- this.pushInstruction({ op: "local.get", index: wgTmp });
199
- this.pushInstruction({
200
- op: "struct.get",
201
- typeIndex: structInfo.typeIndex,
202
- fieldIndex: 0,
203
- });
204
- this.pushInstruction({ op: "i64.const", value: 1n });
205
- this.pushInstruction("i64.sub");
206
- this.pushInstruction({
207
- op: "struct.set",
208
- typeIndex: structInfo.typeIndex,
209
- fieldIndex: 0,
210
- });
211
- }
212
- this.releaseTemp(wgTmp, wgW);
213
- }
214
-
215
- emitBinaryCall(name, call, targetWasmType) {
216
- const args = call.args;
217
- if (name === "Size") {
218
- this._emitBinarySize(args[0]);
219
- return;
220
- }
221
- if (
222
- name === "AppendUint16" ||
223
- name === "AppendUint32" ||
224
- name === "AppendUint64"
225
- ) {
226
- this.emitBinaryOrderMethodCall(
227
- "binary.LittleEndian",
228
- name,
229
- null,
230
- args,
231
- targetWasmType,
232
- );
233
- return;
234
- }
235
- if (name === "Read") {
236
- this._emitBinaryRead(args[0], args[1], args[2]);
237
- return;
238
- }
239
- if (name === "Write") {
240
- this._emitBinaryWrite(args[0], args[1], args[2]);
241
- return;
242
- }
243
- throw new Error(`Unsupported binary call: binary.${name}`);
244
- }
245
-
246
- _emitBinarySize(arg) {
247
- const t = arg._type ?? this._resolveExprGoType(arg);
248
- const sizeOf = (gt) => {
249
- if (!gt) return -1;
250
- if (gt.kind === "basic") {
251
- switch (gt.name) {
252
- case "bool":
253
- case "int8":
254
- case "uint8":
255
- case "byte":
256
- return 1;
257
- case "int16":
258
- case "uint16":
259
- return 2;
260
- case "int32":
261
- case "uint32":
262
- case "float32":
263
- case "rune":
264
- return 4;
265
- case "int64":
266
- case "uint64":
267
- case "float64":
268
- case "int":
269
- case "uint":
270
- case "uintptr":
271
- return 8;
272
- default:
273
- return -1;
274
- }
275
- }
276
- if (gt.kind === "array" || gt.kind === "ArrayType") {
277
- const es = sizeOf(gt.elem);
278
- const len = gt.len ?? gt.size ?? 0;
279
- return es > 0 ? es * len : -1;
280
- }
281
- if (
282
- gt.kind === "pointer" ||
283
- gt.kind === "PointerType" ||
284
- gt.kind === "StarExpr"
285
- ) {
286
- return sizeOf(gt.base ?? gt.expr ?? gt.operand);
287
- }
288
- if (gt.kind === "struct" || gt.kind === "StructType") {
289
- let total = 0;
290
- if (gt.fields instanceof Map) {
291
- for (const fType of gt.fields.values()) {
292
- const s = sizeOf(fType);
293
- if (s < 0) return -1;
294
- total += s;
295
- }
296
- return total;
297
- }
298
- }
299
- if (gt.name && this.mod.checker?.types?.has(gt.name)) {
300
- const resolved = this.mod.checker.types.get(gt.name);
301
- return sizeOf(resolved.underlying ?? resolved);
302
- }
303
- return -1;
304
- };
305
- const s = sizeOf(t);
306
- if (s >= 0) {
307
- this.pushInstruction({ op: "i64.const", value: BigInt(s) });
308
- } else {
309
- this.pushInstruction({ op: "i64.const", value: -1n });
310
- }
311
- }
312
-
313
- _emitBinaryRead(rExpr, orderExpr, dataExpr) {
314
- const byteGo = { kind: "basic", name: "byte" };
315
- const sliceInfo = this.mod.getSliceType(byteGo);
316
- const arrInfo = sliceInfo.arrInfo;
317
- const sliceW = {
318
- kind: "ref",
319
- nullable: true,
320
- typeIndex: sliceInfo.typeIndex,
321
- };
322
- const arrW = {
323
- kind: "ref",
324
- nullable: true,
325
- typeIndex: arrInfo.typeIndex,
326
- };
327
-
328
- // If data is a slice ([]byte): read directly into data slice
329
- const dataType = dataExpr._type ?? this._resolveExprGoType(dataExpr);
330
- if (isSliceType(dataType, this.mod.checker)) {
331
- const sTmp = this.acquireTemp(sliceW);
332
- this.emitExpr(dataExpr, sliceW);
333
- this.pushInstruction({ op: "local.set", index: sTmp });
334
-
335
- const rTmp = this.acquireTemp("anyref");
336
- this.emitExpr(rExpr, "anyref");
337
- this.pushInstruction({ op: "local.set", index: rTmp });
338
-
339
- this.pushInstruction({ op: "local.get", index: rTmp });
340
- this.pushInstruction({ op: "local.get", index: sTmp });
341
- const dispatchReadIdx = this.mod.resolveFuncIndex(
342
- "__dispatch_io.Reader_Read",
343
- );
344
- this.pushInstruction({ op: "call", funcIndex: dispatchReadIdx });
345
-
346
- // Drop n (int), return err
347
- const errTmp = this.acquireTemp("anyref");
348
- this.pushInstruction({ op: "local.set", index: errTmp });
349
- this.pushInstruction("drop"); // drop n
350
- this.pushInstruction({ op: "local.get", index: errTmp });
351
-
352
- this.releaseTemp(errTmp, "anyref");
353
- this.releaseTemp(rTmp, "anyref");
354
- this.releaseTemp(sTmp, sliceW);
355
- return;
356
- }
357
-
358
- // Scalar pointer: determine sz (1, 2, 4, 8)
359
- let sz = 4;
360
- const baseType =
361
- dataType?.base ?? dataType?.expr ?? dataType?.operand ?? dataType;
362
- if (baseType?.name === "uint16" || baseType?.name === "int16") sz = 2;
363
- else if (
364
- baseType?.name === "uint64" ||
365
- baseType?.name === "int64" ||
366
- baseType?.name === "int" ||
367
- baseType?.name === "uint" ||
368
- baseType?.name === "float64"
369
- )
370
- sz = 8;
371
- else if (
372
- baseType?.name === "byte" ||
373
- baseType?.name === "uint8" ||
374
- baseType?.name === "int8" ||
375
- baseType?.name === "bool"
376
- )
377
- sz = 1;
378
- else if (baseType?.name === "float32") sz = 4;
379
-
380
- const arrTmp = this.acquireTemp(arrW);
381
- this.pushInstruction({ op: "i32.const", value: sz });
382
- this.pushInstruction({
383
- op: "array.new_default",
384
- typeIndex: arrInfo.typeIndex,
385
- });
386
- this.pushInstruction({ op: "local.set", index: arrTmp });
387
-
388
- const bufTmp = this.acquireTemp(sliceW);
389
- this.pushInstruction({ op: "local.get", index: arrTmp });
390
- this.pushInstruction({ op: "i32.const", value: 0 });
391
- this.pushInstruction({ op: "i32.const", value: sz });
392
- this.pushInstruction({ op: "i32.const", value: sz });
393
- this.pushInstruction({
394
- op: "struct.new",
395
- typeIndex: sliceInfo.typeIndex,
396
- });
397
- this.pushInstruction({ op: "local.set", index: bufTmp });
398
-
399
- const rTmp = this.acquireTemp("anyref");
400
- this.emitExpr(rExpr, "anyref");
401
- this.pushInstruction({ op: "local.set", index: rTmp });
402
-
403
- this.pushInstruction({ op: "local.get", index: rTmp });
404
- this.pushInstruction({ op: "local.get", index: bufTmp });
405
- const dispatchReadIdx = this.mod.resolveFuncIndex(
406
- "__dispatch_io.Reader_Read",
407
- );
408
- this.pushInstruction({ op: "call", funcIndex: dispatchReadIdx });
409
-
410
- const errTmp = this.acquireTemp("anyref");
411
- const nTmp = this.acquireTemp("i64");
412
- this.pushInstruction({ op: "local.set", index: errTmp });
413
- this.pushInstruction({ op: "local.set", index: nTmp });
414
-
415
- // if err != nil -> return err
416
- this.pushInstruction({ op: "block", blockType: "anyref" });
417
- this.pushInstruction({ op: "local.get", index: errTmp });
418
- this.pushInstruction("ref.is_null");
419
- this.pushInstruction("i32.eqz");
420
- this.pushInstruction({ op: "if", blockType: "void" });
421
- this.pushInstruction({ op: "local.get", index: errTmp });
422
- this.pushInstruction({ op: "br", depth: 1 });
423
- this.pushInstruction("end");
424
-
425
- // if n < sz -> return io.EOF
426
- this.pushInstruction({ op: "local.get", index: nTmp });
427
- this.pushInstruction({ op: "i64.const", value: BigInt(sz) });
428
- this.pushInstruction("i64.lt_s");
429
- this.pushInstruction({ op: "if", blockType: "void" });
430
- this.emitIoConst("EOF", "anyref");
431
- this.pushInstruction({ op: "br", depth: 1 });
432
- this.pushInstruction("end");
433
-
434
- // Decode scalar from arrTmp and write to target
435
- const isAddressOf = dataExpr.kind === "UnaryExpr" && dataExpr.op === "&";
436
- const targetNode = isAddressOf
437
- ? (dataExpr.operand ?? dataExpr.expr)
438
- : {
439
- kind: "UnaryExpr",
440
- op: "*",
441
- operand: { ...dataExpr, _type: dataType },
442
- _type: baseType,
443
- };
444
-
445
- const isBig =
446
- orderExpr?._type?.name?.includes("BigEndian") ||
447
- orderExpr?.field === "BigEndian";
448
-
449
- let wType = "i32";
450
- if (sz === 8) {
451
- wType = baseType?.name === "float64" ? "f64" : "i64";
452
- } else if (sz === 4 && baseType?.name === "float32") {
453
- wType = "f32";
454
- }
455
-
456
- this._emitAssignToTarget(targetNode, wType, baseType, () => {
457
- if (sz === 1) {
458
- this.pushInstruction({ op: "local.get", index: arrTmp });
459
- this.pushInstruction({ op: "i32.const", value: 0 });
460
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
461
- if (baseType?.name === "int8") {
462
- this.pushInstruction("i32.extend8_s");
463
- }
464
- } else if (sz === 2) {
465
- if (isBig) {
466
- this.pushInstruction({ op: "local.get", index: arrTmp });
467
- this.pushInstruction({ op: "i32.const", value: 0 });
468
- this.pushInstruction({
469
- op: "array.get",
470
- typeIndex: arrInfo.typeIndex,
471
- });
472
- this.pushInstruction({ op: "i32.const", value: 8 });
473
- this.pushInstruction("i32.shl");
474
- this.pushInstruction({ op: "local.get", index: arrTmp });
475
- this.pushInstruction({ op: "i32.const", value: 1 });
476
- this.pushInstruction({
477
- op: "array.get",
478
- typeIndex: arrInfo.typeIndex,
479
- });
480
- this.pushInstruction("i32.or");
481
- } else {
482
- this.pushInstruction({ op: "local.get", index: arrTmp });
483
- this.pushInstruction({ op: "i32.const", value: 0 });
484
- this.pushInstruction({
485
- op: "array.get",
486
- typeIndex: arrInfo.typeIndex,
487
- });
488
- this.pushInstruction({ op: "local.get", index: arrTmp });
489
- this.pushInstruction({ op: "i32.const", value: 1 });
490
- this.pushInstruction({
491
- op: "array.get",
492
- typeIndex: arrInfo.typeIndex,
493
- });
494
- this.pushInstruction({ op: "i32.const", value: 8 });
495
- this.pushInstruction("i32.shl");
496
- this.pushInstruction("i32.or");
497
- }
498
- if (baseType?.name === "int16") {
499
- this.pushInstruction("i32.extend16_s");
500
- }
501
- } else if (sz === 4) {
502
- for (let i = 0; i < 4; i++) {
503
- this.pushInstruction({ op: "local.get", index: arrTmp });
504
- this.pushInstruction({ op: "i32.const", value: i });
505
- this.pushInstruction({
506
- op: "array.get",
507
- typeIndex: arrInfo.typeIndex,
508
- });
509
- }
510
- if (isBig) {
511
- const b3 = this.acquireTemp("i32");
512
- const b2 = this.acquireTemp("i32");
513
- const b1 = this.acquireTemp("i32");
514
- const b0 = this.acquireTemp("i32");
515
- this.pushInstruction({ op: "local.set", index: b3 });
516
- this.pushInstruction({ op: "local.set", index: b2 });
517
- this.pushInstruction({ op: "local.set", index: b1 });
518
- this.pushInstruction({ op: "local.set", index: b0 });
519
- this.pushInstruction({ op: "local.get", index: b0 });
520
- this.pushInstruction({ op: "i32.const", value: 24 });
521
- this.pushInstruction("i32.shl");
522
- this.pushInstruction({ op: "local.get", index: b1 });
523
- this.pushInstruction({ op: "i32.const", value: 16 });
524
- this.pushInstruction("i32.shl");
525
- this.pushInstruction("i32.or");
526
- this.pushInstruction({ op: "local.get", index: b2 });
527
- this.pushInstruction({ op: "i32.const", value: 8 });
528
- this.pushInstruction("i32.shl");
529
- this.pushInstruction("i32.or");
530
- this.pushInstruction({ op: "local.get", index: b3 });
531
- this.pushInstruction("i32.or");
532
- this.releaseTemp(b0, "i32");
533
- this.releaseTemp(b1, "i32");
534
- this.releaseTemp(b2, "i32");
535
- this.releaseTemp(b3, "i32");
536
- } else {
537
- const b3 = this.acquireTemp("i32");
538
- const b2 = this.acquireTemp("i32");
539
- const b1 = this.acquireTemp("i32");
540
- const b0 = this.acquireTemp("i32");
541
- this.pushInstruction({ op: "local.set", index: b3 });
542
- this.pushInstruction({ op: "local.set", index: b2 });
543
- this.pushInstruction({ op: "local.set", index: b1 });
544
- this.pushInstruction({ op: "local.set", index: b0 });
545
- this.pushInstruction({ op: "local.get", index: b0 });
546
- this.pushInstruction({ op: "local.get", index: b1 });
547
- this.pushInstruction({ op: "i32.const", value: 8 });
548
- this.pushInstruction("i32.shl");
549
- this.pushInstruction("i32.or");
550
- this.pushInstruction({ op: "local.get", index: b2 });
551
- this.pushInstruction({ op: "i32.const", value: 16 });
552
- this.pushInstruction("i32.shl");
553
- this.pushInstruction("i32.or");
554
- this.pushInstruction({ op: "local.get", index: b3 });
555
- this.pushInstruction({ op: "i32.const", value: 24 });
556
- this.pushInstruction("i32.shl");
557
- this.pushInstruction("i32.or");
558
- this.releaseTemp(b0, "i32");
559
- this.releaseTemp(b1, "i32");
560
- this.releaseTemp(b2, "i32");
561
- this.releaseTemp(b3, "i32");
562
- }
563
- if (baseType?.name === "float32") {
564
- this.pushInstruction("f32.reinterpret_i32");
565
- }
566
- } else if (sz === 8) {
567
- const bTmps = [];
568
- for (let i = 0; i < 8; i++) {
569
- this.pushInstruction({ op: "local.get", index: arrTmp });
570
- this.pushInstruction({ op: "i32.const", value: i });
571
- this.pushInstruction({
572
- op: "array.get",
573
- typeIndex: arrInfo.typeIndex,
574
- });
575
- this.pushInstruction("i64.extend_i32_u");
576
- const bt = this.acquireTemp("i64");
577
- this.pushInstruction({ op: "local.set", index: bt });
578
- bTmps.push(bt);
579
- }
580
- this.pushInstruction({ op: "i64.const", value: 0n });
581
- for (let i = 0; i < 8; i++) {
582
- const shift = isBig ? (7 - i) * 8 : i * 8;
583
- this.pushInstruction({ op: "local.get", index: bTmps[i] });
584
- if (shift > 0) {
585
- this.pushInstruction({ op: "i64.const", value: BigInt(shift) });
586
- this.pushInstruction("i64.shl");
587
- }
588
- this.pushInstruction("i64.or");
589
- }
590
- for (const bt of bTmps) this.releaseTemp(bt, "i64");
591
- if (baseType?.name === "float64") {
592
- this.pushInstruction("f64.reinterpret_i64");
593
- }
594
- }
595
- });
596
-
597
- // return nil error
598
- this.pushInstruction({ op: "ref.null", heapType: "any" });
599
- this.pushInstruction("end"); // end block
600
-
601
- this.releaseTemp(nTmp, "i64");
602
- this.releaseTemp(errTmp, "anyref");
603
- this.releaseTemp(rTmp, "anyref");
604
- this.releaseTemp(bufTmp, sliceW);
605
- this.releaseTemp(arrTmp, arrW);
606
- }
607
-
608
- _emitBinaryWrite(wExpr, orderExpr, dataExpr) {
609
- const byteGo = { kind: "basic", name: "byte" };
610
- const sliceInfo = this.mod.getSliceType(byteGo);
611
- const arrInfo = sliceInfo.arrInfo;
612
- const sliceW = {
613
- kind: "ref",
614
- nullable: true,
615
- typeIndex: sliceInfo.typeIndex,
616
- };
617
- const arrW = {
618
- kind: "ref",
619
- nullable: true,
620
- typeIndex: arrInfo.typeIndex,
621
- };
622
-
623
- const dataType = dataExpr._type ?? this._resolveExprGoType(dataExpr);
624
- if (isSliceType(dataType, this.mod.checker)) {
625
- const sTmp = this.acquireTemp(sliceW);
626
- this.emitExpr(dataExpr, sliceW);
627
- this.pushInstruction({ op: "local.set", index: sTmp });
628
-
629
- const wTmp = this.acquireTemp("anyref");
630
- this.emitExpr(wExpr, "anyref");
631
- this.pushInstruction({ op: "local.set", index: wTmp });
632
-
633
- this.pushInstruction({ op: "local.get", index: wTmp });
634
- this.pushInstruction({ op: "local.get", index: sTmp });
635
- const dispatchWriteIdx = this.mod.resolveFuncIndex(
636
- "__dispatch_io.Writer_Write",
637
- );
638
- this.pushInstruction({ op: "call", funcIndex: dispatchWriteIdx });
639
-
640
- const errTmp = this.acquireTemp("anyref");
641
- this.pushInstruction({ op: "local.set", index: errTmp });
642
- this.pushInstruction("drop"); // drop n
643
- this.pushInstruction({ op: "local.get", index: errTmp });
644
-
645
- this.releaseTemp(errTmp, "anyref");
646
- this.releaseTemp(wTmp, "anyref");
647
- this.releaseTemp(sTmp, sliceW);
648
- return;
649
- }
650
-
651
- let sz = 4;
652
- if (dataType?.name === "uint16" || dataType?.name === "int16") sz = 2;
653
- else if (
654
- dataType?.name === "uint64" ||
655
- dataType?.name === "int64" ||
656
- dataType?.name === "int" ||
657
- dataType?.name === "uint" ||
658
- dataType?.name === "float64"
659
- )
660
- sz = 8;
661
- else if (
662
- dataType?.name === "byte" ||
663
- dataType?.name === "uint8" ||
664
- dataType?.name === "int8" ||
665
- dataType?.name === "bool"
666
- )
667
- sz = 1;
668
- else if (dataType?.name === "float32") sz = 4;
669
-
670
- const isBig =
671
- orderExpr?._type?.name?.includes("BigEndian") ||
672
- orderExpr?.field === "BigEndian";
673
-
674
- const arrTmp = this.acquireTemp(arrW);
675
- this.pushInstruction({ op: "i32.const", value: sz });
676
- this.pushInstruction({
677
- op: "array.new_default",
678
- typeIndex: arrInfo.typeIndex,
679
- });
680
- this.pushInstruction({ op: "local.set", index: arrTmp });
681
-
682
- if (sz === 1) {
683
- const vTmp = this.acquireTemp("i32");
684
- this.emitExpr(dataExpr, "i32");
685
- this.pushInstruction({ op: "local.set", index: vTmp });
686
-
687
- this.pushInstruction({ op: "local.get", index: arrTmp });
688
- this.pushInstruction({ op: "i32.const", value: 0 });
689
- this.pushInstruction({ op: "local.get", index: vTmp });
690
- this.pushInstruction({ op: "i32.const", value: 0xff });
691
- this.pushInstruction("i32.and");
692
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
693
- this.releaseTemp(vTmp, "i32");
694
- } else if (sz === 2) {
695
- const vTmp = this.acquireTemp("i32");
696
- this.emitExpr(dataExpr, "i32");
697
- this.pushInstruction({ op: "local.set", index: vTmp });
698
-
699
- // byte 0
700
- this.pushInstruction({ op: "local.get", index: arrTmp });
701
- this.pushInstruction({ op: "i32.const", value: 0 });
702
- this.pushInstruction({ op: "local.get", index: vTmp });
703
- if (isBig) {
704
- this.pushInstruction({ op: "i32.const", value: 8 });
705
- this.pushInstruction("i32.shr_u");
706
- }
707
- this.pushInstruction({ op: "i32.const", value: 0xff });
708
- this.pushInstruction("i32.and");
709
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
710
-
711
- // byte 1
712
- this.pushInstruction({ op: "local.get", index: arrTmp });
713
- this.pushInstruction({ op: "i32.const", value: 1 });
714
- this.pushInstruction({ op: "local.get", index: vTmp });
715
- if (!isBig) {
716
- this.pushInstruction({ op: "i32.const", value: 8 });
717
- this.pushInstruction("i32.shr_u");
718
- }
719
- this.pushInstruction({ op: "i32.const", value: 0xff });
720
- this.pushInstruction("i32.and");
721
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
722
- this.releaseTemp(vTmp, "i32");
723
- } else if (sz === 4) {
724
- const vTmp = this.acquireTemp("i32");
725
- if (dataType?.name === "float32") {
726
- this.emitExpr(dataExpr, "f32");
727
- this.pushInstruction("i32.reinterpret_f32");
728
- } else {
729
- this.emitExpr(dataExpr, "i32");
730
- }
731
- this.pushInstruction({ op: "local.set", index: vTmp });
732
-
733
- for (let i = 0; i < 4; i++) {
734
- const shift = isBig ? (3 - i) * 8 : i * 8;
735
- this.pushInstruction({ op: "local.get", index: arrTmp });
736
- this.pushInstruction({ op: "i32.const", value: i });
737
- this.pushInstruction({ op: "local.get", index: vTmp });
738
- if (shift > 0) {
739
- this.pushInstruction({ op: "i32.const", value: shift });
740
- this.pushInstruction("i32.shr_u");
741
- }
742
- this.pushInstruction({ op: "i32.const", value: 0xff });
743
- this.pushInstruction("i32.and");
744
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
745
- }
746
- this.releaseTemp(vTmp, "i32");
747
- } else if (sz === 8) {
748
- const vTmp = this.acquireTemp("i64");
749
- if (dataType?.name === "float64") {
750
- this.emitExpr(dataExpr, "f64");
751
- this.pushInstruction("i64.reinterpret_f64");
752
- } else {
753
- this.emitExpr(dataExpr, "i64");
754
- }
755
- this.pushInstruction({ op: "local.set", index: vTmp });
756
-
757
- for (let i = 0; i < 8; i++) {
758
- const shift = isBig ? (7 - i) * 8 : i * 8;
759
- this.pushInstruction({ op: "local.get", index: arrTmp });
760
- this.pushInstruction({ op: "i32.const", value: i });
761
- this.pushInstruction({ op: "local.get", index: vTmp });
762
- if (shift > 0) {
763
- this.pushInstruction({ op: "i64.const", value: BigInt(shift) });
764
- this.pushInstruction("i64.shr_u");
765
- }
766
- this.pushInstruction("i32.wrap_i64");
767
- this.pushInstruction({ op: "i32.const", value: 0xff });
768
- this.pushInstruction("i32.and");
769
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
770
- }
771
- this.releaseTemp(vTmp, "i64");
772
- }
773
-
774
- const bufTmp = this.acquireTemp(sliceW);
775
- this.pushInstruction({ op: "local.get", index: arrTmp });
776
- this.pushInstruction({ op: "i32.const", value: 0 });
777
- this.pushInstruction({ op: "i32.const", value: sz });
778
- this.pushInstruction({ op: "i32.const", value: sz });
779
- this.pushInstruction({
780
- op: "struct.new",
781
- typeIndex: sliceInfo.typeIndex,
782
- });
783
- this.pushInstruction({ op: "local.set", index: bufTmp });
784
-
785
- const wTmp = this.acquireTemp("anyref");
786
- this.emitExpr(wExpr, "anyref");
787
- this.pushInstruction({ op: "local.set", index: wTmp });
788
-
789
- this.pushInstruction({ op: "local.get", index: wTmp });
790
- this.pushInstruction({ op: "local.get", index: bufTmp });
791
- const dispatchWriteIdx = this.mod.resolveFuncIndex(
792
- "__dispatch_io.Writer_Write",
793
- );
794
- this.pushInstruction({ op: "call", funcIndex: dispatchWriteIdx });
795
-
796
- const errTmp = this.acquireTemp("anyref");
797
- this.pushInstruction({ op: "local.set", index: errTmp });
798
- this.pushInstruction("drop"); // drop n
799
- this.pushInstruction({ op: "local.get", index: errTmp });
800
-
801
- this.releaseTemp(errTmp, "anyref");
802
- this.releaseTemp(wTmp, "anyref");
803
- this.releaseTemp(bufTmp, sliceW);
804
- this.releaseTemp(arrTmp, arrW);
805
- }
806
-
807
- emitBinaryOrderMethodCall(
808
- recvTypeName,
809
- method,
810
- recvExpr,
811
- args,
812
- targetWasmType,
813
- ) {
814
- const isBig =
815
- recvTypeName?.includes("BigEndian") ||
816
- recvExpr?.field === "BigEndian" ||
817
- false;
818
-
819
- const byteGo = { kind: "basic", name: "byte" };
820
- const sliceInfo = this.mod.getSliceType(byteGo);
821
- const arrInfo = sliceInfo.arrInfo;
822
- const sliceW = {
823
- kind: "ref",
824
- nullable: true,
825
- typeIndex: sliceInfo.typeIndex,
826
- };
827
- const arrW = {
828
- kind: "ref",
829
- nullable: true,
830
- typeIndex: arrInfo.typeIndex,
831
- };
832
-
833
- if (method === "String") {
834
- const strIdx = this.mod.internString(
835
- isBig ? "BigEndian" : "LittleEndian",
836
- );
837
- this.pushInstruction({ op: "i32.const", value: strIdx });
838
- this.pushInstruction({
839
- op: "call",
840
- funcIndex: this.mod.getStringImportIndex(),
841
- });
842
- return;
843
- }
844
-
845
- if (method === "Uint16") {
846
- const sTmp = this.acquireTemp(sliceW);
847
- this.emitExpr(args[0], sliceW);
848
- this.pushInstruction({ op: "local.set", index: sTmp });
849
-
850
- const arrTmp = this.acquireTemp(arrW);
851
- const offTmp = this.acquireTemp("i32");
852
- const lenTmp = this.acquireTemp("i32");
853
- this._emitSliceUnpack(sTmp, sliceInfo, {
854
- arr: arrTmp,
855
- off: offTmp,
856
- len: lenTmp,
857
- });
858
-
859
- this.pushInstruction({ op: "local.get", index: arrTmp });
860
- this.pushInstruction({ op: "local.get", index: offTmp });
861
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
862
-
863
- this.pushInstruction({ op: "local.get", index: arrTmp });
864
- this.pushInstruction({ op: "local.get", index: offTmp });
865
- this.pushInstruction({ op: "i32.const", value: 1 });
866
- this.pushInstruction("i32.add");
867
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
868
-
869
- if (isBig) {
870
- // (b0 << 8) | b1
871
- this.pushInstruction({ op: "local.set", index: lenTmp }); // b1
872
- this.pushInstruction({ op: "i32.const", value: 8 });
873
- this.pushInstruction("i32.shl"); // b0 << 8
874
- this.pushInstruction({ op: "local.get", index: lenTmp });
875
- this.pushInstruction("i32.or");
876
- } else {
877
- // b0 | (b1 << 8)
878
- this.pushInstruction({ op: "i32.const", value: 8 });
879
- this.pushInstruction("i32.shl");
880
- this.pushInstruction("i32.or");
881
- }
882
-
883
- if ((targetWasmType ?? "i32") === "i64") {
884
- this.pushInstruction("i64.extend_i32_u");
885
- }
886
- this.releaseTemp(lenTmp, "i32");
887
- this.releaseTemp(offTmp, "i32");
888
- this.releaseTemp(arrTmp, arrW);
889
- this.releaseTemp(sTmp, sliceW);
890
- return;
891
- }
892
-
893
- if (method === "Uint32") {
894
- const sTmp = this.acquireTemp(sliceW);
895
- this.emitExpr(args[0], sliceW);
896
- this.pushInstruction({ op: "local.set", index: sTmp });
897
-
898
- const arrTmp = this.acquireTemp(arrW);
899
- const offTmp = this.acquireTemp("i32");
900
- this._emitSliceUnpack(sTmp, sliceInfo, { arr: arrTmp, off: offTmp });
901
-
902
- const bTmps = [];
903
- for (let i = 0; i < 4; i++) {
904
- this.pushInstruction({ op: "local.get", index: arrTmp });
905
- this.pushInstruction({ op: "local.get", index: offTmp });
906
- if (i > 0) {
907
- this.pushInstruction({ op: "i32.const", value: i });
908
- this.pushInstruction("i32.add");
909
- }
910
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
911
- const bt = this.acquireTemp("i32");
912
- this.pushInstruction({ op: "local.set", index: bt });
913
- bTmps.push(bt);
914
- }
915
-
916
- this.pushInstruction({ op: "i32.const", value: 0 });
917
- for (let i = 0; i < 4; i++) {
918
- const shift = isBig ? (3 - i) * 8 : i * 8;
919
- this.pushInstruction({ op: "local.get", index: bTmps[i] });
920
- if (shift > 0) {
921
- this.pushInstruction({ op: "i32.const", value: shift });
922
- this.pushInstruction("i32.shl");
923
- }
924
- this.pushInstruction("i32.or");
925
- }
926
- for (const bt of bTmps) this.releaseTemp(bt, "i32");
927
-
928
- if ((targetWasmType ?? "i32") === "i64") {
929
- this.pushInstruction("i64.extend_i32_u");
930
- }
931
- this.releaseTemp(offTmp, "i32");
932
- this.releaseTemp(arrTmp, arrW);
933
- this.releaseTemp(sTmp, sliceW);
934
- return;
935
- }
936
-
937
- if (method === "Uint64") {
938
- const sTmp = this.acquireTemp(sliceW);
939
- this.emitExpr(args[0], sliceW);
940
- this.pushInstruction({ op: "local.set", index: sTmp });
941
-
942
- const arrTmp = this.acquireTemp(arrW);
943
- const offTmp = this.acquireTemp("i32");
944
- this._emitSliceUnpack(sTmp, sliceInfo, { arr: arrTmp, off: offTmp });
945
-
946
- const bTmps = [];
947
- for (let i = 0; i < 8; i++) {
948
- this.pushInstruction({ op: "local.get", index: arrTmp });
949
- this.pushInstruction({ op: "local.get", index: offTmp });
950
- if (i > 0) {
951
- this.pushInstruction({ op: "i32.const", value: i });
952
- this.pushInstruction("i32.add");
953
- }
954
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
955
- this.pushInstruction("i64.extend_i32_u");
956
- const bt = this.acquireTemp("i64");
957
- this.pushInstruction({ op: "local.set", index: bt });
958
- bTmps.push(bt);
959
- }
960
-
961
- this.pushInstruction({ op: "i64.const", value: 0n });
962
- for (let i = 0; i < 8; i++) {
963
- const shift = isBig ? (7 - i) * 8 : i * 8;
964
- this.pushInstruction({ op: "local.get", index: bTmps[i] });
965
- if (shift > 0) {
966
- this.pushInstruction({ op: "i64.const", value: BigInt(shift) });
967
- this.pushInstruction("i64.shl");
968
- }
969
- this.pushInstruction("i64.or");
970
- }
971
- for (const bt of bTmps) this.releaseTemp(bt, "i64");
972
-
973
- this.releaseTemp(offTmp, "i32");
974
- this.releaseTemp(arrTmp, arrW);
975
- this.releaseTemp(sTmp, sliceW);
976
- return;
977
- }
978
-
979
- if (method === "PutUint16") {
980
- const sTmp = this.acquireTemp(sliceW);
981
- this.emitExpr(args[0], sliceW);
982
- this.pushInstruction({ op: "local.set", index: sTmp });
983
-
984
- const vTmp = this.acquireTemp("i32");
985
- this.emitExpr(args[1], "i32");
986
- this.pushInstruction({ op: "local.set", index: vTmp });
987
-
988
- const arrTmp = this.acquireTemp(arrW);
989
- const offTmp = this.acquireTemp("i32");
990
- this._emitSliceUnpack(sTmp, sliceInfo, { arr: arrTmp, off: offTmp });
991
-
992
- // b[0]
993
- this.pushInstruction({ op: "local.get", index: arrTmp });
994
- this.pushInstruction({ op: "local.get", index: offTmp });
995
- this.pushInstruction({ op: "local.get", index: vTmp });
996
- if (isBig) {
997
- this.pushInstruction({ op: "i32.const", value: 8 });
998
- this.pushInstruction("i32.shr_u");
999
- }
1000
- this.pushInstruction({ op: "i32.const", value: 0xff });
1001
- this.pushInstruction("i32.and");
1002
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
1003
-
1004
- // b[1]
1005
- this.pushInstruction({ op: "local.get", index: arrTmp });
1006
- this.pushInstruction({ op: "local.get", index: offTmp });
1007
- this.pushInstruction({ op: "i32.const", value: 1 });
1008
- this.pushInstruction("i32.add");
1009
- this.pushInstruction({ op: "local.get", index: vTmp });
1010
- if (!isBig) {
1011
- this.pushInstruction({ op: "i32.const", value: 8 });
1012
- this.pushInstruction("i32.shr_u");
1013
- }
1014
- this.pushInstruction({ op: "i32.const", value: 0xff });
1015
- this.pushInstruction("i32.and");
1016
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
1017
-
1018
- this.releaseTemp(offTmp, "i32");
1019
- this.releaseTemp(arrTmp, arrW);
1020
- this.releaseTemp(vTmp, "i32");
1021
- this.releaseTemp(sTmp, sliceW);
1022
- return;
1023
- }
1024
-
1025
- if (method === "PutUint32") {
1026
- const sTmp = this.acquireTemp(sliceW);
1027
- this.emitExpr(args[0], sliceW);
1028
- this.pushInstruction({ op: "local.set", index: sTmp });
1029
-
1030
- const vTmp = this.acquireTemp("i32");
1031
- this.emitExpr(args[1], "i32");
1032
- this.pushInstruction({ op: "local.set", index: vTmp });
1033
-
1034
- const arrTmp = this.acquireTemp(arrW);
1035
- const offTmp = this.acquireTemp("i32");
1036
- this._emitSliceUnpack(sTmp, sliceInfo, { arr: arrTmp, off: offTmp });
1037
-
1038
- for (let i = 0; i < 4; i++) {
1039
- const shift = isBig ? (3 - i) * 8 : i * 8;
1040
- this.pushInstruction({ op: "local.get", index: arrTmp });
1041
- this.pushInstruction({ op: "local.get", index: offTmp });
1042
- if (i > 0) {
1043
- this.pushInstruction({ op: "i32.const", value: i });
1044
- this.pushInstruction("i32.add");
1045
- }
1046
- this.pushInstruction({ op: "local.get", index: vTmp });
1047
- if (shift > 0) {
1048
- this.pushInstruction({ op: "i32.const", value: shift });
1049
- this.pushInstruction("i32.shr_u");
1050
- }
1051
- this.pushInstruction({ op: "i32.const", value: 0xff });
1052
- this.pushInstruction("i32.and");
1053
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
1054
- }
1055
-
1056
- this.releaseTemp(offTmp, "i32");
1057
- this.releaseTemp(arrTmp, arrW);
1058
- this.releaseTemp(vTmp, "i32");
1059
- this.releaseTemp(sTmp, sliceW);
1060
- return;
1061
- }
1062
-
1063
- if (method === "PutUint64") {
1064
- const sTmp = this.acquireTemp(sliceW);
1065
- this.emitExpr(args[0], sliceW);
1066
- this.pushInstruction({ op: "local.set", index: sTmp });
1067
-
1068
- const vTmp = this.acquireTemp("i64");
1069
- this.emitExpr(args[1], "i64");
1070
- this.pushInstruction({ op: "local.set", index: vTmp });
1071
-
1072
- const arrTmp = this.acquireTemp(arrW);
1073
- const offTmp = this.acquireTemp("i32");
1074
- this._emitSliceUnpack(sTmp, sliceInfo, { arr: arrTmp, off: offTmp });
1075
-
1076
- for (let i = 0; i < 8; i++) {
1077
- const shift = isBig ? (7 - i) * 8 : i * 8;
1078
- this.pushInstruction({ op: "local.get", index: arrTmp });
1079
- this.pushInstruction({ op: "local.get", index: offTmp });
1080
- if (i > 0) {
1081
- this.pushInstruction({ op: "i32.const", value: i });
1082
- this.pushInstruction("i32.add");
1083
- }
1084
- this.pushInstruction({ op: "local.get", index: vTmp });
1085
- if (shift > 0) {
1086
- this.pushInstruction({ op: "i64.const", value: BigInt(shift) });
1087
- this.pushInstruction("i64.shr_u");
1088
- }
1089
- this.pushInstruction("i32.wrap_i64");
1090
- this.pushInstruction({ op: "i32.const", value: 0xff });
1091
- this.pushInstruction("i32.and");
1092
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
1093
- }
1094
-
1095
- this.releaseTemp(offTmp, "i32");
1096
- this.releaseTemp(arrTmp, arrW);
1097
- this.releaseTemp(vTmp, "i64");
1098
- this.releaseTemp(sTmp, sliceW);
1099
- return;
1100
- }
1101
-
1102
- if (
1103
- method === "AppendUint16" ||
1104
- method === "AppendUint32" ||
1105
- method === "AppendUint64"
1106
- ) {
1107
- const byteCount =
1108
- method === "AppendUint16" ? 2 : method === "AppendUint32" ? 4 : 8;
1109
- const sNode = args[0];
1110
- const sTmp = this.acquireTemp(sliceW);
1111
- this.emitExpr(sNode, sliceW);
1112
- this.pushInstruction({ op: "local.set", index: sTmp });
1113
-
1114
- const oldArrTmp = this.acquireTemp(arrW);
1115
- const oldOffTmp = this.acquireTemp("i32");
1116
- const oldLenTmp = this.acquireTemp("i32");
1117
- const oldCapTmp = this.acquireTemp("i32");
1118
- this._emitSliceUnpack(sTmp, sliceInfo, {
1119
- arr: oldArrTmp,
1120
- off: oldOffTmp,
1121
- len: oldLenTmp,
1122
- cap: oldCapTmp,
1123
- });
1124
- this.releaseTemp(sTmp, sliceW);
1125
-
1126
- const newArrTmp = this.acquireTemp(arrW);
1127
- const newOffTmp = this.acquireTemp("i32");
1128
- const newCapTmp = this.acquireTemp("i32");
1129
- const newLenTmp = this.acquireTemp("i32");
1130
-
1131
- this.pushInstruction({ op: "local.get", index: oldLenTmp });
1132
- this.pushInstruction({ op: "i32.const", value: byteCount });
1133
- this.pushInstruction("i32.add");
1134
- this.pushInstruction({ op: "local.set", index: newLenTmp });
1135
-
1136
- this._emitGrowSlice({
1137
- arrInfo,
1138
- elemGoType: byteGo,
1139
- oldArrTmp,
1140
- oldOffTmp,
1141
- oldLenTmp,
1142
- oldCapTmp,
1143
- newArrTmp,
1144
- newOffTmp,
1145
- newLenTmp,
1146
- newCapTmp,
1147
- });
1148
-
1149
- if (byteCount === 2) {
1150
- const vTmp = this.acquireTemp("i32");
1151
- this.emitExpr(args[1], "i32");
1152
- this.pushInstruction({ op: "local.set", index: vTmp });
1153
-
1154
- for (let i = 0; i < 2; i++) {
1155
- const shift = isBig ? (1 - i) * 8 : i * 8;
1156
- this.pushInstruction({ op: "local.get", index: newArrTmp });
1157
- this.pushInstruction({ op: "local.get", index: newOffTmp });
1158
- this.pushInstruction({ op: "local.get", index: oldLenTmp });
1159
- this.pushInstruction("i32.add");
1160
- if (i > 0) {
1161
- this.pushInstruction({ op: "i32.const", value: i });
1162
- this.pushInstruction("i32.add");
1163
- }
1164
- this.pushInstruction({ op: "local.get", index: vTmp });
1165
- if (shift > 0) {
1166
- this.pushInstruction({ op: "i32.const", value: shift });
1167
- this.pushInstruction("i32.shr_u");
1168
- }
1169
- this.pushInstruction({ op: "i32.const", value: 0xff });
1170
- this.pushInstruction("i32.and");
1171
- this.pushInstruction({
1172
- op: "array.set",
1173
- typeIndex: arrInfo.typeIndex,
1174
- });
1175
- }
1176
- this.releaseTemp(vTmp, "i32");
1177
- } else if (byteCount === 4) {
1178
- const vTmp = this.acquireTemp("i32");
1179
- this.emitExpr(args[1], "i32");
1180
- this.pushInstruction({ op: "local.set", index: vTmp });
1181
-
1182
- for (let i = 0; i < 4; i++) {
1183
- const shift = isBig ? (3 - i) * 8 : i * 8;
1184
- this.pushInstruction({ op: "local.get", index: newArrTmp });
1185
- this.pushInstruction({ op: "local.get", index: newOffTmp });
1186
- this.pushInstruction({ op: "local.get", index: oldLenTmp });
1187
- this.pushInstruction("i32.add");
1188
- if (i > 0) {
1189
- this.pushInstruction({ op: "i32.const", value: i });
1190
- this.pushInstruction("i32.add");
1191
- }
1192
- this.pushInstruction({ op: "local.get", index: vTmp });
1193
- if (shift > 0) {
1194
- this.pushInstruction({ op: "i32.const", value: shift });
1195
- this.pushInstruction("i32.shr_u");
1196
- }
1197
- this.pushInstruction({ op: "i32.const", value: 0xff });
1198
- this.pushInstruction("i32.and");
1199
- this.pushInstruction({
1200
- op: "array.set",
1201
- typeIndex: arrInfo.typeIndex,
1202
- });
1203
- }
1204
- this.releaseTemp(vTmp, "i32");
1205
- } else {
1206
- const vTmp = this.acquireTemp("i64");
1207
- this.emitExpr(args[1], "i64");
1208
- this.pushInstruction({ op: "local.set", index: vTmp });
1209
-
1210
- for (let i = 0; i < 8; i++) {
1211
- const shift = isBig ? (7 - i) * 8 : i * 8;
1212
- this.pushInstruction({ op: "local.get", index: newArrTmp });
1213
- this.pushInstruction({ op: "local.get", index: newOffTmp });
1214
- this.pushInstruction({ op: "local.get", index: oldLenTmp });
1215
- this.pushInstruction("i32.add");
1216
- if (i > 0) {
1217
- this.pushInstruction({ op: "i32.const", value: i });
1218
- this.pushInstruction("i32.add");
1219
- }
1220
- this.pushInstruction({ op: "local.get", index: vTmp });
1221
- if (shift > 0) {
1222
- this.pushInstruction({ op: "i64.const", value: BigInt(shift) });
1223
- this.pushInstruction("i64.shr_u");
1224
- }
1225
- this.pushInstruction("i32.wrap_i64");
1226
- this.pushInstruction({ op: "i32.const", value: 0xff });
1227
- this.pushInstruction("i32.and");
1228
- this.pushInstruction({
1229
- op: "array.set",
1230
- typeIndex: arrInfo.typeIndex,
1231
- });
1232
- }
1233
- this.releaseTemp(vTmp, "i64");
1234
- }
1235
-
1236
- this.pushInstruction({ op: "local.get", index: newArrTmp });
1237
- this.pushInstruction({ op: "local.get", index: newOffTmp });
1238
- this.pushInstruction({ op: "local.get", index: newLenTmp });
1239
- this.pushInstruction({ op: "local.get", index: newCapTmp });
1240
- this.pushInstruction({
1241
- op: "struct.new",
1242
- typeIndex: sliceInfo.typeIndex,
1243
- });
1244
-
1245
- this.releaseTemp(newCapTmp, "i32");
1246
- this.releaseTemp(newLenTmp, "i32");
1247
- this.releaseTemp(newOffTmp, "i32");
1248
- this.releaseTemp(newArrTmp, arrW);
1249
- this.releaseTemp(oldCapTmp, "i32");
1250
- this.releaseTemp(oldLenTmp, "i32");
1251
- this.releaseTemp(oldOffTmp, "i32");
1252
- this.releaseTemp(oldArrTmp, arrW);
1253
- return;
1254
- }
1255
-
1256
- throw new Error(`Unsupported binary method: ${method}`);
1257
- }
1258
-
1259
- emitSha256Call(name, call, _targetWasmType) {
1260
- const args = call.args;
1261
- if (name === "Sum256") {
1262
- const byteGo = { kind: "basic", name: "byte" };
1263
- const sliceInfo = this.mod.getSliceType(byteGo);
1264
- const arrInfo = sliceInfo.arrInfo;
1265
- const sliceW = {
1266
- kind: "ref",
1267
- nullable: true,
1268
- typeIndex: sliceInfo.typeIndex,
1269
- };
1270
- const arrW = {
1271
- kind: "ref",
1272
- nullable: true,
1273
- typeIndex: arrInfo.typeIndex,
1274
- };
1275
-
1276
- const sTmp = this.acquireTemp(sliceW);
1277
- this.emitExpr(args[0], sliceW);
1278
- this.pushInstruction({ op: "local.set", index: sTmp });
1279
-
1280
- const arrTmp = this.acquireTemp(arrW);
1281
- const offTmp = this.acquireTemp("i32");
1282
- const lenTmp = this.acquireTemp("i32");
1283
- this._emitSliceUnpack(sTmp, sliceInfo, {
1284
- arr: arrTmp,
1285
- off: offTmp,
1286
- len: lenTmp,
1287
- });
1288
-
1289
- // raw_bytes_init(len)
1290
- this.pushInstruction({ op: "local.get", index: lenTmp });
1291
- this._callStdlib("raw_bytes_init");
1292
-
1293
- const iLoc = this.acquireTemp("i32");
1294
- this.pushInstruction({ op: "i32.const", value: 0 });
1295
- this.pushInstruction({ op: "local.set", index: iLoc });
1296
-
1297
- this.pushInstruction({ op: "block", blockType: "void" });
1298
- this.pushInstruction({ op: "loop", blockType: "void" });
1299
- this.pushInstruction({ op: "local.get", index: iLoc });
1300
- this.pushInstruction({ op: "local.get", index: lenTmp });
1301
- this.pushInstruction("i32.ge_s");
1302
- this.pushInstruction({ op: "br_if", depth: 1 });
1303
-
1304
- // raw_bytes_push(arr[off + i])
1305
- this.pushInstruction({ op: "local.get", index: arrTmp });
1306
- this.pushInstruction({ op: "local.get", index: offTmp });
1307
- this.pushInstruction({ op: "local.get", index: iLoc });
1308
- this.pushInstruction("i32.add");
1309
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
1310
- this._callStdlib("raw_bytes_push");
1311
-
1312
- this.pushInstruction({ op: "local.get", index: iLoc });
1313
- this.pushInstruction({ op: "i32.const", value: 1 });
1314
- this.pushInstruction("i32.add");
1315
- this.pushInstruction({ op: "local.set", index: iLoc });
1316
- this.pushInstruction({ op: "br", depth: 0 });
1317
- this.pushInstruction("end");
1318
- this.pushInstruction("end");
1319
-
1320
- // crypto_sha256_sum()
1321
- this._callStdlib("crypto_sha256_sum");
1322
- this.pushInstruction("drop"); // 32
1323
-
1324
- // allocate [32]byte array
1325
- const arr32Info = this.mod.getArrayType(byteGo);
1326
- const outArrTmp = this.acquireTemp({
1327
- kind: "ref",
1328
- nullable: true,
1329
- typeIndex: arr32Info.typeIndex,
1330
- });
1331
- this.pushInstruction({ op: "i32.const", value: 32 });
1332
- this.pushInstruction({
1333
- op: "array.new_default",
1334
- typeIndex: arr32Info.typeIndex,
1335
- });
1336
- this.pushInstruction({ op: "local.set", index: outArrTmp });
1337
-
1338
- this.pushInstruction({ op: "i32.const", value: 0 });
1339
- this.pushInstruction({ op: "local.set", index: iLoc });
1340
-
1341
- this.pushInstruction({ op: "block", blockType: "void" });
1342
- this.pushInstruction({ op: "loop", blockType: "void" });
1343
- this.pushInstruction({ op: "local.get", index: iLoc });
1344
- this.pushInstruction({ op: "i32.const", value: 32 });
1345
- this.pushInstruction("i32.ge_s");
1346
- this.pushInstruction({ op: "br_if", depth: 1 });
1347
-
1348
- this.pushInstruction({ op: "local.get", index: outArrTmp });
1349
- this.pushInstruction({ op: "local.get", index: iLoc });
1350
- this.pushInstruction({ op: "local.get", index: iLoc });
1351
- this._callStdlib("raw_bytes_get");
1352
- this.pushInstruction({ op: "array.set", typeIndex: arr32Info.typeIndex });
1353
-
1354
- this.pushInstruction({ op: "local.get", index: iLoc });
1355
- this.pushInstruction({ op: "i32.const", value: 1 });
1356
- this.pushInstruction("i32.add");
1357
- this.pushInstruction({ op: "local.set", index: iLoc });
1358
- this.pushInstruction({ op: "br", depth: 0 });
1359
- this.pushInstruction("end");
1360
- this.pushInstruction("end");
1361
-
1362
- this.pushInstruction({ op: "local.get", index: outArrTmp });
1363
-
1364
- this.releaseTemp(outArrTmp, {
1365
- kind: "ref",
1366
- nullable: true,
1367
- typeIndex: arr32Info.typeIndex,
1368
- });
1369
- this.releaseTemp(iLoc, "i32");
1370
- this.releaseTemp(lenTmp, "i32");
1371
- this.releaseTemp(offTmp, "i32");
1372
- this.releaseTemp(arrTmp, arrW);
1373
- this.releaseTemp(sTmp, sliceW);
1374
- return;
1375
- }
1376
-
1377
- if (name === "New") {
1378
- const structInfo = this.mod.getStructType("sha256.digest");
1379
- const byteGo = { kind: "basic", name: "byte" };
1380
- const sliceInfo = this.mod.getSliceType(byteGo);
1381
- const arrInfo = sliceInfo.arrInfo;
1382
-
1383
- this.pushInstruction({ op: "ref.null", heapType: arrInfo.typeIndex });
1384
- this.pushInstruction({ op: "i32.const", value: 0 });
1385
- this.pushInstruction({ op: "i32.const", value: 0 });
1386
- this.pushInstruction({ op: "i32.const", value: 0 });
1387
- this.pushInstruction({
1388
- op: "struct.new",
1389
- typeIndex: sliceInfo.typeIndex,
1390
- });
1391
- this.pushInstruction({
1392
- op: "struct.new",
1393
- typeIndex: structInfo.typeIndex,
1394
- });
1395
- return;
1396
- }
1397
-
1398
- throw new Error(`Unsupported sha256 call: sha256.${name}`);
1399
- }
1400
-
1401
- emitHexCall(name, call, _targetWasmType) {
1402
- const args = call.args;
1403
- const byteGo = { kind: "basic", name: "byte" };
1404
- const sliceInfo = this.mod.getSliceType(byteGo);
1405
- const arrInfo = sliceInfo.arrInfo;
1406
- const sliceW = {
1407
- kind: "ref",
1408
- nullable: true,
1409
- typeIndex: sliceInfo.typeIndex,
1410
- };
1411
- const arrW = {
1412
- kind: "ref",
1413
- nullable: true,
1414
- typeIndex: arrInfo.typeIndex,
1415
- };
1416
-
1417
- if (name === "EncodedLen") {
1418
- this.emitExpr(args[0], "i64");
1419
- this.pushInstruction({ op: "i64.const", value: 2n });
1420
- this.pushInstruction("i64.mul");
1421
- return;
1422
- }
1423
-
1424
- if (name === "DecodedLen") {
1425
- this.emitExpr(args[0], "i64");
1426
- this.pushInstruction({ op: "i64.const", value: 2n });
1427
- this.pushInstruction("i64.div_s");
1428
- return;
1429
- }
1430
-
1431
- if (name === "EncodeToString") {
1432
- const sTmp = this.acquireTemp(sliceW);
1433
- this.emitExpr(args[0], sliceW);
1434
- this.pushInstruction({ op: "local.set", index: sTmp });
1435
-
1436
- const arrTmp = this.acquireTemp(arrW);
1437
- const offTmp = this.acquireTemp("i32");
1438
- const lenTmp = this.acquireTemp("i32");
1439
- this._emitSliceUnpack(sTmp, sliceInfo, {
1440
- arr: arrTmp,
1441
- off: offTmp,
1442
- len: lenTmp,
1443
- });
1444
-
1445
- this.pushInstruction({ op: "local.get", index: lenTmp });
1446
- this._callStdlib("raw_bytes_init");
1447
-
1448
- const iLoc = this.acquireTemp("i32");
1449
- this.pushInstruction({ op: "i32.const", value: 0 });
1450
- this.pushInstruction({ op: "local.set", index: iLoc });
1451
-
1452
- this.pushInstruction({ op: "block", blockType: "void" });
1453
- this.pushInstruction({ op: "loop", blockType: "void" });
1454
- this.pushInstruction({ op: "local.get", index: iLoc });
1455
- this.pushInstruction({ op: "local.get", index: lenTmp });
1456
- this.pushInstruction("i32.ge_s");
1457
- this.pushInstruction({ op: "br_if", depth: 1 });
1458
-
1459
- this.pushInstruction({ op: "local.get", index: arrTmp });
1460
- this.pushInstruction({ op: "local.get", index: offTmp });
1461
- this.pushInstruction({ op: "local.get", index: iLoc });
1462
- this.pushInstruction("i32.add");
1463
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
1464
- this._callStdlib("raw_bytes_push");
1465
-
1466
- this.pushInstruction({ op: "local.get", index: iLoc });
1467
- this.pushInstruction({ op: "i32.const", value: 1 });
1468
- this.pushInstruction("i32.add");
1469
- this.pushInstruction({ op: "local.set", index: iLoc });
1470
- this.pushInstruction({ op: "br", depth: 0 });
1471
- this.pushInstruction("end");
1472
- this.pushInstruction("end");
1473
-
1474
- this._callStdlib("hex_encode_to_string");
1475
-
1476
- this.releaseTemp(iLoc, "i32");
1477
- this.releaseTemp(lenTmp, "i32");
1478
- this.releaseTemp(offTmp, "i32");
1479
- this.releaseTemp(arrTmp, arrW);
1480
- this.releaseTemp(sTmp, sliceW);
1481
- return;
1482
- }
1483
-
1484
- if (name === "DecodeString") {
1485
- this.emitExpr(args[0], "externref");
1486
- this._callStdlib("hex_decode_string");
1487
- const nTmp = this.acquireTemp("i32");
1488
- this.pushInstruction({ op: "local.set", index: nTmp });
1489
-
1490
- this._callStdlib("hex_get_err");
1491
- const errStrTmp = this.acquireTemp("externref");
1492
- this.pushInstruction({ op: "local.set", index: errStrTmp });
1493
-
1494
- const retSliceTmp = this.acquireTemp(sliceW);
1495
- const retErrTmp = this.acquireTemp("anyref");
1496
-
1497
- this.pushInstruction({ op: "local.get", index: errStrTmp });
1498
- this.pushInstruction("ref.is_null");
1499
- this.pushInstruction("i32.eqz");
1500
- this.pushInstruction({ op: "if", blockType: "void" });
1501
-
1502
- // Error case: return nil slice, err
1503
- this.pushInstruction({ op: "ref.null", heapType: arrInfo.typeIndex });
1504
- this.pushInstruction({ op: "i32.const", value: 0 });
1505
- this.pushInstruction({ op: "i32.const", value: 0 });
1506
- this.pushInstruction({ op: "i32.const", value: 0 });
1507
- this.pushInstruction({
1508
- op: "struct.new",
1509
- typeIndex: sliceInfo.typeIndex,
1510
- });
1511
- this.pushInstruction({ op: "local.set", index: retSliceTmp });
1512
-
1513
- this.pushInstruction({ op: "local.get", index: errStrTmp });
1514
- this.pushInstruction({ op: "ref.null", heapType: "any" });
1515
- this.pushInstruction({
1516
- op: "call",
1517
- funcIndex: this.mod.resolveFuncIndex("__mk_error"),
1518
- });
1519
- this.pushInstruction({ op: "local.set", index: retErrTmp });
1520
-
1521
- this.pushInstruction("else");
1522
-
1523
- // Success case: allocate slice and copy bytes
1524
- const outArrTmp = this.acquireTemp(arrW);
1525
- this.pushInstruction({ op: "local.get", index: nTmp });
1526
- this.pushInstruction({
1527
- op: "array.new_default",
1528
- typeIndex: arrInfo.typeIndex,
1529
- });
1530
- this.pushInstruction({ op: "local.set", index: outArrTmp });
1531
-
1532
- const iLoc = this.acquireTemp("i32");
1533
- this.pushInstruction({ op: "i32.const", value: 0 });
1534
- this.pushInstruction({ op: "local.set", index: iLoc });
1535
-
1536
- this.pushInstruction({ op: "block", blockType: "void" });
1537
- this.pushInstruction({ op: "loop", blockType: "void" });
1538
- this.pushInstruction({ op: "local.get", index: iLoc });
1539
- this.pushInstruction({ op: "local.get", index: nTmp });
1540
- this.pushInstruction("i32.ge_s");
1541
- this.pushInstruction({ op: "br_if", depth: 1 });
1542
-
1543
- this.pushInstruction({ op: "local.get", index: outArrTmp });
1544
- this.pushInstruction({ op: "local.get", index: iLoc });
1545
- this.pushInstruction({ op: "local.get", index: iLoc });
1546
- this._callStdlib("raw_bytes_get");
1547
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
1548
-
1549
- this.pushInstruction({ op: "local.get", index: iLoc });
1550
- this.pushInstruction({ op: "i32.const", value: 1 });
1551
- this.pushInstruction("i32.add");
1552
- this.pushInstruction({ op: "local.set", index: iLoc });
1553
- this.pushInstruction({ op: "br", depth: 0 });
1554
- this.pushInstruction("end");
1555
- this.pushInstruction("end");
1556
-
1557
- this.pushInstruction({ op: "local.get", index: outArrTmp });
1558
- this.pushInstruction({ op: "i32.const", value: 0 });
1559
- this.pushInstruction({ op: "local.get", index: nTmp });
1560
- this.pushInstruction({ op: "local.get", index: nTmp });
1561
- this.pushInstruction({
1562
- op: "struct.new",
1563
- typeIndex: sliceInfo.typeIndex,
1564
- });
1565
- this.pushInstruction({ op: "local.set", index: retSliceTmp });
1566
- this.pushInstruction({ op: "ref.null", heapType: "any" });
1567
- this.pushInstruction({ op: "local.set", index: retErrTmp });
1568
-
1569
- this.releaseTemp(iLoc, "i32");
1570
- this.releaseTemp(outArrTmp, arrW);
1571
- this.pushInstruction("end");
1572
-
1573
- this.pushInstruction({ op: "local.get", index: retSliceTmp });
1574
- this.pushInstruction({ op: "local.get", index: retErrTmp });
1575
-
1576
- this.releaseTemp(retSliceTmp, sliceW);
1577
- this.releaseTemp(retErrTmp, "anyref");
1578
- this.releaseTemp(errStrTmp, "externref");
1579
- this.releaseTemp(nTmp, "i32");
1580
- return;
1581
- }
1582
-
1583
- if (name === "Encode") {
1584
- const dstTmp = this.acquireTemp(sliceW);
1585
- this.emitExpr(args[0], sliceW);
1586
- this.pushInstruction({ op: "local.set", index: dstTmp });
1587
-
1588
- const srcTmp = this.acquireTemp(sliceW);
1589
- this.emitExpr(args[1], sliceW);
1590
- this.pushInstruction({ op: "local.set", index: srcTmp });
1591
-
1592
- const srcArr = this.acquireTemp(arrW);
1593
- const srcOff = this.acquireTemp("i32");
1594
- const srcLen = this.acquireTemp("i32");
1595
- this._emitSliceUnpack(srcTmp, sliceInfo, {
1596
- arr: srcArr,
1597
- off: srcOff,
1598
- len: srcLen,
1599
- });
1600
-
1601
- this.pushInstruction({ op: "local.get", index: srcLen });
1602
- this._callStdlib("raw_bytes_init");
1603
-
1604
- const iLoc = this.acquireTemp("i32");
1605
- this.pushInstruction({ op: "i32.const", value: 0 });
1606
- this.pushInstruction({ op: "local.set", index: iLoc });
1607
-
1608
- this.pushInstruction({ op: "block", blockType: "void" });
1609
- this.pushInstruction({ op: "loop", blockType: "void" });
1610
- this.pushInstruction({ op: "local.get", index: iLoc });
1611
- this.pushInstruction({ op: "local.get", index: srcLen });
1612
- this.pushInstruction("i32.ge_s");
1613
- this.pushInstruction({ op: "br_if", depth: 1 });
1614
-
1615
- this.pushInstruction({ op: "local.get", index: srcArr });
1616
- this.pushInstruction({ op: "local.get", index: srcOff });
1617
- this.pushInstruction({ op: "local.get", index: iLoc });
1618
- this.pushInstruction("i32.add");
1619
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
1620
- this._callStdlib("raw_bytes_push");
1621
-
1622
- this.pushInstruction({ op: "local.get", index: iLoc });
1623
- this.pushInstruction({ op: "i32.const", value: 1 });
1624
- this.pushInstruction("i32.add");
1625
- this.pushInstruction({ op: "local.set", index: iLoc });
1626
- this.pushInstruction({ op: "br", depth: 0 });
1627
- this.pushInstruction("end");
1628
- this.pushInstruction("end");
1629
-
1630
- this._callStdlib("hex_encode_to_string");
1631
- const strTmp = this.acquireTemp("externref");
1632
- this.pushInstruction({ op: "local.set", index: strTmp });
1633
-
1634
- const dstArr = this.acquireTemp(arrW);
1635
- const dstOff = this.acquireTemp("i32");
1636
- const dstLen = this.acquireTemp("i32");
1637
- this._emitSliceUnpack(dstTmp, sliceInfo, {
1638
- arr: dstArr,
1639
- off: dstOff,
1640
- len: dstLen,
1641
- });
1642
-
1643
- const hexLenTmp = this.acquireTemp("i32");
1644
- this.pushInstruction({ op: "local.get", index: strTmp });
1645
- this.pushInstruction({
1646
- op: "call",
1647
- funcIndex: this.mod.getStringLenImportIndex(),
1648
- });
1649
- this.pushInstruction({ op: "local.set", index: hexLenTmp });
1650
-
1651
- this.pushInstruction({ op: "i32.const", value: 0 });
1652
- this.pushInstruction({ op: "local.set", index: iLoc });
1653
-
1654
- this.pushInstruction({ op: "block", blockType: "void" });
1655
- this.pushInstruction({ op: "loop", blockType: "void" });
1656
- this.pushInstruction({ op: "local.get", index: iLoc });
1657
- this.pushInstruction({ op: "local.get", index: hexLenTmp });
1658
- this.pushInstruction("i32.ge_s");
1659
- this.pushInstruction({ op: "br_if", depth: 1 });
1660
-
1661
- this.pushInstruction({ op: "local.get", index: dstArr });
1662
- this.pushInstruction({ op: "local.get", index: dstOff });
1663
- this.pushInstruction({ op: "local.get", index: iLoc });
1664
- this.pushInstruction("i32.add");
1665
- this.pushInstruction({ op: "local.get", index: strTmp });
1666
- this.pushInstruction({ op: "local.get", index: iLoc });
1667
- this.pushInstruction({
1668
- op: "call",
1669
- funcIndex: this.mod.getStringCodePointAtImportIndex(),
1670
- });
1671
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
1672
-
1673
- this.pushInstruction({ op: "local.get", index: iLoc });
1674
- this.pushInstruction({ op: "i32.const", value: 1 });
1675
- this.pushInstruction("i32.add");
1676
- this.pushInstruction({ op: "local.set", index: iLoc });
1677
- this.pushInstruction({ op: "br", depth: 0 });
1678
- this.pushInstruction("end");
1679
- this.pushInstruction("end");
1680
-
1681
- this.pushInstruction({ op: "local.get", index: hexLenTmp });
1682
- this.pushInstruction("i64.extend_i32_s");
1683
-
1684
- this.releaseTemp(hexLenTmp, "i32");
1685
- this.releaseTemp(dstLen, "i32");
1686
- this.releaseTemp(dstOff, "i32");
1687
- this.releaseTemp(dstArr, arrW);
1688
- this.releaseTemp(strTmp, "externref");
1689
- this.releaseTemp(iLoc, "i32");
1690
- this.releaseTemp(srcLen, "i32");
1691
- this.releaseTemp(srcOff, "i32");
1692
- this.releaseTemp(srcArr, arrW);
1693
- this.releaseTemp(srcTmp, sliceW);
1694
- this.releaseTemp(dstTmp, sliceW);
1695
- return;
1696
- }
1697
-
1698
- if (name === "Decode") {
1699
- const dstTmp = this.acquireTemp(sliceW);
1700
- this.emitExpr(args[0], sliceW);
1701
- this.pushInstruction({ op: "local.set", index: dstTmp });
1702
-
1703
- const srcTmp = this.acquireTemp(sliceW);
1704
- this.emitExpr(args[1], sliceW);
1705
- this.pushInstruction({ op: "local.set", index: srcTmp });
1706
-
1707
- const srcArr = this.acquireTemp(arrW);
1708
- const srcOff = this.acquireTemp("i32");
1709
- const srcLen = this.acquireTemp("i32");
1710
- this._emitSliceUnpack(srcTmp, sliceInfo, {
1711
- arr: srcArr,
1712
- off: srcOff,
1713
- len: srcLen,
1714
- });
1715
-
1716
- this.pushInstruction({ op: "local.get", index: srcLen });
1717
- this._callStdlib("bytes_to_str_init");
1718
-
1719
- const iLoc = this.acquireTemp("i32");
1720
- this.pushInstruction({ op: "i32.const", value: 0 });
1721
- this.pushInstruction({ op: "local.set", index: iLoc });
1722
-
1723
- this.pushInstruction({ op: "block", blockType: "void" });
1724
- this.pushInstruction({ op: "loop", blockType: "void" });
1725
- this.pushInstruction({ op: "local.get", index: iLoc });
1726
- this.pushInstruction({ op: "local.get", index: srcLen });
1727
- this.pushInstruction("i32.ge_s");
1728
- this.pushInstruction({ op: "br_if", depth: 1 });
1729
-
1730
- this.pushInstruction({ op: "local.get", index: srcArr });
1731
- this.pushInstruction({ op: "local.get", index: srcOff });
1732
- this.pushInstruction({ op: "local.get", index: iLoc });
1733
- this.pushInstruction("i32.add");
1734
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
1735
- this._callStdlib("bytes_to_str_push");
1736
-
1737
- this.pushInstruction({ op: "local.get", index: iLoc });
1738
- this.pushInstruction({ op: "i32.const", value: 1 });
1739
- this.pushInstruction("i32.add");
1740
- this.pushInstruction({ op: "local.set", index: iLoc });
1741
- this.pushInstruction({ op: "br", depth: 0 });
1742
- this.pushInstruction("end");
1743
- this.pushInstruction("end");
1744
-
1745
- this._callStdlib("bytes_to_str_finish");
1746
- this._callStdlib("hex_decode_string");
1747
- const nTmp = this.acquireTemp("i32");
1748
- this.pushInstruction({ op: "local.set", index: nTmp });
1749
-
1750
- this._callStdlib("hex_get_err");
1751
- const errStrTmp = this.acquireTemp("externref");
1752
- this.pushInstruction({ op: "local.set", index: errStrTmp });
1753
-
1754
- const retNTmp = this.acquireTemp("i64");
1755
- const retErrTmp = this.acquireTemp("anyref");
1756
-
1757
- this.pushInstruction({ op: "local.get", index: errStrTmp });
1758
- this.pushInstruction("ref.is_null");
1759
- this.pushInstruction("i32.eqz");
1760
- this.pushInstruction({ op: "if", blockType: "void" });
1761
-
1762
- // Error case
1763
- this.pushInstruction({ op: "i64.const", value: 0n });
1764
- this.pushInstruction({ op: "local.set", index: retNTmp });
1765
- this.pushInstruction({ op: "local.get", index: errStrTmp });
1766
- this.pushInstruction({ op: "ref.null", heapType: "any" });
1767
- this.pushInstruction({
1768
- op: "call",
1769
- funcIndex: this.mod.resolveFuncIndex("__mk_error"),
1770
- });
1771
- this.pushInstruction({ op: "local.set", index: retErrTmp });
1772
-
1773
- this.pushInstruction("else");
1774
-
1775
- // Success case: copy bytes into dst
1776
- const dstArr = this.acquireTemp(arrW);
1777
- const dstOff = this.acquireTemp("i32");
1778
- const dstLen = this.acquireTemp("i32");
1779
- this._emitSliceUnpack(dstTmp, sliceInfo, {
1780
- arr: dstArr,
1781
- off: dstOff,
1782
- len: dstLen,
1783
- });
1784
-
1785
- this.pushInstruction({ op: "i32.const", value: 0 });
1786
- this.pushInstruction({ op: "local.set", index: iLoc });
1787
-
1788
- this.pushInstruction({ op: "block", blockType: "void" });
1789
- this.pushInstruction({ op: "loop", blockType: "void" });
1790
- this.pushInstruction({ op: "local.get", index: iLoc });
1791
- this.pushInstruction({ op: "local.get", index: nTmp });
1792
- this.pushInstruction("i32.ge_s");
1793
- this.pushInstruction({ op: "br_if", depth: 1 });
1794
-
1795
- this.pushInstruction({ op: "local.get", index: dstArr });
1796
- this.pushInstruction({ op: "local.get", index: dstOff });
1797
- this.pushInstruction({ op: "local.get", index: iLoc });
1798
- this.pushInstruction("i32.add");
1799
- this.pushInstruction({ op: "local.get", index: iLoc });
1800
- this._callStdlib("raw_bytes_get");
1801
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
1802
-
1803
- this.pushInstruction({ op: "local.get", index: iLoc });
1804
- this.pushInstruction({ op: "i32.const", value: 1 });
1805
- this.pushInstruction("i32.add");
1806
- this.pushInstruction({ op: "local.set", index: iLoc });
1807
- this.pushInstruction({ op: "br", depth: 0 });
1808
- this.pushInstruction("end");
1809
- this.pushInstruction("end");
1810
-
1811
- this.pushInstruction({ op: "local.get", index: nTmp });
1812
- this.pushInstruction("i64.extend_i32_s");
1813
- this.pushInstruction({ op: "local.set", index: retNTmp });
1814
- this.pushInstruction({ op: "ref.null", heapType: "any" });
1815
- this.pushInstruction({ op: "local.set", index: retErrTmp });
1816
-
1817
- this.releaseTemp(dstLen, "i32");
1818
- this.releaseTemp(dstOff, "i32");
1819
- this.releaseTemp(dstArr, arrW);
1820
- this.pushInstruction("end");
1821
-
1822
- this.pushInstruction({ op: "local.get", index: retNTmp });
1823
- this.pushInstruction({ op: "local.get", index: retErrTmp });
1824
-
1825
- this.releaseTemp(retErrTmp, "anyref");
1826
- this.releaseTemp(retNTmp, "i64");
1827
- this.releaseTemp(errStrTmp, "externref");
1828
- this.releaseTemp(nTmp, "i32");
1829
- this.releaseTemp(iLoc, "i32");
1830
- this.releaseTemp(srcLen, "i32");
1831
- this.releaseTemp(srcOff, "i32");
1832
- this.releaseTemp(srcArr, arrW);
1833
- this.releaseTemp(srcTmp, sliceW);
1834
- this.releaseTemp(dstTmp, sliceW);
1835
- return;
1836
- }
1837
-
1838
- throw new Error(`Unsupported hex call: hex.${name}`);
1839
- }
1840
-
1841
- emitBase64Call(name, call, _targetWasmType) {
1842
- if (name === "NewEncoding") {
1843
- const structInfo = this.mod.getStructType("base64.Encoding");
1844
- this.emitExpr(call.args[0], "externref");
1845
- this._callStdlib("base64_new_encoding");
1846
- this.pushInstruction({
1847
- op: "struct.new",
1848
- typeIndex: structInfo.typeIndex,
1849
- });
1850
- return;
1851
- }
1852
- throw new Error(`Unsupported base64 call: base64.${name}`);
1853
- }
1854
-
1855
- emitBase64EncodingMethodCall(method, recvExpr, args, _targetWasmType) {
1856
- const structInfo = this.mod.getStructType("base64.Encoding");
1857
- const encW = {
1858
- kind: "ref",
1859
- nullable: true,
1860
- typeIndex: structInfo.typeIndex,
1861
- };
1862
- const modeTmp = this.acquireTemp("i32");
1863
-
1864
- if (recvExpr?.field === "URLEncoding") {
1865
- this.pushInstruction({ op: "i32.const", value: 1 });
1866
- this.pushInstruction({ op: "local.set", index: modeTmp });
1867
- } else if (recvExpr?.field === "RawStdEncoding") {
1868
- this.pushInstruction({ op: "i32.const", value: 2 });
1869
- this.pushInstruction({ op: "local.set", index: modeTmp });
1870
- } else if (recvExpr?.field === "RawURLEncoding") {
1871
- this.pushInstruction({ op: "i32.const", value: 3 });
1872
- this.pushInstruction({ op: "local.set", index: modeTmp });
1873
- } else if (recvExpr?.field === "StdEncoding") {
1874
- this.pushInstruction({ op: "i32.const", value: 0 });
1875
- this.pushInstruction({ op: "local.set", index: modeTmp });
1876
- } else {
1877
- const eTmp = this.acquireTemp(encW);
1878
- this.emitExpr(recvExpr, encW);
1879
- this.pushInstruction({ op: "local.tee", index: eTmp });
1880
- this.pushInstruction({
1881
- op: "struct.get",
1882
- typeIndex: structInfo.typeIndex,
1883
- fieldIndex: 0,
1884
- });
1885
- this.pushInstruction({ op: "local.set", index: modeTmp });
1886
- this.releaseTemp(eTmp, encW);
1887
- }
1888
-
1889
- if (method === "EncodedLen") {
1890
- const nTmp = this.acquireTemp("i64");
1891
- this.emitExpr(args[0], "i64");
1892
- this.pushInstruction({ op: "local.set", index: nTmp });
1893
-
1894
- this.pushInstruction({ op: "local.get", index: modeTmp });
1895
- this.pushInstruction({ op: "i32.const", value: 2 });
1896
- this.pushInstruction("i32.and");
1897
- this.pushInstruction({ op: "if", blockType: "i64" });
1898
- // (n * 8 + 5) / 6
1899
- this.pushInstruction({ op: "local.get", index: nTmp });
1900
- this.pushInstruction({ op: "i64.const", value: 8n });
1901
- this.pushInstruction("i64.mul");
1902
- this.pushInstruction({ op: "i64.const", value: 5n });
1903
- this.pushInstruction("i64.add");
1904
- this.pushInstruction({ op: "i64.const", value: 6n });
1905
- this.pushInstruction("i64.div_s");
1906
- this.pushInstruction("else");
1907
- // (n + 2) / 3 * 4
1908
- this.pushInstruction({ op: "local.get", index: nTmp });
1909
- this.pushInstruction({ op: "i64.const", value: 2n });
1910
- this.pushInstruction("i64.add");
1911
- this.pushInstruction({ op: "i64.const", value: 3n });
1912
- this.pushInstruction("i64.div_s");
1913
- this.pushInstruction({ op: "i64.const", value: 4n });
1914
- this.pushInstruction("i64.mul");
1915
- this.pushInstruction("end");
1916
-
1917
- this.releaseTemp(nTmp, "i64");
1918
- this.releaseTemp(modeTmp, "i32");
1919
- return;
1920
- }
1921
-
1922
- if (method === "DecodedLen") {
1923
- this.emitExpr(args[0], "i64");
1924
- this.pushInstruction({ op: "i64.const", value: 3n });
1925
- this.pushInstruction("i64.mul");
1926
- this.pushInstruction({ op: "i64.const", value: 4n });
1927
- this.pushInstruction("i64.div_s");
1928
- this.releaseTemp(modeTmp, "i32");
1929
- return;
1930
- }
1931
-
1932
- const byteGo = { kind: "basic", name: "byte" };
1933
- const sliceInfo = this.mod.getSliceType(byteGo);
1934
- const arrInfo = sliceInfo.arrInfo;
1935
- const sliceW = {
1936
- kind: "ref",
1937
- nullable: true,
1938
- typeIndex: sliceInfo.typeIndex,
1939
- };
1940
- const arrW = {
1941
- kind: "ref",
1942
- nullable: true,
1943
- typeIndex: arrInfo.typeIndex,
1944
- };
1945
-
1946
- if (method === "EncodeToString") {
1947
- const sTmp = this.acquireTemp(sliceW);
1948
- this.emitExpr(args[0], sliceW);
1949
- this.pushInstruction({ op: "local.set", index: sTmp });
1950
-
1951
- const arrTmp = this.acquireTemp(arrW);
1952
- const offTmp = this.acquireTemp("i32");
1953
- const lenTmp = this.acquireTemp("i32");
1954
- this._emitSliceUnpack(sTmp, sliceInfo, {
1955
- arr: arrTmp,
1956
- off: offTmp,
1957
- len: lenTmp,
1958
- });
1959
-
1960
- this.pushInstruction({ op: "local.get", index: lenTmp });
1961
- this._callStdlib("raw_bytes_init");
1962
-
1963
- const iLoc = this.acquireTemp("i32");
1964
- this.pushInstruction({ op: "i32.const", value: 0 });
1965
- this.pushInstruction({ op: "local.set", index: iLoc });
1966
-
1967
- this.pushInstruction({ op: "block", blockType: "void" });
1968
- this.pushInstruction({ op: "loop", blockType: "void" });
1969
- this.pushInstruction({ op: "local.get", index: iLoc });
1970
- this.pushInstruction({ op: "local.get", index: lenTmp });
1971
- this.pushInstruction("i32.ge_s");
1972
- this.pushInstruction({ op: "br_if", depth: 1 });
1973
-
1974
- this.pushInstruction({ op: "local.get", index: arrTmp });
1975
- this.pushInstruction({ op: "local.get", index: offTmp });
1976
- this.pushInstruction({ op: "local.get", index: iLoc });
1977
- this.pushInstruction("i32.add");
1978
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
1979
- this._callStdlib("raw_bytes_push");
1980
-
1981
- this.pushInstruction({ op: "local.get", index: iLoc });
1982
- this.pushInstruction({ op: "i32.const", value: 1 });
1983
- this.pushInstruction("i32.add");
1984
- this.pushInstruction({ op: "local.set", index: iLoc });
1985
- this.pushInstruction({ op: "br", depth: 0 });
1986
- this.pushInstruction("end");
1987
- this.pushInstruction("end");
1988
-
1989
- this.pushInstruction({ op: "local.get", index: modeTmp });
1990
- this._callStdlib("base64_encode_to_string");
1991
-
1992
- this.releaseTemp(iLoc, "i32");
1993
- this.releaseTemp(lenTmp, "i32");
1994
- this.releaseTemp(offTmp, "i32");
1995
- this.releaseTemp(arrTmp, arrW);
1996
- this.releaseTemp(sTmp, sliceW);
1997
- this.releaseTemp(modeTmp, "i32");
1998
- return;
1999
- }
2000
-
2001
- if (method === "DecodeString") {
2002
- this.pushInstruction({ op: "local.get", index: modeTmp });
2003
- this.emitExpr(args[0], "externref");
2004
- this._callStdlib("base64_decode_string");
2005
- const nTmp = this.acquireTemp("i32");
2006
- this.pushInstruction({ op: "local.set", index: nTmp });
2007
-
2008
- this._callStdlib("base64_get_err");
2009
- const errStrTmp = this.acquireTemp("externref");
2010
- this.pushInstruction({ op: "local.set", index: errStrTmp });
2011
-
2012
- const retSliceTmp = this.acquireTemp(sliceW);
2013
- const retErrTmp = this.acquireTemp("anyref");
2014
-
2015
- this.pushInstruction({ op: "local.get", index: errStrTmp });
2016
- this.pushInstruction("ref.is_null");
2017
- this.pushInstruction("i32.eqz");
2018
- this.pushInstruction({ op: "if", blockType: "void" });
2019
-
2020
- // Error case
2021
- this.pushInstruction({ op: "ref.null", heapType: arrInfo.typeIndex });
2022
- this.pushInstruction({ op: "i32.const", value: 0 });
2023
- this.pushInstruction({ op: "i32.const", value: 0 });
2024
- this.pushInstruction({ op: "i32.const", value: 0 });
2025
- this.pushInstruction({
2026
- op: "struct.new",
2027
- typeIndex: sliceInfo.typeIndex,
2028
- });
2029
- this.pushInstruction({ op: "local.set", index: retSliceTmp });
2030
-
2031
- this.pushInstruction({ op: "local.get", index: errStrTmp });
2032
- this.pushInstruction({ op: "ref.null", heapType: "any" });
2033
- this.pushInstruction({
2034
- op: "call",
2035
- funcIndex: this.mod.resolveFuncIndex("__mk_error"),
2036
- });
2037
- this.pushInstruction({ op: "local.set", index: retErrTmp });
2038
-
2039
- this.pushInstruction("else");
2040
-
2041
- // Success case
2042
- const outArrTmp = this.acquireTemp(arrW);
2043
- this.pushInstruction({ op: "local.get", index: nTmp });
2044
- this.pushInstruction({
2045
- op: "array.new_default",
2046
- typeIndex: arrInfo.typeIndex,
2047
- });
2048
- this.pushInstruction({ op: "local.set", index: outArrTmp });
2049
-
2050
- const iLoc = this.acquireTemp("i32");
2051
- this.pushInstruction({ op: "i32.const", value: 0 });
2052
- this.pushInstruction({ op: "local.set", index: iLoc });
2053
-
2054
- this.pushInstruction({ op: "block", blockType: "void" });
2055
- this.pushInstruction({ op: "loop", blockType: "void" });
2056
- this.pushInstruction({ op: "local.get", index: iLoc });
2057
- this.pushInstruction({ op: "local.get", index: nTmp });
2058
- this.pushInstruction("i32.ge_s");
2059
- this.pushInstruction({ op: "br_if", depth: 1 });
2060
-
2061
- this.pushInstruction({ op: "local.get", index: outArrTmp });
2062
- this.pushInstruction({ op: "local.get", index: iLoc });
2063
- this.pushInstruction({ op: "local.get", index: iLoc });
2064
- this._callStdlib("raw_bytes_get");
2065
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
2066
-
2067
- this.pushInstruction({ op: "local.get", index: iLoc });
2068
- this.pushInstruction({ op: "i32.const", value: 1 });
2069
- this.pushInstruction("i32.add");
2070
- this.pushInstruction({ op: "local.set", index: iLoc });
2071
- this.pushInstruction({ op: "br", depth: 0 });
2072
- this.pushInstruction("end");
2073
- this.pushInstruction("end");
2074
-
2075
- this.pushInstruction({ op: "local.get", index: outArrTmp });
2076
- this.pushInstruction({ op: "i32.const", value: 0 });
2077
- this.pushInstruction({ op: "local.get", index: nTmp });
2078
- this.pushInstruction({ op: "local.get", index: nTmp });
2079
- this.pushInstruction({
2080
- op: "struct.new",
2081
- typeIndex: sliceInfo.typeIndex,
2082
- });
2083
- this.pushInstruction({ op: "local.set", index: retSliceTmp });
2084
- this.pushInstruction({ op: "ref.null", heapType: "any" });
2085
- this.pushInstruction({ op: "local.set", index: retErrTmp });
2086
-
2087
- this.releaseTemp(iLoc, "i32");
2088
- this.releaseTemp(outArrTmp, arrW);
2089
- this.pushInstruction("end");
2090
-
2091
- this.pushInstruction({ op: "local.get", index: retSliceTmp });
2092
- this.pushInstruction({ op: "local.get", index: retErrTmp });
2093
-
2094
- this.releaseTemp(retSliceTmp, sliceW);
2095
- this.releaseTemp(retErrTmp, "anyref");
2096
- this.releaseTemp(errStrTmp, "externref");
2097
- this.releaseTemp(nTmp, "i32");
2098
- this.releaseTemp(modeTmp, "i32");
2099
- return;
2100
- }
2101
-
2102
- if (method === "Encode") {
2103
- const dstTmp = this.acquireTemp(sliceW);
2104
- this.emitExpr(args[0], sliceW);
2105
- this.pushInstruction({ op: "local.set", index: dstTmp });
2106
-
2107
- const srcTmp = this.acquireTemp(sliceW);
2108
- this.emitExpr(args[1], sliceW);
2109
- this.pushInstruction({ op: "local.set", index: srcTmp });
2110
-
2111
- const srcArr = this.acquireTemp(arrW);
2112
- const srcOff = this.acquireTemp("i32");
2113
- const srcLen = this.acquireTemp("i32");
2114
- this._emitSliceUnpack(srcTmp, sliceInfo, {
2115
- arr: srcArr,
2116
- off: srcOff,
2117
- len: srcLen,
2118
- });
2119
-
2120
- this.pushInstruction({ op: "local.get", index: srcLen });
2121
- this._callStdlib("raw_bytes_init");
2122
-
2123
- const iLoc = this.acquireTemp("i32");
2124
- this.pushInstruction({ op: "i32.const", value: 0 });
2125
- this.pushInstruction({ op: "local.set", index: iLoc });
2126
-
2127
- this.pushInstruction({ op: "block", blockType: "void" });
2128
- this.pushInstruction({ op: "loop", blockType: "void" });
2129
- this.pushInstruction({ op: "local.get", index: iLoc });
2130
- this.pushInstruction({ op: "local.get", index: srcLen });
2131
- this.pushInstruction("i32.ge_s");
2132
- this.pushInstruction({ op: "br_if", depth: 1 });
2133
-
2134
- this.pushInstruction({ op: "local.get", index: srcArr });
2135
- this.pushInstruction({ op: "local.get", index: srcOff });
2136
- this.pushInstruction({ op: "local.get", index: iLoc });
2137
- this.pushInstruction("i32.add");
2138
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
2139
- this._callStdlib("raw_bytes_push");
2140
-
2141
- this.pushInstruction({ op: "local.get", index: iLoc });
2142
- this.pushInstruction({ op: "i32.const", value: 1 });
2143
- this.pushInstruction("i32.add");
2144
- this.pushInstruction({ op: "local.set", index: iLoc });
2145
- this.pushInstruction({ op: "br", depth: 0 });
2146
- this.pushInstruction("end");
2147
- this.pushInstruction("end");
2148
-
2149
- this.pushInstruction({ op: "local.get", index: modeTmp });
2150
- this._callStdlib("base64_encode_to_string");
2151
- const strTmp = this.acquireTemp("externref");
2152
- this.pushInstruction({ op: "local.set", index: strTmp });
2153
-
2154
- const dstArr = this.acquireTemp(arrW);
2155
- const dstOff = this.acquireTemp("i32");
2156
- const dstLen = this.acquireTemp("i32");
2157
- this._emitSliceUnpack(dstTmp, sliceInfo, {
2158
- arr: dstArr,
2159
- off: dstOff,
2160
- len: dstLen,
2161
- });
2162
-
2163
- const b64LenTmp = this.acquireTemp("i32");
2164
- this.pushInstruction({ op: "local.get", index: strTmp });
2165
- this.pushInstruction({
2166
- op: "call",
2167
- funcIndex: this.mod.getStringLenImportIndex(),
2168
- });
2169
- this.pushInstruction({ op: "local.set", index: b64LenTmp });
2170
-
2171
- this.pushInstruction({ op: "i32.const", value: 0 });
2172
- this.pushInstruction({ op: "local.set", index: iLoc });
2173
-
2174
- this.pushInstruction({ op: "block", blockType: "void" });
2175
- this.pushInstruction({ op: "loop", blockType: "void" });
2176
- this.pushInstruction({ op: "local.get", index: iLoc });
2177
- this.pushInstruction({ op: "local.get", index: b64LenTmp });
2178
- this.pushInstruction("i32.ge_s");
2179
- this.pushInstruction({ op: "br_if", depth: 1 });
2180
-
2181
- this.pushInstruction({ op: "local.get", index: dstArr });
2182
- this.pushInstruction({ op: "local.get", index: dstOff });
2183
- this.pushInstruction({ op: "local.get", index: iLoc });
2184
- this.pushInstruction("i32.add");
2185
- this.pushInstruction({ op: "local.get", index: strTmp });
2186
- this.pushInstruction({ op: "local.get", index: iLoc });
2187
- this.pushInstruction({
2188
- op: "call",
2189
- funcIndex: this.mod.getStringCodePointAtImportIndex(),
2190
- });
2191
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
2192
-
2193
- this.pushInstruction({ op: "local.get", index: iLoc });
2194
- this.pushInstruction({ op: "i32.const", value: 1 });
2195
- this.pushInstruction("i32.add");
2196
- this.pushInstruction({ op: "local.set", index: iLoc });
2197
- this.pushInstruction({ op: "br", depth: 0 });
2198
- this.pushInstruction("end");
2199
- this.pushInstruction("end");
2200
-
2201
- this.releaseTemp(b64LenTmp, "i32");
2202
- this.releaseTemp(dstLen, "i32");
2203
- this.releaseTemp(dstOff, "i32");
2204
- this.releaseTemp(dstArr, arrW);
2205
- this.releaseTemp(strTmp, "externref");
2206
- this.releaseTemp(iLoc, "i32");
2207
- this.releaseTemp(srcLen, "i32");
2208
- this.releaseTemp(srcOff, "i32");
2209
- this.releaseTemp(srcArr, arrW);
2210
- this.releaseTemp(srcTmp, sliceW);
2211
- this.releaseTemp(dstTmp, sliceW);
2212
- this.releaseTemp(modeTmp, "i32");
2213
- return;
2214
- }
2215
-
2216
- if (method === "Decode") {
2217
- const dstTmp = this.acquireTemp(sliceW);
2218
- this.emitExpr(args[0], sliceW);
2219
- this.pushInstruction({ op: "local.set", index: dstTmp });
2220
-
2221
- const srcTmp = this.acquireTemp(sliceW);
2222
- this.emitExpr(args[1], sliceW);
2223
- this.pushInstruction({ op: "local.set", index: srcTmp });
2224
-
2225
- const srcArr = this.acquireTemp(arrW);
2226
- const srcOff = this.acquireTemp("i32");
2227
- const srcLen = this.acquireTemp("i32");
2228
- this._emitSliceUnpack(srcTmp, sliceInfo, {
2229
- arr: srcArr,
2230
- off: srcOff,
2231
- len: srcLen,
2232
- });
2233
-
2234
- this.pushInstruction({ op: "local.get", index: srcLen });
2235
- this._callStdlib("bytes_to_str_init");
2236
-
2237
- const iLoc = this.acquireTemp("i32");
2238
- this.pushInstruction({ op: "i32.const", value: 0 });
2239
- this.pushInstruction({ op: "local.set", index: iLoc });
2240
-
2241
- this.pushInstruction({ op: "block", blockType: "void" });
2242
- this.pushInstruction({ op: "loop", blockType: "void" });
2243
- this.pushInstruction({ op: "local.get", index: iLoc });
2244
- this.pushInstruction({ op: "local.get", index: srcLen });
2245
- this.pushInstruction("i32.ge_s");
2246
- this.pushInstruction({ op: "br_if", depth: 1 });
2247
-
2248
- this.pushInstruction({ op: "local.get", index: srcArr });
2249
- this.pushInstruction({ op: "local.get", index: srcOff });
2250
- this.pushInstruction({ op: "local.get", index: iLoc });
2251
- this.pushInstruction("i32.add");
2252
- this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
2253
- this._callStdlib("bytes_to_str_push");
2254
-
2255
- this.pushInstruction({ op: "local.get", index: iLoc });
2256
- this.pushInstruction({ op: "i32.const", value: 1 });
2257
- this.pushInstruction("i32.add");
2258
- this.pushInstruction({ op: "local.set", index: iLoc });
2259
- this.pushInstruction({ op: "br", depth: 0 });
2260
- this.pushInstruction("end");
2261
- this.pushInstruction("end");
2262
-
2263
- this._callStdlib("bytes_to_str_finish");
2264
- const srcStrTmp = this.acquireTemp("externref");
2265
- this.pushInstruction({ op: "local.set", index: srcStrTmp });
2266
-
2267
- this.pushInstruction({ op: "local.get", index: modeTmp });
2268
- this.pushInstruction({ op: "local.get", index: srcStrTmp });
2269
- this._callStdlib("base64_decode_string");
2270
- const nTmp = this.acquireTemp("i32");
2271
- this.pushInstruction({ op: "local.set", index: nTmp });
2272
-
2273
- this._callStdlib("base64_get_err");
2274
- const errStrTmp = this.acquireTemp("externref");
2275
- this.pushInstruction({ op: "local.set", index: errStrTmp });
2276
-
2277
- const retNTmp = this.acquireTemp("i64");
2278
- const retErrTmp = this.acquireTemp("anyref");
2279
-
2280
- this.pushInstruction({ op: "local.get", index: errStrTmp });
2281
- this.pushInstruction("ref.is_null");
2282
- this.pushInstruction("i32.eqz");
2283
- this.pushInstruction({ op: "if", blockType: "void" });
2284
-
2285
- // Error case
2286
- this.pushInstruction({ op: "i64.const", value: 0n });
2287
- this.pushInstruction({ op: "local.set", index: retNTmp });
2288
- this.pushInstruction({ op: "local.get", index: errStrTmp });
2289
- this.pushInstruction({ op: "ref.null", heapType: "any" });
2290
- this.pushInstruction({
2291
- op: "call",
2292
- funcIndex: this.mod.resolveFuncIndex("__mk_error"),
2293
- });
2294
- this.pushInstruction({ op: "local.set", index: retErrTmp });
2295
-
2296
- this.pushInstruction("else");
2297
-
2298
- // Success case: copy bytes into dst
2299
- const dstArr = this.acquireTemp(arrW);
2300
- const dstOff = this.acquireTemp("i32");
2301
- const dstLen = this.acquireTemp("i32");
2302
- this._emitSliceUnpack(dstTmp, sliceInfo, {
2303
- arr: dstArr,
2304
- off: dstOff,
2305
- len: dstLen,
2306
- });
2307
-
2308
- this.pushInstruction({ op: "i32.const", value: 0 });
2309
- this.pushInstruction({ op: "local.set", index: iLoc });
2310
-
2311
- this.pushInstruction({ op: "block", blockType: "void" });
2312
- this.pushInstruction({ op: "loop", blockType: "void" });
2313
- this.pushInstruction({ op: "local.get", index: iLoc });
2314
- this.pushInstruction({ op: "local.get", index: nTmp });
2315
- this.pushInstruction("i32.ge_s");
2316
- this.pushInstruction({ op: "br_if", depth: 1 });
2317
-
2318
- this.pushInstruction({ op: "local.get", index: dstArr });
2319
- this.pushInstruction({ op: "local.get", index: dstOff });
2320
- this.pushInstruction({ op: "local.get", index: iLoc });
2321
- this.pushInstruction("i32.add");
2322
- this.pushInstruction({ op: "local.get", index: iLoc });
2323
- this._callStdlib("raw_bytes_get");
2324
- this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
2325
-
2326
- this.pushInstruction({ op: "local.get", index: iLoc });
2327
- this.pushInstruction({ op: "i32.const", value: 1 });
2328
- this.pushInstruction("i32.add");
2329
- this.pushInstruction({ op: "local.set", index: iLoc });
2330
- this.pushInstruction({ op: "br", depth: 0 });
2331
- this.pushInstruction("end");
2332
- this.pushInstruction("end");
2333
-
2334
- this.pushInstruction({ op: "local.get", index: nTmp });
2335
- this.pushInstruction("i64.extend_i32_s");
2336
- this.pushInstruction({ op: "local.set", index: retNTmp });
2337
- this.pushInstruction({ op: "ref.null", heapType: "any" });
2338
- this.pushInstruction({ op: "local.set", index: retErrTmp });
2339
-
2340
- this.releaseTemp(dstLen, "i32");
2341
- this.releaseTemp(dstOff, "i32");
2342
- this.releaseTemp(dstArr, arrW);
2343
- this.pushInstruction("end");
2344
-
2345
- this.pushInstruction({ op: "local.get", index: retNTmp });
2346
- this.pushInstruction({ op: "local.get", index: retErrTmp });
2347
-
2348
- this.releaseTemp(retErrTmp, "anyref");
2349
- this.releaseTemp(retNTmp, "i64");
2350
- this.releaseTemp(errStrTmp, "externref");
2351
- this.releaseTemp(nTmp, "i32");
2352
- this.releaseTemp(srcStrTmp, "externref");
2353
- this.releaseTemp(iLoc, "i32");
2354
- this.releaseTemp(srcLen, "i32");
2355
- this.releaseTemp(srcOff, "i32");
2356
- this.releaseTemp(srcArr, arrW);
2357
- this.releaseTemp(srcTmp, sliceW);
2358
- this.releaseTemp(dstTmp, sliceW);
2359
- this.releaseTemp(modeTmp, "i32");
2360
- return;
2361
- }
2362
-
2363
- if (method === "WithPadding") {
2364
- const padTmp = this.acquireTemp("i64");
2365
- this.emitExpr(args[0], "i64");
2366
- this.pushInstruction({ op: "local.set", index: padTmp });
2367
-
2368
- const newModeTmp = this.acquireTemp("i32");
2369
- this.pushInstruction({ op: "local.get", index: padTmp });
2370
- this.pushInstruction({ op: "i64.const", value: -1n });
2371
- this.pushInstruction("i64.eq");
2372
- this.pushInstruction({ op: "if", blockType: "void" });
2373
- this.pushInstruction({ op: "local.get", index: modeTmp });
2374
- this.pushInstruction({ op: "i32.const", value: 1 });
2375
- this.pushInstruction("i32.and");
2376
- this.pushInstruction({ op: "i32.const", value: 2 });
2377
- this.pushInstruction("i32.or");
2378
- this.pushInstruction({ op: "local.set", index: newModeTmp });
2379
- this.pushInstruction("else");
2380
- this.pushInstruction({ op: "local.get", index: modeTmp });
2381
- this.pushInstruction({ op: "i32.const", value: 1 });
2382
- this.pushInstruction("i32.and");
2383
- this.pushInstruction({ op: "local.set", index: newModeTmp });
2384
- this.pushInstruction("end");
2385
-
2386
- this.pushInstruction({ op: "local.get", index: newModeTmp });
2387
- this.pushInstruction({
2388
- op: "struct.new",
2389
- typeIndex: structInfo.typeIndex,
2390
- });
2391
-
2392
- this.releaseTemp(newModeTmp, "i32");
2393
- this.releaseTemp(padTmp, "i64");
2394
- this.releaseTemp(modeTmp, "i32");
2395
- return;
2396
- }
2397
-
2398
- throw new Error(`Unsupported base64 method: ${method}`);
2399
- }
2400
- }