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
@@ -4,13 +4,35 @@
4
4
 
5
5
  import {
6
6
  isArrayType,
7
+ isComplex,
8
+ isComplex64,
7
9
  isInterfaceType,
8
10
  isPointerToStruct,
9
- isSigned,
10
11
  isStringType,
11
12
  toWasmType,
12
13
  } from "./types.js";
13
14
 
15
+ function _complexTypeFor(mod, t) {
16
+ if (!isComplex(t)) return null;
17
+ const is64 = isComplex64(t);
18
+ return mod.getComplexType(is64 ? "complex64" : "complex128");
19
+ }
20
+
21
+ function _resolveStructType(mod, goType) {
22
+ let t = goType;
23
+ while (t && (t.kind === "TypeName" || t.kind === "Ident")) {
24
+ const info = mod.getStructType(t.name);
25
+ if (info) return info;
26
+ const resolved = mod.checker?.types?.get(t.name);
27
+ if (!resolved || resolved === t) break;
28
+ t = resolved;
29
+ }
30
+ if (t?.kind === "named") return mod.getStructType(t.name) ?? null;
31
+ if ((t?.kind === "struct" || t?.kind === "StructType") && t.name)
32
+ return mod.getStructType(t.name) ?? null;
33
+ return null;
34
+ }
35
+
14
36
  export class MapsEmitter {
15
37
  emitMapHelper(fn) {
16
38
  const kind = fn._mapHelperKind;
@@ -20,10 +42,10 @@ export class MapsEmitter {
20
42
  this.emitMapMake(mapInfo);
21
43
  break;
22
44
  case "get":
23
- this.emitMapGet(mapInfo);
45
+ this.emitMapLookup(mapInfo, false);
24
46
  break;
25
47
  case "get_ok":
26
- this.emitMapGetOk(mapInfo);
48
+ this.emitMapLookup(mapInfo, true);
27
49
  break;
28
50
  case "set":
29
51
  this.emitMapSet(mapInfo);
@@ -38,31 +60,19 @@ export class MapsEmitter {
38
60
  this.emitMapClear(mapInfo);
39
61
  break;
40
62
  case "keys":
41
- this.emitMapKeys(mapInfo);
63
+ this.emitMapProject(mapInfo, false);
42
64
  break;
43
65
  case "values":
44
- this.emitMapValues(mapInfo);
45
- break;
46
- case "clone":
47
- this.emitMapClone(mapInfo);
66
+ this.emitMapProject(mapInfo, true);
48
67
  break;
49
68
  }
50
69
  }
51
70
 
52
- // Struct info for a Go type used as a map key (named struct or alias).
71
+ // Struct info for a Go type used as a map key (named struct, alias, or complex).
53
72
  _structInfoForGoType(goType) {
54
- let t = goType;
55
- while (t && (t.kind === "TypeName" || t.kind === "Ident")) {
56
- const info = this.mod.getStructType(t.name);
57
- if (info) return info;
58
- const resolved = this.mod.checker?.types?.get(t.name);
59
- if (!resolved || resolved === t) break;
60
- t = resolved;
61
- }
62
- if (t?.kind === "named") return this.mod.getStructType(t.name) ?? null;
63
- if ((t?.kind === "struct" || t?.kind === "StructType") && t.name)
64
- return this.mod.getStructType(t.name) ?? null;
65
- return null;
73
+ return (
74
+ _complexTypeFor(this.mod, goType) ?? _resolveStructType(this.mod, goType)
75
+ );
66
76
  }
67
77
 
68
78
  _unsupportedMapKey(_keyGoType) {
@@ -166,6 +176,34 @@ export class MapsEmitter {
166
176
  this.pushInstruction("i32.mul");
167
177
  return;
168
178
  }
179
+ if (wType === "v128") {
180
+ // Lane-wise like a [4]float32 key: h = 17; h = h*31 + hash(lane).
181
+ const isMask = this._isSimdMaskType(keyGoType);
182
+ const laneType = {
183
+ kind: "basic",
184
+ name: isMask ? "int32" : "float32",
185
+ };
186
+ const h = this.allocLocal(null, "i32");
187
+ this.pushInstruction({ op: "i32.const", value: 17 });
188
+ this.pushInstruction({ op: "local.set", index: h });
189
+ for (let lane = 0; lane < 4; lane++) {
190
+ const lt = this.allocLocal(null, isMask ? "i32" : "f32");
191
+ this.pushInstruction({ op: "local.get", index: keyLocal });
192
+ this.pushInstruction({
193
+ op: isMask ? "i32x4.extract_lane" : "f32x4.extract_lane",
194
+ lane,
195
+ });
196
+ this.pushInstruction({ op: "local.set", index: lt });
197
+ this.pushInstruction({ op: "local.get", index: h });
198
+ this.pushInstruction({ op: "i32.const", value: 31 });
199
+ this.pushInstruction("i32.mul");
200
+ this.emitKeyHash(lt, laneType);
201
+ this.pushInstruction("i32.add");
202
+ this.pushInstruction({ op: "local.set", index: h });
203
+ }
204
+ this.pushInstruction({ op: "local.get", index: h });
205
+ return;
206
+ }
169
207
  // Floats: `x + 0.0` folds -0 onto +0 (they are equal keys in Go) and
170
208
  // NaN elements never match (f32.eq/f64.eq returns false in key comparison).
171
209
  if (wType === "f32") {
@@ -336,6 +374,12 @@ export class MapsEmitter {
336
374
  this.pushInstruction("f64.eq");
337
375
  return;
338
376
  }
377
+ if (wType === "v128") {
378
+ this.pushInstruction({ op: "local.get", index: k1Local });
379
+ this.pushInstruction({ op: "local.get", index: k2Local });
380
+ this._emitSimdEq(keyGoType);
381
+ return;
382
+ }
339
383
  const structInfo = this._structInfoForGoType(keyGoType);
340
384
  if (
341
385
  structInfo &&
@@ -373,44 +417,6 @@ export class MapsEmitter {
373
417
  this.pushInstruction("ref.eq");
374
418
  }
375
419
 
376
- emitElemLt(v1Loc, v2Loc, elemGoType) {
377
- if (isStringType(elemGoType, this.mod.checker)) {
378
- this.pushInstruction({ op: "local.get", index: v1Loc });
379
- this.pushInstruction({ op: "local.get", index: v2Loc });
380
- this.pushInstruction({
381
- op: "call",
382
- funcIndex: this.mod.getStringCmpImportIndex("<"),
383
- });
384
- return;
385
- }
386
- const wType = toWasmType(elemGoType, this.mod.checker, this.mod);
387
- if (wType === "i64") {
388
- this.pushInstruction({ op: "local.get", index: v1Loc });
389
- this.pushInstruction({ op: "local.get", index: v2Loc });
390
- this.pushInstruction(isSigned(elemGoType) ? "i64.lt_s" : "i64.lt_u");
391
- return;
392
- }
393
- if (wType === "i32") {
394
- this.pushInstruction({ op: "local.get", index: v1Loc });
395
- this.pushInstruction({ op: "local.get", index: v2Loc });
396
- this.pushInstruction(isSigned(elemGoType) ? "i32.lt_s" : "i32.lt_u");
397
- return;
398
- }
399
- if (wType === "f32") {
400
- this.pushInstruction({ op: "local.get", index: v1Loc });
401
- this.pushInstruction({ op: "local.get", index: v2Loc });
402
- this.pushInstruction("f32.lt");
403
- return;
404
- }
405
- if (wType === "f64") {
406
- this.pushInstruction({ op: "local.get", index: v1Loc });
407
- this.pushInstruction({ op: "local.get", index: v2Loc });
408
- this.pushInstruction("f64.lt");
409
- return;
410
- }
411
- this.pushInstruction({ op: "i32.const", value: 0 });
412
- }
413
-
414
420
  emitMapMake(mapInfo) {
415
421
  const nBucketsLoc = this.allocLocal(null, "i32");
416
422
  const cLoc = this.allocLocal(null, "i32");
@@ -488,7 +494,7 @@ export class MapsEmitter {
488
494
  this.pushInstruction({ op: "return" });
489
495
  }
490
496
 
491
- emitMapGet(mapInfo) {
497
+ emitMapLookup(mapInfo, withOk) {
492
498
  const hLoc = this.allocLocal(null, "i32");
493
499
  const bLoc = this.allocLocal(null, "i32");
494
500
  const idxLoc = this.allocLocal(null, "i32");
@@ -499,11 +505,12 @@ export class MapsEmitter {
499
505
  });
500
506
  const entryKeyLoc = this.allocLocal(null, mapInfo.keyWType);
501
507
 
502
- // If m == null -> return zero
508
+ // If m == null -> return zero (and false when withOk)
503
509
  this.pushInstruction({ op: "local.get", index: 0 });
504
510
  this.pushInstruction("ref.is_null");
505
511
  this.pushInstruction({ op: "if", blockType: "void" });
506
512
  this.emitZeroValue(mapInfo.valGoType, mapInfo.valWType);
513
+ if (withOk) this.pushInstruction({ op: "i32.const", value: 0 });
507
514
  this.pushInstruction({ op: "return" });
508
515
  this.pushInstruction("end");
509
516
 
@@ -585,6 +592,7 @@ export class MapsEmitter {
585
592
  typeIndex: mapInfo.entryTypeIndex,
586
593
  fieldIndex: 1,
587
594
  });
595
+ if (withOk) this.pushInstruction({ op: "i32.const", value: 1 });
588
596
  this.pushInstruction({ op: "return" });
589
597
  this.pushInstruction("end");
590
598
  this.pushInstruction("end");
@@ -602,121 +610,7 @@ export class MapsEmitter {
602
610
 
603
611
  // Not found
604
612
  this.emitZeroValue(mapInfo.valGoType, mapInfo.valWType);
605
- this.pushInstruction({ op: "return" });
606
- }
607
-
608
- emitMapGetOk(mapInfo) {
609
- const hLoc = this.allocLocal(null, "i32");
610
- const bLoc = this.allocLocal(null, "i32");
611
- const idxLoc = this.allocLocal(null, "i32");
612
- const entryLoc = this.allocLocal(null, {
613
- kind: "ref",
614
- nullable: true,
615
- typeIndex: mapInfo.entryTypeIndex,
616
- });
617
- const entryKeyLoc = this.allocLocal(null, mapInfo.keyWType);
618
-
619
- // If m == null -> return zero, false
620
- this.pushInstruction({ op: "local.get", index: 0 });
621
- this.pushInstruction("ref.is_null");
622
- this.pushInstruction({ op: "if", blockType: "void" });
623
- this.emitZeroValue(mapInfo.valGoType, mapInfo.valWType);
624
- this.pushInstruction({ op: "i32.const", value: 0 });
625
- this.pushInstruction({ op: "return" });
626
- this.pushInstruction("end");
627
-
628
- this.emitKeyHash(1, mapInfo.keyGoType);
629
- this.pushInstruction({ op: "local.set", index: hLoc });
630
-
631
- this.pushInstruction({ op: "local.get", index: hLoc });
632
- this.pushInstruction({ op: "local.get", index: 0 });
633
- this.pushInstruction({
634
- op: "struct.get",
635
- typeIndex: mapInfo.typeIndex,
636
- fieldIndex: 8,
637
- });
638
- this.pushInstruction({ op: "i32.const", value: 1 });
639
- this.pushInstruction("i32.sub");
640
- this.pushInstruction("i32.and");
641
- this.pushInstruction({ op: "local.set", index: bLoc });
642
-
643
- this.pushInstruction({ op: "local.get", index: 0 });
644
- this.pushInstruction({
645
- op: "struct.get",
646
- typeIndex: mapInfo.typeIndex,
647
- fieldIndex: 0,
648
- });
649
- this.pushInstruction({ op: "local.get", index: bLoc });
650
- this.pushInstruction({
651
- op: "array.get",
652
- typeIndex: mapInfo.bucketsTypeIndex,
653
- });
654
- this.pushInstruction({ op: "local.set", index: idxLoc });
655
-
656
- this.pushInstruction({ op: "block", blockType: "void" });
657
- this.pushInstruction({ op: "loop", blockType: "void" });
658
- this.pushInstruction({ op: "local.get", index: idxLoc });
659
- this.pushInstruction({ op: "i32.const", value: -1 });
660
- this.pushInstruction("i32.eq");
661
- this.pushInstruction({ op: "br_if", depth: 1 });
662
-
663
- this.pushInstruction({ op: "local.get", index: 0 });
664
- this.pushInstruction({
665
- op: "struct.get",
666
- typeIndex: mapInfo.typeIndex,
667
- fieldIndex: 1,
668
- });
669
- this.pushInstruction({ op: "local.get", index: idxLoc });
670
- this.pushInstruction({
671
- op: "array.get",
672
- typeIndex: mapInfo.entriesTypeIndex,
673
- });
674
- this.pushInstruction({ op: "local.set", index: entryLoc });
675
-
676
- this.pushInstruction({ op: "local.get", index: entryLoc });
677
- this.pushInstruction({
678
- op: "struct.get",
679
- typeIndex: mapInfo.entryTypeIndex,
680
- fieldIndex: 5,
681
- });
682
- this.pushInstruction({ op: "i32.const", value: 1 });
683
- this.pushInstruction("i32.eq");
684
- this.pushInstruction({ op: "if", blockType: "void" });
685
-
686
- this.pushInstruction({ op: "local.get", index: entryLoc });
687
- this.pushInstruction({
688
- op: "struct.get",
689
- typeIndex: mapInfo.entryTypeIndex,
690
- fieldIndex: 0,
691
- });
692
- this.pushInstruction({ op: "local.set", index: entryKeyLoc });
693
-
694
- this.emitKeyEq(1, entryKeyLoc, mapInfo.keyGoType);
695
- this.pushInstruction({ op: "if", blockType: "void" });
696
- this.pushInstruction({ op: "local.get", index: entryLoc });
697
- this.pushInstruction({
698
- op: "struct.get",
699
- typeIndex: mapInfo.entryTypeIndex,
700
- fieldIndex: 1,
701
- });
702
- this.pushInstruction({ op: "i32.const", value: 1 });
703
- this.pushInstruction({ op: "return" });
704
- this.pushInstruction("end");
705
- this.pushInstruction("end");
706
-
707
- this.pushInstruction({ op: "local.get", index: entryLoc });
708
- this.pushInstruction({
709
- op: "struct.get",
710
- typeIndex: mapInfo.entryTypeIndex,
711
- fieldIndex: 2,
712
- });
713
- this.pushInstruction({ op: "local.set", index: idxLoc });
714
- this.pushInstruction({ op: "br", depth: 0 });
715
- this.pushInstruction("end");
716
- this.pushInstruction("end");
717
-
718
- this.emitZeroValue(mapInfo.valGoType, mapInfo.valWType);
719
- this.pushInstruction({ op: "i32.const", value: 0 });
613
+ if (withOk) this.pushInstruction({ op: "i32.const", value: 0 });
720
614
  this.pushInstruction({ op: "return" });
721
615
  }
722
616
 
@@ -1144,6 +1038,9 @@ export class MapsEmitter {
1144
1038
 
1145
1039
  // new_entry = struct.new (key, val, next=buckets[b], order_prev=oldTail, order_next=-1, active=1)
1146
1040
  this.pushInstruction({ op: "local.get", index: 1 });
1041
+ // The stored key is a copy: later writes to the caller's array or
1042
+ // struct must not change the map's key.
1043
+ this._emitCopyMapEntry(mapInfo.keyGoType, mapInfo.keyWType);
1147
1044
  this.pushInstruction({ op: "local.get", index: 2 });
1148
1045
  this.pushInstruction({ op: "local.get", index: 0 });
1149
1046
  this.pushInstruction({
@@ -1684,120 +1581,10 @@ export class MapsEmitter {
1684
1581
  this.pushInstruction({ op: "return" });
1685
1582
  }
1686
1583
 
1687
- emitMapKeys(mapInfo) {
1688
- const sliceInfo = this.mod.getSliceType(mapInfo.keyGoType);
1689
- const lenLoc = this.allocLocal(null, "i32");
1690
- const arrLoc = this.allocLocal(null, {
1691
- kind: "ref",
1692
- nullable: true,
1693
- typeIndex: sliceInfo.arrInfo.typeIndex,
1694
- });
1695
- const iLoc = this.allocLocal(null, "i32");
1696
- const idxLoc = this.allocLocal(null, "i32");
1697
- const entryLoc = this.allocLocal(null, {
1698
- kind: "ref",
1699
- nullable: true,
1700
- typeIndex: mapInfo.entryTypeIndex,
1701
- });
1702
-
1703
- this.pushInstruction({ op: "local.get", index: 0 });
1704
- this.pushInstruction("ref.is_null");
1705
- this.pushInstruction({ op: "if", blockType: "void" });
1706
- this.pushInstruction({
1707
- op: "global.get",
1708
- index: sliceInfo.emptyGlobalIndex,
1709
- });
1710
- this.pushInstruction({ op: "return" });
1711
- this.pushInstruction("end");
1712
-
1713
- this.pushInstruction({ op: "local.get", index: 0 });
1714
- this.pushInstruction({
1715
- op: "struct.get",
1716
- typeIndex: mapInfo.typeIndex,
1717
- fieldIndex: 2,
1718
- });
1719
- this.pushInstruction({ op: "local.set", index: lenLoc });
1720
-
1721
- this.pushInstruction({ op: "local.get", index: lenLoc });
1722
- this.pushInstruction({
1723
- op: "array.new_default",
1724
- typeIndex: sliceInfo.arrInfo.typeIndex,
1725
- });
1726
- this.pushInstruction({ op: "local.set", index: arrLoc });
1727
-
1728
- this.pushInstruction({ op: "i32.const", value: 0 });
1729
- this.pushInstruction({ op: "local.set", index: iLoc });
1730
-
1731
- this.pushInstruction({ op: "local.get", index: 0 });
1732
- this.pushInstruction({
1733
- op: "struct.get",
1734
- typeIndex: mapInfo.typeIndex,
1735
- fieldIndex: 5,
1736
- });
1737
- this.pushInstruction({ op: "local.set", index: idxLoc });
1738
-
1739
- this.pushInstruction({ op: "block", blockType: "void" });
1740
- this.pushInstruction({ op: "loop", blockType: "void" });
1741
- this.pushInstruction({ op: "local.get", index: idxLoc });
1742
- this.pushInstruction({ op: "i32.const", value: -1 });
1743
- this.pushInstruction("i32.eq");
1744
- this.pushInstruction({ op: "br_if", depth: 1 });
1745
-
1746
- this.pushInstruction({ op: "local.get", index: 0 });
1747
- this.pushInstruction({
1748
- op: "struct.get",
1749
- typeIndex: mapInfo.typeIndex,
1750
- fieldIndex: 1,
1751
- });
1752
- this.pushInstruction({ op: "local.get", index: idxLoc });
1753
- this.pushInstruction({
1754
- op: "array.get",
1755
- typeIndex: mapInfo.entriesTypeIndex,
1756
- });
1757
- this.pushInstruction({ op: "local.set", index: entryLoc });
1758
-
1759
- this.pushInstruction({ op: "local.get", index: arrLoc });
1760
- this.pushInstruction({ op: "local.get", index: iLoc });
1761
- this.pushInstruction({ op: "local.get", index: entryLoc });
1762
- this.pushInstruction({
1763
- op: "struct.get",
1764
- typeIndex: mapInfo.entryTypeIndex,
1765
- fieldIndex: 0,
1766
- });
1767
- this.pushInstruction({
1768
- op: "array.set",
1769
- typeIndex: sliceInfo.arrInfo.typeIndex,
1770
- });
1771
-
1772
- this.pushInstruction({ op: "local.get", index: iLoc });
1773
- this.pushInstruction({ op: "i32.const", value: 1 });
1774
- this.pushInstruction("i32.add");
1775
- this.pushInstruction({ op: "local.set", index: iLoc });
1776
-
1777
- this.pushInstruction({ op: "local.get", index: entryLoc });
1778
- this.pushInstruction({
1779
- op: "struct.get",
1780
- typeIndex: mapInfo.entryTypeIndex,
1781
- fieldIndex: 4,
1782
- });
1783
- this.pushInstruction({ op: "local.set", index: idxLoc });
1784
- this.pushInstruction({ op: "br", depth: 0 });
1785
- this.pushInstruction("end");
1786
- this.pushInstruction("end");
1787
-
1788
- this.pushInstruction({ op: "local.get", index: arrLoc });
1789
- this.pushInstruction({ op: "i32.const", value: 0 });
1790
- this.pushInstruction({ op: "local.get", index: lenLoc });
1791
- this.pushInstruction({ op: "local.get", index: lenLoc });
1792
- this.pushInstruction({
1793
- op: "struct.new",
1794
- typeIndex: sliceInfo.typeIndex,
1795
- });
1796
- this.pushInstruction({ op: "return" });
1797
- }
1798
-
1799
- emitMapValues(mapInfo) {
1800
- const sliceInfo = this.mod.getSliceType(mapInfo.valGoType);
1584
+ emitMapProject(mapInfo, isValues) {
1585
+ const sliceInfo = this.mod.getSliceType(
1586
+ isValues ? mapInfo.valGoType : mapInfo.keyGoType,
1587
+ );
1801
1588
  const lenLoc = this.allocLocal(null, "i32");
1802
1589
  const arrLoc = this.allocLocal(null, {
1803
1590
  kind: "ref",
@@ -1874,7 +1661,7 @@ export class MapsEmitter {
1874
1661
  this.pushInstruction({
1875
1662
  op: "struct.get",
1876
1663
  typeIndex: mapInfo.entryTypeIndex,
1877
- fieldIndex: 1,
1664
+ fieldIndex: isValues ? 1 : 0,
1878
1665
  });
1879
1666
  this.pushInstruction({
1880
1667
  op: "array.set",
@@ -1907,93 +1694,4 @@ export class MapsEmitter {
1907
1694
  });
1908
1695
  this.pushInstruction({ op: "return" });
1909
1696
  }
1910
-
1911
- emitMapClone(mapInfo) {
1912
- const dstLoc = this.allocLocal(null, mapInfo.wType);
1913
- const idxLoc = this.allocLocal(null, "i32");
1914
- const entryLoc = this.allocLocal(null, {
1915
- kind: "ref",
1916
- nullable: true,
1917
- typeIndex: mapInfo.entryTypeIndex,
1918
- });
1919
-
1920
- this.pushInstruction({ op: "local.get", index: 0 });
1921
- this.pushInstruction("ref.is_null");
1922
- this.pushInstruction({ op: "if", blockType: "void" });
1923
- this.pushInstruction({ op: "ref.null", heapType: mapInfo.typeIndex });
1924
- this.pushInstruction({ op: "return" });
1925
- this.pushInstruction("end");
1926
-
1927
- this.pushInstruction({ op: "local.get", index: 0 });
1928
- this.pushInstruction({
1929
- op: "struct.get",
1930
- typeIndex: mapInfo.typeIndex,
1931
- fieldIndex: 2,
1932
- });
1933
- this.pushInstruction({
1934
- op: "call",
1935
- funcIndex: this.mod.resolveFuncIndex(mapInfo.makeFuncName),
1936
- });
1937
- this.pushInstruction({ op: "local.set", index: dstLoc });
1938
-
1939
- this.pushInstruction({ op: "local.get", index: 0 });
1940
- this.pushInstruction({
1941
- op: "struct.get",
1942
- typeIndex: mapInfo.typeIndex,
1943
- fieldIndex: 5,
1944
- });
1945
- this.pushInstruction({ op: "local.set", index: idxLoc });
1946
-
1947
- this.pushInstruction({ op: "block", blockType: "void" });
1948
- this.pushInstruction({ op: "loop", blockType: "void" });
1949
- this.pushInstruction({ op: "local.get", index: idxLoc });
1950
- this.pushInstruction({ op: "i32.const", value: -1 });
1951
- this.pushInstruction("i32.eq");
1952
- this.pushInstruction({ op: "br_if", depth: 1 });
1953
-
1954
- this.pushInstruction({ op: "local.get", index: 0 });
1955
- this.pushInstruction({
1956
- op: "struct.get",
1957
- typeIndex: mapInfo.typeIndex,
1958
- fieldIndex: 1,
1959
- });
1960
- this.pushInstruction({ op: "local.get", index: idxLoc });
1961
- this.pushInstruction({
1962
- op: "array.get",
1963
- typeIndex: mapInfo.entriesTypeIndex,
1964
- });
1965
- this.pushInstruction({ op: "local.set", index: entryLoc });
1966
-
1967
- this.pushInstruction({ op: "local.get", index: dstLoc });
1968
- this.pushInstruction({ op: "local.get", index: entryLoc });
1969
- this.pushInstruction({
1970
- op: "struct.get",
1971
- typeIndex: mapInfo.entryTypeIndex,
1972
- fieldIndex: 0,
1973
- });
1974
- this.pushInstruction({ op: "local.get", index: entryLoc });
1975
- this.pushInstruction({
1976
- op: "struct.get",
1977
- typeIndex: mapInfo.entryTypeIndex,
1978
- fieldIndex: 1,
1979
- });
1980
- this.pushInstruction({
1981
- op: "call",
1982
- funcIndex: this.mod.resolveFuncIndex(mapInfo.setFuncName),
1983
- });
1984
-
1985
- this.pushInstruction({ op: "local.get", index: entryLoc });
1986
- this.pushInstruction({
1987
- op: "struct.get",
1988
- typeIndex: mapInfo.entryTypeIndex,
1989
- fieldIndex: 4,
1990
- });
1991
- this.pushInstruction({ op: "local.set", index: idxLoc });
1992
- this.pushInstruction({ op: "br", depth: 0 });
1993
- this.pushInstruction("end");
1994
- this.pushInstruction("end");
1995
-
1996
- this.pushInstruction({ op: "local.get", index: dstLoc });
1997
- this.pushInstruction({ op: "return" });
1998
- }
1999
1697
  }