gofront 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +13 -13
  2. package/package.json +8 -37
  3. package/src/backend/js/expressions.js +1341 -148
  4. package/src/backend/js/fmt-runtime.js +573 -0
  5. package/src/backend/js/index.js +375 -57
  6. package/src/backend/js/runtime.js +1460 -133
  7. package/src/backend/js/statements.js +900 -86
  8. package/src/backend/js/stdlib/bits.js +87 -14
  9. package/src/backend/js/stdlib/builder.js +41 -6
  10. package/src/backend/js/stdlib/bytes.js +253 -7
  11. package/src/backend/js/stdlib/errors.js +2 -1
  12. package/src/backend/js/stdlib/fmt.js +349 -10
  13. package/src/backend/js/stdlib/index.js +8 -3
  14. package/src/backend/js/stdlib/json.js +247 -52
  15. package/src/backend/js/stdlib/maps.js +0 -8
  16. package/src/backend/js/stdlib/math.js +17 -1
  17. package/src/backend/js/stdlib/simd.js +10 -0
  18. package/src/backend/js/stdlib/slices.js +36 -6
  19. package/src/backend/js/stdlib/strconv.js +10 -5
  20. package/src/backend/js/stdlib/strings.js +83 -4
  21. package/src/backend/js/stdlib/testing.js +7 -0
  22. package/src/backend/js/stdlib/time.js +79 -55
  23. package/src/backend/js/stdlib/unicode.js +1 -1
  24. package/src/backend/js/stdlib/utf8.js +1 -1
  25. package/src/backend/js/templ.js +38 -76
  26. package/src/backend/js/type-info.js +272 -0
  27. package/src/backend/shared/fmt-types.js +188 -0
  28. package/src/backend/wasm/boundary.js +436 -80
  29. package/src/backend/wasm/emit-builtins.js +303 -13
  30. package/src/backend/wasm/emit-exprs.js +1397 -203
  31. package/src/backend/wasm/emit-maps.js +61 -13
  32. package/src/backend/wasm/emit-stmts.js +1359 -164
  33. package/src/backend/wasm/emit.js +512 -77
  34. package/src/backend/wasm/encode.js +43 -13
  35. package/src/backend/wasm/globals.js +452 -0
  36. package/src/backend/wasm/index.js +194 -2489
  37. package/src/backend/wasm/method-expr.js +381 -0
  38. package/src/backend/wasm/module-emitter.js +2240 -0
  39. package/src/backend/wasm/monomorph.js +62 -4
  40. package/src/backend/wasm/prescan.js +397 -0
  41. package/src/backend/wasm/stdlib/bytes.js +1804 -127
  42. package/src/backend/wasm/stdlib/core.js +1574 -199
  43. package/src/backend/wasm/stdlib/index.js +0 -5
  44. package/src/backend/wasm/stdlib/io.js +1567 -150
  45. package/src/backend/wasm/stdlib/packages.js +2 -0
  46. package/src/backend/wasm/stdlib/simd.js +293 -28
  47. package/src/backend/wasm/stdlib/time.js +1041 -12
  48. package/src/backend/wasm/types.js +200 -15
  49. package/src/backend/wasm/variadic.js +93 -0
  50. package/src/backend/wasm/wat.js +47 -20
  51. package/src/{cli-core.js → cli/cli-core.js} +236 -10
  52. package/src/{test-runner.js → cli/test-runner.js} +332 -39
  53. package/src/{vendor.js → cli/vendor.js} +3 -4
  54. package/src/compiler.js +107 -269
  55. package/src/index.js +15 -169
  56. package/src/{lexer.js → lexer/lexer.js} +102 -55
  57. package/src/{tokens.js → lexer/tokens.js} +1 -0
  58. package/src/link/sourcemap.js +97 -0
  59. package/src/link/stdlib.js +515 -0
  60. package/src/link/wasm.js +294 -0
  61. package/src/lower/bounds.js +394 -0
  62. package/src/lower/boxing.js +1 -1
  63. package/src/lower/captures.js +176 -32
  64. package/src/lower/index.js +26 -18
  65. package/src/lower/json-codecs.js +1398 -0
  66. package/src/lower/ownership.js +22 -1
  67. package/src/lower/range.js +86 -1
  68. package/src/lower/reachability.js +132 -0
  69. package/src/parser/declarations.js +58 -13
  70. package/src/parser/expressions.js +29 -7
  71. package/src/parser/index.js +2 -1
  72. package/src/parser/statements.js +37 -22
  73. package/src/{templ-parser.js → parser/templ.js} +138 -15
  74. package/src/parser/types.js +69 -9
  75. package/src/resolver.js +22 -1
  76. package/src/typechecker/assignability.js +176 -17
  77. package/src/typechecker/const-fold.js +356 -0
  78. package/src/typechecker/constants.js +256 -0
  79. package/src/typechecker/expressions.js +931 -122
  80. package/src/typechecker/index.js +459 -67
  81. package/src/typechecker/init-order.js +330 -0
  82. package/src/typechecker/resolve.js +451 -56
  83. package/src/typechecker/statements.js +90 -9
  84. package/src/typechecker/stdlib/core.js +333 -55
  85. package/src/typechecker/stdlib/excluded.js +898 -0
  86. package/src/typechecker/stdlib/extended.js +322 -26
  87. package/src/typechecker/{stdlib.js → stdlib/index.js} +5 -5
  88. package/src/typechecker/stdlib/simd.js +65 -15
  89. package/src/typechecker/termination.js +1 -1
  90. package/src/typechecker/types.js +149 -25
  91. package/stdlib/bytes/iter.go +192 -0
  92. package/stdlib/bytes/search.go +240 -0
  93. package/stdlib/bytes/split.go +218 -0
  94. package/stdlib/cmp/cmp.go +65 -0
  95. package/stdlib/encoding/json/errors.go +31 -0
  96. package/stdlib/encoding/json/indent.go +71 -0
  97. package/stdlib/encoding/json/number.go +12 -0
  98. package/stdlib/encoding/json/stream.go +173 -0
  99. package/stdlib/errors/overlay.go +12 -0
  100. package/stdlib/hash/hash.go +53 -0
  101. package/stdlib/internal/jsonrt/dec.go +738 -0
  102. package/stdlib/internal/jsonrt/enc.go +366 -0
  103. package/stdlib/internal/jsonrt/indent.go +135 -0
  104. package/stdlib/internal/jsonrt/number.go +27 -0
  105. package/stdlib/internal/jsonrt/reader.go +73 -0
  106. package/stdlib/internal/jsonrt/scanner.go +649 -0
  107. package/stdlib/io/io.go +346 -0
  108. package/stdlib/iter/iter.go +18 -0
  109. package/stdlib/maps/iter.go +65 -0
  110. package/stdlib/math/extra.go +270 -0
  111. package/stdlib/slices/extra.go +73 -0
  112. package/stdlib/slices/iter.go +113 -0
  113. package/stdlib/sort/sort.go +561 -0
  114. package/stdlib/strconv/quote.go +341 -0
  115. package/stdlib/strings/extra.go +35 -0
  116. package/stdlib/strings/iter.go +122 -0
  117. package/stdlib/sync/extra.go +105 -0
  118. package/stdlib/unicode/unicode.go +112 -0
  119. package/stdlib/unicode/utf8/bytes.go +239 -0
  120. package/src/backend/wasm/const-fold.js +0 -205
  121. package/src/backend/wasm/emit-stdlib.js +0 -13
  122. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  123. /package/src/{colors.js → cli/colors.js} +0 -0
  124. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  125. /package/src/{minifier.js → cli/minifier.js} +0 -0
  126. /package/src/{project-config.js → cli/project-config.js} +0 -0
  127. /package/src/{pwa.js → cli/pwa.js} +0 -0
  128. /package/src/{templ-lexer.js → lexer/templ-lexer.js} +0 -0
