porffor 0.2.0-fde989a → 0.14.0-0d97d1e6a

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 (61) hide show
  1. package/CONTRIBUTING.md +256 -0
  2. package/LICENSE +20 -20
  3. package/README.md +131 -86
  4. package/asur/README.md +2 -0
  5. package/asur/index.js +1262 -0
  6. package/byg/index.js +216 -0
  7. package/compiler/2c.js +2 -53
  8. package/compiler/{sections.js → assemble.js} +95 -21
  9. package/compiler/builtins/annexb_string.js +72 -0
  10. package/compiler/builtins/annexb_string.ts +18 -0
  11. package/compiler/builtins/array.ts +145 -0
  12. package/compiler/builtins/base64.ts +76 -0
  13. package/compiler/builtins/boolean.ts +18 -0
  14. package/compiler/builtins/crypto.ts +120 -0
  15. package/compiler/builtins/date.ts +2067 -0
  16. package/compiler/builtins/escape.ts +141 -0
  17. package/compiler/builtins/function.ts +5 -0
  18. package/compiler/builtins/int.ts +145 -0
  19. package/compiler/builtins/number.ts +529 -0
  20. package/compiler/builtins/object.ts +4 -0
  21. package/compiler/builtins/porffor.d.ts +60 -0
  22. package/compiler/builtins/set.ts +187 -0
  23. package/compiler/builtins/string.ts +1080 -0
  24. package/compiler/builtins/symbol.ts +61 -0
  25. package/compiler/builtins.js +440 -285
  26. package/compiler/{codeGen.js → codegen.js} +1116 -489
  27. package/compiler/decompile.js +3 -4
  28. package/compiler/embedding.js +22 -22
  29. package/compiler/encoding.js +94 -10
  30. package/compiler/expression.js +1 -1
  31. package/compiler/generated_builtins.js +1670 -0
  32. package/compiler/index.js +27 -43
  33. package/compiler/log.js +6 -3
  34. package/compiler/opt.js +55 -41
  35. package/compiler/parse.js +38 -30
  36. package/compiler/precompile.js +120 -0
  37. package/compiler/prefs.js +31 -0
  38. package/compiler/prototype.js +31 -46
  39. package/compiler/types.js +38 -0
  40. package/compiler/wasmSpec.js +33 -8
  41. package/compiler/wrap.js +107 -71
  42. package/package.json +9 -5
  43. package/porf +2 -0
  44. package/rhemyn/compile.js +46 -27
  45. package/rhemyn/parse.js +322 -320
  46. package/rhemyn/test/parse.js +58 -58
  47. package/runner/compare.js +33 -34
  48. package/runner/debug.js +117 -0
  49. package/runner/index.js +78 -11
  50. package/runner/profiler.js +75 -0
  51. package/runner/repl.js +40 -13
  52. package/runner/sizes.js +37 -37
  53. package/runner/version.js +10 -8
  54. package/compiler/builtins/base64.js +0 -92
  55. package/filesize.cmd +0 -2
  56. package/runner/info.js +0 -89
  57. package/runner/profile.js +0 -46
  58. package/runner/results.json +0 -1
  59. package/runner/transform.js +0 -15
  60. package/tmp.c +0 -661
  61. package/util/enum.js +0 -20
