gofront 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +14 -14
  2. package/package.json +10 -38
  3. package/src/backend/js/expressions.js +2060 -389
  4. package/src/backend/js/index.js +586 -174
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +936 -1644
  7. package/src/backend/js/statements.js +1349 -132
  8. package/src/backend/js/stdlib/index.js +51 -94
  9. package/src/backend/js/templ.js +67 -118
  10. package/src/backend/js/type-info.js +436 -0
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +80 -0
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +753 -872
  15. package/src/backend/wasm/emit-builtins.js +914 -237
  16. package/src/backend/wasm/emit-exprs.js +1456 -195
  17. package/src/backend/wasm/emit-maps.js +78 -380
  18. package/src/backend/wasm/emit-stmts.js +1659 -214
  19. package/src/backend/wasm/emit.js +614 -88
  20. package/src/backend/wasm/encode.js +43 -13
  21. package/src/backend/wasm/globals.js +491 -0
  22. package/src/backend/wasm/glue.js +2 -4
  23. package/src/backend/wasm/index.js +406 -3195
  24. package/src/backend/wasm/method-expr.js +392 -0
  25. package/src/backend/wasm/module-emitter.js +1615 -0
  26. package/src/backend/wasm/monomorph.js +164 -9
  27. package/src/backend/wasm/natives.js +596 -0
  28. package/src/backend/wasm/prescan.js +249 -0
  29. package/src/backend/wasm/prune-funcs.js +89 -0
  30. package/src/backend/wasm/stdlib/index.js +2 -37
  31. package/src/backend/wasm/stdlib/simd.js +293 -28
  32. package/src/backend/wasm/types.js +260 -27
  33. package/src/backend/wasm/variadic.js +93 -0
  34. package/src/backend/wasm/wat.js +47 -20
  35. package/src/{cli-core.js → cli/cli-core.js} +241 -11
  36. package/src/{test-runner.js → cli/test-runner.js} +188 -122
  37. package/src/{vendor.js → cli/vendor.js} +3 -4
  38. package/src/compiler.js +202 -386
  39. package/src/index.js +15 -169
  40. package/src/{lexer.js → lexer/lexer.js} +203 -62
  41. package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
  42. package/src/{tokens.js → lexer/tokens.js} +2 -0
  43. package/src/link/sourcemap.js +97 -0
  44. package/src/link/stdlib.js +737 -0
  45. package/src/link/type-names.js +148 -0
  46. package/src/link/wasm.js +318 -0
  47. package/src/lower/bounds.js +547 -0
  48. package/src/lower/boxing.js +1 -1
  49. package/src/lower/captures.js +267 -64
  50. package/src/lower/embedding.js +32 -3
  51. package/src/lower/errors-as.js +196 -0
  52. package/src/lower/fmt-formatters.js +905 -0
  53. package/src/lower/functions.js +2 -0
  54. package/src/lower/gen-types.js +274 -0
  55. package/src/lower/index.js +33 -19
  56. package/src/lower/json-codecs.js +1379 -0
  57. package/src/lower/ownership.js +47 -8
  58. package/src/lower/range.js +86 -1
  59. package/src/lower/reachability.js +150 -0
  60. package/src/lower/walk.js +12 -0
  61. package/src/parser/declarations.js +83 -15
  62. package/src/parser/expressions.js +110 -18
  63. package/src/parser/index.js +2 -1
  64. package/src/parser/statements.js +38 -22
  65. package/src/{templ-parser.js → parser/templ.js} +179 -17
  66. package/src/parser/types.js +70 -9
  67. package/src/resolver.js +21 -1
  68. package/src/typechecker/assignability.js +291 -19
  69. package/src/typechecker/const-fold.js +399 -0
  70. package/src/typechecker/constants.js +282 -0
  71. package/src/typechecker/expressions.js +1220 -183
  72. package/src/typechecker/index.js +659 -92
  73. package/src/typechecker/init-order.js +426 -0
  74. package/src/typechecker/operand-text.js +40 -0
  75. package/src/typechecker/resolve.js +613 -62
  76. package/src/typechecker/statements.js +212 -20
  77. package/src/typechecker/stdlib/excluded.js +902 -0
  78. package/src/typechecker/stdlib/index.js +38 -0
  79. package/src/typechecker/stdlib/simd.js +65 -15
  80. package/src/typechecker/termination.js +11 -2
  81. package/src/typechecker/types.js +268 -514
  82. package/stdlib/bytes/buffer.go +479 -0
  83. package/stdlib/bytes/bytes.go +1010 -0
  84. package/stdlib/bytes/reader.go +161 -0
  85. package/stdlib/cmp/cmp.go +65 -0
  86. package/stdlib/context/context.go +115 -0
  87. package/stdlib/crypto/rand/rand.go +34 -0
  88. package/stdlib/crypto/sha256/sha256.go +249 -0
  89. package/stdlib/encoding/base64/base64.go +331 -0
  90. package/stdlib/encoding/binary/binary.go +332 -0
  91. package/stdlib/encoding/hex/hex.go +140 -0
  92. package/stdlib/encoding/json/errors.go +31 -0
  93. package/stdlib/encoding/json/indent.go +71 -0
  94. package/stdlib/encoding/json/json.go +62 -0
  95. package/stdlib/encoding/json/number.go +12 -0
  96. package/stdlib/encoding/json/stream.go +173 -0
  97. package/stdlib/errors/errors.go +174 -0
  98. package/stdlib/fmt/errors.go +110 -0
  99. package/stdlib/fmt/format.go +732 -0
  100. package/stdlib/fmt/print.go +1232 -0
  101. package/stdlib/gom/gom.go +293 -0
  102. package/stdlib/hash/hash.go +53 -0
  103. package/stdlib/html/html.go +251 -0
  104. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  105. package/stdlib/internal/jsonrt/dec.go +871 -0
  106. package/stdlib/internal/jsonrt/enc.go +516 -0
  107. package/stdlib/internal/jsonrt/indent.go +135 -0
  108. package/stdlib/internal/jsonrt/number.go +27 -0
  109. package/stdlib/internal/jsonrt/reader.go +73 -0
  110. package/stdlib/internal/jsonrt/scanner.go +658 -0
  111. package/stdlib/io/io.go +502 -0
  112. package/stdlib/iter/iter.go +18 -0
  113. package/stdlib/maps/maps.go +131 -0
  114. package/stdlib/math/bits/bits.go +507 -0
  115. package/stdlib/math/extra.go +272 -0
  116. package/stdlib/math/math.go +439 -0
  117. package/stdlib/math/rand/rand.go +297 -0
  118. package/stdlib/os/os.go +93 -0
  119. package/stdlib/path/filepath/filepath.go +47 -0
  120. package/stdlib/path/path.go +394 -0
  121. package/stdlib/regexp/regexp.go +231 -0
  122. package/stdlib/slices/slices.go +526 -0
  123. package/stdlib/slices/sort.go +209 -0
  124. package/stdlib/slices/zsort_cmp.go +480 -0
  125. package/stdlib/slices/zsort_ordered.go +482 -0
  126. package/stdlib/sort/sort.go +500 -0
  127. package/stdlib/sort/zsort_func.go +480 -0
  128. package/stdlib/sort/zsort_iface.go +480 -0
  129. package/stdlib/strconv/float.go +1699 -0
  130. package/stdlib/strconv/isprint.go +752 -0
  131. package/stdlib/strconv/quote.go +526 -0
  132. package/stdlib/strconv/strconv.go +616 -0
  133. package/stdlib/strings/builder.go +95 -0
  134. package/stdlib/strings/reader.go +163 -0
  135. package/stdlib/strings/replacer.go +102 -0
  136. package/stdlib/strings/strings.go +807 -0
  137. package/stdlib/sync/sync.go +268 -0
  138. package/stdlib/testing/async_js.go +61 -0
  139. package/stdlib/testing/benchmark.go +297 -0
  140. package/stdlib/testing/testing.go +523 -0
  141. package/stdlib/time/duration.go +233 -0
  142. package/stdlib/time/format.go +745 -0
  143. package/stdlib/time/parse.go +790 -0
  144. package/stdlib/time/sleep_js.go +63 -0
  145. package/stdlib/time/time.go +834 -0
  146. package/stdlib/unicode/unicode.go +250 -0
  147. package/stdlib/unicode/utf8/utf8.go +464 -0
  148. package/src/backend/js/stdlib/base64.js +0 -12
  149. package/src/backend/js/stdlib/binary.js +0 -102
  150. package/src/backend/js/stdlib/bits.js +0 -46
  151. package/src/backend/js/stdlib/builder.js +0 -63
  152. package/src/backend/js/stdlib/bytes.js +0 -122
  153. package/src/backend/js/stdlib/errors.js +0 -44
  154. package/src/backend/js/stdlib/fmt.js +0 -178
  155. package/src/backend/js/stdlib/gom.js +0 -155
  156. package/src/backend/js/stdlib/hex.js +0 -17
  157. package/src/backend/js/stdlib/html.js +0 -20
  158. package/src/backend/js/stdlib/io.js +0 -137
  159. package/src/backend/js/stdlib/json.js +0 -972
  160. package/src/backend/js/stdlib/maps.js +0 -45
  161. package/src/backend/js/stdlib/math.js +0 -69
  162. package/src/backend/js/stdlib/os.js +0 -13
  163. package/src/backend/js/stdlib/path.js +0 -48
  164. package/src/backend/js/stdlib/rand.js +0 -32
  165. package/src/backend/js/stdlib/regexp.js +0 -54
  166. package/src/backend/js/stdlib/sha256.js +0 -12
  167. package/src/backend/js/stdlib/shared.js +0 -17
  168. package/src/backend/js/stdlib/simd.js +0 -24
  169. package/src/backend/js/stdlib/slices.js +0 -77
  170. package/src/backend/js/stdlib/sort.js +0 -30
  171. package/src/backend/js/stdlib/strconv.js +0 -74
  172. package/src/backend/js/stdlib/strings.js +0 -222
  173. package/src/backend/js/stdlib/sync.js +0 -13
  174. package/src/backend/js/stdlib/testing.js +0 -34
  175. package/src/backend/js/stdlib/time.js +0 -128
  176. package/src/backend/js/stdlib/unicode.js +0 -25
  177. package/src/backend/js/stdlib/utf8.js +0 -26
  178. package/src/backend/wasm/const-fold.js +0 -205
  179. package/src/backend/wasm/emit-stdlib.js +0 -13
  180. package/src/backend/wasm/stdlib/bytes.js +0 -5039
  181. package/src/backend/wasm/stdlib/core.js +0 -8903
  182. package/src/backend/wasm/stdlib/io.js +0 -2161
  183. package/src/backend/wasm/stdlib/packages.js +0 -2400
  184. package/src/backend/wasm/stdlib/pure.js +0 -720
  185. package/src/backend/wasm/stdlib/time.js +0 -1200
  186. package/src/typechecker/stdlib/core.js +0 -801
  187. package/src/typechecker/stdlib/extended.js +0 -914
  188. package/src/typechecker/stdlib.js +0 -22
  189. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  190. /package/src/{colors.js → cli/colors.js} +0 -0
  191. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  192. /package/src/{minifier.js → cli/minifier.js} +0 -0
  193. /package/src/{project-config.js → cli/project-config.js} +0 -0
  194. /package/src/{pwa.js → cli/pwa.js} +0 -0
