jz 0.1.1 → 0.2.1

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.
package/module/date.js ADDED
@@ -0,0 +1,783 @@
1
+ /**
2
+ * Date module — deterministic UTC algorithms first.
3
+ *
4
+ * Current scope: Date.UTC(...), Date object construction, timestamp/string
5
+ * construction, UTC getters/setters, UTC-backed local getters, toISOString,
6
+ * toUTCString. Timezone-aware local-time methods and locale-sensitive formatting
7
+ * are deliberately staged later.
8
+ *
9
+ * @module date
10
+ */
11
+
12
+ import { typed, asF64, toNumF64, allocPtr } from '../src/ir.js'
13
+ import { emit } from '../src/emit.js'
14
+ import { inc, PTR } from '../src/ctx.js'
15
+ import { VAL } from '../src/analyze.js'
16
+
17
+ const MS_PER_DAY = 86400000
18
+ const MAX_TIME = 8640000000000000
19
+
20
+ export default (ctx) => {
21
+ Object.assign(ctx.core.stdlibDeps, {
22
+ __date_days_from_year: [],
23
+ __date_make_day: ['__date_days_from_year'],
24
+ __date_make_time: [],
25
+ __date_time_clip: [],
26
+ __date_utc: ['__date_make_day', '__date_make_time', '__date_time_clip'],
27
+ __date_digit: ['__char_at'],
28
+ __date_parse_iso_date: ['__str_byteLen', '__char_at', '__date_digit', '__date_make_day', '__date_time_clip'],
29
+ __date_from_value: ['__ptr_type', '__to_num', '__date_parse_iso_date'],
30
+ __date_day: [],
31
+ __date_time_within_day: ['__date_day'],
32
+ __date_weekday: ['__date_day'],
33
+ __date_year_from_time: ['__date_days_from_year'],
34
+ __date_in_leap_year: ['__date_year_from_time', '__date_days_from_year'],
35
+ __date_day_within_year: ['__date_day', '__date_year_from_time', '__date_days_from_year'],
36
+ __date_month_from_time: ['__date_day_within_year', '__date_in_leap_year'],
37
+ __date_month_start: [],
38
+ __date_date_from_time: ['__date_day_within_year', '__date_month_from_time', '__date_in_leap_year', '__date_month_start'],
39
+ __date_hour_from_time: ['__date_time_within_day'],
40
+ __date_min_from_time: ['__date_time_within_day', '__date_hour_from_time'],
41
+ __date_sec_from_time: ['__date_time_within_day', '__date_hour_from_time', '__date_min_from_time'],
42
+ __date_ms_from_time: ['__date_time_within_day', '__date_hour_from_time', '__date_min_from_time', '__date_sec_from_time'],
43
+ __date_set_time: ['__date_time_clip'],
44
+ __date_set_utc_date: ['__date_set_time', '__date_make_day', '__date_year_from_time', '__date_month_from_time', '__date_time_within_day'],
45
+ __date_set_utc_month: ['__date_set_time', '__date_make_day', '__date_year_from_time', '__date_time_within_day'],
46
+ __date_set_utc_full_year: ['__date_set_time', '__date_make_day', '__date_time_within_day'],
47
+ __date_set_utc_hours: ['__date_set_time', '__date_day', '__date_make_time'],
48
+ __date_set_utc_minutes: ['__date_set_time', '__date_day', '__date_make_time', '__date_hour_from_time'],
49
+ __date_set_utc_seconds: ['__date_set_time', '__date_day', '__date_make_time', '__date_hour_from_time', '__date_min_from_time'],
50
+ __date_set_utc_milliseconds: ['__date_set_time', '__date_day', '__date_make_time', '__date_hour_from_time', '__date_min_from_time', '__date_sec_from_time'],
51
+ __date_write2: [],
52
+ __date_write3: [],
53
+ __date_write4: [],
54
+ __date_to_iso_string: ['__mkstr', '__alloc', '__itoa', '__date_year_from_time', '__date_month_from_time', '__date_date_from_time', '__date_hour_from_time', '__date_min_from_time', '__date_sec_from_time', '__date_ms_from_time', '__date_write2', '__date_write3', '__date_write4'],
55
+ __date_to_utc_string: ['__mkstr', '__alloc', '__itoa', '__date_weekday', '__date_date_from_time', '__date_month_from_time', '__date_year_from_time', '__date_hour_from_time', '__date_min_from_time', '__date_sec_from_time', '__date_write2', '__date_write4'],
56
+ })
57
+
58
+ const dateArg = (node, fallback, required = false) => {
59
+ if (node === undefined) return typed(['f64.const', required ? NaN : fallback], 'f64')
60
+ if (Array.isArray(node) && node[0] == null && node[1] === undefined) return typed(['f64.const', NaN], 'f64')
61
+ return toNumF64(node, emit(node))
62
+ }
63
+
64
+ const missingArg = (node) => node === undefined
65
+
66
+ ctx.core.emit['Date.UTC'] = (year, month, date, hours, minutes, seconds, ms) => {
67
+ inc('__date_utc')
68
+ return typed(['call', '$__date_utc',
69
+ asF64(dateArg(year, NaN, true)),
70
+ asF64(dateArg(month, 0)),
71
+ asF64(dateArg(date, 1)),
72
+ asF64(dateArg(hours, 0)),
73
+ asF64(dateArg(minutes, 0)),
74
+ asF64(dateArg(seconds, 0)),
75
+ asF64(dateArg(ms, 0)),
76
+ ], 'f64')
77
+ }
78
+
79
+ // ── Core algorithms ───────────────────────────────────────────────────────
80
+
81
+ ctx.core.stdlib['__date_days_from_year'] = `(func $__date_days_from_year (param $y f64) (result f64)
82
+ (f64.add
83
+ (f64.add
84
+ (f64.mul (f64.const 365) (f64.sub (local.get $y) (f64.const 1970)))
85
+ (f64.floor (f64.div (f64.sub (local.get $y) (f64.const 1969)) (f64.const 4))))
86
+ (f64.sub
87
+ (f64.floor (f64.div (f64.sub (local.get $y) (f64.const 1601)) (f64.const 400)))
88
+ (f64.floor (f64.div (f64.sub (local.get $y) (f64.const 1901)) (f64.const 100))))))`
89
+
90
+ ctx.core.stdlib['__date_make_day'] = `(func $__date_make_day (param $year f64) (param $month f64) (param $date f64) (result f64)
91
+ (local $y f64) (local $m f64) (local $dt f64) (local $q f64) (local $ym f64) (local $mn f64)
92
+ (local $mi i32) (local $leap f64) (local $day f64)
93
+ (local.set $y (f64.trunc (local.get $year)))
94
+ (local.set $m (f64.trunc (local.get $month)))
95
+ (local.set $dt (f64.trunc (local.get $date)))
96
+ (local.set $q (f64.floor (f64.div (local.get $m) (f64.const 12))))
97
+ (local.set $ym (f64.add (local.get $y) (local.get $q)))
98
+ (local.set $mn (f64.sub (local.get $m) (f64.mul (local.get $q) (f64.const 12))))
99
+ (local.set $mi (i32.trunc_sat_f64_s (local.get $mn)))
100
+ (local.set $leap
101
+ (if (result f64)
102
+ (f64.eq
103
+ (f64.sub
104
+ (call $__date_days_from_year (f64.add (local.get $ym) (f64.const 1)))
105
+ (call $__date_days_from_year (local.get $ym)))
106
+ (f64.const 366))
107
+ (then (f64.const 1))
108
+ (else (f64.const 0))))
109
+ (if (i32.ge_s (local.get $mi) (i32.const 1)) (then (local.set $day (f64.const 31))))
110
+ (if (i32.ge_s (local.get $mi) (i32.const 2)) (then (local.set $day (f64.add (f64.const 59) (local.get $leap)))))
111
+ (if (i32.ge_s (local.get $mi) (i32.const 3)) (then (local.set $day (f64.add (f64.const 90) (local.get $leap)))))
112
+ (if (i32.ge_s (local.get $mi) (i32.const 4)) (then (local.set $day (f64.add (f64.const 120) (local.get $leap)))))
113
+ (if (i32.ge_s (local.get $mi) (i32.const 5)) (then (local.set $day (f64.add (f64.const 151) (local.get $leap)))))
114
+ (if (i32.ge_s (local.get $mi) (i32.const 6)) (then (local.set $day (f64.add (f64.const 181) (local.get $leap)))))
115
+ (if (i32.ge_s (local.get $mi) (i32.const 7)) (then (local.set $day (f64.add (f64.const 212) (local.get $leap)))))
116
+ (if (i32.ge_s (local.get $mi) (i32.const 8)) (then (local.set $day (f64.add (f64.const 243) (local.get $leap)))))
117
+ (if (i32.ge_s (local.get $mi) (i32.const 9)) (then (local.set $day (f64.add (f64.const 273) (local.get $leap)))))
118
+ (if (i32.ge_s (local.get $mi) (i32.const 10)) (then (local.set $day (f64.add (f64.const 304) (local.get $leap)))))
119
+ (if (i32.ge_s (local.get $mi) (i32.const 11)) (then (local.set $day (f64.add (f64.const 334) (local.get $leap)))))
120
+ (f64.add
121
+ (f64.add (call $__date_days_from_year (local.get $ym)) (local.get $day))
122
+ (f64.sub (local.get $dt) (f64.const 1))))`
123
+
124
+ ctx.core.stdlib['__date_make_time'] = `(func $__date_make_time (param $hour f64) (param $min f64) (param $sec f64) (param $ms f64) (result f64)
125
+ (f64.add
126
+ (f64.add
127
+ (f64.mul (f64.trunc (local.get $hour)) (f64.const 3600000))
128
+ (f64.mul (f64.trunc (local.get $min)) (f64.const 60000)))
129
+ (f64.add
130
+ (f64.mul (f64.trunc (local.get $sec)) (f64.const 1000))
131
+ (f64.trunc (local.get $ms)))))`
132
+
133
+ ctx.core.stdlib['__date_time_clip'] = `(func $__date_time_clip (param $time f64) (result f64)
134
+ (if (result f64)
135
+ (i32.or
136
+ (f64.ne (local.get $time) (local.get $time))
137
+ (f64.gt (f64.abs (local.get $time)) (f64.const ${MAX_TIME})))
138
+ (then (f64.const nan))
139
+ (else (f64.add (f64.trunc (local.get $time)) (f64.const 0)))))`
140
+
141
+ ctx.core.stdlib['__date_utc'] = `(func $__date_utc (param $year f64) (param $month f64) (param $date f64) (param $hours f64) (param $minutes f64) (param $seconds f64) (param $ms f64) (result f64)
142
+ (local $y f64)
143
+ (local.set $y (f64.trunc (local.get $year)))
144
+ (if
145
+ (i32.and
146
+ (f64.eq (local.get $y) (local.get $y))
147
+ (i32.and (f64.ge (local.get $y) (f64.const 0)) (f64.le (local.get $y) (f64.const 99))))
148
+ (then (local.set $y (f64.add (local.get $y) (f64.const 1900)))))
149
+ (call $__date_time_clip
150
+ (f64.add
151
+ (f64.mul
152
+ (call $__date_make_day (local.get $y) (local.get $month) (local.get $date))
153
+ (f64.const ${MS_PER_DAY}))
154
+ (call $__date_make_time (local.get $hours) (local.get $minutes) (local.get $seconds) (local.get $ms)))))`
155
+
156
+ ctx.core.stdlib['__date_digit'] = `(func $__date_digit (param $str i64) (param $i i32) (result i32)
157
+ (local $c i32)
158
+ (local.set $c (call $__char_at (local.get $str) (local.get $i)))
159
+ (if (result i32)
160
+ (i32.and (i32.ge_s (local.get $c) (i32.const 48)) (i32.le_s (local.get $c) (i32.const 57)))
161
+ (then (i32.sub (local.get $c) (i32.const 48)))
162
+ (else (i32.const -1))))`
163
+
164
+ ctx.core.stdlib['__date_parse_iso_date'] = `(func $__date_parse_iso_date (param $str i64) (result f64)
165
+ (local $y f64) (local $m f64) (local $d f64)
166
+ (local $d0 i32) (local $d1 i32) (local $d2 i32) (local $d3 i32)
167
+ (if (i32.lt_s (call $__str_byteLen (local.get $str)) (i32.const 10))
168
+ (then (return (f64.const nan))))
169
+ (if (i32.ne (call $__char_at (local.get $str) (i32.const 4)) (i32.const 45))
170
+ (then (return (f64.const nan))))
171
+ (if (i32.ne (call $__char_at (local.get $str) (i32.const 7)) (i32.const 45))
172
+ (then (return (f64.const nan))))
173
+
174
+ (local.set $d0 (call $__date_digit (local.get $str) (i32.const 0)))
175
+ (local.set $d1 (call $__date_digit (local.get $str) (i32.const 1)))
176
+ (local.set $d2 (call $__date_digit (local.get $str) (i32.const 2)))
177
+ (local.set $d3 (call $__date_digit (local.get $str) (i32.const 3)))
178
+ (if (i32.or (i32.or (i32.lt_s (local.get $d0) (i32.const 0)) (i32.lt_s (local.get $d1) (i32.const 0)))
179
+ (i32.or (i32.lt_s (local.get $d2) (i32.const 0)) (i32.lt_s (local.get $d3) (i32.const 0))))
180
+ (then (return (f64.const nan))))
181
+ (local.set $y (f64.convert_i32_s
182
+ (i32.add
183
+ (i32.add (i32.mul (local.get $d0) (i32.const 1000)) (i32.mul (local.get $d1) (i32.const 100)))
184
+ (i32.add (i32.mul (local.get $d2) (i32.const 10)) (local.get $d3)))))
185
+
186
+ (local.set $d0 (call $__date_digit (local.get $str) (i32.const 5)))
187
+ (local.set $d1 (call $__date_digit (local.get $str) (i32.const 6)))
188
+ (if (i32.or (i32.lt_s (local.get $d0) (i32.const 0)) (i32.lt_s (local.get $d1) (i32.const 0)))
189
+ (then (return (f64.const nan))))
190
+ (local.set $m (f64.convert_i32_s (i32.add (i32.mul (local.get $d0) (i32.const 10)) (local.get $d1))))
191
+ (if (i32.or (f64.lt (local.get $m) (f64.const 1)) (f64.gt (local.get $m) (f64.const 12)))
192
+ (then (return (f64.const nan))))
193
+
194
+ (local.set $d0 (call $__date_digit (local.get $str) (i32.const 8)))
195
+ (local.set $d1 (call $__date_digit (local.get $str) (i32.const 9)))
196
+ (if (i32.or (i32.lt_s (local.get $d0) (i32.const 0)) (i32.lt_s (local.get $d1) (i32.const 0)))
197
+ (then (return (f64.const nan))))
198
+ (local.set $d (f64.convert_i32_s (i32.add (i32.mul (local.get $d0) (i32.const 10)) (local.get $d1))))
199
+ (if (i32.or (f64.lt (local.get $d) (f64.const 1)) (f64.gt (local.get $d) (f64.const 31)))
200
+ (then (return (f64.const nan))))
201
+
202
+ (call $__date_time_clip
203
+ (f64.mul
204
+ (call $__date_make_day (local.get $y) (f64.sub (local.get $m) (f64.const 1)) (local.get $d))
205
+ (f64.const ${MS_PER_DAY}))))`
206
+
207
+ ctx.core.stdlib['__date_from_value'] = `(func $__date_from_value (param $v i64) (result f64)
208
+ (local $f f64)
209
+ (local.set $f (f64.reinterpret_i64 (local.get $v)))
210
+ (if (f64.eq (local.get $f) (local.get $f))
211
+ (then (return (call $__date_time_clip (local.get $f)))))
212
+ (if (i32.eq (call $__ptr_type (local.get $v)) (i32.const ${PTR.STRING}))
213
+ (then (return (call $__date_parse_iso_date (local.get $v)))))
214
+ (call $__date_time_clip (call $__to_num (local.get $v))))`
215
+
216
+ // ── Time decomposition (ECMA-262 §21.4.1) ────────────────────────────────
217
+
218
+ ctx.core.stdlib['__date_day'] = `(func $__date_day (param $t f64) (result f64)
219
+ (f64.floor (f64.div (local.get $t) (f64.const ${MS_PER_DAY}))))`
220
+
221
+ ctx.core.stdlib['__date_time_within_day'] = `(func $__date_time_within_day (param $t f64) (result f64)
222
+ (f64.sub (local.get $t) (f64.mul (call $__date_day (local.get $t)) (f64.const ${MS_PER_DAY}))))`
223
+
224
+ ctx.core.stdlib['__date_weekday'] = `(func $__date_weekday (param $t f64) (result f64)
225
+ (local $wd i32)
226
+ (if (f64.ne (local.get $t) (local.get $t)) (then (return (f64.const nan))))
227
+ (local.set $wd (i32.rem_s (i32.add (i32.trunc_sat_f64_s (call $__date_day (local.get $t))) (i32.const 4)) (i32.const 7)))
228
+ (if (i32.lt_s (local.get $wd) (i32.const 0)) (then (local.set $wd (i32.add (local.get $wd) (i32.const 7)))))
229
+ (f64.convert_i32_s (local.get $wd)))`
230
+
231
+ ctx.core.stdlib['__date_year_from_time'] = `(func $__date_year_from_time (param $t f64) (result f64)
232
+ (local $day f64) (local $y f64)
233
+ (if (f64.ne (local.get $t) (local.get $t)) (then (return (f64.const nan))))
234
+ (local.set $day (call $__date_day (local.get $t)))
235
+ (local.set $y (f64.floor (f64.add (f64.const 1970) (f64.div (local.get $day) (f64.const 365.2425)))))
236
+ (if (f64.gt (call $__date_days_from_year (local.get $y)) (local.get $day))
237
+ (then (local.set $y (f64.sub (local.get $y) (f64.const 1)))))
238
+ (if (f64.le (call $__date_days_from_year (f64.add (local.get $y) (f64.const 1))) (local.get $day))
239
+ (then (local.set $y (f64.add (local.get $y) (f64.const 1)))))
240
+ (local.get $y))`
241
+
242
+ ctx.core.stdlib['__date_in_leap_year'] = `(func $__date_in_leap_year (param $t f64) (result f64)
243
+ (local $y f64)
244
+ (local.set $y (call $__date_year_from_time (local.get $t)))
245
+ (if (result f64)
246
+ (f64.eq (f64.sub (call $__date_days_from_year (f64.add (local.get $y) (f64.const 1))) (call $__date_days_from_year (local.get $y))) (f64.const 366))
247
+ (then (f64.const 1))
248
+ (else (f64.const 0))))`
249
+
250
+ ctx.core.stdlib['__date_day_within_year'] = `(func $__date_day_within_year (param $t f64) (result f64)
251
+ (f64.sub (call $__date_day (local.get $t)) (call $__date_days_from_year (call $__date_year_from_time (local.get $t)))))`
252
+
253
+ ctx.core.stdlib['__date_month_from_time'] = `(func $__date_month_from_time (param $t f64) (result f64)
254
+ (local $dwy i32) (local $leap i32) (local $m i32)
255
+ (if (f64.ne (local.get $t) (local.get $t)) (then (return (f64.const nan))))
256
+ (local.set $dwy (i32.trunc_sat_f64_s (call $__date_day_within_year (local.get $t))))
257
+ (local.set $leap (i32.trunc_sat_f64_s (call $__date_in_leap_year (local.get $t))))
258
+ (local.set $m (i32.const 0))
259
+ (if (i32.ge_s (local.get $dwy) (i32.const 31)) (then (local.set $m (i32.const 1))))
260
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 59) (local.get $leap))) (then (local.set $m (i32.const 2))))
261
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 90) (local.get $leap))) (then (local.set $m (i32.const 3))))
262
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 120) (local.get $leap))) (then (local.set $m (i32.const 4))))
263
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 151) (local.get $leap))) (then (local.set $m (i32.const 5))))
264
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 181) (local.get $leap))) (then (local.set $m (i32.const 6))))
265
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 212) (local.get $leap))) (then (local.set $m (i32.const 7))))
266
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 243) (local.get $leap))) (then (local.set $m (i32.const 8))))
267
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 273) (local.get $leap))) (then (local.set $m (i32.const 9))))
268
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 304) (local.get $leap))) (then (local.set $m (i32.const 10))))
269
+ (if (i32.ge_s (local.get $dwy) (i32.add (i32.const 334) (local.get $leap))) (then (local.set $m (i32.const 11))))
270
+ (f64.convert_i32_s (local.get $m)))`
271
+
272
+ ctx.core.stdlib['__date_month_start'] = `(func $__date_month_start (param $month i32) (param $leap i32) (result i32)
273
+ (if (i32.eq (local.get $month) (i32.const 0)) (then (return (i32.const 0))))
274
+ (if (i32.eq (local.get $month) (i32.const 1)) (then (return (i32.const 31))))
275
+ (if (i32.eq (local.get $month) (i32.const 2)) (then (return (i32.add (i32.const 59) (local.get $leap)))))
276
+ (if (i32.eq (local.get $month) (i32.const 3)) (then (return (i32.add (i32.const 90) (local.get $leap)))))
277
+ (if (i32.eq (local.get $month) (i32.const 4)) (then (return (i32.add (i32.const 120) (local.get $leap)))))
278
+ (if (i32.eq (local.get $month) (i32.const 5)) (then (return (i32.add (i32.const 151) (local.get $leap)))))
279
+ (if (i32.eq (local.get $month) (i32.const 6)) (then (return (i32.add (i32.const 181) (local.get $leap)))))
280
+ (if (i32.eq (local.get $month) (i32.const 7)) (then (return (i32.add (i32.const 212) (local.get $leap)))))
281
+ (if (i32.eq (local.get $month) (i32.const 8)) (then (return (i32.add (i32.const 243) (local.get $leap)))))
282
+ (if (i32.eq (local.get $month) (i32.const 9)) (then (return (i32.add (i32.const 273) (local.get $leap)))))
283
+ (if (i32.eq (local.get $month) (i32.const 10)) (then (return (i32.add (i32.const 304) (local.get $leap)))))
284
+ (if (i32.eq (local.get $month) (i32.const 11)) (then (return (i32.add (i32.const 334) (local.get $leap)))))
285
+ (i32.const 334))`
286
+
287
+ ctx.core.stdlib['__date_date_from_time'] = `(func $__date_date_from_time (param $t f64) (result f64)
288
+ (local $dwy i32) (local $m i32) (local $leap i32)
289
+ (if (f64.ne (local.get $t) (local.get $t)) (then (return (f64.const nan))))
290
+ (local.set $dwy (i32.trunc_sat_f64_s (call $__date_day_within_year (local.get $t))))
291
+ (local.set $m (i32.trunc_sat_f64_s (call $__date_month_from_time (local.get $t))))
292
+ (local.set $leap (i32.trunc_sat_f64_s (call $__date_in_leap_year (local.get $t))))
293
+ (f64.convert_i32_s (i32.add (i32.sub (local.get $dwy) (call $__date_month_start (local.get $m) (local.get $leap))) (i32.const 1))))`
294
+
295
+ ctx.core.stdlib['__date_hour_from_time'] = `(func $__date_hour_from_time (param $t f64) (result f64)
296
+ (f64.floor (f64.div (call $__date_time_within_day (local.get $t)) (f64.const 3600000))))`
297
+
298
+ ctx.core.stdlib['__date_min_from_time'] = `(func $__date_min_from_time (param $t f64) (result f64)
299
+ (f64.floor (f64.div (f64.sub (call $__date_time_within_day (local.get $t)) (f64.mul (call $__date_hour_from_time (local.get $t)) (f64.const 3600000))) (f64.const 60000))))`
300
+
301
+ ctx.core.stdlib['__date_sec_from_time'] = `(func $__date_sec_from_time (param $t f64) (result f64)
302
+ (f64.floor (f64.div (f64.sub (f64.sub (call $__date_time_within_day (local.get $t)) (f64.mul (call $__date_hour_from_time (local.get $t)) (f64.const 3600000))) (f64.mul (call $__date_min_from_time (local.get $t)) (f64.const 60000))) (f64.const 1000))))`
303
+
304
+ ctx.core.stdlib['__date_ms_from_time'] = `(func $__date_ms_from_time (param $t f64) (result f64)
305
+ (f64.sub (f64.sub (f64.sub (call $__date_time_within_day (local.get $t)) (f64.mul (call $__date_hour_from_time (local.get $t)) (f64.const 3600000))) (f64.mul (call $__date_min_from_time (local.get $t)) (f64.const 60000))) (f64.mul (call $__date_sec_from_time (local.get $t)) (f64.const 1000))))`
306
+
307
+ // ── Setter helpers ────────────────────────────────────────────────────────
308
+
309
+ ctx.core.stdlib['__date_set_time'] = `(func $__date_set_time (param $ptr i32) (param $day f64) (param $time f64) (result f64)
310
+ (local $v f64)
311
+ (local.set $v (call $__date_time_clip (f64.add (f64.mul (local.get $day) (f64.const ${MS_PER_DAY})) (local.get $time))))
312
+ (f64.store (local.get $ptr) (local.get $v))
313
+ (local.get $v))`
314
+
315
+ ctx.core.stdlib['__date_set_utc_date'] = `(func $__date_set_utc_date (param $ptr i32) (param $t f64) (param $dt f64) (result f64)
316
+ (call $__date_set_time (local.get $ptr)
317
+ (call $__date_make_day (call $__date_year_from_time (local.get $t)) (call $__date_month_from_time (local.get $t)) (local.get $dt))
318
+ (call $__date_time_within_day (local.get $t))))`
319
+
320
+ ctx.core.stdlib['__date_set_utc_month'] = `(func $__date_set_utc_month (param $ptr i32) (param $t f64) (param $m f64) (param $dt f64) (result f64)
321
+ (call $__date_set_time (local.get $ptr)
322
+ (call $__date_make_day (call $__date_year_from_time (local.get $t)) (local.get $m) (local.get $dt))
323
+ (call $__date_time_within_day (local.get $t))))`
324
+
325
+ ctx.core.stdlib['__date_set_utc_full_year'] = `(func $__date_set_utc_full_year (param $ptr i32) (param $t f64) (param $y f64) (param $m f64) (param $dt f64) (result f64)
326
+ (if (f64.ne (local.get $t) (local.get $t))
327
+ (then (local.set $t (f64.const 0))))
328
+ (call $__date_set_time (local.get $ptr)
329
+ (call $__date_make_day (local.get $y) (local.get $m) (local.get $dt))
330
+ (call $__date_time_within_day (local.get $t))))`
331
+
332
+ ctx.core.stdlib['__date_set_utc_hours'] = `(func $__date_set_utc_hours (param $ptr i32) (param $t f64) (param $h f64) (param $m f64) (param $s f64) (param $ms f64) (result f64)
333
+ (call $__date_set_time (local.get $ptr)
334
+ (call $__date_day (local.get $t))
335
+ (call $__date_make_time (local.get $h) (local.get $m) (local.get $s) (local.get $ms))))`
336
+
337
+ ctx.core.stdlib['__date_set_utc_minutes'] = `(func $__date_set_utc_minutes (param $ptr i32) (param $t f64) (param $m f64) (param $s f64) (param $ms f64) (result f64)
338
+ (call $__date_set_time (local.get $ptr)
339
+ (call $__date_day (local.get $t))
340
+ (call $__date_make_time (call $__date_hour_from_time (local.get $t)) (local.get $m) (local.get $s) (local.get $ms))))`
341
+
342
+ ctx.core.stdlib['__date_set_utc_seconds'] = `(func $__date_set_utc_seconds (param $ptr i32) (param $t f64) (param $s f64) (param $ms f64) (result f64)
343
+ (call $__date_set_time (local.get $ptr)
344
+ (call $__date_day (local.get $t))
345
+ (call $__date_make_time (call $__date_hour_from_time (local.get $t)) (call $__date_min_from_time (local.get $t)) (local.get $s) (local.get $ms))))`
346
+
347
+ ctx.core.stdlib['__date_set_utc_milliseconds'] = `(func $__date_set_utc_milliseconds (param $ptr i32) (param $t f64) (param $ms f64) (result f64)
348
+ (call $__date_set_time (local.get $ptr)
349
+ (call $__date_day (local.get $t))
350
+ (call $__date_make_time (call $__date_hour_from_time (local.get $t)) (call $__date_min_from_time (local.get $t)) (call $__date_sec_from_time (local.get $t)) (local.get $ms))))`
351
+
352
+ // ── Digit formatters ──────────────────────────────────────────────────────
353
+
354
+ ctx.core.stdlib['__date_write2'] = `(func $__date_write2 (param $buf i32) (param $v i32)
355
+ (i32.store8 (local.get $buf) (i32.add (i32.const 48) (i32.div_u (local.get $v) (i32.const 10))))
356
+ (i32.store8 (i32.add (local.get $buf) (i32.const 1)) (i32.add (i32.const 48) (i32.rem_u (local.get $v) (i32.const 10)))))`
357
+
358
+ ctx.core.stdlib['__date_write3'] = `(func $__date_write3 (param $buf i32) (param $v i32)
359
+ (local $d i32)
360
+ (local.set $d (i32.div_u (local.get $v) (i32.const 100)))
361
+ (i32.store8 (local.get $buf) (i32.add (i32.const 48) (local.get $d)))
362
+ (local.set $v (i32.rem_u (local.get $v) (i32.const 100)))
363
+ (local.set $d (i32.div_u (local.get $v) (i32.const 10)))
364
+ (i32.store8 (i32.add (local.get $buf) (i32.const 1)) (i32.add (i32.const 48) (local.get $d)))
365
+ (i32.store8 (i32.add (local.get $buf) (i32.const 2)) (i32.add (i32.const 48) (i32.rem_u (local.get $v) (i32.const 10)))))`
366
+
367
+ ctx.core.stdlib['__date_write4'] = `(func $__date_write4 (param $buf i32) (param $v i32)
368
+ (local $d i32)
369
+ (local.set $d (i32.div_u (local.get $v) (i32.const 1000)))
370
+ (i32.store8 (local.get $buf) (i32.add (i32.const 48) (local.get $d)))
371
+ (local.set $v (i32.rem_u (local.get $v) (i32.const 1000)))
372
+ (local.set $d (i32.div_u (local.get $v) (i32.const 100)))
373
+ (i32.store8 (i32.add (local.get $buf) (i32.const 1)) (i32.add (i32.const 48) (local.get $d)))
374
+ (local.set $v (i32.rem_u (local.get $v) (i32.const 100)))
375
+ (local.set $d (i32.div_u (local.get $v) (i32.const 10)))
376
+ (i32.store8 (i32.add (local.get $buf) (i32.const 2)) (i32.add (i32.const 48) (local.get $d)))
377
+ (i32.store8 (i32.add (local.get $buf) (i32.const 3)) (i32.add (i32.const 48) (i32.rem_u (local.get $v) (i32.const 10)))))`
378
+
379
+ // ── toISOString ───────────────────────────────────────────────────────────
380
+
381
+ ctx.core.stdlib['__date_to_iso_string'] = `(func $__date_to_iso_string (param $t f64) (result f64)
382
+ (local $buf i32) (local $p i32) (local $year f64) (local $yv i32) (local $nd i32)
383
+ (if (f64.ne (local.get $t) (local.get $t)) (then (return (call $__mkstr (i32.const 0) (i32.const 0)))))
384
+ (local.set $buf (call $__alloc (i32.const 40)))
385
+ (local.set $p (local.get $buf))
386
+ (local.set $year (call $__date_year_from_time (local.get $t)))
387
+ (if (f64.lt (local.get $year) (f64.const 0))
388
+ (then
389
+ (i32.store8 (local.get $p) (i32.const 45))
390
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
391
+ (local.set $year (f64.neg (local.get $year)))))
392
+ (local.set $yv (i32.trunc_sat_f64_u (local.get $year)))
393
+ (if (i32.le_u (local.get $yv) (i32.const 9999))
394
+ (then
395
+ (call $__date_write4 (local.get $p) (local.get $yv))
396
+ (local.set $p (i32.add (local.get $p) (i32.const 4))))
397
+ (else
398
+ (local.set $nd (call $__itoa (local.get $yv) (local.get $p)))
399
+ (local.set $p (i32.add (local.get $p) (local.get $nd)))))
400
+ (i32.store8 (local.get $p) (i32.const 45))
401
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
402
+ (call $__date_write2 (local.get $p) (i32.add (i32.trunc_sat_f64_s (call $__date_month_from_time (local.get $t))) (i32.const 1)))
403
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
404
+ (i32.store8 (local.get $p) (i32.const 45))
405
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
406
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_date_from_time (local.get $t))))
407
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
408
+ (i32.store8 (local.get $p) (i32.const 84))
409
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
410
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_hour_from_time (local.get $t))))
411
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
412
+ (i32.store8 (local.get $p) (i32.const 58))
413
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
414
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_min_from_time (local.get $t))))
415
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
416
+ (i32.store8 (local.get $p) (i32.const 58))
417
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
418
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_sec_from_time (local.get $t))))
419
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
420
+ (i32.store8 (local.get $p) (i32.const 46))
421
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
422
+ (call $__date_write3 (local.get $p) (i32.trunc_sat_f64_s (call $__date_ms_from_time (local.get $t))))
423
+ (local.set $p (i32.add (local.get $p) (i32.const 3)))
424
+ (i32.store8 (local.get $p) (i32.const 90))
425
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
426
+ (call $__mkstr (local.get $buf) (i32.sub (local.get $p) (local.get $buf))))`
427
+
428
+ // ── toUTCString ───────────────────────────────────────────────────────────
429
+
430
+ ctx.core.stdlib['__date_to_utc_string'] = `(func $__date_to_utc_string (param $t f64) (result f64)
431
+ (local $buf i32) (local $p i32) (local $wd i32) (local $year f64) (local $yv i32) (local $nd i32) (local $month i32)
432
+ (if (f64.ne (local.get $t) (local.get $t)) (then (return (call $__mkstr (i32.const 0) (i32.const 0)))))
433
+ (local.set $buf (call $__alloc (i32.const 48)))
434
+ (local.set $p (local.get $buf))
435
+ (local.set $wd (i32.trunc_sat_f64_s (call $__date_weekday (local.get $t))))
436
+ (if (i32.eq (local.get $wd) (i32.const 0))
437
+ (then
438
+ (i32.store8 (local.get $p) (i32.const 83))
439
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 117))
440
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 110))))
441
+ (if (i32.eq (local.get $wd) (i32.const 1))
442
+ (then
443
+ (i32.store8 (local.get $p) (i32.const 77))
444
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 111))
445
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 110))))
446
+ (if (i32.eq (local.get $wd) (i32.const 2))
447
+ (then
448
+ (i32.store8 (local.get $p) (i32.const 84))
449
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 117))
450
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 101))))
451
+ (if (i32.eq (local.get $wd) (i32.const 3))
452
+ (then
453
+ (i32.store8 (local.get $p) (i32.const 87))
454
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 101))
455
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 100))))
456
+ (if (i32.eq (local.get $wd) (i32.const 4))
457
+ (then
458
+ (i32.store8 (local.get $p) (i32.const 84))
459
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 104))
460
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 117))))
461
+ (if (i32.eq (local.get $wd) (i32.const 5))
462
+ (then
463
+ (i32.store8 (local.get $p) (i32.const 70))
464
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 114))
465
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 105))))
466
+ (if (i32.eq (local.get $wd) (i32.const 6))
467
+ (then
468
+ (i32.store8 (local.get $p) (i32.const 83))
469
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 97))
470
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 116))))
471
+ (local.set $p (i32.add (local.get $p) (i32.const 3)))
472
+ (i32.store8 (local.get $p) (i32.const 44))
473
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 32))
474
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
475
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_date_from_time (local.get $t))))
476
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
477
+ (i32.store8 (local.get $p) (i32.const 32))
478
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
479
+ (local.set $month (i32.trunc_sat_f64_s (call $__date_month_from_time (local.get $t))))
480
+ (if (i32.eq (local.get $month) (i32.const 0))
481
+ (then
482
+ (i32.store8 (local.get $p) (i32.const 74))
483
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 97))
484
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 110))))
485
+ (if (i32.eq (local.get $month) (i32.const 1))
486
+ (then
487
+ (i32.store8 (local.get $p) (i32.const 70))
488
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 101))
489
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 98))))
490
+ (if (i32.eq (local.get $month) (i32.const 2))
491
+ (then
492
+ (i32.store8 (local.get $p) (i32.const 77))
493
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 97))
494
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 114))))
495
+ (if (i32.eq (local.get $month) (i32.const 3))
496
+ (then
497
+ (i32.store8 (local.get $p) (i32.const 65))
498
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 112))
499
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 114))))
500
+ (if (i32.eq (local.get $month) (i32.const 4))
501
+ (then
502
+ (i32.store8 (local.get $p) (i32.const 77))
503
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 97))
504
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 121))))
505
+ (if (i32.eq (local.get $month) (i32.const 5))
506
+ (then
507
+ (i32.store8 (local.get $p) (i32.const 74))
508
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 117))
509
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 110))))
510
+ (if (i32.eq (local.get $month) (i32.const 6))
511
+ (then
512
+ (i32.store8 (local.get $p) (i32.const 74))
513
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 117))
514
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 108))))
515
+ (if (i32.eq (local.get $month) (i32.const 7))
516
+ (then
517
+ (i32.store8 (local.get $p) (i32.const 65))
518
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 117))
519
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 103))))
520
+ (if (i32.eq (local.get $month) (i32.const 8))
521
+ (then
522
+ (i32.store8 (local.get $p) (i32.const 83))
523
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 101))
524
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 112))))
525
+ (if (i32.eq (local.get $month) (i32.const 9))
526
+ (then
527
+ (i32.store8 (local.get $p) (i32.const 79))
528
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 99))
529
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 116))))
530
+ (if (i32.eq (local.get $month) (i32.const 10))
531
+ (then
532
+ (i32.store8 (local.get $p) (i32.const 78))
533
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 111))
534
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 118))))
535
+ (if (i32.eq (local.get $month) (i32.const 11))
536
+ (then
537
+ (i32.store8 (local.get $p) (i32.const 68))
538
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 101))
539
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 99))))
540
+ (local.set $p (i32.add (local.get $p) (i32.const 3)))
541
+ (i32.store8 (local.get $p) (i32.const 32))
542
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
543
+ (local.set $year (call $__date_year_from_time (local.get $t)))
544
+ (if (f64.lt (local.get $year) (f64.const 0))
545
+ (then
546
+ (i32.store8 (local.get $p) (i32.const 45))
547
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
548
+ (local.set $year (f64.neg (local.get $year)))))
549
+ (local.set $yv (i32.trunc_sat_f64_u (local.get $year)))
550
+ (if (i32.le_u (local.get $yv) (i32.const 9999))
551
+ (then
552
+ (call $__date_write4 (local.get $p) (local.get $yv))
553
+ (local.set $p (i32.add (local.get $p) (i32.const 4))))
554
+ (else
555
+ (local.set $nd (call $__itoa (local.get $yv) (local.get $p)))
556
+ (local.set $p (i32.add (local.get $p) (local.get $nd)))))
557
+ (i32.store8 (local.get $p) (i32.const 32))
558
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
559
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_hour_from_time (local.get $t))))
560
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
561
+ (i32.store8 (local.get $p) (i32.const 58))
562
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
563
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_min_from_time (local.get $t))))
564
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
565
+ (i32.store8 (local.get $p) (i32.const 58))
566
+ (local.set $p (i32.add (local.get $p) (i32.const 1)))
567
+ (call $__date_write2 (local.get $p) (i32.trunc_sat_f64_s (call $__date_sec_from_time (local.get $t))))
568
+ (local.set $p (i32.add (local.get $p) (i32.const 2)))
569
+ (i32.store8 (local.get $p) (i32.const 32))
570
+ (i32.store8 (i32.add (local.get $p) (i32.const 1)) (i32.const 71))
571
+ (i32.store8 (i32.add (local.get $p) (i32.const 2)) (i32.const 77))
572
+ (i32.store8 (i32.add (local.get $p) (i32.const 3)) (i32.const 84))
573
+ (local.set $p (i32.add (local.get $p) (i32.const 4)))
574
+ (call $__mkstr (local.get $buf) (i32.sub (local.get $p) (local.get $buf))))`
575
+
576
+ // === Minimal Date value object ===
577
+ // Represented as PTR.OBJECT with a single f64 slot at offset 0 (the time value).
578
+ // No schemaId (aux=0); dynamic property access falls through to undefined.
579
+
580
+ ctx.core.emit['new.Date'] = (ms, month, date, hours, minutes, seconds, millis) => {
581
+ let timeVal
582
+ if (ms === undefined || ms === null) {
583
+ const now = ctx.core.emit['Date.now']
584
+ if (!now) throw new Error('Date constructor requires Date.now support')
585
+ timeVal = now()
586
+ } else if (!missingArg(month)) {
587
+ inc('__date_utc')
588
+ timeVal = typed(['call', '$__date_utc',
589
+ asF64(dateArg(ms, NaN, true)),
590
+ asF64(dateArg(month, 0)),
591
+ asF64(dateArg(date, 1)),
592
+ asF64(dateArg(hours, 0)),
593
+ asF64(dateArg(minutes, 0)),
594
+ asF64(dateArg(seconds, 0)),
595
+ asF64(dateArg(millis, 0)),
596
+ ], 'f64')
597
+ } else {
598
+ inc('__date_from_value')
599
+ timeVal = typed(['call', '$__date_from_value', ['i64.reinterpret_f64', asF64(emit(ms))]], 'f64')
600
+ }
601
+ const out = allocPtr({ type: PTR.OBJECT, len: 1, cap: 1, stride: 8, tag: 'date' })
602
+ return typed(['block', ['result', 'f64'],
603
+ out.init,
604
+ ['f64.store', ['local.get', `$${out.local}`], timeVal],
605
+ out.ptr], 'f64')
606
+ }
607
+
608
+ const emitDateGetTime = (dateExpr) => {
609
+ const d = asF64(emit(dateExpr))
610
+ return typed(['f64.load', ['i32.wrap_i64', ['i64.reinterpret_f64', d]]], 'f64')
611
+ }
612
+
613
+ const emitDateSetTime = (dateExpr, ms) => {
614
+ inc('__date_time_clip')
615
+ const d = asF64(emit(dateExpr))
616
+ const t = typed(['call', '$__date_time_clip', toNumF64(ms, emit(ms))], 'f64')
617
+ return typed(['block', ['result', 'f64'],
618
+ ['f64.store', ['i32.wrap_i64', ['i64.reinterpret_f64', d]], t],
619
+ t], 'f64')
620
+ }
621
+
622
+ ctx.core.emit['.getTime'] = emitDateGetTime
623
+ ctx.core.emit[`.${VAL.DATE}:getTime`] = emitDateGetTime
624
+
625
+ ctx.core.emit['.valueOf'] = emitDateGetTime
626
+ ctx.core.emit[`.${VAL.DATE}:valueOf`] = emitDateGetTime
627
+
628
+ ctx.core.emit['.setTime'] = emitDateSetTime
629
+ ctx.core.emit[`.${VAL.DATE}:setTime`] = emitDateSetTime
630
+
631
+ // ── UTC getter emit handlers ──────────────────────────────────────────────
632
+
633
+ const emitDateLoad = (dateExpr) =>
634
+ typed(['f64.load', ['i32.wrap_i64', ['i64.reinterpret_f64', asF64(emit(dateExpr))]]], 'f64')
635
+
636
+ const dateGetter = (fn) => (dateExpr) => {
637
+ inc(fn)
638
+ return typed(['call', `$${fn}`, emitDateLoad(dateExpr)], 'f64')
639
+ }
640
+
641
+ ctx.core.emit['.getUTCFullYear'] = dateGetter('__date_year_from_time')
642
+ ctx.core.emit[`.${VAL.DATE}:getUTCFullYear`] = dateGetter('__date_year_from_time')
643
+
644
+ ctx.core.emit['.getUTCMonth'] = dateGetter('__date_month_from_time')
645
+ ctx.core.emit[`.${VAL.DATE}:getUTCMonth`] = dateGetter('__date_month_from_time')
646
+
647
+ ctx.core.emit['.getUTCDate'] = dateGetter('__date_date_from_time')
648
+ ctx.core.emit[`.${VAL.DATE}:getUTCDate`] = dateGetter('__date_date_from_time')
649
+
650
+ ctx.core.emit['.getUTCDay'] = dateGetter('__date_weekday')
651
+ ctx.core.emit[`.${VAL.DATE}:getUTCDay`] = dateGetter('__date_weekday')
652
+
653
+ ctx.core.emit['.getUTCHours'] = dateGetter('__date_hour_from_time')
654
+ ctx.core.emit[`.${VAL.DATE}:getUTCHours`] = dateGetter('__date_hour_from_time')
655
+
656
+ ctx.core.emit['.getUTCMinutes'] = dateGetter('__date_min_from_time')
657
+ ctx.core.emit[`.${VAL.DATE}:getUTCMinutes`] = dateGetter('__date_min_from_time')
658
+
659
+ ctx.core.emit['.getUTCSeconds'] = dateGetter('__date_sec_from_time')
660
+ ctx.core.emit[`.${VAL.DATE}:getUTCSeconds`] = dateGetter('__date_sec_from_time')
661
+
662
+ ctx.core.emit['.getUTCMilliseconds'] = dateGetter('__date_ms_from_time')
663
+ ctx.core.emit[`.${VAL.DATE}:getUTCMilliseconds`] = dateGetter('__date_ms_from_time')
664
+
665
+ // UTC-backed local getters. Full timezone-aware local time is intentionally
666
+ // staged separately; these aliases make deterministic/server Date use cases
667
+ // available without a timezone database.
668
+ ctx.core.emit['.getFullYear'] = ctx.core.emit['.getUTCFullYear']
669
+ ctx.core.emit[`.${VAL.DATE}:getFullYear`] = ctx.core.emit[`.${VAL.DATE}:getUTCFullYear`]
670
+
671
+ ctx.core.emit['.getMonth'] = ctx.core.emit['.getUTCMonth']
672
+ ctx.core.emit[`.${VAL.DATE}:getMonth`] = ctx.core.emit[`.${VAL.DATE}:getUTCMonth`]
673
+
674
+ ctx.core.emit['.getDate'] = ctx.core.emit['.getUTCDate']
675
+ ctx.core.emit[`.${VAL.DATE}:getDate`] = ctx.core.emit[`.${VAL.DATE}:getUTCDate`]
676
+
677
+ ctx.core.emit['.getDay'] = ctx.core.emit['.getUTCDay']
678
+ ctx.core.emit[`.${VAL.DATE}:getDay`] = ctx.core.emit[`.${VAL.DATE}:getUTCDay`]
679
+
680
+ // ── UTC setter emit handlers ──────────────────────────────────────────────
681
+
682
+ const emitDatePtr = (dateExpr) =>
683
+ ['i32.wrap_i64', ['i64.reinterpret_f64', asF64(emit(dateExpr))]]
684
+
685
+ ctx.core.emit['.setUTCDate'] = (dateExpr, dt) => {
686
+ inc('__date_set_utc_date')
687
+ return typed(['call', '$__date_set_utc_date', emitDatePtr(dateExpr), emitDateLoad(dateExpr), asF64(toNumF64(dt, emit(dt)))], 'f64')
688
+ }
689
+ ctx.core.emit[`.${VAL.DATE}:setUTCDate`] = ctx.core.emit['.setUTCDate']
690
+
691
+ ctx.core.emit['.setUTCMonth'] = (dateExpr, month, dt) => {
692
+ inc('__date_set_utc_month')
693
+ const m = asF64(toNumF64(month, emit(month)))
694
+ const t = emitDateLoad(dateExpr)
695
+ const d = missingArg(dt)
696
+ ? (inc('__date_date_from_time'), typed(['call', '$__date_date_from_time', t], 'f64'))
697
+ : asF64(toNumF64(dt, emit(dt)))
698
+ return typed(['call', '$__date_set_utc_month', emitDatePtr(dateExpr), t, m, d], 'f64')
699
+ }
700
+ ctx.core.emit[`.${VAL.DATE}:setUTCMonth`] = ctx.core.emit['.setUTCMonth']
701
+
702
+ ctx.core.emit['.setUTCFullYear'] = (dateExpr, year, month, dt) => {
703
+ inc('__date_set_utc_full_year')
704
+ const y = asF64(toNumF64(year, emit(year)))
705
+ const t = emitDateLoad(dateExpr)
706
+ const m = missingArg(month)
707
+ ? (inc('__date_month_from_time'), typed(['if', ['result', 'f64'],
708
+ ['f64.ne', t, t],
709
+ ['then', ['f64.const', 0]],
710
+ ['else', ['call', '$__date_month_from_time', t]]], 'f64'))
711
+ : asF64(toNumF64(month, emit(month)))
712
+ const d = missingArg(dt)
713
+ ? (inc('__date_date_from_time'), typed(['if', ['result', 'f64'],
714
+ ['f64.ne', t, t],
715
+ ['then', ['f64.const', 1]],
716
+ ['else', ['call', '$__date_date_from_time', t]]], 'f64'))
717
+ : asF64(toNumF64(dt, emit(dt)))
718
+ return typed(['call', '$__date_set_utc_full_year', emitDatePtr(dateExpr), t, y, m, d], 'f64')
719
+ }
720
+ ctx.core.emit[`.${VAL.DATE}:setUTCFullYear`] = ctx.core.emit['.setUTCFullYear']
721
+
722
+ ctx.core.emit['.setUTCHours'] = (dateExpr, hour, min, sec, ms) => {
723
+ inc('__date_set_utc_hours')
724
+ const h = asF64(toNumF64(hour, emit(hour)))
725
+ const t = emitDateLoad(dateExpr)
726
+ const m = missingArg(min)
727
+ ? (inc('__date_min_from_time'), typed(['call', '$__date_min_from_time', t], 'f64'))
728
+ : asF64(toNumF64(min, emit(min)))
729
+ const s = missingArg(sec)
730
+ ? (inc('__date_sec_from_time'), typed(['call', '$__date_sec_from_time', t], 'f64'))
731
+ : asF64(toNumF64(sec, emit(sec)))
732
+ const msec = missingArg(ms)
733
+ ? (inc('__date_ms_from_time'), typed(['call', '$__date_ms_from_time', t], 'f64'))
734
+ : asF64(toNumF64(ms, emit(ms)))
735
+ return typed(['call', '$__date_set_utc_hours', emitDatePtr(dateExpr), t, h, m, s, msec], 'f64')
736
+ }
737
+ ctx.core.emit[`.${VAL.DATE}:setUTCHours`] = ctx.core.emit['.setUTCHours']
738
+
739
+ ctx.core.emit['.setUTCMinutes'] = (dateExpr, min, sec, ms) => {
740
+ inc('__date_set_utc_minutes')
741
+ const m = asF64(toNumF64(min, emit(min)))
742
+ const t = emitDateLoad(dateExpr)
743
+ const s = missingArg(sec)
744
+ ? (inc('__date_sec_from_time'), typed(['call', '$__date_sec_from_time', t], 'f64'))
745
+ : asF64(toNumF64(sec, emit(sec)))
746
+ const msec = missingArg(ms)
747
+ ? (inc('__date_ms_from_time'), typed(['call', '$__date_ms_from_time', t], 'f64'))
748
+ : asF64(toNumF64(ms, emit(ms)))
749
+ return typed(['call', '$__date_set_utc_minutes', emitDatePtr(dateExpr), t, m, s, msec], 'f64')
750
+ }
751
+ ctx.core.emit[`.${VAL.DATE}:setUTCMinutes`] = ctx.core.emit['.setUTCMinutes']
752
+
753
+ ctx.core.emit['.setUTCSeconds'] = (dateExpr, sec, ms) => {
754
+ inc('__date_set_utc_seconds')
755
+ const s = asF64(toNumF64(sec, emit(sec)))
756
+ const t = emitDateLoad(dateExpr)
757
+ const msec = missingArg(ms)
758
+ ? (inc('__date_ms_from_time'), typed(['call', '$__date_ms_from_time', t], 'f64'))
759
+ : asF64(toNumF64(ms, emit(ms)))
760
+ return typed(['call', '$__date_set_utc_seconds', emitDatePtr(dateExpr), t, s, msec], 'f64')
761
+ }
762
+ ctx.core.emit[`.${VAL.DATE}:setUTCSeconds`] = ctx.core.emit['.setUTCSeconds']
763
+
764
+ ctx.core.emit['.setUTCMilliseconds'] = (dateExpr, ms) => {
765
+ inc('__date_set_utc_milliseconds')
766
+ return typed(['call', '$__date_set_utc_milliseconds', emitDatePtr(dateExpr), emitDateLoad(dateExpr), asF64(toNumF64(ms, emit(ms)))], 'f64')
767
+ }
768
+ ctx.core.emit[`.${VAL.DATE}:setUTCMilliseconds`] = ctx.core.emit['.setUTCMilliseconds']
769
+
770
+ // ── Stringification ───────────────────────────────────────────────────────
771
+
772
+ ctx.core.emit['.toISOString'] = (dateExpr) => {
773
+ inc('__date_to_iso_string')
774
+ return typed(['call', '$__date_to_iso_string', emitDateLoad(dateExpr)], 'f64')
775
+ }
776
+ ctx.core.emit[`.${VAL.DATE}:toISOString`] = ctx.core.emit['.toISOString']
777
+
778
+ ctx.core.emit['.toUTCString'] = (dateExpr) => {
779
+ inc('__date_to_utc_string')
780
+ return typed(['call', '$__date_to_utc_string', emitDateLoad(dateExpr)], 'f64')
781
+ }
782
+ ctx.core.emit[`.${VAL.DATE}:toUTCString`] = ctx.core.emit['.toUTCString']
783
+ }