@@ -0,0 +1,2067 @@
1
+ // 21.4.1.3 Day (t)
2
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-day
3
+ // 1. Return 𝔽(floor(ℝ(t / msPerDay))).
4
+ export const __ecma262_Day = (t: number): number => Math.floor(t / 86400000);
5
+
6
+ // 21.4.1.4 TimeWithinDay (t)
7
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-day
8
+ // 1. Return 𝔽(ℝ(t) modulo ℝ(msPerDay)).
9
+ export const __ecma262_TimeWithinDay = (t: number): number => t % 86400000;
10
+
11
+ // 21.4.1.5 DaysInYear (y)
12
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-daysinyear
13
+ export const __ecma262_DaysInYear = (y: number): number => {
14
+ // 1. Let ry be ℝ(y).
15
+
16
+ // 2. If (ry modulo 400) = 0, return 366𝔽.
17
+ if (y % 400 == 0) return 366;
18
+
19
+ // 3. If (ry modulo 100) = 0, return 365𝔽.
20
+ if (y % 100 == 0) return 365;
21
+
22
+ // 4. If (ry modulo 4) = 0, return 366𝔽.
23
+ if (y % 4 == 0) return 366;
24
+
25
+ // 5. Return 365𝔽.
26
+ return 365;
27
+ };
28
+
29
+ // 21.4.1.6 DayFromYear (y)
30
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-dayfromyear
31
+ export const __ecma262_DayFromYear = (y: number): number => {
32
+ // 1. Let ry be ℝ(y).
33
+ // 2. NOTE: In the following steps, numYears1, numYears4, numYears100, and numYears400
34
+ // represent the number of years divisible by 1, 4, 100, and 400, respectively,
35
+ // that occur between the epoch and the start of year y.
36
+ // The number is negative if y is before the epoch.
37
+
38
+ // 3. Let numYears1 be (ry - 1970).
39
+ const numYears1: number = y - 1970;
40
+
41
+ // 4. Let numYears4 be floor((ry - 1969) / 4).
42
+ const numYears4: number = Math.floor((y - 1969) / 4);
43
+
44
+ // 5. Let numYears100 be floor((ry - 1901) / 100).
45
+ const numYears100: number = Math.floor((y - 1901) / 100);
46
+
47
+ // 6. Let numYears400 be floor((ry - 1601) / 400).
48
+ const numYears400: number = Math.floor((y - 1601) / 400);
49
+
50
+ // 7. Return 𝔽(365 × numYears1 + numYears4 - numYears100 + numYears400).
51
+ return 365 * numYears1 + numYears4 - numYears100 + numYears400;
52
+ };
53
+
54
+ // 21.4.1.7 TimeFromYear (y)
55
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-timefromyear
56
+ // 1. Return msPerDay × DayFromYear(y).
57
+ export const __ecma262_TimeFromYear = (y: number): number => 86400000 * __ecma262_DayFromYear(y);
58
+
59
+ // 21.4.1.8 YearFromTime (t)
60
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-yearfromtime
61
+ export const __ecma262_YearFromTime = (t: number): number => {
62
+ // 1. Return the largest integral Number y (closest to +∞) such that TimeFromYear(y) ≤ t.
63
+
64
+ // guess year with floor(t / (365.2425 * msPerDay)) + 1970
65
+ const y: number = Math.floor(t / 31556952000) + 1970;
66
+
67
+ // get timestamp for guessed year
68
+ const t2: number = __ecma262_TimeFromYear(y);
69
+
70
+ // if timestamp is higher, we guessed too high
71
+ if (t2 > t) return y - 1;
72
+
73
+ // if timestamp + days in year is lower, we guessed too low
74
+ if ((t2 + __ecma262_DaysInYear(y) * 86400000) <= t) return y + 1;
75
+
76
+ // we guessed correct
77
+ return y;
78
+ };
79
+
80
+ // 21.4.1.9 DayWithinYear (t)
81
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-daywithinyear
82
+ // 1. Return Day(t) - DayFromYear(YearFromTime(t)).
83
+ export const __ecma262_DayWithinYear = (t: number): number => __ecma262_Day(t) - __ecma262_DayFromYear(__ecma262_YearFromTime(t));
84
+
85
+ // 21.4.1.10 InLeapYear (t)
86
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-inleapyear
87
+ // 1. If DaysInYear(YearFromTime(t)) is 366𝔽, return 1𝔽; else return +0𝔽.
88
+ export const __ecma262_InLeapYear = (t: number): number => __ecma262_DaysInYear(__ecma262_YearFromTime(t)) == 366 ? 1 : 0;
89
+
90
+ // 21.4.1.11 MonthFromTime (t)
91
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-monthfromtime
92
+ export const __ecma262_MonthFromTime = (t: number): number => {
93
+ // 1. Let inLeapYear be InLeapYear(t).
94
+ const inLeapYear: number = __ecma262_InLeapYear(t);
95
+
96
+ // 2. Let dayWithinYear be DayWithinYear(t).
97
+ const dayWithinYear: number = __ecma262_DayWithinYear(t);
98
+
99
+ // 3. If dayWithinYear < 31𝔽, return +0𝔽.
100
+ if (dayWithinYear < 31) return 0;
101
+
102
+ // 4. If dayWithinYear < 59𝔽 + inLeapYear, return 1𝔽.
103
+ if (dayWithinYear < 59 + inLeapYear) return 1;
104
+
105
+ // 5. If dayWithinYear < 90𝔽 + inLeapYear, return 2𝔽.
106
+ if (dayWithinYear < 90 + inLeapYear) return 2;
107
+
108
+ // 6. If dayWithinYear < 120𝔽 + inLeapYear, return 3𝔽.
109
+ if (dayWithinYear < 120 + inLeapYear) return 3;
110
+
111
+ // 7. If dayWithinYear < 151𝔽 + inLeapYear, return 4𝔽.
112
+ if (dayWithinYear < 151 + inLeapYear) return 4;
113
+
114
+ // 8. If dayWithinYear < 181𝔽 + inLeapYear, return 5𝔽.
115
+ if (dayWithinYear < 181 + inLeapYear) return 5;
116
+
117
+ // 9. If dayWithinYear < 212𝔽 + inLeapYear, return 6𝔽.
118
+ if (dayWithinYear < 212 + inLeapYear) return 6;
119
+
120
+ // 10. If dayWithinYear < 243𝔽 + inLeapYear, return 7𝔽.
121
+ if (dayWithinYear < 243 + inLeapYear) return 7;
122
+
123
+ // 11. If dayWithinYear < 273𝔽 + inLeapYear, return 8𝔽.
124
+ if (dayWithinYear < 273 + inLeapYear) return 8;
125
+
126
+ // 12. If dayWithinYear < 304𝔽 + inLeapYear, return 9𝔽.
127
+ if (dayWithinYear < 304 + inLeapYear) return 9;
128
+
129
+ // 13. If dayWithinYear < 334𝔽 + inLeapYear, return 10𝔽.
130
+ if (dayWithinYear < 334 + inLeapYear) return 10;
131
+
132
+ // 14. Assert: dayWithinYear < 365𝔽 + inLeapYear.
133
+
134
+ // 15. Return 11𝔽.
135
+ return 11;
136
+ };
137
+
138
+ // 21.4.1.12 DateFromTime (t)
139
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-datefromtime
140
+ export const __ecma262_DateFromTime = (t: number): number => {
141
+ // 1. Let inLeapYear be InLeapYear(t).
142
+ const inLeapYear: number = __ecma262_InLeapYear(t);
143
+
144
+ // 2. Let dayWithinYear be DayWithinYear(t).
145
+ const dayWithinYear: number = __ecma262_DayWithinYear(t);
146
+
147
+ // 3. Let month be MonthFromTime(t).
148
+ const month = __ecma262_MonthFromTime(t);
149
+
150
+ // 4. If month is +0𝔽, return dayWithinYear + 1𝔽.
151
+ if (month == 0) return dayWithinYear + 1;
152
+
153
+ // 5. If month is 1𝔽, return dayWithinYear - 30𝔽.
154
+ if (month == 1) return dayWithinYear - 30;
155
+
156
+ // 6. If month is 2𝔽, return dayWithinYear - 58𝔽 - inLeapYear.
157
+ if (month == 2) return dayWithinYear - 58 - inLeapYear;
158
+
159
+ // 7. If month is 3𝔽, return dayWithinYear - 89𝔽 - inLeapYear.
160
+ if (month == 3) return dayWithinYear - 89 - inLeapYear;
161
+
162
+ // 8. If month is 4𝔽, return dayWithinYear - 119𝔽 - inLeapYear.
163
+ if (month == 4) return dayWithinYear - 119 - inLeapYear;
164
+
165
+ // 9. If month is 5𝔽, return dayWithinYear - 150𝔽 - inLeapYear.
166
+ if (month == 5) return dayWithinYear - 150 - inLeapYear;
167
+
168
+ // 10. If month is 6𝔽, return dayWithinYear - 180𝔽 - inLeapYear.
169
+ if (month == 6) return dayWithinYear - 180 - inLeapYear;
170
+
171
+ // 11. If month is 7𝔽, return dayWithinYear - 211𝔽 - inLeapYear.
172
+ if (month == 7) return dayWithinYear - 211 - inLeapYear;
173
+
174
+ // 12. If month is 8𝔽, return dayWithinYear - 242𝔽 - inLeapYear.
175
+ if (month == 8) return dayWithinYear - 242 - inLeapYear;
176
+
177
+ // 13. If month is 9𝔽, return dayWithinYear - 272𝔽 - inLeapYear.
178
+ if (month == 9) return dayWithinYear - 272 - inLeapYear;
179
+
180
+ // 14. If month is 10𝔽, return dayWithinYear - 303𝔽 - inLeapYear.
181
+ if (month == 10) return dayWithinYear - 303 - inLeapYear;
182
+
183
+ // 15. Assert: month is 11𝔽.
184
+
185
+ // 16. Return dayWithinYear - 333𝔽 - inLeapYear.
186
+ return dayWithinYear - 333 - inLeapYear;
187
+ };
188
+
189
+ // 21.4.1.13 WeekDay (t)
190
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-weekday
191
+ // 1. Return 𝔽(ℝ(Day(t) + 4𝔽) modulo 7).
192
+ export const __ecma262_WeekDay = (t: number): number => (__ecma262_Day(t) + 4) % 7;
193
+
194
+ // 21.4.1.14 HourFromTime (t)
195
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-hourfromtime
196
+ // 1. Return 𝔽(floor(ℝ(t / msPerHour)) modulo HoursPerDay).
197
+ export const __ecma262_HourFromTime = (t: number): number => Math.floor(t / 3600000) % 24;
198
+
199
+ // 21.4.1.15 MinFromTime (t)
200
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-minfromtime
201
+ // 1. Return 𝔽(floor(ℝ(t / msPerMinute)) modulo MinutesPerHour).
202
+ export const __ecma262_MinFromTime = (t: number): number => Math.floor(t / 60000) % 60;
203
+
204
+ // 21.4.1.16 SecFromTime (t)
205
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-secfromtime
206
+ // 1. Return 𝔽(floor(ℝ(t / msPerSecond)) modulo SecondsPerMinute).
207
+ export const __ecma262_SecFromTime = (t: number): number => Math.floor(t / 1000) % 60;
208
+
209
+ // 21.4.1.17 msFromTime (t)
210
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-msfromtime
211
+ // 1. Return 𝔽(ℝ(t) modulo ℝ(msPerSecond)).
212
+ export const __ecma262_msFromTime = (t: number): number => t % 1000;
213
+
214
+
215
+ // // 21.4.1.21 GetNamedTimeZoneOffsetNanoseconds (timeZoneIdentifier, epochNanoseconds)
216
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-getnamedtimezoneoffsetnanoseconds
217
+ // export const __ecma262_GetNamedTimeZoneOffsetNanoseconds = (timeZoneIdentifier: bytestring, epochNanoseconds: number /* BigInt (unused) */): number => {
218
+ // // 1. Assert: timeZoneIdentifier is "UTC".
219
+
220
+ // // 2. Return 0.
221
+ // return 0;
222
+ // };
223
+
224
+ // // 21.4.1.23 AvailableNamedTimeZoneIdentifiers ()
225
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-availablenamedtimezoneidentifiers
226
+ // export const __ecma262_AvailableNamedTimeZoneIdentifiers = (): bytestring[] => {
227
+ // // 1. If the implementation does not include local political rules for any time zones, then
228
+ // // a. Return « the Time Zone Identifier Record { [[Identifier]]: "UTC", [[PrimaryIdentifier]]: "UTC" } ».
229
+ // return [ 'UTC' ];
230
+ // };
231
+
232
+ // // 21.4.1.24 SystemTimeZoneIdentifier ()
233
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-systemtimezoneidentifier
234
+ // export const __ecma262_SystemTimeZoneIdentifier = (): bytestring => {
235
+ // // 1. If the implementation only supports the UTC time zone, return "UTC".
236
+ // return 'UTC';
237
+ // };
238
+
239
+ // 21.4.1.25 LocalTime (t)
240
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-localtime
241
+ // slightly break spec here by just simplifying the abstraction for if implementation does not include local political rules for any time zones
242
+ export const __ecma262_LocalTime = (t: number): number => t;
243
+
244
+ // 21.4.1.26 UTC (t)
245
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-utc-t
246
+ // slightly break spec here by just simplifying the abstraction for if implementation does not include local political rules for any time zones
247
+ export const __ecma262_UTC = (t: number): number => {
248
+ // 1. If t is not finite, return NaN.
249
+ if (!Number.isFinite(t)) return NaN;
250
+
251
+ return t;
252
+ };
253
+
254
+
255
+ // todo: move this somewhere generic?
256
+ // 7.1.5 ToIntegerOrInfinity (argument)
257
+ // https://tc39.es/ecma262/multipage/abstract-operations.html#sec-tointegerorinfinity
258
+ export const __ecma262_ToIntegerOrInfinity = (argument: unknown): number => {
259
+ // 1. Let number be ? ToNumber(argument).
260
+ let number: number = Number(argument);
261
+
262
+ // 2. If number is one of NaN, +0𝔽, or -0𝔽, return 0.
263
+ if (Number.isNaN(number)) return 0;
264
+
265
+ // 3. If number is +∞𝔽, return +∞.
266
+ // 4. If number is -∞𝔽, return -∞.
267
+ if (!Number.isFinite(number)) return number;
268
+
269
+ // 5. Return truncate(ℝ(number)).
270
+ number = Math.trunc(number);
271
+
272
+ // return 0 for -0
273
+ if (number == 0) return 0;
274
+ return number;
275
+ };
276
+
277
+ // 21.4.1.27 MakeTime (hour, min, sec, ms)
278
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-maketime
279
+ export const __ecma262_MakeTime = (hour: number, min: number, sec: number, ms: number): number => {
280
+ // 1. If hour is not finite, min is not finite, sec is not finite, or ms is not finite, return NaN.
281
+ if (Porffor.fastOr(!Number.isFinite(hour), !Number.isFinite(min), !Number.isFinite(sec), !Number.isFinite(ms))) return NaN;
282
+
283
+ // 2. Let h be 𝔽(! ToIntegerOrInfinity(hour)).
284
+ const h: number = __ecma262_ToIntegerOrInfinity(hour);
285
+ // 3. Let m be 𝔽(! ToIntegerOrInfinity(min)).
286
+ const m: number = __ecma262_ToIntegerOrInfinity(min);
287
+ // 4. Let s be 𝔽(! ToIntegerOrInfinity(sec)).
288
+ const s: number = __ecma262_ToIntegerOrInfinity(sec);
289
+ // 5. Let milli be 𝔽(! ToIntegerOrInfinity(ms)).
290
+ const milli: number = __ecma262_ToIntegerOrInfinity(ms);
291
+
292
+ // 6. Return ((h × msPerHour + m × msPerMinute) + s × msPerSecond) + milli.
293
+ return ((h * 3600000 + m * 60000) + s * 1000) + milli;
294
+ };
295
+
296
+ // 21.4.1.28 MakeDay (year, month, date)
297
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-makeday
298
+ export const __ecma262_MakeDay = (year: number, month: number, date: number): number => {
299
+ // 1. If year is not finite, month is not finite, or date is not finite, return NaN.
300
+ if (Porffor.fastOr(!Number.isFinite(year), !Number.isFinite(month), !Number.isFinite(date))) return NaN;
301
+
302
+ // 2. Let y be 𝔽(! ToIntegerOrInfinity(year)).
303
+ const y: number = __ecma262_ToIntegerOrInfinity(year);
304
+ // 3. Let m be 𝔽(! ToIntegerOrInfinity(month)).
305
+ const m: number = __ecma262_ToIntegerOrInfinity(month);
306
+ // 4. Let dt be 𝔽(! ToIntegerOrInfinity(date)).
307
+ const dt: number = __ecma262_ToIntegerOrInfinity(date);
308
+
309
+ // 5. Let ym be y + 𝔽(floor(ℝ(m) / 12)).
310
+ let ym: number = y + Math.floor(m / 12);
311
+
312
+ // 6. If ym is not finite, return NaN.
313
+ if (!Number.isFinite(ym)) return NaN;
314
+
315
+ // 7. Let mn be 𝔽(ℝ(m) modulo 12).
316
+ const mn: number = m % 12;
317
+
318
+ // 8. Find a finite time value t such that YearFromTime(t) is ym, MonthFromTime(t) is mn, and DateFromTime(t) is 1𝔽; but if this is not possible (because some argument is out of range), return NaN.
319
+
320
+ // https://howardhinnant.github.io/date_algorithms.html#days_from_civil
321
+ if (mn <= 1) ym -= 1;
322
+
323
+ const era: number = Math.trunc((ym >= 0 ? ym : (ym - 399)) / 400);
324
+ const yoe: number = ym - era * 400;
325
+ const doy: number = Math.trunc((153 * (mn + (mn > 1 ? -2 : 10)) + 2) / 5);
326
+ const doe: number = yoe * 365 + Math.trunc(yoe / 4) - Math.trunc(yoe / 100) + doy;
327
+ const day: number = era * 146097 + doe - 719468;
328
+
329
+ // 9. Return Day(t) + dt - 1𝔽.
330
+ // day = Day(t) (our day calculated is already as day)
331
+ return day + dt - 1;
332
+ };
333
+
334
+ // 21.4.1.29 MakeDate (day, time)
335
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-makedate
336
+ export const __ecma262_MakeDate = (day: number, time: number): number => {
337
+ // 1. If day is not finite or time is not finite, return NaN.
338
+ if (Porffor.fastOr(!Number.isFinite(day), !Number.isFinite(time))) return NaN;
339
+
340
+ // 2. Let tv be day × msPerDay + time.
341
+ const tv: number = day * 86400000 + time;
342
+
343
+ // 3. If tv is not finite, return NaN.
344
+ if (!Number.isFinite(tv)) return NaN;
345
+
346
+ // 4. Return tv.
347
+ return tv;
348
+ };
349
+
350
+ // 21.4.1.30 MakeFullYear (year)
351
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-makefullyear
352
+ export const __ecma262_MakeFullYear = (year: number): number => {
353
+ // 1. If year is NaN, return NaN.
354
+ if (Number.isNaN(year)) return NaN;
355
+
356
+ // 2. Let truncated be ! ToIntegerOrInfinity(year).
357
+ const truncated: number = __ecma262_ToIntegerOrInfinity(year);
358
+
359
+ // 3. If truncated is in the inclusive interval from 0 to 99, return 1900𝔽 + 𝔽(truncated).
360
+ if (Porffor.fastAnd(truncated >= 0, truncated <= 99)) return 1900 + truncated;
361
+
362
+ // 4. Return 𝔽(truncated).
363
+ return truncated;
364
+ };
365
+
366
+
367
+ // 21.4.1.31 TimeClip (time)
368
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-timeclip
369
+ export const __ecma262_TimeClip = (time: number): number => {
370
+ // 1. If time is not finite, return NaN.
371
+ if (!Number.isFinite(time)) return NaN;
372
+
373
+ // 2. If abs(ℝ(time)) > 8.64 × 10**15, return NaN.
374
+ if (Math.abs(time) > 8.64e+15) return NaN;
375
+
376
+ // 3. Return 𝔽(! ToIntegerOrInfinity(time)).
377
+ return __ecma262_ToIntegerOrInfinity(time);
378
+ };
379
+
380
+
381
+ // 21.4.3.1 Date.now ()
382
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.now
383
+ // This function returns the time value designating the UTC date and time of the occurrence of the call to it.
384
+ export const __Date_now = (): number => Math.trunc(performance.timeOrigin + performance.now());
385
+
386
+ // 21.4.3.4 Date.UTC (year [, month [, date [, hours [, minutes [, seconds [, ms ]]]]]])
387
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.utc
388
+ export const __Date_UTC = (year: unknown, month: unknown, date: unknown, hours: unknown, minutes: unknown, seconds: unknown, ms: unknown): number => {
389
+ // todo: passing undefined to params should not act like no arg was passed
390
+
391
+ // 1. Let y be ? ToNumber(year).
392
+ const y: number = Number(year);
393
+
394
+ // 2. If month is present, let m be ? ToNumber(month); else let m be +0𝔽.
395
+ let m: number = 0;
396
+ if (Porffor.rawType(month) != Porffor.TYPES.undefined) m = Number(month);
397
+
398
+ // 3. If date is present, let dt be ? ToNumber(date); else let dt be 1𝔽.
399
+ let dt: number = 1;
400
+ if (Porffor.rawType(date) != Porffor.TYPES.undefined) dt = Number(date);
401
+
402
+ // 4. If hours is present, let h be ? ToNumber(hours); else let h be +0𝔽.
403
+ let h: number = 0;
404
+ if (Porffor.rawType(hours) != Porffor.TYPES.undefined) h = Number(hours);
405
+
406
+ // 5. If minutes is present, let min be ? ToNumber(minutes); else let min be +0𝔽.
407
+ let min: number = 0;
408
+ if (Porffor.rawType(minutes) != Porffor.TYPES.undefined) min = Number(minutes);
409
+
410
+ // 6. If seconds is present, let s be ? ToNumber(seconds); else let s be +0𝔽.
411
+ let s: number = 0;
412
+ if (Porffor.rawType(seconds) != Porffor.TYPES.undefined) s = Number(seconds);
413
+
414
+ // 7. If ms is present, let milli be ? ToNumber(ms); else let milli be +0𝔽.
415
+ let milli: number = 0;
416
+ if (Porffor.rawType(ms) != Porffor.TYPES.undefined) h = Number(ms);
417
+
418
+ // 8. Let yr be MakeFullYear(y).
419
+ const yr: number = __ecma262_MakeFullYear(y);
420
+
421
+ // 9. Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))).
422
+ return __ecma262_TimeClip(__ecma262_MakeDate(__ecma262_MakeDay(yr, m, dt), __ecma262_MakeTime(h, min, s, milli)));
423
+ };
424
+
425
+
426
+ export const __ecma262_WeekDayName = (tv: number): bytestring => {
427
+ // Name of the entry in Table 62 with the Number WeekDay(tv).
428
+ // Table 62: Names of days of the week
429
+ // Number Name
430
+ // +0𝔽 "Sun"
431
+ // 1𝔽 "Mon"
432
+ // 2𝔽 "Tue"
433
+ // 3𝔽 "Wed"
434
+ // 4𝔽 "Thu"
435
+ // 5𝔽 "Fri"
436
+ // 6𝔽 "Sat"
437
+
438
+ const weekday: number = __ecma262_WeekDay(tv);
439
+
440
+ const lut: bytestring = 'SunMonTueWedThuFriSat';
441
+
442
+ let out: bytestring = '';
443
+ out.length = 3;
444
+
445
+ let outPtr: number = Porffor.wasm`local.get ${out}`;
446
+ let lutPtr: number = Porffor.wasm`local.get ${lut}` + (weekday * 3);
447
+
448
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(lutPtr++, 0, 4), 0, 4);
449
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(lutPtr++, 0, 4), 0, 4);
450
+ Porffor.wasm.i32.store8(outPtr, Porffor.wasm.i32.load8_u(lutPtr, 0, 4), 0, 4);
451
+
452
+ return out;
453
+ };
454
+
455
+ export const __ecma262_MonthName = (tv: number): bytestring => {
456
+ // Name of the entry in Table 63 with the Number MonthFromTime(tv).
457
+ // Table 63: Names of months of the year
458
+ // Number Name
459
+ // +0𝔽 "Jan"
460
+ // 1𝔽 "Feb"
461
+ // 2𝔽 "Mar"
462
+ // 3𝔽 "Apr"
463
+ // 4𝔽 "May"
464
+ // 5𝔽 "Jun"
465
+ // 6𝔽 "Jul"
466
+ // 7𝔽 "Aug"
467
+ // 8𝔽 "Sep"
468
+ // 9𝔽 "Oct"
469
+ // 10𝔽 "Nov"
470
+ // 11𝔽 "Dec"
471
+
472
+ const month: number = __ecma262_MonthFromTime(tv);
473
+
474
+ const lut: bytestring = 'JanFebMarAprMayJunJulAugSepOctNovDec';
475
+
476
+ let out: bytestring = '';
477
+ out.length = 3;
478
+
479
+ let outPtr: number = Porffor.wasm`local.get ${out}`;
480
+ let lutPtr: number = Porffor.wasm`local.get ${lut}` + (month * 3);
481
+
482
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(lutPtr++, 0, 4), 0, 4);
483
+ Porffor.wasm.i32.store8(outPtr++, Porffor.wasm.i32.load8_u(lutPtr++, 0, 4), 0, 4);
484
+ Porffor.wasm.i32.store8(outPtr, Porffor.wasm.i32.load8_u(lutPtr, 0, 4), 0, 4);
485
+
486
+ return out;
487
+ };
488
+
489
+ export const __ecma262_ParseMonthName = (ptr: number): number => {
490
+ const a: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 4);
491
+
492
+ if (a == 74) { // J
493
+ const b: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 5);
494
+
495
+ if (b == 97) return 0; // a - Jan
496
+ if (b == 117) { // u
497
+ const c: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 6);
498
+ if (c == 110) return 5; // n - Jun
499
+ if (c == 108) return 6; // l - Jul
500
+ }
501
+ }
502
+
503
+ if (a == 77) { // M
504
+ const b: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 5);
505
+ if (b == 97) { // a
506
+ const c: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 6);
507
+ if (c == 114) return 2; // r - Mar
508
+ if (c == 121) return 4; // y - May
509
+ }
510
+ }
511
+
512
+ if (a == 65) { // A
513
+ const b: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 5);
514
+ if (b == 112) return 3; // p - Apr
515
+ if (b == 117) return 7; // u - Aug
516
+ }
517
+
518
+ if (a == 70) return 1; // F - Feb
519
+ if (a == 83) return 8; // S - Sep
520
+ if (a == 79) return 9; // O - Oct
521
+ if (a == 78) return 10; // N - Nov
522
+ if (a == 68) return 11; // D - Dec
523
+
524
+ return -1;
525
+ };
526
+
527
+
528
+ // DTSF parser
529
+ export const __ecma262_ParseDTSF = (string: bytestring): number => {
530
+ // formats we need to support:
531
+ // > new Date().toISOString()
532
+ // '2024-05-12T02:44:01.529Z'
533
+
534
+ let y: number = 0;
535
+ let m: number = 0;
536
+ let dt: number = 1;
537
+ let h: number = 0;
538
+ let min: number = 0;
539
+ let s: number = 0;
540
+ let milli: number = 0;
541
+ let tzHour: number = 0;
542
+ let tzMin: number = 0;
543
+
544
+ let n: number = 0;
545
+ let nInd: number = 0;
546
+ let z: boolean = false;
547
+
548
+ const len: i32 = string.length;
549
+ const endPtr: i32 = Porffor.wasm`local.get ${string}` + len;
550
+ let ptr: i32 = Porffor.wasm`local.get ${string}`;
551
+
552
+ while (ptr <= endPtr) { // <= to include extra null byte to set last n
553
+ const chr: i32 = Porffor.wasm.i32.load8_u(ptr++, 0, 4);
554
+ if (Porffor.fastAnd(chr >= 48, chr <= 57)) { // 0-9
555
+ n *= 10;
556
+ n += chr - 48;
557
+ continue;
558
+ }
559
+
560
+ if (chr == 45) { // -
561
+ if (Porffor.fastOr(ptr == Porffor.wasm`local.get ${string}`, nInd == 7)) n = -n;
562
+ }
563
+
564
+ if (n > 0) {
565
+ if (nInd == 0) y = n;
566
+ else if (nInd == 1) m = n - 1;
567
+ else if (nInd == 2) dt = n;
568
+ else if (nInd == 3) h = n;
569
+ else if (nInd == 4) min = n;
570
+ else if (nInd == 5) s = n;
571
+ else if (nInd == 6) milli = n;
572
+ else if (nInd == 7) tzHour = n;
573
+ else if (nInd == 8) tzMin = n;
574
+
575
+ n = 0;
576
+ nInd++;
577
+ }
578
+
579
+ if (chr == 90) { // Z
580
+ if (ptr == len) z = true;
581
+ }
582
+ }
583
+
584
+ h += tzHour;
585
+ min += tzMin;
586
+
587
+ return __ecma262_TimeClip(__ecma262_MakeDate(__ecma262_MakeDay(y, m, dt), __ecma262_MakeTime(h, min, s, milli)));
588
+
589
+ // we do not support local time yet so useless check
590
+ // let t: number = __ecma262_TimeClip(__ecma262_MakeDate(__ecma262_MakeDay(y, m, dt), __ecma262_MakeTime(h, min, s, milli)));
591
+
592
+ // "When the time zone offset is absent, date-only forms are interpreted as a UTC time
593
+ // and date-time forms are interpreted as local time.
594
+ // This is due to a historical spec error that was not consistent with ISO 8601
595
+ // but could not be changed due to web compatibility." :))
596
+ // if (Porffor.fastAnd(
597
+ // nInd > 3, // not date-only
598
+ // z == false, // not utc (ending with Z)
599
+ // nInd < 8, // no time zone offset
600
+ // )) {
601
+ // t = __ecma262_UTC(t);
602
+ // }
603
+
604
+ // return t;
605
+ };
606
+
607
+ // RFC 7231 or Date.prototype.toString() parser
608
+ export const __ecma262_ParseRFC7231OrToString = (string: bytestring): number => {
609
+ // formats we need to support:
610
+ // > new Date().toUTCString()
611
+ // 'Sun, 12 May 2024 02:44:10 GMT'
612
+ // > new Date().toString()
613
+ // 'Sun May 12 2024 02:44:13 GMT+0000 (UTC)'
614
+
615
+ // skip week day
616
+ let ptr: i32 = Porffor.wasm`local.get ${string}` + 4;
617
+
618
+ // skip potential ' '
619
+ if (Porffor.wasm.i32.load8_u(ptr, 0, 4) == 32) ptr++;
620
+
621
+ let dt: number = 0;
622
+ let m: number = -1;
623
+
624
+ // check if date now via numerical
625
+ let chr: i32 = Porffor.wasm.i32.load8_u(ptr, 0, 4);
626
+ if (Porffor.fastAnd(chr >= 48, chr <= 57)) { // 0-9
627
+ // date, month name
628
+ while (true) { // use >0 check instead of !=' ' to handle malformed
629
+ chr = Porffor.wasm.i32.load8_u(ptr++, 0, 4);
630
+ if (chr < 48) break;
631
+
632
+ dt *= 10;
633
+ dt += chr - 48;
634
+ }
635
+
636
+ m = __ecma262_ParseMonthName(ptr);
637
+ ptr += 3;
638
+ } else {
639
+ // month name, date
640
+ m = __ecma262_ParseMonthName(ptr);
641
+ ptr += 4;
642
+
643
+ while (true) { // use >0 check instead of !=' ' to handle malformed
644
+ chr = Porffor.wasm.i32.load8_u(ptr++, 0, 4);
645
+ if (chr < 48) break;
646
+
647
+ dt *= 10;
648
+ dt += chr - 48;
649
+ }
650
+ }
651
+
652
+ // check we parsed month and date correctly
653
+ if (Porffor.fastOr(m == -1, dt == 0, dt > 31)) {
654
+ return NaN;
655
+ }
656
+
657
+ let y: number = 0;
658
+ let h: number = 0;
659
+ let min: number = 0;
660
+ let s: number = 0;
661
+ let tz: number = 0;
662
+
663
+ let n: number = 0;
664
+ let nInd: number = 0;
665
+
666
+ const len: i32 = string.length;
667
+ const endPtr: i32 = Porffor.wasm`local.get ${string}` + len;
668
+
669
+ while (ptr <= endPtr) { // <= to include extra null byte to set last n
670
+ const chr: i32 = Porffor.wasm.i32.load8_u(ptr++, 0, 4);
671
+ if (Porffor.fastAnd(chr >= 48, chr <= 57)) { // 0-9
672
+ n *= 10;
673
+ n += chr - 48;
674
+ continue;
675
+ }
676
+
677
+ if (chr == 45) { // -
678
+ if (nInd == 4) n = -n;
679
+ }
680
+
681
+ if (n > 0) {
682
+ if (nInd == 0) y = n;
683
+ else if (nInd == 1) h = n;
684
+ else if (nInd == 2) min = n;
685
+ else if (nInd == 3) s = n;
686
+ else if (nInd == 4) tz = n;
687
+
688
+ n = 0;
689
+ nInd++;
690
+ }
691
+ }
692
+
693
+ return __ecma262_TimeClip(__ecma262_MakeDate(__ecma262_MakeDay(y, m, dt), __ecma262_MakeTime(h, min, s, 0)));
694
+ };
695
+
696
+ // 21.4.3.2 Date.parse (string)
697
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.parse
698
+ export const __Date_parse = (string: bytestring): number => {
699
+ // formats we need to support:
700
+ // > new Date().toISOString()
701
+ // '2024-05-12T02:44:01.529Z'
702
+ // > new Date().toUTCString()
703
+ // 'Sun, 12 May 2024 02:44:10 GMT'
704
+ // > new Date().toString()
705
+ // 'Sun May 12 2024 02:44:13 GMT+0000 (UTC)'
706
+
707
+ // if first char is numerical, use DTSF parser
708
+ const chr: i32 = Porffor.wasm.i32.load8_u(string, 0, 4);;
709
+ if (Porffor.fastAnd(chr >= 48, chr <= 57)) { // 0-9
710
+ return __ecma262_ParseDTSF(string);
711
+ }
712
+
713
+ // else, use RFC 7231 or Date.prototype.toString() parser
714
+ return __ecma262_ParseRFC7231OrToString(string);
715
+ };
716
+
717
+
718
+ // dark wasm magic for a basic allocator, sorry.
719
+ export const __Porffor_date_allocate = (): Date => {
720
+ const hack: bytestring = '';
721
+
722
+ if (hack.length == 0) {
723
+ hack.length = Porffor.wasm`i32.const 1
724
+ memory.grow 0
725
+ drop
726
+ memory.size 0
727
+ i32.const 1
728
+ i32.sub
729
+ i32.const 65536
730
+ i32.mul
731
+ i32.from_u`;
732
+ }
733
+
734
+ const ptr: number = hack.length;
735
+ hack.length = ptr + 8;
736
+
737
+ return ptr;
738
+ };
739
+
740
+ export const __Porffor_date_read = (ptr: Date): number => Porffor.wasm.f64.load(ptr, 0, 0);
741
+ export const __Porffor_date_write = (ptr: Date, val: number) => {
742
+ Porffor.wasm.f64.store(ptr, val, 0, 0);
743
+ };
744
+
745
+ // 21.4.2.1 Date (...values)
746
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date
747
+ export const Date$constructor = (v0: unknown, v1: unknown, v2: unknown, v3: unknown, v4: unknown, v5: unknown, v6: unknown): Date => {
748
+ // todo: passing undefined to params should not act like no arg was passed
749
+
750
+ // 2. Let numberOfArgs be the number of elements in values.
751
+ // sorry.
752
+ const numberOfArgs: i32 =
753
+ (Porffor.rawType(v0) != Porffor.TYPES.undefined) +
754
+ (Porffor.rawType(v1) != Porffor.TYPES.undefined) +
755
+ (Porffor.rawType(v2) != Porffor.TYPES.undefined) +
756
+ (Porffor.rawType(v3) != Porffor.TYPES.undefined) +
757
+ (Porffor.rawType(v4) != Porffor.TYPES.undefined) +
758
+ (Porffor.rawType(v5) != Porffor.TYPES.undefined) +
759
+ (Porffor.rawType(v6) != Porffor.TYPES.undefined);
760
+
761
+ let dv: number = 0;
762
+
763
+ // 3. If numberOfArgs = 0, then
764
+ if (numberOfArgs == 0) {
765
+ // a. Let dv be the time value (UTC) identifying the current time.
766
+ dv = __Date_now();
767
+ } else if (numberOfArgs == 1) {
768
+ // 4. Else if numberOfArgs = 1, the n
769
+ // a. Let value be values[0].
770
+ const value: any = v0;
771
+
772
+ const valueType: i32 = Porffor.rawType(v0);
773
+
774
+ let tv: number = 0;
775
+
776
+ // b. If value is an Object and value has a [[DateValue]] internal slot, then
777
+ if (valueType == Porffor.TYPES.date) {
778
+ // i. Let tv be value.[[DateValue]].
779
+ tv = __Porffor_date_read(value);
780
+ } else {
781
+ // c. Else,
782
+ // ii. If v is a String, then
783
+ if (Porffor.fastOr(valueType == Porffor.TYPES.string, valueType == Porffor.TYPES.bytestring)) {
784
+ // 1. Assert: The next step never returns an abrupt completion because v is a String.
785
+
786
+ // 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
787
+ tv = __Date_parse(value);
788
+ } else {
789
+ // iii. Else,
790
+ // 1. Let tv be ? ToNumber(v).
791
+ tv = Number(value);
792
+ }
793
+ }
794
+
795
+ // d. Let dv be TimeClip(tv).
796
+ dv = __ecma262_TimeClip(tv);
797
+ } else {
798
+ // 5. Else,
799
+ // a. Assert: numberOfArgs ≥ 2.
800
+
801
+ // b. Let y be ? ToNumber(values[0]).
802
+ const y: number = Number(v0);
803
+
804
+ // c. Let m be ? ToNumber(values[1]).
805
+ const m: number = Number(v1);
806
+
807
+ // d. If numberOfArgs > 2, let dt be ? ToNumber(values[2]); else let dt be 1𝔽.
808
+ let dt: number = 1;
809
+ if (numberOfArgs > 2) dt = Number(v2);
810
+
811
+ // e. If numberOfArgs > 3, let h be ? ToNumber(values[3]); else let h be +0𝔽.
812
+ let h: number = 0;
813
+ if (numberOfArgs > 3) h = Number(v3);
814
+
815
+ // f. If numberOfArgs > 4, let min be ? ToNumber(values[4]); else let min be +0𝔽.
816
+ let min: number = 0;
817
+ if (numberOfArgs > 4) min = Number(v4);
818
+
819
+ // g. If numberOfArgs > 5, let s be ? ToNumber(values[5]); else let s be +0𝔽.
820
+ let s: number = 0;
821
+ if (numberOfArgs > 5) s = Number(v5);
822
+
823
+ // h. If numberOfArgs > 6, let milli be ? ToNumber(values[6]); else let milli be +0𝔽.
824
+ let milli: number = 0;
825
+ if (numberOfArgs > 6) milli = Number(v6);
826
+
827
+ // i. Let yr be MakeFullYear(y).
828
+ const yr: number = __ecma262_MakeFullYear(y);
829
+
830
+ // j. Let finalDate be MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)).
831
+ const finalDate: number = __ecma262_MakeDate(__ecma262_MakeDay(yr, m, dt), __ecma262_MakeTime(h, min, s, milli));
832
+
833
+ // k. Let dv be TimeClip(UTC(finalDate)).
834
+ dv = __ecma262_TimeClip(__ecma262_UTC(finalDate));
835
+ }
836
+
837
+ // 6. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »).
838
+ const O: Date = __Porffor_date_allocate();
839
+
840
+ // 7. Set O.[[DateValue]] to dv.
841
+ __Porffor_date_write(O, dv);
842
+
843
+ // 8. Return O.
844
+ return O;
845
+ };
846
+
847
+
848
+ // 21.4.4 Properties of the Date Prototype Object
849
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-properties-of-the-date-prototype-object
850
+
851
+ // 21.4.4.2 Date.prototype.getDate ()
852
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getdate
853
+ export const __Date_prototype_getDate = (_this: Date) => {
854
+ // 1. Let dateObject be the this value.
855
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
856
+ // 3. Let t be dateObject.[[DateValue]].
857
+ const t: number = __Porffor_date_read(_this);
858
+
859
+ // 4. If t is NaN, return NaN.
860
+ if (Number.isNaN(t)) return NaN;
861
+
862
+ // 5. Return DateFromTime(LocalTime(t)).
863
+ return __ecma262_DateFromTime(__ecma262_LocalTime(t));
864
+ };
865
+
866
+ // 21.4.4.3 Date.prototype.getDay ()
867
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getday
868
+ export const __Date_prototype_getDay = (_this: Date) => {
869
+ // 1. Let dateObject be the this value.
870
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
871
+ // 3. Let t be dateObject.[[DateValue]].
872
+ const t: number = __Porffor_date_read(_this);
873
+
874
+ // 4. If t is NaN, return NaN.
875
+ if (Number.isNaN(t)) return NaN;
876
+
877
+ // 5. Return WeekDay(LocalTime(t)).
878
+ return __ecma262_WeekDay(__ecma262_LocalTime(t));
879
+ };
880
+
881
+ // 21.4.4.4 Date.prototype.getFullYear ()
882
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getfullyear
883
+ export const __Date_prototype_getFullYear = (_this: Date) => {
884
+ // 1. Let dateObject be the this value.
885
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
886
+ // 3. Let t be dateObject.[[DateValue]].
887
+ const t: number = __Porffor_date_read(_this);
888
+
889
+ // 4. If t is NaN, return NaN.
890
+ if (Number.isNaN(t)) return NaN;
891
+
892
+ // 5. Return YearFromTime(LocalTime(t)).
893
+ return __ecma262_YearFromTime(__ecma262_LocalTime(t));
894
+ };
895
+
896
+ // 21.4.4.5 Date.prototype.getHours ()
897
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.gethours
898
+ export const __Date_prototype_getHours = (_this: Date) => {
899
+ // 1. Let dateObject be the this value.
900
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
901
+ // 3. Let t be dateObject.[[DateValue]].
902
+ const t: number = __Porffor_date_read(_this);
903
+
904
+ // 4. If t is NaN, return NaN.
905
+ if (Number.isNaN(t)) return NaN;
906
+
907
+ // 5. Return HourFromTime(LocalTime(t)).
908
+ return __ecma262_HourFromTime(__ecma262_LocalTime(t));
909
+ };
910
+
911
+ // 21.4.4.6 Date.prototype.getMilliseconds ()
912
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getmilliseconds
913
+ export const __Date_prototype_getMilliseconds = (_this: Date) => {
914
+ // 1. Let dateObject be the this value.
915
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
916
+ // 3. Let t be dateObject.[[DateValue]].
917
+ const t: number = __Porffor_date_read(_this);
918
+
919
+ // 4. If t is NaN, return NaN.
920
+ if (Number.isNaN(t)) return NaN;
921
+
922
+ // 5. Return msFromTime(LocalTime(t)).
923
+ return __ecma262_msFromTime(__ecma262_LocalTime(t));
924
+ };
925
+
926
+ // 21.4.4.7 Date.prototype.getMinutes ()
927
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getminutes
928
+ export const __Date_prototype_getMinutes = (_this: Date) => {
929
+ // 1. Let dateObject be the this value.
930
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
931
+ // 3. Let t be dateObject.[[DateValue]].
932
+ const t: number = __Porffor_date_read(_this);
933
+
934
+ // 4. If t is NaN, return NaN.
935
+ if (Number.isNaN(t)) return NaN;
936
+
937
+ // 5. Return MinFromTime(LocalTime(t)).
938
+ return __ecma262_MinFromTime(__ecma262_LocalTime(t));
939
+ };
940
+
941
+ // 21.4.4.8 Date.prototype.getMonth ()
942
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getmonth
943
+ export const __Date_prototype_getMonth = (_this: Date) => {
944
+ // 1. Let dateObject be the this value.
945
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
946
+ // 3. Let t be dateObject.[[DateValue]].
947
+ const t: number = __Porffor_date_read(_this);
948
+
949
+ // 4. If t is NaN, return NaN.
950
+ if (Number.isNaN(t)) return NaN;
951
+
952
+ // 5. Return MonthFromTime(LocalTime(t)).
953
+ return __ecma262_MonthFromTime(__ecma262_LocalTime(t));
954
+ };
955
+
956
+ // 21.4.4.9 Date.prototype.getSeconds ()
957
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getseconds
958
+ export const __Date_prototype_getSeconds = (_this: Date) => {
959
+ // 1. Let dateObject be the this value.
960
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
961
+ // 3. Let t be dateObject.[[DateValue]].
962
+ const t: number = __Porffor_date_read(_this);
963
+
964
+ // 4. If t is NaN, return NaN.
965
+ if (Number.isNaN(t)) return NaN;
966
+
967
+ // 5. Return SecFromTime(LocalTime(t)).
968
+ return __ecma262_SecFromTime(__ecma262_LocalTime(t));
969
+ };
970
+
971
+ // 21.4.4.10 Date.prototype.getTime ()
972
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.gettime
973
+ export const __Date_prototype_getTime = (_this: Date) => {
974
+ // 1. Let dateObject be the this value.
975
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
976
+ // 3. Return dateObject.[[DateValue]].
977
+ return __Porffor_date_read(_this);
978
+ };
979
+
980
+ // 21.4.4.11 Date.prototype.getTimezoneOffset ()
981
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.gettimezoneoffset
982
+ export const __Date_prototype_getTimezoneOffset = (_this: Date) => {
983
+ // 1. Let dateObject be the this value.
984
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
985
+ // 3. Let t be dateObject.[[DateValue]].
986
+ const t: number = __Porffor_date_read(_this);
987
+
988
+ // 4. If t is NaN, return NaN.
989
+ if (Number.isNaN(t)) return NaN;
990
+
991
+ // 5. Return (t - LocalTime(t)) / msPerMinute.
992
+ return (t - __ecma262_LocalTime(t)) / 60000;
993
+ };
994
+
995
+ // 21.4.4.12 Date.prototype.getUTCDate ()
996
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutcdate
997
+ export const __Date_prototype_getUTCDate = (_this: Date) => {
998
+ // 1. Let dateObject be the this value.
999
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1000
+ // 3. Let t be dateObject.[[DateValue]].
1001
+ const t: number = __Porffor_date_read(_this);
1002
+
1003
+ // 4. If t is NaN, return NaN.
1004
+ if (Number.isNaN(t)) return NaN;
1005
+
1006
+ // 5. Return DateFromTime(t).
1007
+ return __ecma262_DateFromTime(t);
1008
+ };
1009
+
1010
+ // 21.4.4.13 Date.prototype.getUTCDay ()
1011
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutcday
1012
+ export const __Date_prototype_getUTCDay = (_this: Date) => {
1013
+ // 1. Let dateObject be the this value.
1014
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1015
+ // 3. Let t be dateObject.[[DateValue]].
1016
+ const t: number = __Porffor_date_read(_this);
1017
+
1018
+ // 4. If t is NaN, return NaN.
1019
+ if (Number.isNaN(t)) return NaN;
1020
+
1021
+ // 5. Return WeekDay(t).
1022
+ return __ecma262_WeekDay(t);
1023
+ };
1024
+
1025
+ // 21.4.4.14 Date.prototype.getUTCFullYear ()
1026
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutcfullyear
1027
+ export const __Date_prototype_getUTCFullYear = (_this: Date) => {
1028
+ // 1. Let dateObject be the this value.
1029
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1030
+ // 3. Let t be dateObject.[[DateValue]].
1031
+ const t: number = __Porffor_date_read(_this);
1032
+
1033
+ // 4. If t is NaN, return NaN.
1034
+ if (Number.isNaN(t)) return NaN;
1035
+
1036
+ // 5. Return YearFromTime(t).
1037
+ return __ecma262_YearFromTime(t);
1038
+ };
1039
+
1040
+ // 21.4.4.15 Date.prototype.getUTCHours ()
1041
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutchours
1042
+ export const __Date_prototype_getUTCHours = (_this: Date) => {
1043
+ // 1. Let dateObject be the this value.
1044
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1045
+ // 3. Let t be dateObject.[[DateValue]].
1046
+ const t: number = __Porffor_date_read(_this);
1047
+
1048
+ // 4. If t is NaN, return NaN.
1049
+ if (Number.isNaN(t)) return NaN;
1050
+
1051
+ // 5. Return HourFromTime(t).
1052
+ return __ecma262_HourFromTime(t);
1053
+ };
1054
+
1055
+ // 21.4.4.16 Date.prototype.getUTCMilliseconds ()
1056
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutcmilliseconds
1057
+ export const __Date_prototype_getUTCMilliseconds = (_this: Date) => {
1058
+ // 1. Let dateObject be the this value.
1059
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1060
+ // 3. Let t be dateObject.[[DateValue]].
1061
+ const t: number = __Porffor_date_read(_this);
1062
+
1063
+ // 4. If t is NaN, return NaN.
1064
+ if (Number.isNaN(t)) return NaN;
1065
+
1066
+ // 5. Return msFromTime(t).
1067
+ return __ecma262_msFromTime(t);
1068
+ };
1069
+
1070
+ // 21.4.4.17 Date.prototype.getUTCMinutes ()
1071
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutcminutes
1072
+ export const __Date_prototype_getUTCMinutes = (_this: Date) => {
1073
+ // 1. Let dateObject be the this value.
1074
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1075
+ // 3. Let t be dateObject.[[DateValue]].
1076
+ const t: number = __Porffor_date_read(_this);
1077
+
1078
+ // 4. If t is NaN, return NaN.
1079
+ if (Number.isNaN(t)) return NaN;
1080
+
1081
+ // 5. Return MinFromTime(t).
1082
+ return __ecma262_MinFromTime(t);
1083
+ };
1084
+
1085
+ // 21.4.4.18 Date.prototype.getUTCMonth ()
1086
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutcmonth
1087
+ export const __Date_prototype_getUTCMonth = (_this: Date) => {
1088
+ // 1. Let dateObject be the this value.
1089
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1090
+ // 3. Let t be dateObject.[[DateValue]].
1091
+ const t: number = __Porffor_date_read(_this);
1092
+
1093
+ // 4. If t is NaN, return NaN.
1094
+ if (Number.isNaN(t)) return NaN;
1095
+
1096
+ // 5. Return MonthFromTime(t).
1097
+ return __ecma262_MonthFromTime(t);
1098
+ };
1099
+
1100
+ // 21.4.4.19 Date.prototype.getUTCSeconds ()
1101
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.getutcseconds
1102
+ export const __Date_prototype_getUTCSeconds = (_this: Date) => {
1103
+ // 1. Let dateObject be the this value.
1104
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1105
+ // 3. Let t be dateObject.[[DateValue]].
1106
+ const t: number = __Porffor_date_read(_this);
1107
+
1108
+ // 4. If t is NaN, return NaN.
1109
+ if (Number.isNaN(t)) return NaN;
1110
+
1111
+ // 5. Return SecFromTime(t).
1112
+ return __ecma262_SecFromTime(t);
1113
+ };
1114
+
1115
+
1116
+ // 21.4.4.20 Date.prototype.setDate (date)
1117
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setdate
1118
+ export const __Date_prototype_setDate = (_this: Date, date: any) => {
1119
+ // 1. Let dateObject be the this value.
1120
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1121
+ // 3. Let t be dateObject.[[DateValue]].
1122
+ let t: number = __Porffor_date_read(_this);
1123
+
1124
+ // 4. Let dt be ? ToNumber(date).
1125
+ const dt: number = Number(date);
1126
+
1127
+ // 5. If t is NaN, return NaN.
1128
+ if (Number.isNaN(t)) return NaN;
1129
+
1130
+ // 6. Set t to LocalTime(t).
1131
+ t = __ecma262_LocalTime(t);
1132
+
1133
+ // 7. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
1134
+ const newDate: number = __ecma262_MakeDate(__ecma262_MakeDay(__ecma262_YearFromTime(t), __ecma262_MonthFromTime(t), dt), __ecma262_TimeWithinDay(t));
1135
+
1136
+ // 8. Let u be TimeClip(UTC(newDate)).
1137
+ const u: number = __ecma262_TimeClip(__ecma262_UTC(newDate));
1138
+
1139
+ // 9. Set dateObject.[[DateValue]] to u.
1140
+ __Porffor_date_write(_this, u);
1141
+
1142
+ // 10. Return u.
1143
+ return u;
1144
+ };
1145
+
1146
+ // 21.4.4.21 Date.prototype.setFullYear (year [, month [, date ]])
1147
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setfullyear
1148
+ export const __Date_prototype_setFullYear = (_this: Date, year: any, month: any, date: any) => {
1149
+ // 1. Let dateObject be the this value.
1150
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1151
+ // 3. Let t be dateObject.[[DateValue]].
1152
+ let t: number = __Porffor_date_read(_this);
1153
+
1154
+ // 4. Let y be ? ToNumber(year).
1155
+ const y: number = Number(year);
1156
+
1157
+ // 5. If t is NaN, set t to +0𝔽; otherwise, set t to LocalTime(t).
1158
+ if (Number.isNaN(t)) t = 0;
1159
+ else t = __ecma262_LocalTime(t);
1160
+
1161
+ // 6. If month is not present, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month).
1162
+ let m: number;
1163
+ if (Porffor.rawType(month) == Porffor.TYPES.undefined) m = __ecma262_MonthFromTime(t);
1164
+ else m = Number(month);
1165
+
1166
+ // 7. If date is not present, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date).
1167
+ let dt: number;
1168
+ if (Porffor.rawType(date) == Porffor.TYPES.undefined) dt = __ecma262_DateFromTime(t);
1169
+ else dt = Number(date);
1170
+
1171
+ // 8. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
1172
+ const newDate: number = __ecma262_MakeDate(__ecma262_MakeDay(y, m, dt), __ecma262_TimeWithinDay(t));
1173
+
1174
+ // 9. Let u be TimeClip(UTC(newDate)).
1175
+ const u: number = __ecma262_TimeClip(__ecma262_UTC(newDate));
1176
+
1177
+ // 10. Set dateObject.[[DateValue]] to u.
1178
+ __Porffor_date_write(_this, u);
1179
+
1180
+ // 11. Return u.
1181
+ return u;
1182
+ };
1183
+
1184
+ // 21.4.4.22 Date.prototype.setHours (hour [, min [, sec [, ms ]]])
1185
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.sethours
1186
+ export const __Date_prototype_setHours = (_this: Date, hour: any, min: any, sec: any, ms: any) => {
1187
+ // 1. Let dateObject be the this value.
1188
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1189
+ // 3. Let t be dateObject.[[DateValue]].
1190
+ let t: number = __Porffor_date_read(_this);
1191
+
1192
+ // 4. Let h be ? ToNumber(hour).
1193
+ const h: number = Number(hour);
1194
+
1195
+ // we reorder the spec steps in this func for easier arg handling
1196
+
1197
+ // 8. If t is NaN, return NaN.
1198
+ if (Number.isNaN(t)) return NaN;
1199
+
1200
+ // 9. Set t to LocalTime(t).
1201
+ t = __ecma262_LocalTime(t);
1202
+
1203
+ // 5. If min is present, let m be ? ToNumber(min).
1204
+ let m: number;
1205
+ if (Porffor.rawType(min) != Porffor.TYPES.undefined) m = Number(min);
1206
+ // 10. If min is not present, let m be MinFromTime(t).
1207
+ else m = __ecma262_MinFromTime(t);
1208
+
1209
+ // 6. If sec is present, let s be ? ToNumber(sec).
1210
+ let s: number;
1211
+ if (Porffor.rawType(sec) != Porffor.TYPES.undefined) s = Number(sec);
1212
+ // 11. If sec is not present, let s be SecFromTime(t).
1213
+ else s = __ecma262_SecFromTime(t);
1214
+
1215
+ // 7. If ms is present, let milli be ? ToNumber(ms).
1216
+ let milli: number;
1217
+ if (Porffor.rawType(ms) != Porffor.TYPES.undefined) milli = Number(ms);
1218
+ // 12. If ms is not present, let milli be msFromTime(t).
1219
+ else milli = __ecma262_msFromTime(t);
1220
+
1221
+ // 13. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
1222
+ const date: number = __ecma262_MakeDate(__ecma262_Day(t), __ecma262_MakeTime(h, m, s, milli));
1223
+
1224
+ // 14. Let u be TimeClip(UTC(date)).
1225
+ const u: number = __ecma262_TimeClip(__ecma262_UTC(date));
1226
+
1227
+ // 15. Set dateObject.[[DateValue]] to u.
1228
+ __Porffor_date_write(_this, u);
1229
+
1230
+ // 16. Return u.
1231
+ return u;
1232
+ };
1233
+
1234
+ // 21.4.4.23 Date.prototype.setMilliseconds (ms)
1235
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setmilliseconds
1236
+ export const __Date_prototype_setMilliseconds = (_this: Date, ms: any) => {
1237
+ // 1. Let dateObject be the this value.
1238
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1239
+ // 3. Let t be dateObject.[[DateValue]].
1240
+ let t: number = __Porffor_date_read(_this);
1241
+
1242
+ // ignore old-style spec setting arg instead of having let
1243
+ // 4. Set ms to ? ToNumber(ms).
1244
+ const milli: number = Number(ms);
1245
+
1246
+ // 5. If t is NaN, return NaN.
1247
+ if (Number.isNaN(t)) return NaN;
1248
+
1249
+ // 6. Set t to LocalTime(t).
1250
+ t = __ecma262_LocalTime(t);
1251
+
1252
+ // 7. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
1253
+ const time: number = __ecma262_MakeTime(__ecma262_HourFromTime(t), __ecma262_MinFromTime(t), __ecma262_SecFromTime(t), milli);
1254
+
1255
+ // 8. Let u be TimeClip(UTC(MakeDate(Day(t), time))).
1256
+ const u: number = __ecma262_TimeClip(__ecma262_UTC(__ecma262_MakeDate(__ecma262_Day(t), time)));
1257
+
1258
+ // 9. Set dateObject.[[DateValue]] to u.
1259
+ __Porffor_date_write(_this, u);
1260
+
1261
+ // 10. Return u.
1262
+ return u;
1263
+ };
1264
+
1265
+ // 21.4.4.24 Date.prototype.setMinutes (min [, sec [, ms ]])
1266
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setminutes
1267
+ export const __Date_prototype_setMinutes = (_this: Date, min: any, sec: any, ms: any) => {
1268
+ // 1. Let dateObject be the this value.
1269
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1270
+ // 3. Let t be dateObject.[[DateValue]].
1271
+ let t: number = __Porffor_date_read(_this);
1272
+
1273
+ // 4. Let m be ? ToNumber(min).
1274
+ const m: number = Number(min);
1275
+
1276
+ // we reorder the spec steps in this func for easier arg handling
1277
+
1278
+ // 7. If t is NaN, return NaN.
1279
+ if (Number.isNaN(t)) return NaN;
1280
+
1281
+ // 8. Set t to LocalTime(t).
1282
+ t = __ecma262_LocalTime(t);
1283
+
1284
+ // 5. If sec is present, let s be ? ToNumber(sec).
1285
+ let s: number;
1286
+ if (Porffor.rawType(sec) != Porffor.TYPES.undefined) s = Number(sec);
1287
+ // 9. If sec is not present, let s be SecFromTime(t).
1288
+ else s = __ecma262_SecFromTime(t);
1289
+
1290
+ // 6. If ms is present, let milli be ? ToNumber(ms).
1291
+ let milli: number;
1292
+ if (Porffor.rawType(ms) != Porffor.TYPES.undefined) milli = Number(ms);
1293
+ // 10. If ms is not present, let milli be msFromTime(t).
1294
+ else milli = __ecma262_msFromTime(t);
1295
+
1296
+ // 11. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
1297
+ const date: number = __ecma262_MakeDate(__ecma262_Day(t), __ecma262_MakeTime(__ecma262_HourFromTime(t), m, s, milli));
1298
+
1299
+ // 12. Let u be TimeClip(UTC(date)).
1300
+ const u: number = __ecma262_TimeClip(__ecma262_UTC(date));
1301
+
1302
+ // 13. Set dateObject.[[DateValue]] to u.
1303
+ __Porffor_date_write(_this, u);
1304
+
1305
+ // 14. Return u.
1306
+ return u;
1307
+ };
1308
+
1309
+ // 21.4.4.25 Date.prototype.setMonth (month [, date ])
1310
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setmonth
1311
+ export const __Date_prototype_setMonth = (_this: Date, month: any, date: any) => {
1312
+ // 1. Let dateObject be the this value.
1313
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1314
+ // 3. Let t be dateObject.[[DateValue]].
1315
+ let t: number = __Porffor_date_read(_this);
1316
+
1317
+ // 4. Let m be ? ToNumber(month).
1318
+ const m: number = Number(month);
1319
+
1320
+ // we reorder the spec steps in this func for easier arg handling
1321
+
1322
+ // 6. If t is NaN, return NaN.
1323
+ if (Number.isNaN(t)) return NaN;
1324
+
1325
+ // 7. Set t to LocalTime(t).
1326
+ t = __ecma262_LocalTime(t);
1327
+
1328
+ // 5. If date is present, let dt be ? ToNumber(date).
1329
+ let dt: number;
1330
+ if (Porffor.rawType(date) != Porffor.TYPES.undefined) dt = Number(date);
1331
+ // 8. If date is not present, let dt be DateFromTime(t).
1332
+ else dt = __ecma262_DateFromTime(t);
1333
+
1334
+ // 9. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
1335
+ const newDate: number = __ecma262_MakeDate(__ecma262_MakeDay(__ecma262_YearFromTime(t), m, dt), __ecma262_TimeWithinDay(t));
1336
+
1337
+ // 10. Let u be TimeClip(UTC(newDate)).
1338
+ const u: number = __ecma262_TimeClip(__ecma262_UTC(newDate));
1339
+
1340
+ // 11. Set dateObject.[[DateValue]] to u.
1341
+ __Porffor_date_write(_this, u);
1342
+
1343
+ // 12. Return u.
1344
+ return u;
1345
+ };
1346
+
1347
+ // 21.4.4.26 Date.prototype.setSeconds (sec [, ms ])
1348
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setseconds
1349
+ export const __Date_prototype_setSeconds = (_this: Date, sec: any, ms: any) => {
1350
+ // 1. Let dateObject be the this value.
1351
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1352
+ // 3. Let t be dateObject.[[DateValue]].
1353
+ let t: number = __Porffor_date_read(_this);
1354
+
1355
+ // 4. Let s be ? ToNumber(sec).
1356
+ const s: number = Number(sec);
1357
+
1358
+ // we reorder the spec steps in this func for easier arg handling
1359
+
1360
+ // 6. If t is NaN, return NaN.
1361
+ if (Number.isNaN(t)) return NaN;
1362
+
1363
+ // 7. Set t to LocalTime(t).
1364
+ t = __ecma262_LocalTime(t);
1365
+
1366
+ // 5. If ms is present, let milli be ? ToNumber(ms).
1367
+ let milli: number;
1368
+ if (Porffor.rawType(ms) != Porffor.TYPES.undefined) milli = Number(ms);
1369
+ // 8. If ms is not present, let milli be msFromTime(t).
1370
+ else milli = __ecma262_msFromTime(t);
1371
+
1372
+ // 9. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
1373
+ const date: number = __ecma262_MakeDate(__ecma262_Day(t), __ecma262_MakeTime(__ecma262_HourFromTime(t), __ecma262_MinFromTime(t), s, milli));
1374
+
1375
+ // 10. Let u be TimeClip(UTC(date)).
1376
+ const u: number = __ecma262_TimeClip(__ecma262_UTC(date));
1377
+
1378
+ // 11. Set dateObject.[[DateValue]] to u.
1379
+ __Porffor_date_write(_this, u);
1380
+
1381
+ // 12. Return u.
1382
+ return u;
1383
+ };
1384
+
1385
+
1386
+ // 21.4.4.27 Date.prototype.setTime (time)
1387
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.settime
1388
+ export const __Date_prototype_setTime = (_this: Date, time: any) => {
1389
+ // 1. Let dateObject be the this value.
1390
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1391
+ // 3. Let t be ? ToNumber(time).
1392
+ const t: number = Number(time);
1393
+
1394
+ // 4. Let v be TimeClip(t).
1395
+ const v: number = __ecma262_TimeClip(t);
1396
+
1397
+ // 5. Set dateObject.[[DateValue]] to v
1398
+ __Porffor_date_write(_this, v);
1399
+
1400
+ // 6. Return v.
1401
+ return v;
1402
+ };
1403
+
1404
+ // 21.4.4.28 Date.prototype.setUTCDate (date)
1405
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setutcdate
1406
+ export const __Date_prototype_setUTCDate = (_this: Date, date: any) => {
1407
+ // 1. Let dateObject be the this value.
1408
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1409
+ // 3. Let t be dateObject.[[DateValue]].
1410
+ const t: number = __Porffor_date_read(_this);
1411
+
1412
+ // 4. Let dt be ? ToNumber(date).
1413
+ const dt: number = Number(date);
1414
+
1415
+ // 5. If t is NaN, return NaN.
1416
+ if (Number.isNaN(t)) return NaN;
1417
+
1418
+ // 6. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
1419
+ const newDate: number = __ecma262_MakeDate(__ecma262_MakeDay(__ecma262_YearFromTime(t), __ecma262_MonthFromTime(t), dt), __ecma262_TimeWithinDay(t));
1420
+
1421
+ // 7. Let v be TimeClip(newDate).
1422
+ const v: number = __ecma262_TimeClip(newDate);
1423
+
1424
+ // 8. Set dateObject.[[DateValue]] to v.
1425
+ __Porffor_date_write(_this, v);
1426
+
1427
+ // 9. Return v.
1428
+ return v;
1429
+ };
1430
+
1431
+ // 21.4.4.29 Date.prototype.setUTCFullYear (year [, month [, date ]])
1432
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setutcfullyear
1433
+ export const __Date_prototype_setUTCFullYear = (_this: Date, year: any, month: any, date: any) => {
1434
+ // 1. Let dateObject be the this value.
1435
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1436
+ // 3. Let t be dateObject.[[DateValue]].
1437
+ let t: number = __Porffor_date_read(_this);
1438
+
1439
+ // 4. If t is NaN, set t to +0𝔽.
1440
+ if (Number.isNaN(t)) t = 0;
1441
+
1442
+ // 5. Let y be ? ToNumber(year).
1443
+ const y: number = Number(year);
1444
+
1445
+ // 6. If month is not present, let m be MonthFromTime(t); otherwise, let m be ? ToNumber(month).
1446
+ let m: number;
1447
+ if (Porffor.rawType(month) == Porffor.TYPES.undefined) m = __ecma262_MonthFromTime(t);
1448
+ else m = Number(month);
1449
+
1450
+ // 7. If date is not present, let dt be DateFromTime(t); otherwise, let dt be ? ToNumber(date).
1451
+ let dt: number;
1452
+ if (Porffor.rawType(date) == Porffor.TYPES.undefined) dt = __ecma262_DateFromTime(t);
1453
+ else dt = Number(date);
1454
+
1455
+ // 8. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
1456
+ const newDate: number = __ecma262_MakeDate(__ecma262_MakeDay(y, m, dt), __ecma262_TimeWithinDay(t));
1457
+
1458
+ // 9. Let v be TimeClip(newDate).
1459
+ const v: number = __ecma262_TimeClip(newDate);
1460
+
1461
+ // 10. Set dateObject.[[DateValue]] to v.
1462
+ __Porffor_date_write(_this, v);
1463
+
1464
+ // 11. Return v.
1465
+ return v;
1466
+ };
1467
+
1468
+ // 21.4.4.30 Date.prototype.setUTCHours (hour [, min [, sec [, ms ]]])
1469
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setutchours
1470
+ export const __Date_prototype_setUTCHours = (_this: Date, hour: any, min: any, sec: any, ms: any) => {
1471
+ // 1. Let dateObject be the this value.
1472
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1473
+ // 3. Let t be dateObject.[[DateValue]].
1474
+ let t: number = __Porffor_date_read(_this);
1475
+
1476
+ // 4. Let h be ? ToNumber(hour).
1477
+ const h: number = Number(hour);
1478
+
1479
+ // we reorder the spec steps in this func for easier arg handling
1480
+
1481
+ // 8. If t is NaN, return NaN.
1482
+ if (Number.isNaN(t)) return NaN;
1483
+
1484
+ // 5. If min is present, let m be ? ToNumber(min).
1485
+ let m: number;
1486
+ if (Porffor.rawType(min) != Porffor.TYPES.undefined) m = Number(min);
1487
+ // 9. If min is not present, let m be MinFromTime(t).
1488
+ else m = __ecma262_MinFromTime(t);
1489
+
1490
+ // 6. If sec is present, let s be ? ToNumber(sec).
1491
+ let s: number;
1492
+ if (Porffor.rawType(sec) != Porffor.TYPES.undefined) s = Number(sec);
1493
+ // 10. If sec is not present, let s be SecFromTime(t).
1494
+ else s = __ecma262_SecFromTime(t);
1495
+
1496
+ // 7. If ms is present, let milli be ? ToNumber(ms).
1497
+ let milli: number;
1498
+ if (Porffor.rawType(ms) != Porffor.TYPES.undefined) milli = Number(ms);
1499
+ // 11. If ms is not present, let milli be msFromTime(t).
1500
+ else milli = __ecma262_msFromTime(t);
1501
+
1502
+ // 12. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
1503
+ const date: number = __ecma262_MakeDate(__ecma262_Day(t), __ecma262_MakeTime(h, m, s, milli));
1504
+
1505
+ // 13. Let v be TimeClip(date).
1506
+ const v: number = __ecma262_TimeClip(date);
1507
+
1508
+ // 14. Set dateObject.[[DateValue]] to v.
1509
+ __Porffor_date_write(_this, v);
1510
+
1511
+ // 15. Return v.
1512
+ return v;
1513
+ };
1514
+
1515
+ // 21.4.4.31 Date.prototype.setUTCMilliseconds (ms)
1516
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setutcmilliseconds
1517
+ export const __Date_prototype_setUTCMilliseconds = (_this: Date, ms: any) => {
1518
+ // 1. Let dateObject be the this value.
1519
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1520
+ // 3. Let t be dateObject.[[DateValue]].
1521
+ let t: number = __Porffor_date_read(_this);
1522
+
1523
+ // ignore old-style spec setting arg instead of having let
1524
+ // 4. Set ms to ? ToNumber(ms).
1525
+ const milli: number = Number(ms);
1526
+
1527
+ // 5. If t is NaN, return NaN.
1528
+ if (Number.isNaN(t)) return NaN;
1529
+
1530
+ // 6. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
1531
+ const time: number = __ecma262_MakeTime(__ecma262_HourFromTime(t), __ecma262_MinFromTime(t), __ecma262_SecFromTime(t), milli);
1532
+
1533
+ // 7. Let v be TimeClip(MakeDate(Day(t), time)).
1534
+ const v: number = __ecma262_TimeClip(__ecma262_MakeDate(__ecma262_Day(t), time));
1535
+
1536
+ // 8. Set dateObject.[[DateValue]] to v.
1537
+ __Porffor_date_write(_this, v);
1538
+
1539
+ // 10. Return v.
1540
+ return v;
1541
+ };
1542
+
1543
+ // 21.4.4.32 Date.prototype.setUTCMinutes (min [, sec [, ms ]])
1544
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setutcminutes
1545
+ export const __Date_prototype_setUTCMinutes = (_this: Date, min: any, sec: any, ms: any) => {
1546
+ // 1. Let dateObject be the this value.
1547
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1548
+ // 3. Let t be dateObject.[[DateValue]].
1549
+ let t: number = __Porffor_date_read(_this);
1550
+
1551
+ // 4. Let m be ? ToNumber(min).
1552
+ const m: number = Number(min);
1553
+
1554
+ // we reorder the spec steps in this func for easier arg handling
1555
+
1556
+ // 7. If t is NaN, return NaN.
1557
+ if (Number.isNaN(t)) return NaN;
1558
+
1559
+ // 5. If sec is present, let s be ? ToNumber(sec).
1560
+ let s: number;
1561
+ if (Porffor.rawType(sec) != Porffor.TYPES.undefined) s = Number(sec);
1562
+ // 8. If sec is not present, let s be SecFromTime(t).
1563
+ else s = __ecma262_SecFromTime(t);
1564
+
1565
+ // 6. If ms is present, let milli be ? ToNumber(ms).
1566
+ let milli: number;
1567
+ if (Porffor.rawType(ms) != Porffor.TYPES.undefined) milli = Number(ms);
1568
+ // 9. If ms is not present, let milli be msFromTime(t).
1569
+ else milli = __ecma262_msFromTime(t);
1570
+
1571
+ // 10. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
1572
+ const date: number = __ecma262_MakeDate(__ecma262_Day(t), __ecma262_MakeTime(__ecma262_HourFromTime(t), m, s, milli));
1573
+
1574
+ // 11. Let v be TimeClip(date).
1575
+ const v: number = __ecma262_TimeClip(date);
1576
+
1577
+ // 12. Set dateObject.[[DateValue]] to v.
1578
+ __Porffor_date_write(_this, v);
1579
+
1580
+ // 13. Return v.
1581
+ return v;
1582
+ };
1583
+
1584
+ // 21.4.4.33 Date.prototype.setUTCMonth (month [, date ])
1585
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setutcmonth
1586
+ export const __Date_prototype_setUTCMonth = (_this: Date, month: any, date: any) => {
1587
+ // 1. Let dateObject be the this value.
1588
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1589
+ // 3. Let t be dateObject.[[DateValue]].
1590
+ let t: number = __Porffor_date_read(_this);
1591
+
1592
+ // 4. Let m be ? ToNumber(month).
1593
+ const m: number = Number(month);
1594
+
1595
+ // we reorder the spec steps in this func for easier arg handling
1596
+
1597
+ // 6. If t is NaN, return NaN.
1598
+ if (Number.isNaN(t)) return NaN;
1599
+
1600
+ // 5. If date is present, let dt be ? ToNumber(date).
1601
+ let dt: number;
1602
+ if (Porffor.rawType(date) != Porffor.TYPES.undefined) dt = Number(date);
1603
+ // 7. If date is not present, let dt be DateFromTime(t).
1604
+ else dt = __ecma262_DateFromTime(t);
1605
+
1606
+ // 8. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
1607
+ const newDate: number = __ecma262_MakeDate(__ecma262_MakeDay(__ecma262_YearFromTime(t), m, dt), __ecma262_TimeWithinDay(t));
1608
+
1609
+ // 9. Let v be TimeClip(newDate).
1610
+ const v: number = __ecma262_TimeClip(newDate);
1611
+
1612
+ // 10. Set dateObject.[[DateValue]] to v.
1613
+ __Porffor_date_write(_this, v);
1614
+
1615
+ // 11. Return v.
1616
+ return v;
1617
+ };
1618
+
1619
+ // 21.4.4.34 Date.prototype.setUTCSeconds (sec [, ms ])
1620
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.setutcseconds
1621
+ export const __Date_prototype_setUTCSeconds = (_this: Date, sec: any, ms: any) => {
1622
+ // 1. Let dateObject be the this value.
1623
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1624
+ // 3. Let t be dateObject.[[DateValue]].
1625
+ let t: number = __Porffor_date_read(_this);
1626
+
1627
+ // 4. Let s be ? ToNumber(sec).
1628
+ const s: number = Number(sec);
1629
+
1630
+ // we reorder the spec steps in this func for easier arg handling
1631
+
1632
+ // 6. If t is NaN, return NaN.
1633
+ if (Number.isNaN(t)) return NaN;
1634
+
1635
+ // 5. If ms is present, let milli be ? ToNumber(ms).
1636
+ let milli: number;
1637
+ if (Porffor.rawType(ms) != Porffor.TYPES.undefined) milli = Number(ms);
1638
+ // 7. If ms is not present, let milli be msFromTime(t).
1639
+ else milli = __ecma262_msFromTime(t);
1640
+
1641
+ // 8. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
1642
+ const date: number = __ecma262_MakeDate(__ecma262_Day(t), __ecma262_MakeTime(__ecma262_HourFromTime(t), __ecma262_MinFromTime(t), s, milli));
1643
+
1644
+ // 9. Let v be TimeClip(date).
1645
+ const v: number = __ecma262_TimeClip(date);
1646
+
1647
+ // 10. Set dateObject.[[DateValue]] to v.
1648
+ __Porffor_date_write(_this, v);
1649
+
1650
+ // 11. Return v.
1651
+ return v;
1652
+ };
1653
+
1654
+
1655
+ // 21.4.1.32 Date Time String Format
1656
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date-time-string-format
1657
+ // The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
1658
+ // YYYY is the year in the proleptic Gregorian calendar as four decimal digits from 0000 to 9999, or as an expanded year of "+" or "-" followed by six decimal digits.
1659
+ // - "-" (hyphen) appears literally twice in the string.
1660
+ // MM is the month of the year as two decimal digits from 01 (January) to 12 (December).
1661
+ // DD is the day of the month as two decimal digits from 01 to 31.
1662
+ // T "T" appears literally in the string, to indicate the beginning of the time element.
1663
+ // HH is the number of complete hours that have passed since midnight as two decimal digits from 00 to 24.
1664
+ // : ":" (colon) appears literally twice in the string.
1665
+ // mm is the number of complete minutes since the start of the hour as two decimal digits from 00 to 59.
1666
+ // ss is the number of complete seconds since the start of the minute as two decimal digits from 00 to 59.
1667
+ // . "." (dot) appears literally in the string.
1668
+ // sss is the number of complete milliseconds since the start of the second as three decimal digits.
1669
+ // Z is the UTC offset representation specified as "Z" (for UTC with no offset) or as either "+" or "-" followed by a time expression HH:mm (a subset of the time zone offset string format for indicating local time ahead of or behind UTC, respectively)
1670
+
1671
+ // fast appending string
1672
+ export const __Porffor_bytestring_appendStr = (str: bytestring, appendage: bytestring): i32 => {
1673
+ const strLen: i32 = str.length;
1674
+ const appendageLen: i32 = appendage.length;
1675
+ let strPtr: i32 = Porffor.wasm`local.get ${str}` + strLen;
1676
+ let appendagePtr: i32 = Porffor.wasm`local.get ${appendage}`;
1677
+ let endPtr: i32 = appendagePtr + appendageLen;
1678
+
1679
+ while (appendagePtr < endPtr) {
1680
+ Porffor.wasm.i32.store8(strPtr++, Porffor.wasm.i32.load8_u(appendagePtr++, 0, 4), 0, 4);
1681
+ }
1682
+
1683
+ str.length = strLen + appendageLen;
1684
+ return 1;
1685
+ };
1686
+
1687
+ // fast appending single character
1688
+ export const __Porffor_bytestring_appendChar = (str: bytestring, char: i32): i32 => {
1689
+ const len: i32 = str.length;
1690
+ Porffor.wasm.i32.store8(Porffor.wasm`local.get ${str}` + len, char, 0, 4);
1691
+ str.length = len + 1;
1692
+ return 1;
1693
+ };
1694
+
1695
+ // fast appending padded number
1696
+ export const __Porffor_bytestring_appendPadNum = (str: bytestring, num: number, len: number): i32 => {
1697
+ let numStr: bytestring = Number.prototype.toFixed(num, 0);
1698
+
1699
+ let strPtr: i32 = Porffor.wasm`local.get ${str}` + str.length;
1700
+
1701
+ let numStrLen: i32 = numStr.length;
1702
+ const strPtrEnd: i32 = strPtr + (len - numStrLen);
1703
+ while (strPtr < strPtrEnd) {
1704
+ Porffor.wasm.i32.store8(strPtr++, 48, 0, 4);
1705
+ }
1706
+
1707
+ let numPtr: i32 = Porffor.wasm`local.get ${numStr}`;
1708
+ const numPtrEnd: i32 = numPtr + numStrLen;
1709
+ while (numPtr < numPtrEnd) {
1710
+ Porffor.wasm.i32.store8(strPtr++, Porffor.wasm.i32.load8_u(numPtr++, 0, 4), 0, 4);
1711
+ }
1712
+
1713
+ str.length = strPtr - Porffor.wasm`local.get ${str}`;
1714
+
1715
+ return 1;
1716
+ };
1717
+
1718
+ // Timestamp to UTC DTSF
1719
+ export const __ecma262_ToUTCDTSF = (t: number): bytestring => {
1720
+ const year: number = __ecma262_YearFromTime(t);
1721
+
1722
+ let out: bytestring = '';
1723
+ out.length = 0;
1724
+
1725
+ if (Porffor.fastOr(year < 0, year >= 10000)) {
1726
+ // extended year format
1727
+ // sign
1728
+ __Porffor_bytestring_appendChar(out, year > 0 ? 43 : 45);
1729
+
1730
+ // 6 digit year
1731
+ __Porffor_bytestring_appendPadNum(out, year, 6);
1732
+ } else {
1733
+ // 4 digit year
1734
+ __Porffor_bytestring_appendPadNum(out, year, 4);
1735
+ }
1736
+ __Porffor_bytestring_appendChar(out, 45); // -
1737
+
1738
+ // 2 digit month (01-12)
1739
+ __Porffor_bytestring_appendPadNum(out, __ecma262_MonthFromTime(t) + 1, 2);
1740
+ __Porffor_bytestring_appendChar(out, 45); // -
1741
+
1742
+ // 2 digit day of the month
1743
+ __Porffor_bytestring_appendPadNum(out, __ecma262_DateFromTime(t), 2);
1744
+ __Porffor_bytestring_appendChar(out, 84); // T
1745
+
1746
+ // 2 digit hour
1747
+ __Porffor_bytestring_appendPadNum(out, __ecma262_HourFromTime(t), 2);
1748
+ __Porffor_bytestring_appendChar(out, 58); // :
1749
+
1750
+ // 2 digit minute
1751
+ __Porffor_bytestring_appendPadNum(out, __ecma262_MinFromTime(t), 2);
1752
+ __Porffor_bytestring_appendChar(out, 58); // :
1753
+
1754
+ // 2 digit second
1755
+ __Porffor_bytestring_appendPadNum(out, __ecma262_SecFromTime(t), 2);
1756
+ __Porffor_bytestring_appendChar(out, 46); // .
1757
+
1758
+ // 3 digit millisecond
1759
+ __Porffor_bytestring_appendPadNum(out, __ecma262_msFromTime(t), 3);
1760
+ __Porffor_bytestring_appendChar(out, 90); // Z
1761
+
1762
+ return out;
1763
+ };
1764
+
1765
+ // 21.4.4.36 Date.prototype.toISOString ()
1766
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.toisostring
1767
+ export const __Date_prototype_toISOString = (_this: Date) => {
1768
+ // 1. Let dateObject be the this value.
1769
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1770
+ // 3. Let tv be dateObject.[[DateValue]].
1771
+ const tv: number = __Porffor_date_read(_this);
1772
+
1773
+ // 4. If tv is NaN, throw a RangeError exception.
1774
+ if (Number.isNaN(tv)) {
1775
+ throw new RangeError('Invalid time value');
1776
+ }
1777
+
1778
+ // 5. Assert: tv is an integral Number.
1779
+
1780
+ // 6. If tv corresponds with a year that cannot be represented in the Date Time String Format, throw a RangeError exception.
1781
+ // todo
1782
+
1783
+ // 7. Return a String representation of tv in the Date Time String Format on the UTC time scale, including all format elements and the UTC offset representation "Z".
1784
+ return __ecma262_ToUTCDTSF(tv);
1785
+ };
1786
+
1787
+ // 21.4.4.37 Date.prototype.toJSON (key)
1788
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.tojson
1789
+ export const __Date_prototype_toJSON = (_this: Date, key: any) => {
1790
+ // 1. Let O be ? ToObject(this value).
1791
+ // 2. Let tv be ? ToPrimitive(O, number).
1792
+ // todo: use generic Number() once it supports Date
1793
+ const tv: number = __Porffor_date_read(_this);
1794
+
1795
+ // 3. If tv is a Number and tv is not finite, return null.
1796
+ if (!Number.isFinite(tv)) return null;
1797
+
1798
+ // 4. Return ? Invoke(O, "toISOString").
1799
+ return __Date_prototype_toISOString(_this);
1800
+ };
1801
+
1802
+
1803
+ // 21.4.4.41.1 TimeString (tv)
1804
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-timestring
1805
+ export const __ecma262_TimeString = (tv: number): bytestring => {
1806
+ // we do not follow spec exactly by using number vars and appending at the end
1807
+
1808
+ // 1. Let hour be ToZeroPaddedDecimalString(ℝ(HourFromTime(tv)), 2).
1809
+ const hour: number = __ecma262_HourFromTime(tv);
1810
+
1811
+ // 2. Let minute be ToZeroPaddedDecimalString(ℝ(MinFromTime(tv)), 2).
1812
+ const minute: number = __ecma262_MinFromTime(tv);
1813
+
1814
+ // 3. Let second be ToZeroPaddedDecimalString(ℝ(SecFromTime(tv)), 2).
1815
+ const second: number = __ecma262_SecFromTime(tv);
1816
+
1817
+ // 4. Return the string-concatenation of hour, ":", minute, ":", second, the code unit 0x0020 (SPACE), and "GMT".
1818
+ let out: bytestring = '';
1819
+ out.length = 0;
1820
+
1821
+ __Porffor_bytestring_appendPadNum(out, hour, 2);
1822
+ __Porffor_bytestring_appendChar(out, 58); // ':'
1823
+
1824
+ __Porffor_bytestring_appendPadNum(out, minute, 2);
1825
+ __Porffor_bytestring_appendChar(out, 58); // ':'
1826
+
1827
+ __Porffor_bytestring_appendPadNum(out, second, 2);
1828
+
1829
+ __Porffor_bytestring_appendChar(out, 32); // ' '
1830
+ __Porffor_bytestring_appendChar(out, 71); // 'G'
1831
+ __Porffor_bytestring_appendChar(out, 77); // 'M'
1832
+ __Porffor_bytestring_appendChar(out, 84); // 'T'
1833
+
1834
+ return out;
1835
+ };
1836
+
1837
+ // 21.4.4.41.2 DateString (tv)
1838
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-datestring
1839
+ export const __ecma262_DateString = (tv: number): bytestring => {
1840
+ // we do not follow spec exactly by using number vars and appending at the end
1841
+
1842
+ // 1. Let weekday be the Name of the entry in Table 62 with the Number WeekDay(tv).
1843
+ const weekday: bytestring = __ecma262_WeekDayName(tv);
1844
+
1845
+ // 2. Let month be the Name of the entry in Table 63 with the Number MonthFromTime(tv).
1846
+ const month: bytestring = __ecma262_MonthName(tv);
1847
+
1848
+ // 3. Let day be ToZeroPaddedDecimalString(ℝ(DateFromTime(tv)), 2).
1849
+ const day: number = __ecma262_DateFromTime(tv);
1850
+
1851
+ // 4. Let yv be YearFromTime(tv).
1852
+ const yv: number = __ecma262_YearFromTime(tv);
1853
+
1854
+ // 5. If yv is +0𝔽 or yv > +0𝔽, let yearSign be the empty String; otherwise, let yearSign be "-".
1855
+ // 6. Let paddedYear be ToZeroPaddedDecimalString(abs(ℝ(yv)), 4).
1856
+ // 7. Return the string-concatenation of weekday, the code unit 0x0020 (SPACE), month, the code unit 0x0020 (SPACE), day, the code unit 0x0020 (SPACE), yearSign, and paddedYear.
1857
+ let out: bytestring = '';
1858
+ out.length = 0;
1859
+
1860
+ // weekday
1861
+ __Porffor_bytestring_appendStr(out, weekday);
1862
+ __Porffor_bytestring_appendChar(out, 32); // ' '
1863
+
1864
+ // month
1865
+ __Porffor_bytestring_appendStr(out, month);
1866
+ __Porffor_bytestring_appendChar(out, 32); // ' '
1867
+
1868
+ // day
1869
+ __Porffor_bytestring_appendPadNum(out, day, 2);
1870
+ __Porffor_bytestring_appendChar(out, 32); // ' '
1871
+
1872
+ // year
1873
+ if (yv < 0) __Porffor_bytestring_appendChar(out, 45); // sign
1874
+ __Porffor_bytestring_appendPadNum(out, yv, 4);
1875
+
1876
+ return out;
1877
+ };
1878
+
1879
+ // 21.4.4.41.3 TimeZoneString (tv)
1880
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-timezonestring
1881
+ export const __ecma262_TimeZoneString = (tv: number) => {
1882
+ // todo: time zone support
1883
+ let out: bytestring = '+0000 (UTC)';
1884
+ return out;
1885
+ };
1886
+
1887
+ // 21.4.4.41.4 ToDateString (tv)
1888
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-todatestring
1889
+ export const __ecma262_ToDateString = (tv: number) => {
1890
+ let out: bytestring = '';
1891
+ out.length = 0;
1892
+
1893
+ // 1. If tv is NaN, return "Invalid Date".
1894
+ if (Number.isNaN(tv)) {
1895
+ out = 'Invalid Date';
1896
+ return out;
1897
+ }
1898
+
1899
+ // 2. Let t be LocalTime(tv).
1900
+ const t: number = __ecma262_LocalTime(tv);
1901
+
1902
+ // 3. Return the string-concatenation of DateString(t), the code unit 0x0020 (SPACE), TimeString(t), and TimeZoneString(tv).
1903
+ __Porffor_bytestring_appendStr(out, __ecma262_DateString(t));
1904
+ __Porffor_bytestring_appendChar(out, 32);
1905
+
1906
+ __Porffor_bytestring_appendStr(out, __ecma262_TimeString(t));
1907
+
1908
+ __Porffor_bytestring_appendStr(out, __ecma262_TimeZoneString(tv));
1909
+
1910
+ return out;
1911
+ };
1912
+
1913
+ // 21.4.4.41 Date.prototype.toString ()
1914
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.tostring
1915
+ export const __Date_prototype_toString = (_this: Date) => {
1916
+ // 1. Let dateObject be the this value.
1917
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1918
+ // 3. Let tv be dateObject.[[DateValue]].
1919
+ const tv: number = __Porffor_date_read(_this);
1920
+
1921
+ // 4. Return ToDateString(tv).
1922
+ return __ecma262_ToDateString(tv);
1923
+ };
1924
+
1925
+ // 21.4.4.42 Date.prototype.toTimeString ()
1926
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.totimestring
1927
+ export const __Date_prototype_toTimeString = (_this: Date) => {
1928
+ // 1. Let dateObject be the this value.
1929
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1930
+ // 3. Let tv be dateObject.[[DateValue]].
1931
+ const tv: number = __Porffor_date_read(_this);
1932
+
1933
+ // 4. If tv is NaN, return "Invalid Date".
1934
+ let out: bytestring = '';
1935
+ out.length = 0;
1936
+
1937
+ if (Number.isNaN(tv)) {
1938
+ out = 'Invalid Date';
1939
+ return out;
1940
+ }
1941
+
1942
+ // 5. Let t be LocalTime(tv).
1943
+ const t: number = __ecma262_LocalTime(tv);
1944
+
1945
+ // 6. Return the string-concatenation of TimeString(t) and TimeZoneString(tv).
1946
+ __Porffor_bytestring_appendStr(out, __ecma262_TimeString(t));
1947
+ __Porffor_bytestring_appendStr(out, __ecma262_TimeZoneString(tv));
1948
+
1949
+ return out;
1950
+ };
1951
+
1952
+
1953
+ // 21.4.4.35 Date.prototype.toDateString ()
1954
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.todatestring
1955
+ export const __Date_prototype_toDateString = (_this: Date) => {
1956
+ // 1. Let dateObject be the this value.
1957
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1958
+ // 3. Let tv be dateObject.[[DateValue]].
1959
+ const tv: number = __Porffor_date_read(_this);
1960
+
1961
+ // 4. If tv is NaN, return "Invalid Date".
1962
+ let out: bytestring = '';
1963
+ out.length = 0;
1964
+
1965
+ if (Number.isNaN(tv)) {
1966
+ out = 'Invalid Date';
1967
+ return out;
1968
+ }
1969
+
1970
+ // 5. Let t be LocalTime(tv).
1971
+ const t: number = __ecma262_LocalTime(tv);
1972
+
1973
+ // 6. Return DateString(t).
1974
+ out = __ecma262_DateString(t);
1975
+ return out;
1976
+ };
1977
+
1978
+ // 21.4.4.43 Date.prototype.toUTCString ()
1979
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.toutcstring
1980
+ export const __Date_prototype_toUTCString = (_this: Date) => {
1981
+ // 1. Let dateObject be the this value.
1982
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
1983
+ // 3. Let tv be dateObject.[[DateValue]].
1984
+ const tv: number = __Porffor_date_read(_this);
1985
+
1986
+ // 4. If tv is NaN, return "Invalid Date".
1987
+ let out: bytestring = '';
1988
+ out.length = 0;
1989
+
1990
+ if (Number.isNaN(tv)) {
1991
+ out = 'Invalid Date';
1992
+ return out;
1993
+ }
1994
+
1995
+ // 5. Let weekday be the Name of the entry in Table 62 with the Number WeekDay(tv).
1996
+ const weekday: bytestring = __ecma262_WeekDayName(tv);
1997
+
1998
+ // 6. Let month be the Name of the entry in Table 63 with the Number MonthFromTime(tv).
1999
+ const month: bytestring = __ecma262_MonthName(tv);
2000
+
2001
+ // 7. Let day be ToZeroPaddedDecimalString(ℝ(DateFromTime(tv)), 2).
2002
+ const day: number = __ecma262_DateFromTime(tv);
2003
+
2004
+ // 8. Let yv be YearFromTime(tv).
2005
+ const yv: number = __ecma262_YearFromTime(tv);
2006
+
2007
+ // 9. If yv is +0𝔽 or yv > +0𝔽, let yearSign be the empty String; otherwise, let yearSign be "-".
2008
+ // 10. Let paddedYear be ToZeroPaddedDecimalString(abs(ℝ(yv)), 4).
2009
+ // 11. Return the string-concatenation of weekday, ",", the code unit 0x0020 (SPACE), day, the code unit 0x0020 (SPACE), month, the code unit 0x0020 (SPACE), yearSign, paddedYear, the code unit 0x0020 (SPACE), and TimeString(tv).
2010
+ // weekday
2011
+ __Porffor_bytestring_appendStr(out, weekday);
2012
+ __Porffor_bytestring_appendChar(out, 44); // ','
2013
+ __Porffor_bytestring_appendChar(out, 32); // ' '
2014
+
2015
+ // day
2016
+ __Porffor_bytestring_appendPadNum(out, day, 2);
2017
+ __Porffor_bytestring_appendChar(out, 32); // ' '
2018
+
2019
+ // month
2020
+ __Porffor_bytestring_appendStr(out, month);
2021
+ __Porffor_bytestring_appendChar(out, 32); // ' '
2022
+
2023
+ // year
2024
+ if (yv < 0) __Porffor_bytestring_appendChar(out, 45); // sign
2025
+ __Porffor_bytestring_appendPadNum(out, yv, 4);
2026
+
2027
+ __Porffor_bytestring_appendChar(out, 32); // ' '
2028
+ __Porffor_bytestring_appendStr(out, __ecma262_TimeString(tv));
2029
+
2030
+ return out;
2031
+ };
2032
+
2033
+ // 21.4.4.38 Date.prototype.toLocaleDateString ([ reserved1 [, reserved2 ]])
2034
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.tolocaledatestring
2035
+ export const __Date_prototype_toLocaleDateString = (_this: Date, reserved1: any, reserved2: any) => {
2036
+ return __Date_prototype_toDateString(_this);
2037
+ };
2038
+
2039
+ // 21.4.4.39 Date.prototype.toLocaleString ([ reserved1 [, reserved2 ]])
2040
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.tolocalestring
2041
+ export const __Date_prototype_toLocaleString = (_this: Date, reserved1: any, reserved2: any) => {
2042
+ return __Date_prototype_toString(_this);
2043
+ };
2044
+
2045
+ // 21.4.4.40 Date.prototype.toLocaleTimeString ([ reserved1 [, reserved2 ]])
2046
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date.prototype.tolocaletimestring
2047
+ export const __Date_prototype_toLocaleTimeString = (_this: Date, reserved1: any, reserved2: any) => {
2048
+ return __Date_prototype_toTimeString(_this);
2049
+ };
2050
+
2051
+ // 21.4.4.44 Date.prototype.valueOf ()
2052
+ // https://tc39.es/ecma262/#sec-date.prototype.valueof
2053
+ export const __Date_prototype_valueOf = (_this: Date) => {
2054
+ // 1. Let dateObject be the this value.
2055
+ // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
2056
+ // 3. Return dateObject.[[DateValue]].
2057
+ return __Porffor_date_read(_this);
2058
+ };
2059
+
2060
+ // 21.4.2.1 Date (...values)
2061
+ // https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-date
2062
+ export const Date = (): bytestring => {
2063
+ // 1. If NewTarget is undefined, then
2064
+ // a. Let now be the time value (UTC) identifying the current time.
2065
+ // b. Return ToDateString(now).
2066
+ return __ecma262_ToDateString(__Date_now());
2067
+ };