@@ -1,1200 +0,0 @@
1
- // src/backend/wasm/stdlib/time.js
2
- // FunctionEmitter mixin: time package.
3
-
4
- const DURATION_VALS = {
5
- Nanosecond: 1n,
6
- Microsecond: 1000n,
7
- Millisecond: 1000000n,
8
- Second: 1000000000n,
9
- Minute: 60000000000n,
10
- Hour: 3600000000000n,
11
- };
12
-
13
- const LAYOUT_STRS = {
14
- RFC3339: "2006-01-02T15:04:05Z07:00",
15
- RFC3339Nano: "2006-01-02T15:04:05.999999999Z07:00",
16
- DateOnly: "2006-01-02",
17
- TimeOnly: "15:04:05",
18
- DateTime: "2006-01-02 15:04:05",
19
- };
20
-
21
- const TIME_INT_CONSTS = {
22
- January: 1,
23
- February: 2,
24
- March: 3,
25
- April: 4,
26
- May: 5,
27
- June: 6,
28
- July: 7,
29
- August: 8,
30
- September: 9,
31
- October: 10,
32
- November: 11,
33
- December: 12,
34
- Sunday: 0,
35
- Monday: 1,
36
- Tuesday: 2,
37
- Wednesday: 3,
38
- Thursday: 4,
39
- Friday: 5,
40
- Saturday: 6,
41
- };
42
-
43
- export class TimeEmitter {
44
- _isTimeConst(expr) {
45
- const f = expr.field;
46
- return (
47
- this._isPkgExpr(expr, "time") &&
48
- (f in DURATION_VALS ||
49
- f in LAYOUT_STRS ||
50
- f in TIME_INT_CONSTS ||
51
- f === "UTC" ||
52
- f === "Local")
53
- );
54
- }
55
-
56
- _isUtcExpr(expr) {
57
- if (!expr) return false;
58
- if (
59
- expr.kind === "SelectorExpr" &&
60
- (expr.sel?.name === "UTC" || expr.field === "UTC")
61
- )
62
- return true;
63
- if (expr.kind === "Ident" && expr.name === "UTC") return true;
64
- return false;
65
- }
66
-
67
- emitTimeConst(field, targetWasmType) {
68
- if (field in DURATION_VALS) {
69
- this.pushInstruction({ op: "i64.const", value: DURATION_VALS[field] });
70
- if (targetWasmType === "i32") {
71
- this.pushInstruction("i32.wrap_i64");
72
- }
73
- return;
74
- }
75
- if (field in LAYOUT_STRS) {
76
- this.emitBasicLit(
77
- { kind: "BasicLit", litKind: "STRING", value: LAYOUT_STRS[field] },
78
- targetWasmType,
79
- );
80
- return;
81
- }
82
- if (field in TIME_INT_CONSTS) {
83
- const v = TIME_INT_CONSTS[field];
84
- if (targetWasmType === "i64") {
85
- this.pushInstruction({ op: "i64.const", value: BigInt(v) });
86
- } else {
87
- this.pushInstruction({ op: "i32.const", value: v });
88
- }
89
- return;
90
- }
91
- if (field === "UTC" || field === "Local") {
92
- this.pushInstruction({ op: "ref.null", heapType: "any" });
93
- }
94
- }
95
-
96
- emitTimeCall(field, call, targetWasmType) {
97
- switch (field) {
98
- case "Now":
99
- this._emitTimeNow(targetWasmType);
100
- break;
101
- case "Since":
102
- this._emitTimeSince(call.args, targetWasmType);
103
- break;
104
- case "Unix":
105
- this._emitTimeUnix(call.args, targetWasmType);
106
- break;
107
- case "Date":
108
- this._emitTimeDate(call.args, targetWasmType);
109
- break;
110
- case "Parse":
111
- this._emitTimeParse(call.args, targetWasmType);
112
- break;
113
- default:
114
- throw new Error(`Unsupported time function '${field}'`);
115
- }
116
- }
117
-
118
- emitTimeMethodCall(field, expr, args, targetWasmType) {
119
- switch (field) {
120
- case "Format":
121
- this._emitTimeMethodFormat(expr, args, targetWasmType);
122
- break;
123
- case "String":
124
- this._emitTimeMethodString(expr, targetWasmType);
125
- break;
126
- case "Unix":
127
- this._emitTimeMethodUnix(expr, targetWasmType);
128
- break;
129
- case "UnixMilli":
130
- this._emitTimeMethodUnixMilli(expr, targetWasmType);
131
- break;
132
- case "Add":
133
- this._emitTimeMethodAdd(expr, args, targetWasmType);
134
- break;
135
- case "Sub":
136
- this._emitTimeMethodSub(expr, args, targetWasmType);
137
- break;
138
- case "Before":
139
- this._emitTimeMethodBefore(expr, args, targetWasmType);
140
- break;
141
- case "After":
142
- this._emitTimeMethodAfter(expr, args, targetWasmType);
143
- break;
144
- case "Equal":
145
- this._emitTimeMethodEqual(expr, args, targetWasmType);
146
- break;
147
- case "Hour":
148
- this._emitTimeMethodHour(expr, targetWasmType);
149
- break;
150
- case "Minute":
151
- this._emitTimeMethodMinute(expr, targetWasmType);
152
- break;
153
- case "Second":
154
- this._emitTimeMethodSecond(expr, targetWasmType);
155
- break;
156
- case "Weekday":
157
- this._emitTimeMethodWeekday(expr, targetWasmType);
158
- break;
159
- case "Year":
160
- this._emitTimeMethodYMD(expr, targetWasmType, 0);
161
- break;
162
- case "Month":
163
- this._emitTimeMethodYMD(expr, targetWasmType, 1);
164
- break;
165
- case "Day":
166
- this._emitTimeMethodYMD(expr, targetWasmType, 2);
167
- break;
168
- case "IsZero":
169
- this._emitTimeMethodIsZero(expr);
170
- break;
171
- case "UnixNano":
172
- this._emitTimeMethodUnixNano(expr, targetWasmType);
173
- break;
174
- case "Nanosecond":
175
- this._emitTimeMethodNanosecond(expr, targetWasmType);
176
- break;
177
- case "UTC":
178
- this._emitTimeMethodUTC(expr);
179
- break;
180
- case "Local":
181
- this._emitTimeMethodLocal(expr);
182
- break;
183
- default:
184
- throw new Error(`Unsupported time.Time method '${field}'`);
185
- }
186
- }
187
-
188
- emitDurationMethodCall(field, expr, _args, _targetWasmType) {
189
- switch (field) {
190
- case "Nanoseconds":
191
- this.emitExpr(expr, "i64");
192
- return;
193
- case "Microseconds":
194
- this.emitExpr(expr, "i64");
195
- this.pushInstruction({ op: "i64.const", value: 1000n });
196
- this.pushInstruction("i64.div_s");
197
- return;
198
- case "Milliseconds":
199
- this.emitExpr(expr, "i64");
200
- this.pushInstruction({ op: "i64.const", value: 1000000n });
201
- this.pushInstruction("i64.div_s");
202
- return;
203
- case "Seconds":
204
- this.emitExpr(expr, "i64");
205
- this.pushInstruction("f64.convert_i64_s");
206
- this.pushInstruction({ op: "f64.const", value: 1000000000.0 });
207
- this.pushInstruction("f64.div");
208
- return;
209
- case "Minutes":
210
- this.emitExpr(expr, "i64");
211
- this.pushInstruction("f64.convert_i64_s");
212
- this.pushInstruction({ op: "f64.const", value: 60000000000.0 });
213
- this.pushInstruction("f64.div");
214
- return;
215
- case "Hours":
216
- this.emitExpr(expr, "i64");
217
- this.pushInstruction("f64.convert_i64_s");
218
- this.pushInstruction({ op: "f64.const", value: 3600000000000.0 });
219
- this.pushInstruction("f64.div");
220
- return;
221
- case "String":
222
- this.emitExpr(expr, "i64");
223
- this._callStdlib("time_duration_string");
224
- return;
225
- default:
226
- throw new Error(`Unsupported time.Duration method '${field}'`);
227
- }
228
- }
229
-
230
- _emitTimeNow(_targetWasmType) {
231
- const timeInfo = this.mod.getStructType("time.Time");
232
- const msTmp = this.acquireTemp("f64");
233
- const offTmp = this.acquireTemp("i32");
234
- this._callStdlib("time_now_ms");
235
- this.pushInstruction({ op: "local.tee", index: msTmp });
236
- this._callStdlib("time_timezone_offset");
237
- this.pushInstruction({ op: "local.set", index: offTmp });
238
- this.pushInstruction({ op: "local.get", index: msTmp });
239
- this.pushInstruction({ op: "f64.const", value: 1000000 });
240
- this.pushInstruction("f64.mul");
241
- this.pushInstruction("i64.trunc_sat_f64_s");
242
- this.pushInstruction({ op: "local.get", index: offTmp });
243
- this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
244
- this.releaseTemp(offTmp, "i32");
245
- this.releaseTemp(msTmp, "f64");
246
- }
247
-
248
- _emitTimeSince(args, targetWasmType) {
249
- const timeInfo = this.mod.getStructType("time.Time");
250
- const timeW = {
251
- kind: "ref",
252
- nullable: true,
253
- typeIndex: timeInfo.typeIndex,
254
- };
255
- const argTmp = this.acquireTemp(timeW);
256
- this.emitExpr(args[0], timeW);
257
- this.pushInstruction({ op: "local.set", index: argTmp });
258
-
259
- const msTmp = this.acquireTemp("f64");
260
- this._callStdlib("time_now_ms");
261
- this.pushInstruction({ op: "local.set", index: msTmp });
262
- this.pushInstruction({ op: "local.get", index: msTmp });
263
- this.pushInstruction({ op: "f64.const", value: 1000000 });
264
- this.pushInstruction("f64.mul");
265
- this.pushInstruction("i64.trunc_sat_f64_s");
266
- this.pushInstruction({ op: "local.get", index: argTmp });
267
- this.pushInstruction({
268
- op: "struct.get",
269
- typeIndex: timeInfo.typeIndex,
270
- fieldIndex: 0,
271
- });
272
- this.pushInstruction("i64.sub");
273
- this.releaseTemp(msTmp, "f64");
274
- this.releaseTemp(argTmp, timeW);
275
-
276
- if (targetWasmType === "i32") {
277
- this.pushInstruction("i32.wrap_i64");
278
- }
279
- }
280
-
281
- _emitTimeUnix(args, _targetWasmType) {
282
- const timeInfo = this.mod.getStructType("time.Time");
283
- const secTmp = this.acquireTemp("i64");
284
- const nsecTmp = this.acquireTemp("i64");
285
- const nanoTmp = this.acquireTemp("i64");
286
- const offTmp = this.acquireTemp("i32");
287
-
288
- this.emitExpr(args[0], "i64");
289
- this.pushInstruction({ op: "local.set", index: secTmp });
290
- this.emitExpr(args[1], "i64");
291
- this.pushInstruction({ op: "local.set", index: nsecTmp });
292
-
293
- this.pushInstruction({ op: "local.get", index: secTmp });
294
- this.pushInstruction({ op: "i64.const", value: 1000000000n });
295
- this.pushInstruction("i64.mul");
296
- this.pushInstruction({ op: "local.get", index: nsecTmp });
297
- this.pushInstruction("i64.add");
298
- this.pushInstruction({ op: "local.tee", index: nanoTmp });
299
-
300
- this.pushInstruction({ op: "i64.const", value: 1000000n });
301
- this.pushInstruction("i64.div_s");
302
- this.pushInstruction("f64.convert_i64_s");
303
- this._callStdlib("time_timezone_offset");
304
- this.pushInstruction({ op: "local.set", index: offTmp });
305
-
306
- this.pushInstruction({ op: "local.get", index: nanoTmp });
307
- this.pushInstruction({ op: "local.get", index: offTmp });
308
- this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
309
-
310
- this.releaseTemp(offTmp, "i32");
311
- this.releaseTemp(nanoTmp, "i64");
312
- this.releaseTemp(nsecTmp, "i64");
313
- this.releaseTemp(secTmp, "i64");
314
- }
315
-
316
- _emitCivilDays(yTmp, mTmp, dTmp, daysTmp) {
317
- // Evaluates:
318
- // if (m <= 2) y -= 1
319
- // era = (y >= 0 ? y : y - 399) / 400
320
- // yoe = y - era * 400
321
- // doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1
322
- // doe = yoe * 365 + yoe / 4 - yoe / 100 + doy
323
- // days = era * 146097 + doe - 719468
324
- const eraTmp = this.acquireTemp("i32");
325
- const yoeTmp = this.acquireTemp("i32");
326
- const doyTmp = this.acquireTemp("i32");
327
- const doeTmp = this.acquireTemp("i32");
328
-
329
- this.pushInstruction({ op: "local.get", index: mTmp });
330
- this.pushInstruction({ op: "i32.const", value: 2 });
331
- this.pushInstruction("i32.le_s");
332
- this.pushInstruction({ op: "if", blockType: "void" });
333
- this.pushInstruction({ op: "local.get", index: yTmp });
334
- this.pushInstruction({ op: "i32.const", value: 1 });
335
- this.pushInstruction("i32.sub");
336
- this.pushInstruction({ op: "local.set", index: yTmp });
337
- this.pushInstruction("end");
338
-
339
- this.pushInstruction({ op: "local.get", index: yTmp });
340
- this.pushInstruction({ op: "i32.const", value: 0 });
341
- this.pushInstruction("i32.ge_s");
342
- this.pushInstruction({ op: "if", blockType: "i32" });
343
- this.pushInstruction({ op: "local.get", index: yTmp });
344
- this.pushInstruction("else");
345
- this.pushInstruction({ op: "local.get", index: yTmp });
346
- this.pushInstruction({ op: "i32.const", value: 399 });
347
- this.pushInstruction("i32.sub");
348
- this.pushInstruction("end");
349
- this.pushInstruction({ op: "i32.const", value: 400 });
350
- this.pushInstruction("i32.div_s");
351
- this.pushInstruction({ op: "local.set", index: eraTmp });
352
- this.pushInstruction({ op: "local.get", index: yTmp });
353
- this.pushInstruction({ op: "local.get", index: eraTmp });
354
- this.pushInstruction({ op: "i32.const", value: 400 });
355
- this.pushInstruction("i32.mul");
356
- this.pushInstruction("i32.sub");
357
- this.pushInstruction({ op: "local.set", index: yoeTmp });
358
-
359
- // doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1
360
- this.pushInstruction({ op: "local.get", index: mTmp });
361
- this.pushInstruction({ op: "i32.const", value: 2 });
362
- this.pushInstruction("i32.gt_s");
363
- this.pushInstruction({ op: "if", blockType: "i32" });
364
- this.pushInstruction({ op: "local.get", index: mTmp });
365
- this.pushInstruction({ op: "i32.const", value: 3 });
366
- this.pushInstruction("i32.sub");
367
- this.pushInstruction("else");
368
- this.pushInstruction({ op: "local.get", index: mTmp });
369
- this.pushInstruction({ op: "i32.const", value: 9 });
370
- this.pushInstruction("i32.add");
371
- this.pushInstruction("end");
372
- this.pushInstruction({ op: "i32.const", value: 153 });
373
- this.pushInstruction("i32.mul");
374
- this.pushInstruction({ op: "i32.const", value: 2 });
375
- this.pushInstruction("i32.add");
376
- this.pushInstruction({ op: "i32.const", value: 5 });
377
- this.pushInstruction("i32.div_s");
378
- this.pushInstruction({ op: "local.get", index: dTmp });
379
- this.pushInstruction("i32.add");
380
- this.pushInstruction({ op: "i32.const", value: 1 });
381
- this.pushInstruction("i32.sub");
382
- this.pushInstruction({ op: "local.set", index: doyTmp });
383
-
384
- // doe = yoe * 365 + yoe / 4 - yoe / 100 + doy
385
- this.pushInstruction({ op: "local.get", index: yoeTmp });
386
- this.pushInstruction({ op: "i32.const", value: 365 });
387
- this.pushInstruction("i32.mul");
388
- this.pushInstruction({ op: "local.get", index: yoeTmp });
389
- this.pushInstruction({ op: "i32.const", value: 4 });
390
- this.pushInstruction("i32.div_s");
391
- this.pushInstruction("i32.add");
392
- this.pushInstruction({ op: "local.get", index: yoeTmp });
393
- this.pushInstruction({ op: "i32.const", value: 100 });
394
- this.pushInstruction("i32.div_s");
395
- this.pushInstruction("i32.sub");
396
- this.pushInstruction({ op: "local.get", index: doyTmp });
397
- this.pushInstruction("i32.add");
398
- this.pushInstruction({ op: "local.set", index: doeTmp });
399
-
400
- // days = era * 146097 + doe - 719468 (in i64)
401
- this.pushInstruction({ op: "local.get", index: eraTmp });
402
- this.pushInstruction("i64.extend_i32_s");
403
- this.pushInstruction({ op: "i64.const", value: 146097n });
404
- this.pushInstruction("i64.mul");
405
- this.pushInstruction({ op: "local.get", index: doeTmp });
406
- this.pushInstruction("i64.extend_i32_s");
407
- this.pushInstruction("i64.add");
408
- this.pushInstruction({ op: "i64.const", value: 719468n });
409
- this.pushInstruction("i64.sub");
410
- this.pushInstruction({ op: "local.set", index: daysTmp });
411
-
412
- this.releaseTemp(doeTmp, "i32");
413
- this.releaseTemp(doyTmp, "i32");
414
- this.releaseTemp(yoeTmp, "i32");
415
- this.releaseTemp(eraTmp, "i32");
416
- }
417
-
418
- _emitTimeDate(args, _targetWasmType) {
419
- const timeInfo = this.mod.getStructType("time.Time");
420
- const yTmp = this.acquireTemp("i32");
421
- const mTmp = this.acquireTemp("i32");
422
- const dTmp = this.acquireTemp("i32");
423
- const hrTmp = this.acquireTemp("i32");
424
- const minTmp = this.acquireTemp("i32");
425
- const secTmp = this.acquireTemp("i32");
426
- const nsecTmp = this.acquireTemp("i64");
427
- const locTmp = this.acquireTemp("anyref");
428
-
429
- this.emitExpr(args[0], "i32");
430
- this.pushInstruction({ op: "local.set", index: yTmp });
431
- this.emitExpr(args[1], "i32");
432
- this.pushInstruction({ op: "local.set", index: mTmp });
433
- this.emitExpr(args[2], "i32");
434
- this.pushInstruction({ op: "local.set", index: dTmp });
435
- this.emitExpr(args[3], "i32");
436
- this.pushInstruction({ op: "local.set", index: hrTmp });
437
- this.emitExpr(args[4], "i32");
438
- this.pushInstruction({ op: "local.set", index: minTmp });
439
- this.emitExpr(args[5], "i32");
440
- this.pushInstruction({ op: "local.set", index: secTmp });
441
- this.emitExpr(args[6], "i64");
442
- this.pushInstruction({ op: "local.set", index: nsecTmp });
443
- this.emitExpr(args[7], "anyref");
444
- this.pushInstruction({ op: "local.set", index: locTmp });
445
-
446
- const daysTmp = this.acquireTemp("i64");
447
- this._emitCivilDays(yTmp, mTmp, dTmp, daysTmp);
448
-
449
- const localSecTmp = this.acquireTemp("i64");
450
- // secOfDay = hr * 3600 + min * 60 + sec
451
- this.pushInstruction({ op: "local.get", index: hrTmp });
452
- this.pushInstruction({ op: "i32.const", value: 3600 });
453
- this.pushInstruction("i32.mul");
454
- this.pushInstruction({ op: "local.get", index: minTmp });
455
- this.pushInstruction({ op: "i32.const", value: 60 });
456
- this.pushInstruction("i32.mul");
457
- this.pushInstruction("i32.add");
458
- this.pushInstruction({ op: "local.get", index: secTmp });
459
- this.pushInstruction("i32.add");
460
- this.pushInstruction("i64.extend_i32_s");
461
- this.pushInstruction({ op: "local.get", index: daysTmp });
462
- this.pushInstruction({ op: "i64.const", value: 86400n });
463
- this.pushInstruction("i64.mul");
464
- this.pushInstruction("i64.add");
465
- this.pushInstruction({ op: "local.set", index: localSecTmp });
466
-
467
- const offTmp = this.acquireTemp("i32");
468
- if (this._isUtcExpr(args[7])) {
469
- this.pushInstruction({ op: "i32.const", value: 0 });
470
- this.pushInstruction({ op: "local.set", index: offTmp });
471
- } else {
472
- this.pushInstruction({ op: "local.get", index: localSecTmp });
473
- this.pushInstruction({ op: "i64.const", value: 1000n });
474
- this.pushInstruction("i64.mul");
475
- this.pushInstruction("f64.convert_i64_s");
476
- this._callStdlib("time_timezone_offset");
477
- this.pushInstruction({ op: "local.set", index: offTmp });
478
- }
479
-
480
- // unixSec = localSec - offset
481
- this.pushInstruction({ op: "local.get", index: localSecTmp });
482
- this.pushInstruction({ op: "local.get", index: offTmp });
483
- this.pushInstruction("i64.extend_i32_s");
484
- this.pushInstruction("i64.sub");
485
- this.pushInstruction({ op: "i64.const", value: 1000000000n });
486
- this.pushInstruction("i64.mul");
487
- this.pushInstruction({ op: "local.get", index: nsecTmp });
488
- this.pushInstruction("i64.add");
489
-
490
- this.pushInstruction({ op: "local.get", index: offTmp });
491
- this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
492
-
493
- this.releaseTemp(offTmp, "i32");
494
- this.releaseTemp(localSecTmp, "i64");
495
- this.releaseTemp(daysTmp, "i64");
496
- this.releaseTemp(locTmp, "anyref");
497
- this.releaseTemp(nsecTmp, "i64");
498
- this.releaseTemp(secTmp, "i32");
499
- this.releaseTemp(minTmp, "i32");
500
- this.releaseTemp(hrTmp, "i32");
501
- this.releaseTemp(dTmp, "i32");
502
- this.releaseTemp(mTmp, "i32");
503
- this.releaseTemp(yTmp, "i32");
504
- }
505
-
506
- _emitTimeParse(args, _targetWasmType) {
507
- const timeInfo = this.mod.getStructType("time.Time");
508
- const timeW = {
509
- kind: "ref",
510
- nullable: true,
511
- typeIndex: timeInfo.typeIndex,
512
- };
513
- const msTmp = this.acquireTemp("f64");
514
- const offTmp = this.acquireTemp("i32");
515
- const errStrTmp = this.acquireTemp("externref");
516
- const resTimeTmp = this.acquireTemp(timeW);
517
- const resErrTmp = this.acquireTemp("anyref");
518
-
519
- this.emitExpr(args[0], "externref");
520
- this.emitExpr(args[1], "externref");
521
- this._callStdlib("time_parse");
522
- this.pushInstruction({ op: "local.set", index: msTmp });
523
- this._callStdlib("time_parse_offset");
524
- this.pushInstruction({ op: "local.set", index: offTmp });
525
- this._callStdlib("time_parse_err");
526
- this.pushInstruction({ op: "local.set", index: errStrTmp });
527
-
528
- this.pushInstruction({ op: "local.get", index: errStrTmp });
529
- this.pushInstruction("ref.is_null");
530
- this.pushInstruction({ op: "if", blockType: "void" });
531
-
532
- // Success
533
- this.pushInstruction({ op: "local.get", index: msTmp });
534
- this.pushInstruction({ op: "f64.const", value: 1000000 });
535
- this.pushInstruction("f64.mul");
536
- this.pushInstruction("i64.trunc_sat_f64_s");
537
- this.pushInstruction({ op: "local.get", index: offTmp });
538
- this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
539
- this.pushInstruction({ op: "local.set", index: resTimeTmp });
540
- this.pushInstruction({ op: "ref.null", heapType: "any" });
541
- this.pushInstruction({ op: "local.set", index: resErrTmp });
542
-
543
- this.pushInstruction("else");
544
-
545
- // Error
546
- this.pushInstruction({ op: "i64.const", value: 0n });
547
- this.pushInstruction({ op: "i32.const", value: 0 });
548
- this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
549
- this.pushInstruction({ op: "local.set", index: resTimeTmp });
550
- this.pushInstruction({ op: "local.get", index: errStrTmp });
551
- this.pushInstruction({ op: "ref.null", heapType: "any" });
552
- this.pushInstruction({
553
- op: "call",
554
- funcIndex: this.mod.resolveFuncIndex("__mk_error"),
555
- });
556
- this.pushInstruction({ op: "local.set", index: resErrTmp });
557
-
558
- this.pushInstruction("end");
559
-
560
- this.pushInstruction({ op: "local.get", index: resTimeTmp });
561
- this.pushInstruction({ op: "local.get", index: resErrTmp });
562
-
563
- this.releaseTemp(resErrTmp, "anyref");
564
- this.releaseTemp(resTimeTmp, timeW);
565
- this.releaseTemp(errStrTmp, "externref");
566
- this.releaseTemp(offTmp, "i32");
567
- this.releaseTemp(msTmp, "f64");
568
- }
569
-
570
- _emitTimeMethodAdd(expr, args, _targetWasmType) {
571
- const timeInfo = this.mod.getStructType("time.Time");
572
- const timeW = {
573
- kind: "ref",
574
- nullable: true,
575
- typeIndex: timeInfo.typeIndex,
576
- };
577
- const rTmp = this.acquireTemp(timeW);
578
- const dTmp = this.acquireTemp("i64");
579
-
580
- this.emitExpr(expr, timeW);
581
- this.pushInstruction({ op: "local.set", index: rTmp });
582
- this.emitExpr(args[0], "i64");
583
- this.pushInstruction({ op: "local.set", index: dTmp });
584
-
585
- this.pushInstruction({ op: "local.get", index: rTmp });
586
- this.pushInstruction({
587
- op: "struct.get",
588
- typeIndex: timeInfo.typeIndex,
589
- fieldIndex: 0,
590
- });
591
- this.pushInstruction({ op: "local.get", index: dTmp });
592
- this.pushInstruction("i64.add");
593
-
594
- this.pushInstruction({ op: "local.get", index: rTmp });
595
- this.pushInstruction({
596
- op: "struct.get",
597
- typeIndex: timeInfo.typeIndex,
598
- fieldIndex: 1,
599
- });
600
-
601
- this.pushInstruction({ op: "struct.new", typeIndex: timeInfo.typeIndex });
602
-
603
- this.releaseTemp(dTmp, "i64");
604
- this.releaseTemp(rTmp, timeW);
605
- }
606
-
607
- _emitTimeMethodSub(expr, args, targetWasmType) {
608
- const timeInfo = this.mod.getStructType("time.Time");
609
- const timeW = {
610
- kind: "ref",
611
- nullable: true,
612
- typeIndex: timeInfo.typeIndex,
613
- };
614
- const rTmp = this.acquireTemp(timeW);
615
- const uTmp = this.acquireTemp(timeW);
616
-
617
- this.emitExpr(expr, timeW);
618
- this.pushInstruction({ op: "local.set", index: rTmp });
619
- this.emitExpr(args[0], timeW);
620
- this.pushInstruction({ op: "local.set", index: uTmp });
621
-
622
- this.pushInstruction({ op: "local.get", index: rTmp });
623
- this.pushInstruction({
624
- op: "struct.get",
625
- typeIndex: timeInfo.typeIndex,
626
- fieldIndex: 0,
627
- });
628
- this.pushInstruction({ op: "local.get", index: uTmp });
629
- this.pushInstruction({
630
- op: "struct.get",
631
- typeIndex: timeInfo.typeIndex,
632
- fieldIndex: 0,
633
- });
634
- this.pushInstruction("i64.sub");
635
-
636
- this.releaseTemp(uTmp, timeW);
637
- this.releaseTemp(rTmp, timeW);
638
-
639
- if (targetWasmType === "i32") {
640
- this.pushInstruction("i32.wrap_i64");
641
- }
642
- }
643
-
644
- _emitTimeMethodBefore(expr, args, _targetWasmType) {
645
- this._emitTimeCmp(expr, args, "i64.lt_s");
646
- }
647
-
648
- _emitTimeMethodAfter(expr, args, _targetWasmType) {
649
- this._emitTimeCmp(expr, args, "i64.gt_s");
650
- }
651
-
652
- _emitTimeMethodEqual(expr, args, _targetWasmType) {
653
- this._emitTimeCmp(expr, args, "i64.eq");
654
- }
655
-
656
- _emitTimeCmp(expr, args, op) {
657
- const timeInfo = this.mod.getStructType("time.Time");
658
- const timeW = {
659
- kind: "ref",
660
- nullable: true,
661
- typeIndex: timeInfo.typeIndex,
662
- };
663
- const rTmp = this.acquireTemp(timeW);
664
- const uTmp = this.acquireTemp(timeW);
665
-
666
- this.emitExpr(expr, timeW);
667
- this.pushInstruction({ op: "local.set", index: rTmp });
668
- this.emitExpr(args[0], timeW);
669
- this.pushInstruction({ op: "local.set", index: uTmp });
670
-
671
- this.pushInstruction({ op: "local.get", index: rTmp });
672
- this.pushInstruction({
673
- op: "struct.get",
674
- typeIndex: timeInfo.typeIndex,
675
- fieldIndex: 0,
676
- });
677
- this.pushInstruction({ op: "local.get", index: uTmp });
678
- this.pushInstruction({
679
- op: "struct.get",
680
- typeIndex: timeInfo.typeIndex,
681
- fieldIndex: 0,
682
- });
683
- this.pushInstruction(op);
684
-
685
- this.releaseTemp(uTmp, timeW);
686
- this.releaseTemp(rTmp, timeW);
687
- }
688
-
689
- _emitTimeGetNano(expr) {
690
- const timeInfo = this.mod.getStructType("time.Time");
691
- this.emitExpr(expr, {
692
- kind: "ref",
693
- nullable: true,
694
- typeIndex: timeInfo.typeIndex,
695
- });
696
- this.pushInstruction({
697
- op: "struct.get",
698
- typeIndex: timeInfo.typeIndex,
699
- fieldIndex: 0,
700
- });
701
- return timeInfo;
702
- }
703
-
704
- _emitTimeMethodUnix(expr, targetWasmType) {
705
- this._emitTimeGetNano(expr);
706
- this.pushInstruction({ op: "i64.const", value: 1000000000n });
707
- this.pushInstruction("i64.div_s");
708
- if (targetWasmType === "i32") {
709
- this.pushInstruction("i32.wrap_i64");
710
- }
711
- }
712
-
713
- _emitTimeMethodUnixMilli(expr, targetWasmType) {
714
- this._emitTimeGetNano(expr);
715
- this.pushInstruction({ op: "i64.const", value: 1000000n });
716
- this.pushInstruction("i64.div_s");
717
- if (targetWasmType === "i32") {
718
- this.pushInstruction("i32.wrap_i64");
719
- }
720
- }
721
-
722
- _emitTimeMethodUnixNano(expr, targetWasmType) {
723
- this._emitTimeGetNano(expr);
724
- if (targetWasmType === "i32") {
725
- this.pushInstruction("i32.wrap_i64");
726
- }
727
- }
728
-
729
- _emitTimeMethodIsZero(expr) {
730
- this._emitTimeGetNano(expr);
731
- this.pushInstruction({ op: "i64.const", value: 0n });
732
- this.pushInstruction("i64.eq");
733
- }
734
-
735
- _emitTimeMethodNanosecond(expr, targetWasmType) {
736
- this._emitTimeGetNano(expr);
737
- this.pushInstruction({ op: "i64.const", value: 1000000000n });
738
- this.pushInstruction("i64.rem_s");
739
- const nsTmp = this.acquireTemp("i64");
740
- this.pushInstruction({ op: "local.tee", index: nsTmp });
741
- this.pushInstruction({ op: "i64.const", value: 0n });
742
- this.pushInstruction("i64.lt_s");
743
- this.pushInstruction({ op: "if", blockType: "i64" });
744
- this.pushInstruction({ op: "local.get", index: nsTmp });
745
- this.pushInstruction({ op: "i64.const", value: 1000000000n });
746
- this.pushInstruction("i64.add");
747
- this.pushInstruction({ op: "else" });
748
- this.pushInstruction({ op: "local.get", index: nsTmp });
749
- this.pushInstruction("end");
750
- this.releaseTemp(nsTmp, "i64");
751
- if (targetWasmType !== "i64") {
752
- this.pushInstruction("i32.wrap_i64");
753
- }
754
- }
755
-
756
- _emitTimeMethodUTC(expr) {
757
- const timeInfo = this._emitTimeGetNano(expr);
758
- this.pushInstruction({ op: "i32.const", value: 0 });
759
- this.pushInstruction({
760
- op: "struct.new",
761
- typeIndex: timeInfo.typeIndex,
762
- });
763
- }
764
-
765
- _emitTimeMethodLocal(expr) {
766
- const timeInfo = this.mod.getStructType("time.Time");
767
- const timeW = {
768
- kind: "ref",
769
- nullable: true,
770
- typeIndex: timeInfo.typeIndex,
771
- };
772
- const rTmp = this.acquireTemp(timeW);
773
- this.emitExpr(expr, timeW);
774
- this.pushInstruction({ op: "local.set", index: rTmp });
775
-
776
- this.pushInstruction({ op: "local.get", index: rTmp });
777
- this.pushInstruction({
778
- op: "struct.get",
779
- typeIndex: timeInfo.typeIndex,
780
- fieldIndex: 0,
781
- });
782
-
783
- this.pushInstruction({ op: "local.get", index: rTmp });
784
- this.pushInstruction({
785
- op: "struct.get",
786
- typeIndex: timeInfo.typeIndex,
787
- fieldIndex: 0,
788
- });
789
- this.pushInstruction({ op: "i64.const", value: 1000000n });
790
- this.pushInstruction("i64.div_s");
791
- this.pushInstruction("f64.convert_i64_s");
792
- this.pushInstruction({
793
- op: "call",
794
- funcIndex: this.mod.getTimezoneOffsetImportIndex(),
795
- });
796
-
797
- this.pushInstruction({
798
- op: "struct.new",
799
- typeIndex: timeInfo.typeIndex,
800
- });
801
- this.releaseTemp(rTmp, timeW);
802
- }
803
-
804
- _emitCivilDateFromDays(daysTmp, yTmp, mTmp, dTmp) {
805
- // Computes (y, m, d) in i32 from days in i64
806
- const d64 = this.acquireTemp("i64");
807
- this.pushInstruction({ op: "local.get", index: daysTmp });
808
- this.pushInstruction({ op: "i64.const", value: 719468n });
809
- this.pushInstruction("i64.add");
810
- this.pushInstruction({ op: "local.set", index: d64 });
811
-
812
- const eraTmp = this.acquireTemp("i32");
813
- const doeTmp = this.acquireTemp("i32");
814
- const yoeTmp = this.acquireTemp("i32");
815
- const doyTmp = this.acquireTemp("i32");
816
- const mpTmp = this.acquireTemp("i32");
817
-
818
- // era = (d64 >= 0 ? d64 : d64 - 146096n) / 146097n
819
- this.pushInstruction({ op: "local.get", index: d64 });
820
- this.pushInstruction({ op: "i64.const", value: 0n });
821
- this.pushInstruction("i64.ge_s");
822
- this.pushInstruction({ op: "if", blockType: "i64" });
823
- this.pushInstruction({ op: "local.get", index: d64 });
824
- this.pushInstruction("else");
825
- this.pushInstruction({ op: "local.get", index: d64 });
826
- this.pushInstruction({ op: "i64.const", value: 146096n });
827
- this.pushInstruction("i64.sub");
828
- this.pushInstruction("end");
829
- this.pushInstruction({ op: "i64.const", value: 146097n });
830
- this.pushInstruction("i64.div_s");
831
- this.pushInstruction("i32.wrap_i64");
832
- this.pushInstruction({ op: "local.set", index: eraTmp });
833
-
834
- // doe = i32(d64 - era * 146097n)
835
- this.pushInstruction({ op: "local.get", index: d64 });
836
- this.pushInstruction({ op: "local.get", index: eraTmp });
837
- this.pushInstruction("i64.extend_i32_s");
838
- this.pushInstruction({ op: "i64.const", value: 146097n });
839
- this.pushInstruction("i64.mul");
840
- this.pushInstruction("i64.sub");
841
- this.pushInstruction("i32.wrap_i64");
842
- this.pushInstruction({ op: "local.set", index: doeTmp });
843
-
844
- // yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365
845
- this.pushInstruction({ op: "local.get", index: doeTmp });
846
- this.pushInstruction({ op: "local.get", index: doeTmp });
847
- this.pushInstruction({ op: "i32.const", value: 1460 });
848
- this.pushInstruction("i32.div_s");
849
- this.pushInstruction("i32.sub");
850
- this.pushInstruction({ op: "local.get", index: doeTmp });
851
- this.pushInstruction({ op: "i32.const", value: 36524 });
852
- this.pushInstruction("i32.div_s");
853
- this.pushInstruction("i32.add");
854
- this.pushInstruction({ op: "local.get", index: doeTmp });
855
- this.pushInstruction({ op: "i32.const", value: 146096 });
856
- this.pushInstruction("i32.div_s");
857
- this.pushInstruction("i32.sub");
858
- this.pushInstruction({ op: "i32.const", value: 365 });
859
- this.pushInstruction("i32.div_s");
860
- this.pushInstruction({ op: "local.set", index: yoeTmp });
861
-
862
- // y = yoe + era * 400
863
- this.pushInstruction({ op: "local.get", index: yoeTmp });
864
- this.pushInstruction({ op: "local.get", index: eraTmp });
865
- this.pushInstruction({ op: "i32.const", value: 400 });
866
- this.pushInstruction("i32.mul");
867
- this.pushInstruction("i32.add");
868
- this.pushInstruction({ op: "local.set", index: yTmp });
869
-
870
- // doy = doe - (365*yoe + yoe/4 - yoe/100)
871
- this.pushInstruction({ op: "local.get", index: doeTmp });
872
- this.pushInstruction({ op: "local.get", index: yoeTmp });
873
- this.pushInstruction({ op: "i32.const", value: 365 });
874
- this.pushInstruction("i32.mul");
875
- this.pushInstruction({ op: "local.get", index: yoeTmp });
876
- this.pushInstruction({ op: "i32.const", value: 4 });
877
- this.pushInstruction("i32.div_s");
878
- this.pushInstruction("i32.add");
879
- this.pushInstruction({ op: "local.get", index: yoeTmp });
880
- this.pushInstruction({ op: "i32.const", value: 100 });
881
- this.pushInstruction("i32.div_s");
882
- this.pushInstruction("i32.sub");
883
- this.pushInstruction("i32.sub");
884
- this.pushInstruction({ op: "local.set", index: doyTmp });
885
-
886
- // mp = (5*doy + 2) / 153
887
- this.pushInstruction({ op: "local.get", index: doyTmp });
888
- this.pushInstruction({ op: "i32.const", value: 5 });
889
- this.pushInstruction("i32.mul");
890
- this.pushInstruction({ op: "i32.const", value: 2 });
891
- this.pushInstruction("i32.add");
892
- this.pushInstruction({ op: "i32.const", value: 153 });
893
- this.pushInstruction("i32.div_s");
894
- this.pushInstruction({ op: "local.set", index: mpTmp });
895
-
896
- // d = doy - (153*mp + 2)/5 + 1
897
- this.pushInstruction({ op: "local.get", index: doyTmp });
898
- this.pushInstruction({ op: "local.get", index: mpTmp });
899
- this.pushInstruction({ op: "i32.const", value: 153 });
900
- this.pushInstruction("i32.mul");
901
- this.pushInstruction({ op: "i32.const", value: 2 });
902
- this.pushInstruction("i32.add");
903
- this.pushInstruction({ op: "i32.const", value: 5 });
904
- this.pushInstruction("i32.div_s");
905
- this.pushInstruction("i32.sub");
906
- this.pushInstruction({ op: "i32.const", value: 1 });
907
- this.pushInstruction("i32.add");
908
- this.pushInstruction({ op: "local.set", index: dTmp });
909
-
910
- // m = mp + (mp < 10 ? 3 : -9)
911
- this.pushInstruction({ op: "local.get", index: mpTmp });
912
- this.pushInstruction({ op: "local.get", index: mpTmp });
913
- this.pushInstruction({ op: "i32.const", value: 10 });
914
- this.pushInstruction("i32.lt_s");
915
- this.pushInstruction({ op: "if", blockType: "i32" });
916
- this.pushInstruction({ op: "i32.const", value: 3 });
917
- this.pushInstruction("else");
918
- this.pushInstruction({ op: "i32.const", value: -9 });
919
- this.pushInstruction("end");
920
- this.pushInstruction("i32.add");
921
- this.pushInstruction({ op: "local.set", index: mTmp });
922
-
923
- // if (m <= 2) y += 1
924
- this.pushInstruction({ op: "local.get", index: mTmp });
925
- this.pushInstruction({ op: "i32.const", value: 2 });
926
- this.pushInstruction("i32.le_s");
927
- this.pushInstruction({ op: "if", blockType: "void" });
928
- this.pushInstruction({ op: "local.get", index: yTmp });
929
- this.pushInstruction({ op: "i32.const", value: 1 });
930
- this.pushInstruction("i32.add");
931
- this.pushInstruction({ op: "local.set", index: yTmp });
932
- this.pushInstruction("end");
933
-
934
- this.releaseTemp(mpTmp, "i32");
935
- this.releaseTemp(doyTmp, "i32");
936
- this.releaseTemp(yoeTmp, "i32");
937
- this.releaseTemp(doeTmp, "i32");
938
- this.releaseTemp(eraTmp, "i32");
939
- this.releaseTemp(d64, "i64");
940
- }
941
-
942
- _emitTimeDecomposeParts(expr) {
943
- const timeInfo = this.mod.getStructType("time.Time");
944
- const timeW = {
945
- kind: "ref",
946
- nullable: true,
947
- typeIndex: timeInfo.typeIndex,
948
- };
949
- const rTmp = this.acquireTemp(timeW);
950
- this.emitExpr(expr, timeW);
951
- this.pushInstruction({ op: "local.set", index: rTmp });
952
-
953
- const localSecTmp = this.acquireTemp("i64");
954
- const daysTmp = this.acquireTemp("i64");
955
- const remSecTmp = this.acquireTemp("i64");
956
- const offTmp = this.acquireTemp("i32");
957
- const nanoTmp = this.acquireTemp("i64");
958
-
959
- this.pushInstruction({ op: "local.get", index: rTmp });
960
- this.pushInstruction({
961
- op: "struct.get",
962
- typeIndex: timeInfo.typeIndex,
963
- fieldIndex: 0,
964
- });
965
- this.pushInstruction({ op: "local.set", index: nanoTmp });
966
-
967
- this.pushInstruction({ op: "local.get", index: rTmp });
968
- this.pushInstruction({
969
- op: "struct.get",
970
- typeIndex: timeInfo.typeIndex,
971
- fieldIndex: 1,
972
- });
973
- this.pushInstruction({ op: "local.set", index: offTmp });
974
-
975
- // localSec = nanoTmp / 1000000000n + offTmp
976
- this.pushInstruction({ op: "local.get", index: nanoTmp });
977
- this.pushInstruction({ op: "i64.const", value: 1000000000n });
978
- this.pushInstruction("i64.div_s");
979
- this.pushInstruction({ op: "local.get", index: offTmp });
980
- this.pushInstruction("i64.extend_i32_s");
981
- this.pushInstruction("i64.add");
982
- this.pushInstruction({ op: "local.set", index: localSecTmp });
983
-
984
- // days = localSec / 86400n
985
- this.pushInstruction({ op: "local.get", index: localSecTmp });
986
- this.pushInstruction({ op: "i64.const", value: 86400n });
987
- this.pushInstruction("i64.div_s");
988
- this.pushInstruction({ op: "local.set", index: daysTmp });
989
-
990
- // remSec = localSec % 86400n
991
- this.pushInstruction({ op: "local.get", index: localSecTmp });
992
- this.pushInstruction({ op: "i64.const", value: 86400n });
993
- this.pushInstruction("i64.rem_s");
994
- this.pushInstruction({ op: "local.tee", index: remSecTmp });
995
- this.pushInstruction({ op: "i64.const", value: 0n });
996
- this.pushInstruction("i64.lt_s");
997
- this.pushInstruction({ op: "if", blockType: "void" });
998
- this.pushInstruction({ op: "local.get", index: remSecTmp });
999
- this.pushInstruction({ op: "i64.const", value: 86400n });
1000
- this.pushInstruction("i64.add");
1001
- this.pushInstruction({ op: "local.set", index: remSecTmp });
1002
- this.pushInstruction({ op: "local.get", index: daysTmp });
1003
- this.pushInstruction({ op: "i64.const", value: 1n });
1004
- this.pushInstruction("i64.sub");
1005
- this.pushInstruction({ op: "local.set", index: daysTmp });
1006
- this.pushInstruction("end");
1007
-
1008
- return { rTmp, timeW, localSecTmp, daysTmp, remSecTmp, offTmp, nanoTmp };
1009
- }
1010
-
1011
- _emitTimeMethodHour(expr, targetWasmType) {
1012
- const p = this._emitTimeDecomposeParts(expr);
1013
- this.pushInstruction({ op: "local.get", index: p.remSecTmp });
1014
- this.pushInstruction({ op: "i64.const", value: 3600n });
1015
- this.pushInstruction("i64.div_s");
1016
- this.pushInstruction("i32.wrap_i64");
1017
- if (targetWasmType === "i64") this.pushInstruction("i64.extend_i32_s");
1018
- this._releaseTimeDecomposeParts(p);
1019
- }
1020
-
1021
- _emitTimeMethodMinute(expr, targetWasmType) {
1022
- const p = this._emitTimeDecomposeParts(expr);
1023
- this.pushInstruction({ op: "local.get", index: p.remSecTmp });
1024
- this.pushInstruction({ op: "i64.const", value: 3600n });
1025
- this.pushInstruction("i64.rem_s");
1026
- this.pushInstruction({ op: "i64.const", value: 60n });
1027
- this.pushInstruction("i64.div_s");
1028
- this.pushInstruction("i32.wrap_i64");
1029
- if (targetWasmType === "i64") this.pushInstruction("i64.extend_i32_s");
1030
- this._releaseTimeDecomposeParts(p);
1031
- }
1032
-
1033
- _emitTimeMethodSecond(expr, targetWasmType) {
1034
- const p = this._emitTimeDecomposeParts(expr);
1035
- this.pushInstruction({ op: "local.get", index: p.remSecTmp });
1036
- this.pushInstruction({ op: "i64.const", value: 60n });
1037
- this.pushInstruction("i64.rem_s");
1038
- this.pushInstruction("i32.wrap_i64");
1039
- if (targetWasmType === "i64") this.pushInstruction("i64.extend_i32_s");
1040
- this._releaseTimeDecomposeParts(p);
1041
- }
1042
-
1043
- _emitTimeMethodWeekday(expr, targetWasmType) {
1044
- const p = this._emitTimeDecomposeParts(expr);
1045
- const wdTmp = this.acquireTemp("i32");
1046
- this.pushInstruction({ op: "local.get", index: p.daysTmp });
1047
- this.pushInstruction({ op: "i64.const", value: 4n });
1048
- this.pushInstruction("i64.add");
1049
- this.pushInstruction({ op: "i64.const", value: 7n });
1050
- this.pushInstruction("i64.rem_s");
1051
- this.pushInstruction("i32.wrap_i64");
1052
- this.pushInstruction({ op: "local.tee", index: wdTmp });
1053
- this.pushInstruction({ op: "i32.const", value: 0 });
1054
- this.pushInstruction("i32.lt_s");
1055
- this.pushInstruction({ op: "if", blockType: "void" });
1056
- this.pushInstruction({ op: "local.get", index: wdTmp });
1057
- this.pushInstruction({ op: "i32.const", value: 7 });
1058
- this.pushInstruction("i32.add");
1059
- this.pushInstruction({ op: "local.set", index: wdTmp });
1060
- this.pushInstruction("end");
1061
-
1062
- this.pushInstruction({ op: "local.get", index: wdTmp });
1063
- if (targetWasmType === "i64") this.pushInstruction("i64.extend_i32_s");
1064
- this.releaseTemp(wdTmp, "i32");
1065
- this._releaseTimeDecomposeParts(p);
1066
- }
1067
-
1068
- _emitTimeMethodYMD(expr, targetWasmType, partIdx) {
1069
- const p = this._emitTimeDecomposeParts(expr);
1070
- const yTmp = this.acquireTemp("i32");
1071
- const mTmp = this.acquireTemp("i32");
1072
- const dTmp = this.acquireTemp("i32");
1073
- this._emitCivilDateFromDays(p.daysTmp, yTmp, mTmp, dTmp);
1074
- this.pushInstruction({
1075
- op: "local.get",
1076
- index: partIdx === 0 ? yTmp : partIdx === 1 ? mTmp : dTmp,
1077
- });
1078
- if (targetWasmType === "i64") this.pushInstruction("i64.extend_i32_s");
1079
- this.releaseTemp(dTmp, "i32");
1080
- this.releaseTemp(mTmp, "i32");
1081
- this.releaseTemp(yTmp, "i32");
1082
- this._releaseTimeDecomposeParts(p);
1083
- }
1084
-
1085
- _releaseTimeDecomposeParts(p) {
1086
- this.releaseTemp(p.nanoTmp, "i64");
1087
- this.releaseTemp(p.offTmp, "i32");
1088
- this.releaseTemp(p.remSecTmp, "i64");
1089
- this.releaseTemp(p.daysTmp, "i64");
1090
- this.releaseTemp(p.localSecTmp, "i64");
1091
- this.releaseTemp(p.rTmp, p.timeW);
1092
- }
1093
-
1094
- _emitTimeMethodFormat(expr, args, _targetWasmType) {
1095
- const p = this._emitTimeDecomposeParts(expr);
1096
- const layoutTmp = this.acquireTemp("externref");
1097
- this.emitExpr(args[0], "externref");
1098
- this.pushInstruction({ op: "local.set", index: layoutTmp });
1099
-
1100
- const yTmp = this.acquireTemp("i32");
1101
- const mTmp = this.acquireTemp("i32");
1102
- const dTmp = this.acquireTemp("i32");
1103
- this._emitCivilDateFromDays(p.daysTmp, yTmp, mTmp, dTmp);
1104
-
1105
- // hr = remSec / 3600
1106
- const hrTmp = this.acquireTemp("i32");
1107
- this.pushInstruction({ op: "local.get", index: p.remSecTmp });
1108
- this.pushInstruction({ op: "i64.const", value: 3600n });
1109
- this.pushInstruction("i64.div_s");
1110
- this.pushInstruction("i32.wrap_i64");
1111
- this.pushInstruction({ op: "local.set", index: hrTmp });
1112
-
1113
- // min = (remSec % 3600) / 60
1114
- const minTmp = this.acquireTemp("i32");
1115
- this.pushInstruction({ op: "local.get", index: p.remSecTmp });
1116
- this.pushInstruction({ op: "i64.const", value: 3600n });
1117
- this.pushInstruction("i64.rem_s");
1118
- this.pushInstruction({ op: "i64.const", value: 60n });
1119
- this.pushInstruction("i64.div_s");
1120
- this.pushInstruction("i32.wrap_i64");
1121
- this.pushInstruction({ op: "local.set", index: minTmp });
1122
-
1123
- // sec = remSec % 60
1124
- const secTmp = this.acquireTemp("i32");
1125
- this.pushInstruction({ op: "local.get", index: p.remSecTmp });
1126
- this.pushInstruction({ op: "i64.const", value: 60n });
1127
- this.pushInstruction("i64.rem_s");
1128
- this.pushInstruction("i32.wrap_i64");
1129
- this.pushInstruction({ op: "local.set", index: secTmp });
1130
-
1131
- // wd = (days + 4) % 7
1132
- const wdTmp = this.acquireTemp("i32");
1133
- this.pushInstruction({ op: "local.get", index: p.daysTmp });
1134
- this.pushInstruction({ op: "i64.const", value: 4n });
1135
- this.pushInstruction("i64.add");
1136
- this.pushInstruction({ op: "i64.const", value: 7n });
1137
- this.pushInstruction("i64.rem_s");
1138
- this.pushInstruction("i32.wrap_i64");
1139
- this.pushInstruction({ op: "local.tee", index: wdTmp });
1140
- this.pushInstruction({ op: "i32.const", value: 0 });
1141
- this.pushInstruction("i32.lt_s");
1142
- this.pushInstruction({ op: "if", blockType: "void" });
1143
- this.pushInstruction({ op: "local.get", index: wdTmp });
1144
- this.pushInstruction({ op: "i32.const", value: 7 });
1145
- this.pushInstruction("i32.add");
1146
- this.pushInstruction({ op: "local.set", index: wdTmp });
1147
- this.pushInstruction("end");
1148
-
1149
- // ms = i32((nanoTmp % 1000000000n) / 1000000n)
1150
- const msTmp = this.acquireTemp("i32");
1151
- this.pushInstruction({ op: "local.get", index: p.nanoTmp });
1152
- this.pushInstruction({ op: "i64.const", value: 1000000000n });
1153
- this.pushInstruction("i64.rem_s");
1154
- this.pushInstruction({ op: "i64.const", value: 1000000n });
1155
- this.pushInstruction("i64.div_s");
1156
- this.pushInstruction("i32.wrap_i64");
1157
- this.pushInstruction({ op: "local.tee", index: msTmp });
1158
- this.pushInstruction({ op: "i32.const", value: 0 });
1159
- this.pushInstruction("i32.lt_s");
1160
- this.pushInstruction({ op: "if", blockType: "void" });
1161
- this.pushInstruction({ op: "local.get", index: msTmp });
1162
- this.pushInstruction({ op: "i32.const", value: 1000 });
1163
- this.pushInstruction("i32.add");
1164
- this.pushInstruction({ op: "local.set", index: msTmp });
1165
- this.pushInstruction("end");
1166
-
1167
- // Call time_format(y, m, d, hr, min, sec, wd, ms, off, layout)
1168
- this.pushInstruction({ op: "local.get", index: yTmp });
1169
- this.pushInstruction({ op: "local.get", index: mTmp });
1170
- this.pushInstruction({ op: "local.get", index: dTmp });
1171
- this.pushInstruction({ op: "local.get", index: hrTmp });
1172
- this.pushInstruction({ op: "local.get", index: minTmp });
1173
- this.pushInstruction({ op: "local.get", index: secTmp });
1174
- this.pushInstruction({ op: "local.get", index: wdTmp });
1175
- this.pushInstruction({ op: "local.get", index: msTmp });
1176
- this.pushInstruction({ op: "local.get", index: p.offTmp });
1177
- this.pushInstruction({ op: "local.get", index: layoutTmp });
1178
- this._callStdlib("time_format");
1179
-
1180
- this.releaseTemp(msTmp, "i32");
1181
- this.releaseTemp(wdTmp, "i32");
1182
- this.releaseTemp(secTmp, "i32");
1183
- this.releaseTemp(minTmp, "i32");
1184
- this.releaseTemp(hrTmp, "i32");
1185
- this.releaseTemp(dTmp, "i32");
1186
- this.releaseTemp(mTmp, "i32");
1187
- this.releaseTemp(yTmp, "i32");
1188
- this.releaseTemp(layoutTmp, "externref");
1189
- this._releaseTimeDecomposeParts(p);
1190
- }
1191
-
1192
- _emitTimeMethodString(expr, targetWasmType) {
1193
- const strLit = {
1194
- kind: "BasicLit",
1195
- litKind: "STRING",
1196
- value: "2006-01-02T15:04:05Z07:00",
1197
- };
1198
- this._emitTimeMethodFormat(expr, [strLit], targetWasmType);
1199
- }
1200
- }