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
@@ -110,6 +110,12 @@ export class TimeEmitter {
110
110
  case "Parse":
111
111
  this._emitTimeParse(call.args, targetWasmType);
112
112
  break;
113
+ case "ParseDuration":
114
+ this._emitTimeParseDuration(call.args, targetWasmType);
115
+ break;
116
+ case "FixedZone":
117
+ this._emitTimeFixedZone(call.args, targetWasmType);
118
+ break;
113
119
  default:
114
120
  throw new Error(`Unsupported time function '${field}'`);
115
121
  }
@@ -132,6 +138,9 @@ export class TimeEmitter {
132
138
  case "Add":
133
139
  this._emitTimeMethodAdd(expr, args, targetWasmType);
134
140
  break;
141
+ case "AddDate":
142
+ this._emitTimeMethodAddDate(expr, args, targetWasmType);
143
+ break;
135
144
  case "Sub":
136
145
  this._emitTimeMethodSub(expr, args, targetWasmType);
137
146
  break;
@@ -144,6 +153,9 @@ export class TimeEmitter {
144
153
  case "Equal":
145
154
  this._emitTimeMethodEqual(expr, args, targetWasmType);
146
155
  break;
156
+ case "Compare":
157
+ this._emitTimeMethodCompare(expr, args, targetWasmType);
158
+ break;
147
159
  case "Hour":
148
160
  this._emitTimeMethodHour(expr, targetWasmType);
149
161
  break;
@@ -165,6 +177,18 @@ export class TimeEmitter {
165
177
  case "Day":
166
178
  this._emitTimeMethodYMD(expr, targetWasmType, 2);
167
179
  break;
180
+ case "YearDay":
181
+ this._emitTimeMethodYearDay(expr, targetWasmType);
182
+ break;
183
+ case "ISOWeek":
184
+ this._emitTimeMethodISOWeek(expr, targetWasmType);
185
+ break;
186
+ case "Zone":
187
+ this._emitTimeMethodZone(expr, targetWasmType);
188
+ break;
189
+ case "Location":
190
+ this._emitTimeMethodLocation(expr, targetWasmType);
191
+ break;
168
192
  case "IsZero":
169
193
  this._emitTimeMethodIsZero(expr);
170
194
  break;
@@ -174,6 +198,24 @@ export class TimeEmitter {
174
198
  case "Nanosecond":
175
199
  this._emitTimeMethodNanosecond(expr, targetWasmType);
176
200
  break;
201
+ case "Truncate":
202
+ this._emitTimeMethodTruncate(expr, args, targetWasmType);
203
+ break;
204
+ case "Round":
205
+ this._emitTimeMethodRound(expr, args, targetWasmType);
206
+ break;
207
+ case "MarshalJSON":
208
+ this._emitTimeMethodMarshalJSON(expr, targetWasmType);
209
+ break;
210
+ case "UnmarshalJSON":
211
+ this._emitTimeMethodUnmarshalJSON(expr, args, targetWasmType);
212
+ break;
213
+ case "MarshalText":
214
+ this._emitTimeMethodMarshalText(expr, targetWasmType);
215
+ break;
216
+ case "UnmarshalText":
217
+ this._emitTimeMethodUnmarshalText(expr, args, targetWasmType);
218
+ break;
177
219
  case "UTC":
178
220
  this._emitTimeMethodUTC(expr);
179
221
  break;
@@ -185,7 +227,7 @@ export class TimeEmitter {
185
227
  }
186
228
  }
187
229
 
188
- emitDurationMethodCall(field, expr, _args, _targetWasmType) {
230
+ emitDurationMethodCall(field, expr, args, _targetWasmType) {
189
231
  switch (field) {
190
232
  case "Nanoseconds":
191
233
  this.emitExpr(expr, "i64");
@@ -218,6 +260,15 @@ export class TimeEmitter {
218
260
  this.pushInstruction({ op: "f64.const", value: 3600000000000.0 });
219
261
  this.pushInstruction("f64.div");
220
262
  return;
263
+ case "Truncate":
264
+ this._emitDurationTruncate(expr, args);
265
+ return;
266
+ case "Round":
267
+ this._emitDurationRound(expr, args);
268
+ return;
269
+ case "Abs":
270
+ this._emitDurationAbs(expr);
271
+ return;
221
272
  case "String":
222
273
  this.emitExpr(expr, "i64");
223
274
  this._callStdlib("time_duration_string");
@@ -236,10 +287,11 @@ export class TimeEmitter {
236
287
  this._callStdlib("time_timezone_offset");
237
288
  this.pushInstruction({ op: "local.set", index: offTmp });
238
289
  this.pushInstruction({ op: "local.get", index: msTmp });
239
- this.pushInstruction({ op: "f64.const", value: 1000000 });
240
- this.pushInstruction("f64.mul");
241
290
  this.pushInstruction("i64.trunc_sat_f64_s");
291
+ this.pushInstruction({ op: "i64.const", value: 1000000n });
292
+ this.pushInstruction("i64.mul");
242
293
  this.pushInstruction({ op: "local.get", index: offTmp });
294
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
243
295
  this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
244
296
  this.releaseTemp(offTmp, "i32");
245
297
  this.releaseTemp(msTmp, "f64");
@@ -260,9 +312,9 @@ export class TimeEmitter {
260
312
  this._callStdlib("time_now_ms");
261
313
  this.pushInstruction({ op: "local.set", index: msTmp });
262
314
  this.pushInstruction({ op: "local.get", index: msTmp });
263
- this.pushInstruction({ op: "f64.const", value: 1000000 });
264
- this.pushInstruction("f64.mul");
265
315
  this.pushInstruction("i64.trunc_sat_f64_s");
316
+ this.pushInstruction({ op: "i64.const", value: 1000000n });
317
+ this.pushInstruction("i64.mul");
266
318
  this.pushInstruction({ op: "local.get", index: argTmp });
267
319
  this.pushInstruction({
268
320
  op: "struct.get",
@@ -305,6 +357,7 @@ export class TimeEmitter {
305
357
 
306
358
  this.pushInstruction({ op: "local.get", index: nanoTmp });
307
359
  this.pushInstruction({ op: "local.get", index: offTmp });
360
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
308
361
  this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
309
362
 
310
363
  this.releaseTemp(offTmp, "i32");
@@ -465,6 +518,9 @@ export class TimeEmitter {
465
518
  this.pushInstruction({ op: "local.set", index: localSecTmp });
466
519
 
467
520
  const offTmp = this.acquireTemp("i32");
521
+ this.pushInstruction({ op: "local.get", index: locTmp });
522
+ this.pushInstruction("ref.is_null");
523
+ this.pushInstruction({ op: "if", blockType: "void" });
468
524
  if (this._isUtcExpr(args[7])) {
469
525
  this.pushInstruction({ op: "i32.const", value: 0 });
470
526
  this.pushInstruction({ op: "local.set", index: offTmp });
@@ -476,6 +532,24 @@ export class TimeEmitter {
476
532
  this._callStdlib("time_timezone_offset");
477
533
  this.pushInstruction({ op: "local.set", index: offTmp });
478
534
  }
535
+ this.pushInstruction("else");
536
+ const locInfo = this.mod.getStructType("time.Location");
537
+ if (locInfo) {
538
+ this.pushInstruction({ op: "local.get", index: locTmp });
539
+ this.pushInstruction({
540
+ op: "ref.cast",
541
+ nullable: true,
542
+ typeIndex: locInfo.typeIndex,
543
+ });
544
+ this.pushInstruction({
545
+ op: "struct.get",
546
+ typeIndex: locInfo.typeIndex,
547
+ fieldIndex: 1,
548
+ });
549
+ this.pushInstruction("i32.wrap_i64");
550
+ this.pushInstruction({ op: "local.set", index: offTmp });
551
+ }
552
+ this.pushInstruction("end");
479
553
 
480
554
  // unixSec = localSec - offset
481
555
  this.pushInstruction({ op: "local.get", index: localSecTmp });
@@ -488,6 +562,7 @@ export class TimeEmitter {
488
562
  this.pushInstruction("i64.add");
489
563
 
490
564
  this.pushInstruction({ op: "local.get", index: offTmp });
565
+ this.pushInstruction({ op: "local.get", index: locTmp });
491
566
  this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
492
567
 
493
568
  this.releaseTemp(offTmp, "i32");
@@ -531,10 +606,14 @@ export class TimeEmitter {
531
606
 
532
607
  // Success
533
608
  this.pushInstruction({ op: "local.get", index: msTmp });
534
- this.pushInstruction({ op: "f64.const", value: 1000000 });
535
- this.pushInstruction("f64.mul");
536
609
  this.pushInstruction("i64.trunc_sat_f64_s");
610
+ this.pushInstruction({ op: "i64.const", value: 1000000n });
611
+ this.pushInstruction("i64.mul");
612
+ this._callStdlib("time_parse_sub_ns");
613
+ this.pushInstruction("i64.extend_i32_s");
614
+ this.pushInstruction("i64.add");
537
615
  this.pushInstruction({ op: "local.get", index: offTmp });
616
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
538
617
  this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
539
618
  this.pushInstruction({ op: "local.set", index: resTimeTmp });
540
619
  this.pushInstruction({ op: "ref.null", heapType: "any" });
@@ -545,6 +624,7 @@ export class TimeEmitter {
545
624
  // Error
546
625
  this.pushInstruction({ op: "i64.const", value: 0n });
547
626
  this.pushInstruction({ op: "i32.const", value: 0 });
627
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
548
628
  this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
549
629
  this.pushInstruction({ op: "local.set", index: resTimeTmp });
550
630
  this.pushInstruction({ op: "local.get", index: errStrTmp });
@@ -598,6 +678,13 @@ export class TimeEmitter {
598
678
  fieldIndex: 1,
599
679
  });
600
680
 
681
+ this.pushInstruction({ op: "local.get", index: rTmp });
682
+ this.pushInstruction({
683
+ op: "struct.get",
684
+ typeIndex: timeInfo.typeIndex,
685
+ fieldIndex: 2,
686
+ });
687
+
601
688
  this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
602
689
 
603
690
  this.releaseTemp(dTmp, "i64");
@@ -756,6 +843,7 @@ export class TimeEmitter {
756
843
  _emitTimeMethodUTC(expr) {
757
844
  const timeInfo = this._emitTimeGetNano(expr);
758
845
  this.pushInstruction({ op: "i32.const", value: 0 });
846
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
759
847
  this.pushInstruction({
760
848
  op: "struct.new",
761
849
  typeIndex: timeInfo.typeIndex,
@@ -793,7 +881,7 @@ export class TimeEmitter {
793
881
  op: "call",
794
882
  funcIndex: this.mod.getTimezoneOffsetImportIndex(),
795
883
  });
796
-
884
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
797
885
  this.pushInstruction({
798
886
  op: "struct.new",
799
887
  typeIndex: timeInfo.typeIndex,
@@ -1146,20 +1234,18 @@ export class TimeEmitter {
1146
1234
  this.pushInstruction({ op: "local.set", index: wdTmp });
1147
1235
  this.pushInstruction("end");
1148
1236
 
1149
- // ms = i32((nanoTmp % 1000000000n) / 1000000n)
1237
+ // ns = i32(nanoTmp % 1000000000n)
1150
1238
  const msTmp = this.acquireTemp("i32");
1151
1239
  this.pushInstruction({ op: "local.get", index: p.nanoTmp });
1152
1240
  this.pushInstruction({ op: "i64.const", value: 1000000000n });
1153
1241
  this.pushInstruction("i64.rem_s");
1154
- this.pushInstruction({ op: "i64.const", value: 1000000n });
1155
- this.pushInstruction("i64.div_s");
1156
1242
  this.pushInstruction("i32.wrap_i64");
1157
1243
  this.pushInstruction({ op: "local.tee", index: msTmp });
1158
1244
  this.pushInstruction({ op: "i32.const", value: 0 });
1159
1245
  this.pushInstruction("i32.lt_s");
1160
1246
  this.pushInstruction({ op: "if", blockType: "void" });
1161
1247
  this.pushInstruction({ op: "local.get", index: msTmp });
1162
- this.pushInstruction({ op: "i32.const", value: 1000 });
1248
+ this.pushInstruction({ op: "i32.const", value: 1000000000 });
1163
1249
  this.pushInstruction("i32.add");
1164
1250
  this.pushInstruction({ op: "local.set", index: msTmp });
1165
1251
  this.pushInstruction("end");
@@ -1197,4 +1283,947 @@ export class TimeEmitter {
1197
1283
  };
1198
1284
  this._emitTimeMethodFormat(expr, [strLit], targetWasmType);
1199
1285
  }
1286
+
1287
+ _emitTimeParseDuration(args, _targetWasmType) {
1288
+ const durTmp = this.acquireTemp("i64");
1289
+ const errStrTmp = this.acquireTemp("externref");
1290
+ const resErrTmp = this.acquireTemp("anyref");
1291
+
1292
+ this.emitExpr(args[0], "externref");
1293
+ this._callStdlib("time_parse_duration");
1294
+ this.pushInstruction({ op: "local.set", index: durTmp });
1295
+ this._callStdlib("time_parse_duration_err");
1296
+ this.pushInstruction({ op: "local.set", index: errStrTmp });
1297
+
1298
+ this.pushInstruction({ op: "local.get", index: errStrTmp });
1299
+ this.pushInstruction("ref.is_null");
1300
+ this.pushInstruction({ op: "if", blockType: "void" });
1301
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1302
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1303
+ this.pushInstruction("else");
1304
+ this.pushInstruction({ op: "local.get", index: errStrTmp });
1305
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
1306
+ this.pushInstruction({
1307
+ op: "call",
1308
+ funcIndex: this.mod.resolveFuncIndex("__mk_error"),
1309
+ });
1310
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
1311
+ this.pushInstruction("end");
1312
+
1313
+ this.pushInstruction({ op: "local.get", index: durTmp });
1314
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
1315
+
1316
+ this.releaseTemp(resErrTmp, "anyref");
1317
+ this.releaseTemp(errStrTmp, "externref");
1318
+ this.releaseTemp(durTmp, "i64");
1319
+ }
1320
+
1321
+ _emitTimeFixedZone(args, _targetWasmType) {
1322
+ const locInfo = this.mod.getStructType("time.Location");
1323
+ this.emitExpr(args[0], "externref");
1324
+ this.emitExpr(args[1], "i64");
1325
+ this.pushInstruction({ op: "struct.new", typeIndex: locInfo.typeIndex });
1326
+ }
1327
+
1328
+ _emitDurationAbs(expr) {
1329
+ const dTmp = this.acquireTemp("i64");
1330
+ this.emitExpr(expr, "i64");
1331
+ this.pushInstruction({ op: "local.tee", index: dTmp });
1332
+ this.pushInstruction({ op: "i64.const", value: 0n });
1333
+ this.pushInstruction("i64.ge_s");
1334
+ this.pushInstruction({ op: "if", blockType: "i64" });
1335
+ this.pushInstruction({ op: "local.get", index: dTmp });
1336
+ this.pushInstruction("else");
1337
+ this.pushInstruction({ op: "local.get", index: dTmp });
1338
+ this.pushInstruction({ op: "i64.const", value: -9223372036854775808n });
1339
+ this.pushInstruction("i64.eq");
1340
+ this.pushInstruction({ op: "if", blockType: "i64" });
1341
+ this.pushInstruction({ op: "i64.const", value: 9223372036854775807n });
1342
+ this.pushInstruction("else");
1343
+ this.pushInstruction({ op: "i64.const", value: 0n });
1344
+ this.pushInstruction({ op: "local.get", index: dTmp });
1345
+ this.pushInstruction("i64.sub");
1346
+ this.pushInstruction("end");
1347
+ this.pushInstruction("end");
1348
+ this.releaseTemp(dTmp, "i64");
1349
+ }
1350
+
1351
+ _emitDurationTruncate(expr, args) {
1352
+ const dTmp = this.acquireTemp("i64");
1353
+ const mTmp = this.acquireTemp("i64");
1354
+ this.emitExpr(expr, "i64");
1355
+ this.pushInstruction({ op: "local.set", index: dTmp });
1356
+ this.emitExpr(args[0], "i64");
1357
+ this.pushInstruction({ op: "local.tee", index: mTmp });
1358
+ this.pushInstruction({ op: "i64.const", value: 0n });
1359
+ this.pushInstruction("i64.le_s");
1360
+ this.pushInstruction({ op: "if", blockType: "i64" });
1361
+ this.pushInstruction({ op: "local.get", index: dTmp });
1362
+ this.pushInstruction("else");
1363
+ this.pushInstruction({ op: "local.get", index: dTmp });
1364
+ this.pushInstruction({ op: "local.get", index: dTmp });
1365
+ this.pushInstruction({ op: "local.get", index: mTmp });
1366
+ this.pushInstruction("i64.rem_s");
1367
+ this.pushInstruction("i64.sub");
1368
+ this.pushInstruction("end");
1369
+ this.releaseTemp(mTmp, "i64");
1370
+ this.releaseTemp(dTmp, "i64");
1371
+ }
1372
+
1373
+ _emitDurationRound(expr, args) {
1374
+ const dTmp = this.acquireTemp("i64");
1375
+ const mTmp = this.acquireTemp("i64");
1376
+ const rTmp = this.acquireTemp("i64");
1377
+ this.emitExpr(expr, "i64");
1378
+ this.pushInstruction({ op: "local.set", index: dTmp });
1379
+ this.emitExpr(args[0], "i64");
1380
+ this.pushInstruction({ op: "local.set", index: mTmp });
1381
+
1382
+ this.pushInstruction({ op: "local.get", index: mTmp });
1383
+ this.pushInstruction({ op: "i64.const", value: 0n });
1384
+ this.pushInstruction("i64.le_s");
1385
+ this.pushInstruction({ op: "if", blockType: "i64" });
1386
+ this.pushInstruction({ op: "local.get", index: dTmp });
1387
+ this.pushInstruction("else");
1388
+
1389
+ this.pushInstruction({ op: "local.get", index: dTmp });
1390
+ this.pushInstruction({ op: "local.get", index: mTmp });
1391
+ this.pushInstruction("i64.rem_s");
1392
+ this.pushInstruction({ op: "local.set", index: rTmp });
1393
+
1394
+ this.pushInstruction({ op: "local.get", index: dTmp });
1395
+ this.pushInstruction({ op: "i64.const", value: 0n });
1396
+ this.pushInstruction("i64.lt_s");
1397
+ this.pushInstruction({ op: "if", blockType: "i64" });
1398
+
1399
+ this.pushInstruction({ op: "i64.const", value: 0n });
1400
+ this.pushInstruction({ op: "local.get", index: rTmp });
1401
+ this.pushInstruction("i64.sub");
1402
+ this.pushInstruction({ op: "local.set", index: rTmp });
1403
+
1404
+ this.pushInstruction({ op: "local.get", index: rTmp });
1405
+ this.pushInstruction({ op: "local.get", index: mTmp });
1406
+ this.pushInstruction({ op: "local.get", index: rTmp });
1407
+ this.pushInstruction("i64.sub");
1408
+ this.pushInstruction("i64.lt_u");
1409
+ this.pushInstruction({ op: "if", blockType: "i64" });
1410
+ this.pushInstruction({ op: "local.get", index: dTmp });
1411
+ this.pushInstruction({ op: "local.get", index: rTmp });
1412
+ this.pushInstruction("i64.add");
1413
+ this.pushInstruction("else");
1414
+ this.pushInstruction({ op: "local.get", index: dTmp });
1415
+ this.pushInstruction({ op: "local.get", index: mTmp });
1416
+ this.pushInstruction("i64.sub");
1417
+ this.pushInstruction({ op: "local.get", index: rTmp });
1418
+ this.pushInstruction("i64.add");
1419
+ this.pushInstruction("end");
1420
+
1421
+ this.pushInstruction("else");
1422
+
1423
+ this.pushInstruction({ op: "local.get", index: rTmp });
1424
+ this.pushInstruction({ op: "local.get", index: mTmp });
1425
+ this.pushInstruction({ op: "local.get", index: rTmp });
1426
+ this.pushInstruction("i64.sub");
1427
+ this.pushInstruction("i64.lt_u");
1428
+ this.pushInstruction({ op: "if", blockType: "i64" });
1429
+ this.pushInstruction({ op: "local.get", index: dTmp });
1430
+ this.pushInstruction({ op: "local.get", index: rTmp });
1431
+ this.pushInstruction("i64.sub");
1432
+ this.pushInstruction("else");
1433
+ this.pushInstruction({ op: "local.get", index: dTmp });
1434
+ this.pushInstruction({ op: "local.get", index: mTmp });
1435
+ this.pushInstruction("i64.add");
1436
+ this.pushInstruction({ op: "local.get", index: rTmp });
1437
+ this.pushInstruction("i64.sub");
1438
+ this.pushInstruction("end");
1439
+
1440
+ this.pushInstruction("end");
1441
+ this.pushInstruction("end");
1442
+
1443
+ this.releaseTemp(rTmp, "i64");
1444
+ this.releaseTemp(mTmp, "i64");
1445
+ this.releaseTemp(dTmp, "i64");
1446
+ }
1447
+
1448
+ _emitTimeMethodCompare(expr, args, targetWasmType) {
1449
+ const timeInfo = this.mod.getStructType("time.Time");
1450
+ const timeW = {
1451
+ kind: "ref",
1452
+ nullable: true,
1453
+ typeIndex: timeInfo.typeIndex,
1454
+ };
1455
+ const tTmp = this.acquireTemp(timeW);
1456
+ const uTmp = this.acquireTemp(timeW);
1457
+ const tNano = this.acquireTemp("i64");
1458
+ const uNano = this.acquireTemp("i64");
1459
+
1460
+ this.emitExpr(expr, timeW);
1461
+ this.pushInstruction({ op: "local.set", index: tTmp });
1462
+ this.emitExpr(args[0], timeW);
1463
+ this.pushInstruction({ op: "local.set", index: uTmp });
1464
+
1465
+ this.pushInstruction({ op: "local.get", index: tTmp });
1466
+ this.pushInstruction({
1467
+ op: "struct.get",
1468
+ typeIndex: timeInfo.typeIndex,
1469
+ fieldIndex: 0,
1470
+ });
1471
+ this.pushInstruction({ op: "local.set", index: tNano });
1472
+ this.pushInstruction({ op: "local.get", index: uTmp });
1473
+ this.pushInstruction({
1474
+ op: "struct.get",
1475
+ typeIndex: timeInfo.typeIndex,
1476
+ fieldIndex: 0,
1477
+ });
1478
+ this.pushInstruction({ op: "local.set", index: uNano });
1479
+
1480
+ this.pushInstruction({ op: "local.get", index: tNano });
1481
+ this.pushInstruction({ op: "local.get", index: uNano });
1482
+ this.pushInstruction("i64.lt_s");
1483
+ this.pushInstruction({ op: "if", blockType: "i32" });
1484
+ this.pushInstruction({ op: "i32.const", value: -1 });
1485
+ this.pushInstruction("else");
1486
+ this.pushInstruction({ op: "local.get", index: tNano });
1487
+ this.pushInstruction({ op: "local.get", index: uNano });
1488
+ this.pushInstruction("i64.gt_s");
1489
+ this.pushInstruction({ op: "if", blockType: "i32" });
1490
+ this.pushInstruction({ op: "i32.const", value: 1 });
1491
+ this.pushInstruction("else");
1492
+ this.pushInstruction({ op: "i32.const", value: 0 });
1493
+ this.pushInstruction("end");
1494
+ this.pushInstruction("end");
1495
+
1496
+ this.releaseTemp(uNano, "i64");
1497
+ this.releaseTemp(tNano, "i64");
1498
+ this.releaseTemp(uTmp, timeW);
1499
+ this.releaseTemp(tTmp, timeW);
1500
+
1501
+ if (targetWasmType === "i64") {
1502
+ this.pushInstruction("i64.extend_i32_s");
1503
+ }
1504
+ }
1505
+
1506
+ _emitTimeMethodYearDay(expr, targetWasmType) {
1507
+ const p = this._emitTimeDecomposeParts(expr);
1508
+ const yTmp = this.acquireTemp("i32");
1509
+ const mTmp = this.acquireTemp("i32");
1510
+ const dTmp = this.acquireTemp("i32");
1511
+ this._emitCivilDateFromDays(p.daysTmp, yTmp, mTmp, dTmp);
1512
+
1513
+ const jan1YTmp = this.acquireTemp("i32");
1514
+ const jan1MTmp = this.acquireTemp("i32");
1515
+ const jan1DTmp = this.acquireTemp("i32");
1516
+ const jan1DaysTmp = this.acquireTemp("i64");
1517
+
1518
+ this.pushInstruction({ op: "local.get", index: yTmp });
1519
+ this.pushInstruction({ op: "local.set", index: jan1YTmp });
1520
+ this.pushInstruction({ op: "i32.const", value: 1 });
1521
+ this.pushInstruction({ op: "local.set", index: jan1MTmp });
1522
+ this.pushInstruction({ op: "i32.const", value: 1 });
1523
+ this.pushInstruction({ op: "local.set", index: jan1DTmp });
1524
+ this._emitCivilDays(jan1YTmp, jan1MTmp, jan1DTmp, jan1DaysTmp);
1525
+
1526
+ this.pushInstruction({ op: "local.get", index: p.daysTmp });
1527
+ this.pushInstruction({ op: "local.get", index: jan1DaysTmp });
1528
+ this.pushInstruction("i64.sub");
1529
+ this.pushInstruction({ op: "i64.const", value: 1n });
1530
+ this.pushInstruction("i64.add");
1531
+
1532
+ if (targetWasmType === "i32") {
1533
+ this.pushInstruction("i32.wrap_i64");
1534
+ }
1535
+
1536
+ this.releaseTemp(jan1DaysTmp, "i64");
1537
+ this.releaseTemp(jan1DTmp, "i32");
1538
+ this.releaseTemp(jan1MTmp, "i32");
1539
+ this.releaseTemp(jan1YTmp, "i32");
1540
+ this.releaseTemp(dTmp, "i32");
1541
+ this.releaseTemp(mTmp, "i32");
1542
+ this.releaseTemp(yTmp, "i32");
1543
+ this._releaseTimeDecomposeParts(p);
1544
+ }
1545
+
1546
+ _emitTimeMethodISOWeek(expr, targetWasmType) {
1547
+ const p = this._emitTimeDecomposeParts(expr);
1548
+ const monOffsetTmp = this.acquireTemp("i32");
1549
+ const thuDaysTmp = this.acquireTemp("i64");
1550
+ this.pushInstruction({ op: "local.get", index: p.daysTmp });
1551
+ this.pushInstruction({ op: "i64.const", value: 3n });
1552
+ this.pushInstruction("i64.add");
1553
+ this.pushInstruction({ op: "i64.const", value: 7n });
1554
+ this.pushInstruction("i64.rem_s");
1555
+ this.pushInstruction("i32.wrap_i64");
1556
+ this.pushInstruction({ op: "local.tee", index: monOffsetTmp });
1557
+ this.pushInstruction({ op: "i32.const", value: 0 });
1558
+ this.pushInstruction("i32.lt_s");
1559
+ this.pushInstruction({ op: "if", blockType: "void" });
1560
+ this.pushInstruction({ op: "local.get", index: monOffsetTmp });
1561
+ this.pushInstruction({ op: "i32.const", value: 7 });
1562
+ this.pushInstruction("i32.add");
1563
+ this.pushInstruction({ op: "local.set", index: monOffsetTmp });
1564
+ this.pushInstruction("end");
1565
+
1566
+ this.pushInstruction({ op: "local.get", index: p.daysTmp });
1567
+ this.pushInstruction({ op: "local.get", index: monOffsetTmp });
1568
+ this.pushInstruction("i64.extend_i32_s");
1569
+ this.pushInstruction("i64.sub");
1570
+ this.pushInstruction({ op: "i64.const", value: 3n });
1571
+ this.pushInstruction("i64.add");
1572
+ this.pushInstruction({ op: "local.set", index: thuDaysTmp });
1573
+
1574
+ const isoYearTmp = this.acquireTemp("i32");
1575
+ const dummyMTmp = this.acquireTemp("i32");
1576
+ const dummyDTmp = this.acquireTemp("i32");
1577
+ this._emitCivilDateFromDays(thuDaysTmp, isoYearTmp, dummyMTmp, dummyDTmp);
1578
+ this.releaseTemp(dummyDTmp, "i32");
1579
+ this.releaseTemp(dummyMTmp, "i32");
1580
+
1581
+ const jan4YTmp = this.acquireTemp("i32");
1582
+ const jan4MTmp = this.acquireTemp("i32");
1583
+ const jan4DTmp = this.acquireTemp("i32");
1584
+ const jan4DaysTmp = this.acquireTemp("i64");
1585
+ this.pushInstruction({ op: "local.get", index: isoYearTmp });
1586
+ this.pushInstruction({ op: "local.set", index: jan4YTmp });
1587
+ this.pushInstruction({ op: "i32.const", value: 1 });
1588
+ this.pushInstruction({ op: "local.set", index: jan4MTmp });
1589
+ this.pushInstruction({ op: "i32.const", value: 4 });
1590
+ this.pushInstruction({ op: "local.set", index: jan4DTmp });
1591
+ this._emitCivilDays(jan4YTmp, jan4MTmp, jan4DTmp, jan4DaysTmp);
1592
+ this.releaseTemp(jan4DTmp, "i32");
1593
+ this.releaseTemp(jan4MTmp, "i32");
1594
+ this.releaseTemp(jan4YTmp, "i32");
1595
+
1596
+ const jan4MonOffTmp = this.acquireTemp("i32");
1597
+ const firstThuDaysTmp = this.acquireTemp("i64");
1598
+ this.pushInstruction({ op: "local.get", index: jan4DaysTmp });
1599
+ this.pushInstruction({ op: "i64.const", value: 3n });
1600
+ this.pushInstruction("i64.add");
1601
+ this.pushInstruction({ op: "i64.const", value: 7n });
1602
+ this.pushInstruction("i64.rem_s");
1603
+ this.pushInstruction("i32.wrap_i64");
1604
+ this.pushInstruction({ op: "local.tee", index: jan4MonOffTmp });
1605
+ this.pushInstruction({ op: "i32.const", value: 0 });
1606
+ this.pushInstruction("i32.lt_s");
1607
+ this.pushInstruction({ op: "if", blockType: "void" });
1608
+ this.pushInstruction({ op: "local.get", index: jan4MonOffTmp });
1609
+ this.pushInstruction({ op: "i32.const", value: 7 });
1610
+ this.pushInstruction("i32.add");
1611
+ this.pushInstruction({ op: "local.set", index: jan4MonOffTmp });
1612
+ this.pushInstruction("end");
1613
+
1614
+ this.pushInstruction({ op: "local.get", index: jan4DaysTmp });
1615
+ this.pushInstruction({ op: "local.get", index: jan4MonOffTmp });
1616
+ this.pushInstruction("i64.extend_i32_s");
1617
+ this.pushInstruction("i64.sub");
1618
+ this.pushInstruction({ op: "i64.const", value: 3n });
1619
+ this.pushInstruction("i64.add");
1620
+ this.pushInstruction({ op: "local.set", index: firstThuDaysTmp });
1621
+
1622
+ const weekTmp = this.acquireTemp("i32");
1623
+ this.pushInstruction({ op: "local.get", index: thuDaysTmp });
1624
+ this.pushInstruction({ op: "local.get", index: firstThuDaysTmp });
1625
+ this.pushInstruction("i64.sub");
1626
+ this.pushInstruction({ op: "i64.const", value: 7n });
1627
+ this.pushInstruction("i64.div_s");
1628
+ this.pushInstruction("i32.wrap_i64");
1629
+ this.pushInstruction({ op: "i32.const", value: 1 });
1630
+ this.pushInstruction("i32.add");
1631
+ this.pushInstruction({ op: "local.set", index: weekTmp });
1632
+
1633
+ this.pushInstruction({ op: "local.get", index: isoYearTmp });
1634
+ this.pushInstruction("i64.extend_i32_s");
1635
+ if (targetWasmType === "i32") this.pushInstruction("i32.wrap_i64");
1636
+ this.pushInstruction({ op: "local.get", index: weekTmp });
1637
+ this.pushInstruction("i64.extend_i32_s");
1638
+ if (targetWasmType === "i32") this.pushInstruction("i32.wrap_i64");
1639
+
1640
+ this.releaseTemp(weekTmp, "i32");
1641
+ this.releaseTemp(firstThuDaysTmp, "i64");
1642
+ this.releaseTemp(jan4MonOffTmp, "i32");
1643
+ this.releaseTemp(jan4DaysTmp, "i64");
1644
+ this.releaseTemp(isoYearTmp, "i32");
1645
+ this.releaseTemp(thuDaysTmp, "i64");
1646
+ this.releaseTemp(monOffsetTmp, "i32");
1647
+ this._releaseTimeDecomposeParts(p);
1648
+ }
1649
+
1650
+ _emitTimeMethodZone(expr, targetWasmType) {
1651
+ const timeInfo = this.mod.getStructType("time.Time");
1652
+ const timeW = {
1653
+ kind: "ref",
1654
+ nullable: true,
1655
+ typeIndex: timeInfo.typeIndex,
1656
+ };
1657
+ const rTmp = this.acquireTemp(timeW);
1658
+ const offTmp = this.acquireTemp("i32");
1659
+ const locTmp = this.acquireTemp("anyref");
1660
+ this.emitExpr(expr, timeW);
1661
+ this.pushInstruction({ op: "local.tee", index: rTmp });
1662
+ this.pushInstruction({
1663
+ op: "struct.get",
1664
+ typeIndex: timeInfo.typeIndex,
1665
+ fieldIndex: 1,
1666
+ });
1667
+ this.pushInstruction({ op: "local.set", index: offTmp });
1668
+
1669
+ this.pushInstruction({ op: "local.get", index: rTmp });
1670
+ this.pushInstruction({
1671
+ op: "struct.get",
1672
+ typeIndex: timeInfo.typeIndex,
1673
+ fieldIndex: 2,
1674
+ });
1675
+ this.pushInstruction({ op: "local.tee", index: locTmp });
1676
+ this.pushInstruction("ref.is_null");
1677
+ this.pushInstruction({ op: "if", blockType: "externref" });
1678
+
1679
+ this.pushInstruction({ op: "local.get", index: offTmp });
1680
+ this.pushInstruction({ op: "i32.const", value: 0 });
1681
+ this.pushInstruction("i32.eq");
1682
+ this.pushInstruction({ op: "if", blockType: "externref" });
1683
+ this.emitBasicLit(
1684
+ { kind: "BasicLit", litKind: "STRING", value: "UTC" },
1685
+ "externref",
1686
+ );
1687
+ this.pushInstruction("else");
1688
+ this.emitBasicLit(
1689
+ { kind: "BasicLit", litKind: "STRING", value: "LOCAL" },
1690
+ "externref",
1691
+ );
1692
+ this.pushInstruction("end");
1693
+
1694
+ this.pushInstruction("else");
1695
+ const locInfo = this.mod.getStructType("time.Location");
1696
+ this.pushInstruction({ op: "local.get", index: locTmp });
1697
+ this.pushInstruction({
1698
+ op: "ref.cast",
1699
+ nullable: true,
1700
+ typeIndex: locInfo.typeIndex,
1701
+ });
1702
+ this.pushInstruction({
1703
+ op: "struct.get",
1704
+ typeIndex: locInfo.typeIndex,
1705
+ fieldIndex: 0,
1706
+ });
1707
+ this.pushInstruction("end");
1708
+
1709
+ this.pushInstruction({ op: "local.get", index: offTmp });
1710
+ this.pushInstruction("i64.extend_i32_s");
1711
+ if (targetWasmType === "i32") {
1712
+ this.pushInstruction("i32.wrap_i64");
1713
+ }
1714
+
1715
+ this.releaseTemp(locTmp, "anyref");
1716
+ this.releaseTemp(offTmp, "i32");
1717
+ this.releaseTemp(rTmp, timeW);
1718
+ }
1719
+
1720
+ _emitTimeMethodLocation(expr, _targetWasmType) {
1721
+ const timeInfo = this.mod.getStructType("time.Time");
1722
+ const locInfo = this.mod.getStructType("time.Location");
1723
+ const timeW = {
1724
+ kind: "ref",
1725
+ nullable: true,
1726
+ typeIndex: timeInfo.typeIndex,
1727
+ };
1728
+ const rTmp = this.acquireTemp(timeW);
1729
+ const offTmp = this.acquireTemp("i32");
1730
+ const locTmp = this.acquireTemp("anyref");
1731
+
1732
+ this.emitExpr(expr, timeW);
1733
+ this.pushInstruction({ op: "local.tee", index: rTmp });
1734
+ this.pushInstruction({
1735
+ op: "struct.get",
1736
+ typeIndex: timeInfo.typeIndex,
1737
+ fieldIndex: 2,
1738
+ });
1739
+ this.pushInstruction({ op: "local.tee", index: locTmp });
1740
+ this.pushInstruction("ref.is_null");
1741
+ this.pushInstruction({
1742
+ op: "if",
1743
+ blockType: { kind: "ref", nullable: true, typeIndex: locInfo.typeIndex },
1744
+ });
1745
+
1746
+ this.pushInstruction({ op: "local.get", index: rTmp });
1747
+ this.pushInstruction({
1748
+ op: "struct.get",
1749
+ typeIndex: timeInfo.typeIndex,
1750
+ fieldIndex: 1,
1751
+ });
1752
+ this.pushInstruction({ op: "local.set", index: offTmp });
1753
+
1754
+ this.pushInstruction({ op: "local.get", index: offTmp });
1755
+ this.pushInstruction({ op: "i32.const", value: 0 });
1756
+ this.pushInstruction("i32.eq");
1757
+ this.pushInstruction({ op: "if", blockType: "externref" });
1758
+ this.emitBasicLit(
1759
+ { kind: "BasicLit", litKind: "STRING", value: "UTC" },
1760
+ "externref",
1761
+ );
1762
+ this.pushInstruction("else");
1763
+ this.emitBasicLit(
1764
+ { kind: "BasicLit", litKind: "STRING", value: "Local" },
1765
+ "externref",
1766
+ );
1767
+ this.pushInstruction("end");
1768
+
1769
+ this.pushInstruction({ op: "local.get", index: offTmp });
1770
+ this.pushInstruction("i64.extend_i32_s");
1771
+
1772
+ this.pushInstruction({ op: "struct.new", typeIndex: locInfo.typeIndex });
1773
+
1774
+ this.pushInstruction("else");
1775
+ this.pushInstruction({ op: "local.get", index: locTmp });
1776
+ this.pushInstruction({
1777
+ op: "ref.cast",
1778
+ nullable: true,
1779
+ typeIndex: locInfo.typeIndex,
1780
+ });
1781
+ this.pushInstruction("end");
1782
+
1783
+ this.releaseTemp(locTmp, "anyref");
1784
+ this.releaseTemp(offTmp, "i32");
1785
+ this.releaseTemp(rTmp, timeW);
1786
+ }
1787
+
1788
+ _emitTimeMethodTruncate(expr, args, _targetWasmType) {
1789
+ const timeInfo = this.mod.getStructType("time.Time");
1790
+ const timeW = {
1791
+ kind: "ref",
1792
+ nullable: true,
1793
+ typeIndex: timeInfo.typeIndex,
1794
+ };
1795
+ const rTmp = this.acquireTemp(timeW);
1796
+ const dTmp = this.acquireTemp("i64");
1797
+ const nanoTmp = this.acquireTemp("i64");
1798
+ const remTmp = this.acquireTemp("i64");
1799
+ const resNanoTmp = this.acquireTemp("i64");
1800
+
1801
+ this.emitExpr(expr, timeW);
1802
+ this.pushInstruction({ op: "local.set", index: rTmp });
1803
+ this.emitExpr(args[0], "i64");
1804
+ this.pushInstruction({ op: "local.set", index: dTmp });
1805
+
1806
+ this.pushInstruction({ op: "local.get", index: rTmp });
1807
+ this.pushInstruction({
1808
+ op: "struct.get",
1809
+ typeIndex: timeInfo.typeIndex,
1810
+ fieldIndex: 0,
1811
+ });
1812
+ this.pushInstruction({ op: "local.set", index: nanoTmp });
1813
+
1814
+ this.pushInstruction({ op: "local.get", index: dTmp });
1815
+ this.pushInstruction({ op: "i64.const", value: 0n });
1816
+ this.pushInstruction("i64.le_s");
1817
+ this.pushInstruction({ op: "if", blockType: "void" });
1818
+ this.pushInstruction({ op: "local.get", index: nanoTmp });
1819
+ this.pushInstruction({ op: "local.set", index: resNanoTmp });
1820
+ this.pushInstruction("else");
1821
+ this.pushInstruction({ op: "local.get", index: nanoTmp });
1822
+ this.pushInstruction({ op: "local.get", index: dTmp });
1823
+ this.pushInstruction("i64.rem_s");
1824
+ this.pushInstruction({ op: "local.tee", index: remTmp });
1825
+ this.pushInstruction({ op: "i64.const", value: 0n });
1826
+ this.pushInstruction("i64.lt_s");
1827
+ this.pushInstruction({ op: "if", blockType: "void" });
1828
+ this.pushInstruction({ op: "local.get", index: remTmp });
1829
+ this.pushInstruction({ op: "local.get", index: dTmp });
1830
+ this.pushInstruction("i64.add");
1831
+ this.pushInstruction({ op: "local.set", index: remTmp });
1832
+ this.pushInstruction("end");
1833
+ this.pushInstruction({ op: "local.get", index: nanoTmp });
1834
+ this.pushInstruction({ op: "local.get", index: remTmp });
1835
+ this.pushInstruction("i64.sub");
1836
+ this.pushInstruction({ op: "local.set", index: resNanoTmp });
1837
+ this.pushInstruction("end");
1838
+
1839
+ this.pushInstruction({ op: "local.get", index: resNanoTmp });
1840
+ this.pushInstruction({ op: "local.get", index: rTmp });
1841
+ this.pushInstruction({
1842
+ op: "struct.get",
1843
+ typeIndex: timeInfo.typeIndex,
1844
+ fieldIndex: 1,
1845
+ });
1846
+ this.pushInstruction({ op: "local.get", index: rTmp });
1847
+ this.pushInstruction({
1848
+ op: "struct.get",
1849
+ typeIndex: timeInfo.typeIndex,
1850
+ fieldIndex: 2,
1851
+ });
1852
+ this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
1853
+
1854
+ this.releaseTemp(resNanoTmp, "i64");
1855
+ this.releaseTemp(remTmp, "i64");
1856
+ this.releaseTemp(nanoTmp, "i64");
1857
+ this.releaseTemp(dTmp, "i64");
1858
+ this.releaseTemp(rTmp, timeW);
1859
+ }
1860
+
1861
+ _emitTimeMethodRound(expr, args, _targetWasmType) {
1862
+ const timeInfo = this.mod.getStructType("time.Time");
1863
+ const timeW = {
1864
+ kind: "ref",
1865
+ nullable: true,
1866
+ typeIndex: timeInfo.typeIndex,
1867
+ };
1868
+ const rTmp = this.acquireTemp(timeW);
1869
+ const dTmp = this.acquireTemp("i64");
1870
+ const nanoTmp = this.acquireTemp("i64");
1871
+ const remTmp = this.acquireTemp("i64");
1872
+ const resNanoTmp = this.acquireTemp("i64");
1873
+
1874
+ this.emitExpr(expr, timeW);
1875
+ this.pushInstruction({ op: "local.set", index: rTmp });
1876
+ this.emitExpr(args[0], "i64");
1877
+ this.pushInstruction({ op: "local.set", index: dTmp });
1878
+
1879
+ this.pushInstruction({ op: "local.get", index: rTmp });
1880
+ this.pushInstruction({
1881
+ op: "struct.get",
1882
+ typeIndex: timeInfo.typeIndex,
1883
+ fieldIndex: 0,
1884
+ });
1885
+ this.pushInstruction({ op: "local.set", index: nanoTmp });
1886
+
1887
+ this.pushInstruction({ op: "local.get", index: dTmp });
1888
+ this.pushInstruction({ op: "i64.const", value: 0n });
1889
+ this.pushInstruction("i64.le_s");
1890
+ this.pushInstruction({ op: "if", blockType: "void" });
1891
+ this.pushInstruction({ op: "local.get", index: nanoTmp });
1892
+ this.pushInstruction({ op: "local.set", index: resNanoTmp });
1893
+ this.pushInstruction("else");
1894
+ this.pushInstruction({ op: "local.get", index: nanoTmp });
1895
+ this.pushInstruction({ op: "local.get", index: dTmp });
1896
+ this.pushInstruction("i64.rem_s");
1897
+ this.pushInstruction({ op: "local.tee", index: remTmp });
1898
+ this.pushInstruction({ op: "i64.const", value: 0n });
1899
+ this.pushInstruction("i64.lt_s");
1900
+ this.pushInstruction({ op: "if", blockType: "void" });
1901
+ this.pushInstruction({ op: "local.get", index: remTmp });
1902
+ this.pushInstruction({ op: "local.get", index: dTmp });
1903
+ this.pushInstruction("i64.add");
1904
+ this.pushInstruction({ op: "local.set", index: remTmp });
1905
+ this.pushInstruction("end");
1906
+
1907
+ this.pushInstruction({ op: "local.get", index: remTmp });
1908
+ this.pushInstruction({ op: "local.get", index: dTmp });
1909
+ this.pushInstruction({ op: "local.get", index: remTmp });
1910
+ this.pushInstruction("i64.sub");
1911
+ this.pushInstruction("i64.lt_u");
1912
+ this.pushInstruction({ op: "if", blockType: "void" });
1913
+ this.pushInstruction({ op: "local.get", index: nanoTmp });
1914
+ this.pushInstruction({ op: "local.get", index: remTmp });
1915
+ this.pushInstruction("i64.sub");
1916
+ this.pushInstruction({ op: "local.set", index: resNanoTmp });
1917
+ this.pushInstruction("else");
1918
+ this.pushInstruction({ op: "local.get", index: nanoTmp });
1919
+ this.pushInstruction({ op: "local.get", index: dTmp });
1920
+ this.pushInstruction("i64.add");
1921
+ this.pushInstruction({ op: "local.get", index: remTmp });
1922
+ this.pushInstruction("i64.sub");
1923
+ this.pushInstruction({ op: "local.set", index: resNanoTmp });
1924
+ this.pushInstruction("end");
1925
+ this.pushInstruction("end");
1926
+
1927
+ this.pushInstruction({ op: "local.get", index: resNanoTmp });
1928
+ this.pushInstruction({ op: "local.get", index: rTmp });
1929
+ this.pushInstruction({
1930
+ op: "struct.get",
1931
+ typeIndex: timeInfo.typeIndex,
1932
+ fieldIndex: 1,
1933
+ });
1934
+ this.pushInstruction({ op: "local.get", index: rTmp });
1935
+ this.pushInstruction({
1936
+ op: "struct.get",
1937
+ typeIndex: timeInfo.typeIndex,
1938
+ fieldIndex: 2,
1939
+ });
1940
+ this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
1941
+
1942
+ this.releaseTemp(resNanoTmp, "i64");
1943
+ this.releaseTemp(remTmp, "i64");
1944
+ this.releaseTemp(nanoTmp, "i64");
1945
+ this.releaseTemp(dTmp, "i64");
1946
+ this.releaseTemp(rTmp, timeW);
1947
+ }
1948
+
1949
+ _emitTimeMethodAddDate(expr, args, _targetWasmType) {
1950
+ const timeInfo = this.mod.getStructType("time.Time");
1951
+ const p = this._emitTimeDecomposeParts(expr);
1952
+
1953
+ const yearsTmp = this.acquireTemp("i32");
1954
+ const monthsTmp = this.acquireTemp("i32");
1955
+ const daysAddTmp = this.acquireTemp("i32");
1956
+ this.emitExpr(args[0], "i32");
1957
+ this.pushInstruction({ op: "local.set", index: yearsTmp });
1958
+ this.emitExpr(args[1], "i32");
1959
+ this.pushInstruction({ op: "local.set", index: monthsTmp });
1960
+ this.emitExpr(args[2], "i32");
1961
+ this.pushInstruction({ op: "local.set", index: daysAddTmp });
1962
+
1963
+ const curY = this.acquireTemp("i32");
1964
+ const curM = this.acquireTemp("i32");
1965
+ const curD = this.acquireTemp("i32");
1966
+ this._emitCivilDateFromDays(p.daysTmp, curY, curM, curD);
1967
+
1968
+ this.pushInstruction({ op: "local.get", index: curY });
1969
+ this.pushInstruction({ op: "local.get", index: yearsTmp });
1970
+ this.pushInstruction("i32.add");
1971
+ this.pushInstruction({ op: "local.set", index: curY });
1972
+
1973
+ this.pushInstruction({ op: "local.get", index: curM });
1974
+ this.pushInstruction({ op: "local.get", index: monthsTmp });
1975
+ this.pushInstruction("i32.add");
1976
+ this.pushInstruction({ op: "local.set", index: curM });
1977
+
1978
+ this.pushInstruction({ op: "local.get", index: curD });
1979
+ this.pushInstruction({ op: "local.get", index: daysAddTmp });
1980
+ this.pushInstruction("i32.add");
1981
+ this.pushInstruction({ op: "local.set", index: curD });
1982
+
1983
+ const newDaysTmp = this.acquireTemp("i64");
1984
+ this._emitCivilDays(curY, curM, curD, newDaysTmp);
1985
+
1986
+ const newLocalSecTmp = this.acquireTemp("i64");
1987
+ this.pushInstruction({ op: "local.get", index: newDaysTmp });
1988
+ this.pushInstruction({ op: "i64.const", value: 86400n });
1989
+ this.pushInstruction("i64.mul");
1990
+ this.pushInstruction({ op: "local.get", index: p.remSecTmp });
1991
+ this.pushInstruction("i64.add");
1992
+ this.pushInstruction({ op: "local.set", index: newLocalSecTmp });
1993
+
1994
+ const nsecTmp = this.acquireTemp("i64");
1995
+ this.pushInstruction({ op: "local.get", index: p.nanoTmp });
1996
+ this.pushInstruction({ op: "i64.const", value: 1000000000n });
1997
+ this.pushInstruction("i64.rem_s");
1998
+ this.pushInstruction({ op: "local.tee", index: nsecTmp });
1999
+ this.pushInstruction({ op: "i64.const", value: 0n });
2000
+ this.pushInstruction("i64.lt_s");
2001
+ this.pushInstruction({ op: "if", blockType: "void" });
2002
+ this.pushInstruction({ op: "local.get", index: nsecTmp });
2003
+ this.pushInstruction({ op: "i64.const", value: 1000000000n });
2004
+ this.pushInstruction("i64.add");
2005
+ this.pushInstruction({ op: "local.set", index: nsecTmp });
2006
+ this.pushInstruction("end");
2007
+
2008
+ this.pushInstruction({ op: "local.get", index: newLocalSecTmp });
2009
+ this.pushInstruction({ op: "local.get", index: p.offTmp });
2010
+ this.pushInstruction("i64.extend_i32_s");
2011
+ this.pushInstruction("i64.sub");
2012
+ this.pushInstruction({ op: "i64.const", value: 1000000000n });
2013
+ this.pushInstruction("i64.mul");
2014
+ this.pushInstruction({ op: "local.get", index: nsecTmp });
2015
+ this.pushInstruction("i64.add");
2016
+
2017
+ this.pushInstruction({ op: "local.get", index: p.offTmp });
2018
+ this.pushInstruction({ op: "local.get", index: p.rTmp });
2019
+ this.pushInstruction({
2020
+ op: "struct.get",
2021
+ typeIndex: timeInfo.typeIndex,
2022
+ fieldIndex: 2,
2023
+ });
2024
+ this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
2025
+
2026
+ this.releaseTemp(nsecTmp, "i64");
2027
+ this.releaseTemp(newLocalSecTmp, "i64");
2028
+ this.releaseTemp(newDaysTmp, "i64");
2029
+ this.releaseTemp(curD, "i32");
2030
+ this.releaseTemp(curM, "i32");
2031
+ this.releaseTemp(curY, "i32");
2032
+ this.releaseTemp(daysAddTmp, "i32");
2033
+ this.releaseTemp(monthsTmp, "i32");
2034
+ this.releaseTemp(yearsTmp, "i32");
2035
+ this._releaseTimeDecomposeParts(p);
2036
+ }
2037
+
2038
+ _emitTimeMethodMarshalText(expr, _targetWasmType) {
2039
+ const rfcLit = {
2040
+ kind: "BasicLit",
2041
+ litKind: "STRING",
2042
+ value: "2006-01-02T15:04:05.999999999Z07:00",
2043
+ };
2044
+ this._emitTimeMethodFormat(expr, [rfcLit], "externref");
2045
+ this._emitStringToByteSlice({ elem: { kind: "basic", name: "byte" } });
2046
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
2047
+ }
2048
+
2049
+ _emitTimeMethodMarshalJSON(expr, _targetWasmType) {
2050
+ const rfcLit = {
2051
+ kind: "BasicLit",
2052
+ litKind: "STRING",
2053
+ value: "2006-01-02T15:04:05.999999999Z07:00",
2054
+ };
2055
+ this._emitTimeMethodFormat(expr, [rfcLit], "externref");
2056
+ const strTmp = this.acquireTemp("externref");
2057
+ this.pushInstruction({ op: "local.set", index: strTmp });
2058
+ const qLit = { kind: "BasicLit", litKind: "STRING", value: '"' };
2059
+ this.emitBasicLit(qLit, "externref");
2060
+ this.pushInstruction({ op: "local.get", index: strTmp });
2061
+ this.pushInstruction({
2062
+ op: "call",
2063
+ funcIndex: this.mod.getStringConcatImportIndex(),
2064
+ });
2065
+ this.emitBasicLit(qLit, "externref");
2066
+ this.pushInstruction({
2067
+ op: "call",
2068
+ funcIndex: this.mod.getStringConcatImportIndex(),
2069
+ });
2070
+ this.releaseTemp(strTmp, "externref");
2071
+ this._emitStringToByteSlice({ elem: { kind: "basic", name: "byte" } });
2072
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
2073
+ }
2074
+
2075
+ _emitTimeMethodUnmarshalText(expr, args, _targetWasmType) {
2076
+ this._emitTimeMethodUnmarshalCore(expr, args[0]);
2077
+ }
2078
+
2079
+ _emitTimeMethodUnmarshalJSON(expr, args, _targetWasmType) {
2080
+ this._emitTimeMethodUnmarshalCore(expr, args[0]);
2081
+ }
2082
+
2083
+ _emitTimeMethodUnmarshalCore(expr, dataArg) {
2084
+ const timeInfo = this.mod.getStructType("time.Time");
2085
+ const timeW = {
2086
+ kind: "ref",
2087
+ nullable: true,
2088
+ typeIndex: timeInfo.typeIndex,
2089
+ };
2090
+ const rTmp = this.acquireTemp(timeW);
2091
+ this.emitExpr(expr, timeW);
2092
+ this.pushInstruction({ op: "local.set", index: rTmp });
2093
+
2094
+ const byteSliceGo = dataArg._type ?? this._resolveExprGoType(dataArg);
2095
+ this.emitExpr(dataArg, this.toWasmType(byteSliceGo));
2096
+ this._emitByteSliceToString(byteSliceGo);
2097
+
2098
+ const strTmp = this.acquireTemp("externref");
2099
+ this.pushInstruction({ op: "local.set", index: strTmp });
2100
+
2101
+ const rfcLit = {
2102
+ kind: "BasicLit",
2103
+ litKind: "STRING",
2104
+ value: "2006-01-02T15:04:05.999999999Z07:00",
2105
+ };
2106
+ this.emitBasicLit(rfcLit, "externref");
2107
+ this.pushInstruction({ op: "local.get", index: strTmp });
2108
+ this._callStdlib("time_parse");
2109
+
2110
+ const msTmp = this.acquireTemp("f64");
2111
+ const offTmp = this.acquireTemp("i32");
2112
+ const errStrTmp = this.acquireTemp("externref");
2113
+ const resErrTmp = this.acquireTemp("anyref");
2114
+
2115
+ this.pushInstruction({ op: "local.set", index: msTmp });
2116
+ this._callStdlib("time_parse_offset");
2117
+ this.pushInstruction({ op: "local.set", index: offTmp });
2118
+ this._callStdlib("time_parse_err");
2119
+ this.pushInstruction({ op: "local.set", index: errStrTmp });
2120
+
2121
+ this.pushInstruction({ op: "local.get", index: errStrTmp });
2122
+ this.pushInstruction("ref.is_null");
2123
+ this.pushInstruction({ op: "if", blockType: "void" });
2124
+
2125
+ this.pushInstruction({ op: "local.get", index: rTmp });
2126
+ this.pushInstruction({ op: "local.get", index: msTmp });
2127
+ this.pushInstruction("i64.trunc_sat_f64_s");
2128
+ this.pushInstruction({ op: "i64.const", value: 1000000n });
2129
+ this.pushInstruction("i64.mul");
2130
+ this._callStdlib("time_parse_sub_ns");
2131
+ this.pushInstruction("i64.extend_i32_s");
2132
+ this.pushInstruction("i64.add");
2133
+ this.pushInstruction({
2134
+ op: "struct.set",
2135
+ typeIndex: timeInfo.typeIndex,
2136
+ fieldIndex: 0,
2137
+ });
2138
+
2139
+ this.pushInstruction({ op: "local.get", index: rTmp });
2140
+ this.pushInstruction({ op: "local.get", index: offTmp });
2141
+ this.pushInstruction({
2142
+ op: "struct.set",
2143
+ typeIndex: timeInfo.typeIndex,
2144
+ fieldIndex: 1,
2145
+ });
2146
+
2147
+ this.pushInstruction({ op: "local.get", index: rTmp });
2148
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
2149
+ this.pushInstruction({
2150
+ op: "struct.set",
2151
+ typeIndex: timeInfo.typeIndex,
2152
+ fieldIndex: 2,
2153
+ });
2154
+
2155
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
2156
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
2157
+
2158
+ this.pushInstruction("else");
2159
+
2160
+ this.pushInstruction({ op: "local.get", index: errStrTmp });
2161
+ this.pushInstruction({ op: "ref.null", heapType: "any" });
2162
+ this.pushInstruction({
2163
+ op: "call",
2164
+ funcIndex: this.mod.resolveFuncIndex("__mk_error"),
2165
+ });
2166
+ this.pushInstruction({ op: "local.set", index: resErrTmp });
2167
+
2168
+ this.pushInstruction("end");
2169
+
2170
+ this.pushInstruction({ op: "local.get", index: resErrTmp });
2171
+
2172
+ this.releaseTemp(resErrTmp, "anyref");
2173
+ this.releaseTemp(errStrTmp, "externref");
2174
+ this.releaseTemp(offTmp, "i32");
2175
+ this.releaseTemp(msTmp, "f64");
2176
+ this.releaseTemp(strTmp, "externref");
2177
+ this.releaseTemp(rTmp, timeW);
2178
+ }
2179
+
2180
+ emitTimeAuxMethodCall(recvTypeName, field, expr, _args, _targetWasmType) {
2181
+ if (field === "String") {
2182
+ if (recvTypeName === "time.Month") {
2183
+ this.emitExpr(expr, "i32");
2184
+ this._callStdlib("time_month_string");
2185
+ return;
2186
+ }
2187
+ if (recvTypeName === "time.Weekday") {
2188
+ this.emitExpr(expr, "i32");
2189
+ this._callStdlib("time_weekday_string");
2190
+ return;
2191
+ }
2192
+ if (recvTypeName === "time.Location") {
2193
+ const locInfo = this.mod.getStructType("time.Location");
2194
+ const locTmp = this.acquireTemp({
2195
+ kind: "ref",
2196
+ nullable: true,
2197
+ typeIndex: locInfo.typeIndex,
2198
+ });
2199
+ this.emitExpr(expr, {
2200
+ kind: "ref",
2201
+ nullable: true,
2202
+ typeIndex: locInfo.typeIndex,
2203
+ });
2204
+ this.pushInstruction({ op: "local.tee", index: locTmp });
2205
+ this.pushInstruction("ref.is_null");
2206
+ this.pushInstruction({ op: "if", blockType: "externref" });
2207
+ this.emitBasicLit(
2208
+ { kind: "BasicLit", litKind: "STRING", value: "UTC" },
2209
+ "externref",
2210
+ );
2211
+ this.pushInstruction("else");
2212
+ this.pushInstruction({ op: "local.get", index: locTmp });
2213
+ this.pushInstruction({
2214
+ op: "struct.get",
2215
+ typeIndex: locInfo.typeIndex,
2216
+ fieldIndex: 0,
2217
+ });
2218
+ this.pushInstruction("end");
2219
+ this.releaseTemp(locTmp, {
2220
+ kind: "ref",
2221
+ nullable: true,
2222
+ typeIndex: locInfo.typeIndex,
2223
+ });
2224
+ return;
2225
+ }
2226
+ }
2227
+ throw new Error(`Unsupported method ${recvTypeName}.${field}`);
2228
+ }
1200
2229
  }