@@ -96,6 +96,8 @@ export class ExtendedPackagesEmitter {
96
96
  this.pushInstruction("drop");
97
97
  if (method === "TryLock" || method === "TryRLock") {
98
98
  this.pushInstruction({ op: "i32.const", value: 1 });
99
+ } else if (method === "RLocker") {
100
+ this.pushInstruction({ op: "ref.null", type: "any" });
99
101
  }
100
102
  }
101
103
 
@@ -1,13 +1,54 @@
1
1
  // src/backend/wasm/stdlib/simd.js
2
2
  // FunctionEmitter mixin: gofront/simd (F32x4 vector math, load/store, composite literals).
3
3
 
4
- const SIMD_BINARY_OPS = {
4
+ // Methods lowered to one instruction over the receiver and its vector arguments.
5
+ const SIMD_LANEWISE_OPS = {
5
6
  Add: "f32x4.add",
6
7
  Sub: "f32x4.sub",
7
8
  Mul: "f32x4.mul",
8
9
  Div: "f32x4.div",
9
10
  Min: "f32x4.min",
10
11
  Max: "f32x4.max",
12
+ Neg: "f32x4.neg",
13
+ Abs: "f32x4.abs",
14
+ Sqrt: "f32x4.sqrt",
15
+ Floor: "f32x4.floor",
16
+ Ceil: "f32x4.ceil",
17
+ Trunc: "f32x4.trunc",
18
+ RoundToEven: "f32x4.nearest",
19
+ Equal: "f32x4.eq",
20
+ NotEqual: "f32x4.ne",
21
+ Less: "f32x4.lt",
22
+ LessEqual: "f32x4.le",
23
+ Greater: "f32x4.gt",
24
+ GreaterEqual: "f32x4.ge",
25
+ };
26
+
27
+ const SIMD_MASK_OPS = {
28
+ And: "v128.and",
29
+ Or: "v128.or",
30
+ Xor: "v128.xor",
31
+ AndNot: "v128.andnot",
32
+ Not: "v128.not",
33
+ Any: "v128.any_true",
34
+ All: "i32x4.all_true",
35
+ };
36
+
37
+ // Methods with their own emitter: name -> FunctionEmitter method.
38
+ const SIMD_SPECIAL_METHODS = {
39
+ MulAdd: "_emitSimdMulAdd",
40
+ Sum: "_emitSimdSum",
41
+ Swizzle: "_emitSimdSwizzle",
42
+ Dot3: "_emitSimdDot3",
43
+ Dot4: "_emitSimdDot4",
44
+ Lane: "_emitSimdLane",
45
+ WithLane: "_emitSimdWithLane",
46
+ Splat: "_emitSimdSplat",
47
+ };
48
+
49
+ const SIMD_MASK_SPECIAL_METHODS = {
50
+ Bits: "_emitSimdMaskBits",
51
+ Lane: "_emitSimdMaskLane",
11
52
  };
12
53
 
13
54
  export class SimdEmitter {
@@ -59,41 +100,162 @@ export class SimdEmitter {
59
100
  this.releaseTemp(tmp, "v128");
60
101
  }
61
102
 
62
- emitSimdMethodCall(method, recvExpr, args, _targetWasmType) {
63
- const op = SIMD_BINARY_OPS[method];
64
- if (op) {
65
- this.emitExpr(recvExpr, "v128");
66
- this.emitExpr(args[0], "v128");
67
- this.pushInstruction(op);
68
- return true;
69
- }
70
- if (method === "Dot3" || method === "Dot4") {
71
- this._emitSimdDot(recvExpr, args[0], method === "Dot3" ? 3 : 4);
72
- return true;
73
- }
74
- if (method === "Lane") {
75
- const laneIdx = this._constIntValue(args[0]) ?? 0;
76
- this.emitExpr(recvExpr, "v128");
77
- this.pushInstruction({ op: "f32x4.extract_lane", lane: laneIdx });
78
- return true;
103
+ _isSimdMaskType(goType) {
104
+ return (
105
+ goType?.name === "simd.Mask32x4" ||
106
+ goType?.name === "Mask32x4" ||
107
+ goType?.simd === "Mask32x4" ||
108
+ goType?.underlying?.simd === "Mask32x4"
109
+ );
110
+ }
111
+
112
+ // Lane-wise equality of two vectors on the stack -> i32 (Go array `==`:
113
+ // NaN != NaN, -0 == +0).
114
+ _emitSimdEq(goType) {
115
+ this.pushInstruction(
116
+ this._isSimdMaskType(goType) ? "i32x4.eq" : "f32x4.eq",
117
+ );
118
+ this.pushInstruction("i32x4.all_true");
119
+ }
120
+
121
+ _emitSimdSum(recvExpr) {
122
+ this.emitExpr(recvExpr, "v128");
123
+ const tmp = this.acquireTemp("v128");
124
+ this.pushInstruction({ op: "local.set", index: tmp });
125
+ this.pushInstruction({ op: "local.get", index: tmp });
126
+ this.pushInstruction({ op: "f32x4.extract_lane", lane: 0 });
127
+ for (let i = 1; i < 4; i++) {
128
+ this.pushInstruction({ op: "local.get", index: tmp });
129
+ this.pushInstruction({ op: "f32x4.extract_lane", lane: i });
130
+ this.pushInstruction("f32.add");
79
131
  }
80
- if (method === "WithLane") {
81
- const laneIdx = this._constIntValue(args[0]) ?? 0;
82
- this.emitExpr(recvExpr, "v128");
83
- this.emitExpr(args[1], "f32");
84
- this.pushInstruction({ op: "f32x4.replace_lane", lane: laneIdx });
85
- return true;
132
+ this.releaseTemp(tmp, "v128");
133
+ }
134
+
135
+ // Lane i (0-3 from a, 4-7 from b) as the four byte indices of an i8x16.shuffle.
136
+ _simdShuffleBytes(lanes) {
137
+ const out = [];
138
+ for (const lane of lanes) {
139
+ for (let k = 0; k < 4; k++) out.push(lane * 4 + k);
86
140
  }
87
- if (method === "Splat") {
88
- this.emitExpr(args[0], "f32");
89
- this.pushInstruction("f32x4.splat");
141
+ return out;
142
+ }
143
+
144
+ _simdLaneConsts(nodes, max) {
145
+ return nodes.map((n) => {
146
+ const v = this._constIntValue(n);
147
+ if (v === null || v < 0 || v > max)
148
+ throw new Error(`simd: lane index must be a constant in [0, ${max}]`);
149
+ return v;
150
+ });
151
+ }
152
+
153
+ _emitSimdSwizzle(recvExpr, args) {
154
+ const lanes = this._simdLaneConsts(args, 3);
155
+ const tmp = this.acquireTemp("v128");
156
+ this.emitExpr(recvExpr, "v128");
157
+ this.pushInstruction({ op: "local.tee", index: tmp });
158
+ this.pushInstruction({ op: "local.get", index: tmp });
159
+ this.pushInstruction({
160
+ op: "i8x16.shuffle",
161
+ lanes: this._simdShuffleBytes(lanes),
162
+ });
163
+ this.releaseTemp(tmp, "v128");
164
+ }
165
+
166
+ _emitSimdSelect(args) {
167
+ const maskTmp = this.acquireTemp("v128");
168
+ this.emitExpr(args[0], "v128");
169
+ this.pushInstruction({ op: "local.set", index: maskTmp });
170
+ this.emitExpr(args[1], "v128");
171
+ this.emitExpr(args[2], "v128");
172
+ this.pushInstruction({ op: "local.get", index: maskTmp });
173
+ this.pushInstruction("v128.bitselect");
174
+ this.releaseTemp(maskTmp, "v128");
175
+ }
176
+
177
+ _emitSimdShuffle(args) {
178
+ const lanes = this._simdLaneConsts(args.slice(2, 6), 7);
179
+ this.emitExpr(args[0], "v128");
180
+ this.emitExpr(args[1], "v128");
181
+ this.pushInstruction({
182
+ op: "i8x16.shuffle",
183
+ lanes: this._simdShuffleBytes(lanes),
184
+ });
185
+ }
186
+
187
+ _emitSimdOp(op, recvExpr, args) {
188
+ this.emitExpr(recvExpr, "v128");
189
+ for (const arg of args) this.emitExpr(arg, "v128");
190
+ this.pushInstruction(op);
191
+ }
192
+
193
+ _emitSimdMaskBits(recvExpr) {
194
+ this._emitSimdOp("i32x4.bitmask", recvExpr, []);
195
+ this.pushInstruction("i64.extend_i32_u");
196
+ }
197
+
198
+ _emitSimdMaskLane(recvExpr, args) {
199
+ const [lane] = this._simdLaneConsts([args[0]], 3);
200
+ this.emitExpr(recvExpr, "v128");
201
+ this.pushInstruction({ op: "i32x4.extract_lane", lane });
202
+ this.pushInstruction({ op: "i32.const", value: 0 });
203
+ this.pushInstruction("i32.ne");
204
+ }
205
+
206
+ _emitSimdMulAdd(recvExpr, args) {
207
+ // Two roundings (mul, then add), not fused.
208
+ this._emitSimdOp("f32x4.mul", recvExpr, [args[0]]);
209
+ this.emitExpr(args[1], "v128");
210
+ this.pushInstruction("f32x4.add");
211
+ }
212
+
213
+ _emitSimdDot3(recvExpr, args) {
214
+ this._emitSimdDot(recvExpr, args[0], 3);
215
+ }
216
+
217
+ _emitSimdDot4(recvExpr, args) {
218
+ this._emitSimdDot(recvExpr, args[0], 4);
219
+ }
220
+
221
+ _emitSimdLane(recvExpr, args) {
222
+ const lane = this._constIntValue(args[0]) ?? 0;
223
+ this.emitExpr(recvExpr, "v128");
224
+ this.pushInstruction({ op: "f32x4.extract_lane", lane });
225
+ }
226
+
227
+ _emitSimdWithLane(recvExpr, args) {
228
+ const lane = this._constIntValue(args[0]) ?? 0;
229
+ this.emitExpr(recvExpr, "v128");
230
+ this.emitExpr(args[1], "f32");
231
+ this.pushInstruction({ op: "f32x4.replace_lane", lane });
232
+ }
233
+
234
+ _emitSimdSplat(_recvExpr, args) {
235
+ this.emitExpr(args[0], "f32");
236
+ this.pushInstruction("f32x4.splat");
237
+ }
238
+
239
+ emitSimdMethodCall(method, recvExpr, args, _targetWasmType, isMask = false) {
240
+ const ops = isMask ? SIMD_MASK_OPS : SIMD_LANEWISE_OPS;
241
+ const specials = isMask ? SIMD_MASK_SPECIAL_METHODS : SIMD_SPECIAL_METHODS;
242
+ if (ops[method]) {
243
+ this._emitSimdOp(ops[method], recvExpr, args);
90
244
  return true;
91
245
  }
92
- return false;
246
+ if (!specials[method]) return false;
247
+ this[specials[method]](recvExpr, args);
248
+ return true;
93
249
  }
94
250
 
95
251
  emitSimdPackageCall(fn, args, _targetWasmType) {
96
252
  switch (fn) {
253
+ case "Select":
254
+ this._emitSimdSelect(args);
255
+ return true;
256
+ case "Shuffle":
257
+ this._emitSimdShuffle(args);
258
+ return true;
97
259
  case "Splat":
98
260
  this.emitExpr(args[0], "f32");
99
261
  this.pushInstruction("f32x4.splat");
@@ -114,6 +276,15 @@ export class SimdEmitter {
114
276
  case "StoreF32x4":
115
277
  this.emitSimdStore(args[0], args[1], args[2]);
116
278
  return true;
279
+ case "LoadF32x4Slice":
280
+ this.emitSimdSliceAccess(args[0], args[1], null);
281
+ return true;
282
+ case "StoreF32x4Slice":
283
+ this.emitSimdSliceAccess(args[0], args[1], args[2]);
284
+ return true;
285
+ case "Pad4":
286
+ this._emitSimdPad4(args[0]);
287
+ return true;
117
288
  default:
118
289
  return false;
119
290
  }
@@ -190,8 +361,102 @@ export class SimdEmitter {
190
361
  this.pushInstruction({ op: "v128.store", align: 2, offset: 0 });
191
362
  }
192
363
 
364
+ // Pad4(n) = (n + 3) &^ 3; a Go int, so always computed as i64.
365
+ _emitSimdPad4(nNode) {
366
+ this.emitExpr(nNode, "i64");
367
+ this.pushInstruction({ op: "i64.const", value: 3n });
368
+ this.pushInstruction("i64.add");
369
+ this.pushInstruction({ op: "i64.const", value: -4n });
370
+ this.pushInstruction("i64.and");
371
+ }
372
+
373
+ // LoadF32x4Slice (valNode null) and StoreF32x4Slice on a []float32: a
374
+ // GC array cannot be read as v128, so each lane is moved on its own.
375
+ emitSimdSliceAccess(sliceNode, indexNode, valNode) {
376
+ const sliceType = sliceNode._type ?? this._resolveExprGoType(sliceNode);
377
+ const elemGoType = this._getArrayElemType(sliceType);
378
+ const arrInfo = this.mod.getArrayType(elemGoType);
379
+ const sliceInfo = this.mod.getSliceType(elemGoType);
380
+ const sTI = sliceInfo.typeIndex;
381
+ const sliceWType = { kind: "ref", nullable: true, typeIndex: sTI };
382
+ const sliceTmp = this.acquireTemp(sliceWType);
383
+ const idx64 = this.acquireTemp("i64");
384
+ const baseTmp = this.acquireTemp("i32");
385
+ const vecTmp = valNode ? this.acquireTemp("v128") : null;
386
+ const lenOf = () => {
387
+ this.pushInstruction({ op: "local.get", index: sliceTmp });
388
+ this.pushInstruction({ op: "struct.get", typeIndex: sTI, fieldIndex: 2 });
389
+ };
390
+
391
+ this.emitExpr(sliceNode, sliceWType);
392
+ this.pushInstruction({ op: "local.set", index: sliceTmp });
393
+ if (this._isI32IndexExpr(indexNode)) {
394
+ this.emitExpr(indexNode, "i32");
395
+ this.pushInstruction("i64.extend_i32_s");
396
+ } else {
397
+ this.emitExpr(indexNode, "i64");
398
+ }
399
+ this.pushInstruction({ op: "local.set", index: idx64 });
400
+ if (valNode) {
401
+ this.emitExpr(valNode, "v128");
402
+ this.pushInstruction({ op: "local.set", index: vecTmp });
403
+ }
404
+
405
+ // Out of range when len < 4 or unsigned(i) > len - 4 (negative i wraps).
406
+ lenOf();
407
+ this.pushInstruction({ op: "i32.const", value: 4 });
408
+ this.pushInstruction("i32.lt_u");
409
+ this._emitBoundsBranch();
410
+ this.pushInstruction({ op: "local.get", index: idx64 });
411
+ lenOf();
412
+ this.pushInstruction({ op: "i32.const", value: 4 });
413
+ this.pushInstruction("i32.sub");
414
+ this.pushInstruction("i64.extend_i32_u");
415
+ this.pushInstruction("i64.gt_u");
416
+ this._emitBoundsBranch();
417
+
418
+ this.pushInstruction({ op: "local.get", index: sliceTmp });
419
+ this.pushInstruction({ op: "struct.get", typeIndex: sTI, fieldIndex: 1 });
420
+ this.pushInstruction({ op: "local.get", index: idx64 });
421
+ this.pushInstruction("i32.wrap_i64");
422
+ this.pushInstruction("i32.add");
423
+ this.pushInstruction({ op: "local.set", index: baseTmp });
424
+
425
+ const elemAt = (lane) => {
426
+ this.pushInstruction({ op: "local.get", index: sliceTmp });
427
+ this.pushInstruction({ op: "struct.get", typeIndex: sTI, fieldIndex: 0 });
428
+ this.pushInstruction({ op: "local.get", index: baseTmp });
429
+ if (lane) {
430
+ this.pushInstruction({ op: "i32.const", value: lane });
431
+ this.pushInstruction("i32.add");
432
+ }
433
+ };
434
+ if (valNode) {
435
+ for (let lane = 0; lane < 4; lane++) {
436
+ elemAt(lane);
437
+ this.pushInstruction({ op: "local.get", index: vecTmp });
438
+ this.pushInstruction({ op: "f32x4.extract_lane", lane });
439
+ this.pushInstruction({ op: "array.set", typeIndex: arrInfo.typeIndex });
440
+ }
441
+ } else {
442
+ elemAt(0);
443
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
444
+ this.pushInstruction("f32x4.splat");
445
+ for (let lane = 1; lane < 4; lane++) {
446
+ elemAt(lane);
447
+ this.pushInstruction({ op: "array.get", typeIndex: arrInfo.typeIndex });
448
+ this.pushInstruction({ op: "f32x4.replace_lane", lane });
449
+ }
450
+ }
451
+ if (vecTmp !== null) this.releaseTemp(vecTmp, "v128");
452
+ this.releaseTemp(baseTmp, "i32");
453
+ this.releaseTemp(idx64, "i64");
454
+ this.releaseTemp(sliceTmp, sliceWType);
455
+ }
456
+
193
457
  _constIntValue(node) {
194
458
  if (!node) return null;
459
+ if (typeof node._constInt === "number") return node._constInt;
195
460
  if (node.kind === "BasicLit" && node.litKind === "INT") {
196
461
  return Number(node.value);
197
462
  }