@ugo-studio/jspp 0.3.0 → 0.3.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.
Files changed (95) hide show
  1. package/LICENSE +25 -25
  2. package/README.md +20 -12
  3. package/dist/analysis/scope.js +5 -3
  4. package/dist/analysis/typeAnalyzer.js +21 -25
  5. package/dist/cli/index.js +14 -4
  6. package/dist/cli/utils.js +61 -0
  7. package/dist/core/codegen/control-flow-handlers.js +10 -9
  8. package/dist/core/codegen/declaration-handlers.js +10 -3
  9. package/dist/core/codegen/destructuring-handlers.js +9 -4
  10. package/dist/core/codegen/expression-handlers.js +40 -29
  11. package/dist/core/codegen/function-handlers.js +78 -12
  12. package/dist/core/codegen/helpers.js +91 -14
  13. package/dist/core/codegen/index.js +4 -2
  14. package/dist/core/codegen/statement-handlers.js +8 -6
  15. package/package.json +2 -2
  16. package/scripts/precompile-headers.ts +249 -50
  17. package/scripts/setup-compiler.ts +63 -63
  18. package/src/prelude/any_value.cpp +636 -0
  19. package/src/prelude/any_value.hpp +23 -16
  20. package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
  21. package/src/prelude/exception.hpp +27 -27
  22. package/src/prelude/iterator_instantiations.hpp +10 -0
  23. package/src/prelude/{index.hpp → jspp.hpp} +10 -16
  24. package/src/prelude/library/array.cpp +191 -0
  25. package/src/prelude/library/array.hpp +5 -178
  26. package/src/prelude/library/console.cpp +125 -0
  27. package/src/prelude/library/console.hpp +9 -97
  28. package/src/prelude/library/error.cpp +100 -0
  29. package/src/prelude/library/error.hpp +8 -108
  30. package/src/prelude/library/function.cpp +69 -0
  31. package/src/prelude/library/function.hpp +6 -5
  32. package/src/prelude/library/global.cpp +96 -0
  33. package/src/prelude/library/global.hpp +12 -28
  34. package/src/prelude/library/global_usings.hpp +15 -0
  35. package/src/prelude/library/math.cpp +258 -0
  36. package/src/prelude/library/math.hpp +6 -288
  37. package/src/prelude/library/object.cpp +379 -0
  38. package/src/prelude/library/object.hpp +5 -267
  39. package/src/prelude/library/performance.cpp +21 -0
  40. package/src/prelude/library/performance.hpp +5 -20
  41. package/src/prelude/library/process.cpp +38 -0
  42. package/src/prelude/library/process.hpp +3 -31
  43. package/src/prelude/library/promise.cpp +131 -0
  44. package/src/prelude/library/promise.hpp +5 -116
  45. package/src/prelude/library/symbol.cpp +56 -0
  46. package/src/prelude/library/symbol.hpp +5 -46
  47. package/src/prelude/library/timer.cpp +88 -0
  48. package/src/prelude/library/timer.hpp +11 -87
  49. package/src/prelude/runtime.cpp +19 -0
  50. package/src/prelude/types.hpp +17 -12
  51. package/src/prelude/utils/access.hpp +122 -31
  52. package/src/prelude/utils/assignment_operators.hpp +99 -99
  53. package/src/prelude/utils/log_any_value/array.hpp +61 -40
  54. package/src/prelude/utils/log_any_value/function.hpp +39 -39
  55. package/src/prelude/utils/log_any_value/object.hpp +60 -3
  56. package/src/prelude/utils/operators.hpp +25 -10
  57. package/src/prelude/utils/operators_primitive.hpp +336 -336
  58. package/src/prelude/utils/well_known_symbols.hpp +24 -24
  59. package/src/prelude/values/array.cpp +1399 -0
  60. package/src/prelude/values/array.hpp +4 -0
  61. package/src/prelude/values/async_iterator.cpp +251 -0
  62. package/src/prelude/values/async_iterator.hpp +60 -32
  63. package/src/prelude/values/function.cpp +262 -0
  64. package/src/prelude/values/function.hpp +10 -30
  65. package/src/prelude/values/iterator.cpp +309 -0
  66. package/src/prelude/values/iterator.hpp +33 -64
  67. package/src/prelude/values/number.cpp +176 -0
  68. package/src/prelude/values/object.cpp +159 -0
  69. package/src/prelude/values/object.hpp +4 -0
  70. package/src/prelude/values/promise.cpp +479 -0
  71. package/src/prelude/values/promise.hpp +9 -2
  72. package/src/prelude/values/prototypes/array.hpp +46 -1348
  73. package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
  74. package/src/prelude/values/prototypes/function.hpp +7 -46
  75. package/src/prelude/values/prototypes/iterator.hpp +15 -191
  76. package/src/prelude/values/prototypes/number.hpp +23 -210
  77. package/src/prelude/values/prototypes/object.hpp +7 -23
  78. package/src/prelude/values/prototypes/promise.hpp +8 -186
  79. package/src/prelude/values/prototypes/string.hpp +28 -553
  80. package/src/prelude/values/prototypes/symbol.hpp +9 -70
  81. package/src/prelude/values/shape.hpp +52 -52
  82. package/src/prelude/values/string.cpp +485 -0
  83. package/src/prelude/values/symbol.cpp +89 -0
  84. package/src/prelude/values/symbol.hpp +101 -101
  85. package/src/prelude/any_value_access.hpp +0 -170
  86. package/src/prelude/any_value_defines.hpp +0 -190
  87. package/src/prelude/any_value_helpers.hpp +0 -374
  88. package/src/prelude/values/helpers/array.hpp +0 -199
  89. package/src/prelude/values/helpers/async_iterator.hpp +0 -275
  90. package/src/prelude/values/helpers/function.hpp +0 -109
  91. package/src/prelude/values/helpers/iterator.hpp +0 -145
  92. package/src/prelude/values/helpers/object.hpp +0 -104
  93. package/src/prelude/values/helpers/promise.hpp +0 -254
  94. package/src/prelude/values/helpers/string.hpp +0 -37
  95. package/src/prelude/values/helpers/symbol.hpp +0 -21
@@ -1,1358 +1,56 @@
1
1
  #pragma once
2
2
 
3
3
  #include "types.hpp"
4
- #include "values/array.hpp"
5
- #include "any_value.hpp"
6
- #include "exception.hpp"
7
- #include "utils/operators.hpp"
8
- #include <algorithm>
9
- #include <vector>
4
+ #include <optional>
10
5
 
11
6
  namespace jspp
12
7
  {
8
+ class AnyValue;
9
+
13
10
  namespace ArrayPrototypes
14
11
  {
15
- inline AnyValue &get_toString_fn()
16
- {
17
- static AnyValue fn = AnyValue::make_function([](const AnyValue &thisVal, std::span<const AnyValue> _) -> AnyValue
18
- { return AnyValue::make_string(thisVal.as_array()->to_std_string()); },
19
- "toString");
20
- return fn;
21
- }
22
-
23
- inline AnyValue &get_iterator_fn()
24
- {
25
- static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> _) -> jspp::JsIterator<jspp::AnyValue>
26
- {
27
- auto arr = thisVal.as_array();
28
- for (uint64_t idx = 0; idx < arr->length; ++idx)
29
- {
30
- co_yield arr->get_property(static_cast<uint32_t>(idx));
31
- }
32
- co_return Constants::UNDEFINED; },
33
- "Symbol.iterator");
34
- return fn;
35
- }
36
-
37
- inline AnyValue &get_length_desc()
38
- {
39
- static auto getter = [](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
40
- {
41
- return AnyValue::make_number(thisVal.as_array()->length);
42
- };
43
-
44
- static auto setter = [](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
45
- {
46
- if (args.empty())
47
- {
48
- return Constants::UNDEFINED;
49
- }
50
-
51
- auto self = thisVal.as_array();
52
- const auto &new_len_val = args[0];
53
- double new_len_double = Operators_Private::ToNumber(new_len_val);
54
-
55
- if (new_len_double < 0 || std::isnan(new_len_double) || std::isinf(new_len_double) || new_len_double != static_cast<uint64_t>(new_len_double))
56
- {
57
- throw Exception::make_exception("Invalid array length", "RangeError");
58
- }
59
- uint64_t new_len = static_cast<uint64_t>(new_len_double);
60
-
61
- // Truncate dense part
62
- if (new_len < self->dense.size())
63
- {
64
- self->dense.resize(new_len);
65
- }
66
-
67
- // Remove sparse elements beyond the new length
68
- for (auto it = self->sparse.begin(); it != self->sparse.end();)
69
- {
70
- if (it->first >= new_len)
71
- {
72
- it = self->sparse.erase(it);
73
- }
74
- else
75
- {
76
- ++it;
77
- }
78
- }
79
-
80
- self->length = new_len;
81
- return new_len_val;
82
- };
83
-
84
- static AnyValue desc = AnyValue::make_accessor_descriptor(getter,
85
- setter,
86
- false,
87
- false);
88
- return desc;
89
- }
90
-
91
- inline AnyValue &get_push_fn()
92
- {
93
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
94
- {
95
- auto self = thisVal.as_array();
96
- for (const auto &arg : args)
97
- {
98
- self->set_property(static_cast<uint32_t>(self->length), arg);
99
- }
100
- return AnyValue::make_number(self->length); },
101
- "push");
102
- return fn;
103
- }
104
-
105
- inline AnyValue &get_pop_fn()
106
- {
107
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
108
- {
109
- auto self = thisVal.as_array();
110
- if (self->length == 0)
111
- {
112
- return Constants::UNDEFINED;
113
- }
114
- uint64_t last_idx = self->length - 1;
115
- AnyValue last_val = self->get_property(static_cast<uint32_t>(last_idx));
116
-
117
- // Remove from dense
118
- if (last_idx < self->dense.size())
119
- {
120
- self->dense.pop_back();
121
- }
122
- // Remove from sparse
123
- self->sparse.erase(static_cast<uint32_t>(last_idx));
124
-
125
- self->length--;
126
- return last_val; },
127
- "pop");
128
- return fn;
129
- }
130
-
131
- inline AnyValue &get_shift_fn()
132
- {
133
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
134
- {
135
- auto self = thisVal.as_array();
136
- if (self->length == 0)
137
- {
138
- return Constants::UNDEFINED;
139
- }
140
- AnyValue first_val = self->get_property(0u);
141
-
142
- // Shift all elements to the left
143
- for (uint64_t i = 0; i < self->length - 1; ++i)
144
- {
145
- self->set_property(static_cast<uint32_t>(i), self->get_property(static_cast<uint32_t>(i + 1)));
146
- }
147
-
148
- // remove last element
149
- uint64_t last_idx = self->length - 1;
150
- if (last_idx < self->dense.size())
151
- {
152
- self->dense.pop_back();
153
- }
154
- self->sparse.erase(static_cast<uint32_t>(last_idx));
155
-
156
- self->length--;
157
-
158
- return first_val; },
159
- "shift");
160
- return fn;
161
- }
162
-
163
- inline AnyValue &get_unshift_fn()
164
- {
165
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
166
- {
167
- auto self = thisVal.as_array();
168
- size_t args_count = args.size();
169
- if (args_count == 0)
170
- {
171
- return AnyValue::make_number(self->length);
172
- }
173
-
174
- // Shift existing elements to the right
175
- for (uint64_t i = self->length; i > 0; --i)
176
- {
177
- self->set_property(static_cast<uint32_t>(i + args_count - 1), self->get_property(static_cast<uint32_t>(i - 1)));
178
- }
179
-
180
- // Insert new elements at the beginning
181
- for (size_t i = 0; i < args_count; ++i)
182
- {
183
- self->set_property(static_cast<uint32_t>(i), args[i]);
184
- }
185
-
186
- return AnyValue::make_number(self->length); },
187
- "unshift");
188
- return fn;
189
- }
190
-
191
- inline AnyValue &get_join_fn()
192
- {
193
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
194
- {
195
- auto self = thisVal.as_array();
196
- std::string sep = ",";
197
- if (!args.empty() && !args[0].is_undefined())
198
- {
199
- sep = args[0].to_std_string();
200
- }
201
-
202
- std::string result = "";
203
- for (uint64_t i = 0; i < self->length; ++i)
204
- {
205
- AnyValue item = self->get_property(static_cast<uint32_t>(i));
206
- if (!item.is_undefined() && !item.is_null())
207
- {
208
- result += item.to_std_string();
209
- }
210
- if (i < self->length - 1)
211
- {
212
- result += sep;
213
- }
214
- }
215
- return AnyValue::make_string(result); },
216
- "join");
217
- return fn;
218
- }
219
-
220
- inline AnyValue &get_forEach_fn()
221
- {
222
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
223
- {
224
- auto self = thisVal.as_array();
225
- if (args.empty() || !args[0].is_function())
226
- {
227
- throw Exception::make_exception("callback is not a function", "TypeError");
228
- }
229
- auto callback = args[0].as_function();
230
- for (uint64_t i = 0; i < self->length; ++i)
231
- {
232
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
233
- if (!val.is_undefined())
234
- { // forEach skips empty slots
235
- AnyValue iVal = AnyValue::make_number(i);
236
- const AnyValue cbArgs[] = {val, iVal, thisVal};
237
- callback->call(thisVal, cbArgs);
238
- }
239
- }
240
- return Constants::UNDEFINED; },
241
- "forEach");
242
- return fn;
243
- }
244
-
245
- inline AnyValue &get_at_fn()
246
- {
247
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
248
- {
249
- auto self = thisVal.as_array();
250
- double len = static_cast<double>(self->length);
251
- double relativeIndex = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
252
- double k;
253
- if (relativeIndex >= 0) k = relativeIndex;
254
- else k = len + relativeIndex;
255
- if (k < 0 || k >= len) return Constants::UNDEFINED;
256
- return self->get_property(static_cast<uint32_t>(k)); },
257
- "at");
258
- return fn;
259
- }
260
-
261
- inline AnyValue &get_includes_fn()
262
- {
263
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
264
- {
265
- auto self = thisVal.as_array();
266
- AnyValue searchElement = args.empty() ? Constants::UNDEFINED : args[0];
267
- double len = static_cast<double>(self->length);
268
- if (len == 0) return Constants::FALSE;
269
- double n = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : 0;
270
- double k;
271
- if (n >= 0) k = n;
272
- else k = len + n;
273
- if (k < 0) k = 0;
274
-
275
- for (uint64_t i = static_cast<uint64_t>(k); i < self->length; ++i)
276
- {
277
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
278
- // SameValueZero algorithm (includes handles NaN)
279
- if (element.is_number() && searchElement.is_number() && std::isnan(element.as_double()) && std::isnan(searchElement.as_double())) return Constants::TRUE;
280
- if (is_strictly_equal_to_primitive(element, searchElement)) return Constants::TRUE;
281
- }
282
- return Constants::FALSE; },
283
- "includes");
284
- return fn;
285
- }
286
-
287
- inline AnyValue &get_indexOf_fn()
288
- {
289
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
290
- {
291
- auto self = thisVal.as_array();
292
- AnyValue searchElement = args.empty() ? Constants::UNDEFINED : args[0];
293
- double len = static_cast<double>(self->length);
294
- if (len == 0) return AnyValue::make_number(-1);
295
- double n = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : 0;
296
- double k;
297
- if (n >= 0) k = n;
298
- else k = len + n;
299
- if (k < 0) k = 0;
300
-
301
- for (uint64_t i = static_cast<uint64_t>(k); i < self->length; ++i)
302
- {
303
- if (self->has_property(std::to_string(i))) {
304
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
305
- if (is_strictly_equal_to_primitive(element, searchElement)) return AnyValue::make_number(i);
306
- }
307
- }
308
- return AnyValue::make_number(-1); },
309
- "indexOf");
310
- return fn;
311
- }
312
-
313
- inline AnyValue &get_lastIndexOf_fn()
314
- {
315
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
316
- {
317
- auto self = thisVal.as_array();
318
- AnyValue searchElement = args.empty() ? Constants::UNDEFINED : args[0];
319
- double len = static_cast<double>(self->length);
320
- if (len == 0) return AnyValue::make_number(-1);
321
- double n = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : len - 1;
322
- double k;
323
- if (n >= 0) k = std::min(n, len - 1);
324
- else k = len + n;
325
-
326
- if (k < 0) return AnyValue::make_number(-1);
327
-
328
- for (int64_t i = static_cast<int64_t>(k); i >= 0; --i)
329
- {
330
- if (self->has_property(std::to_string(i))) {
331
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
332
- if (is_strictly_equal_to_primitive(element, searchElement)) return AnyValue::make_number(i);
333
- }
334
- }
335
- return AnyValue::make_number(-1); },
336
- "lastIndexOf");
337
- return fn;
338
- }
339
-
340
- inline AnyValue &get_find_fn()
341
- {
342
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
343
- {
344
- auto self = thisVal.as_array();
345
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
346
- auto callback = args[0].as_function();
347
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
348
-
349
- for (uint64_t i = 0; i < self->length; ++i)
350
- {
351
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
352
- AnyValue kVal = AnyValue::make_number(i);
353
- const AnyValue cbArgs[] = {element, kVal, thisVal};
354
-
355
- if (is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
356
- return element;
357
- }
358
- }
359
- return Constants::UNDEFINED; },
360
- "find");
361
- return fn;
362
- }
363
-
364
- inline AnyValue &get_findIndex_fn()
365
- {
366
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
367
- {
368
- auto self = thisVal.as_array();
369
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
370
- auto callback = args[0].as_function();
371
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
372
-
373
- for (uint64_t i = 0; i < self->length; ++i)
374
- {
375
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
376
- AnyValue kVal = AnyValue::make_number(i);
377
- const AnyValue cbArgs[] = {element, kVal, thisVal};
378
-
379
- if (is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
380
- return AnyValue::make_number(i);
381
- }
382
- }
383
- return AnyValue::make_number(-1); },
384
- "findIndex");
385
- return fn;
386
- }
387
-
388
- inline AnyValue &get_findLast_fn()
389
- {
390
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
391
- {
392
- auto self = thisVal.as_array();
393
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
394
- auto callback = args[0].as_function();
395
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
396
-
397
- for (int64_t i = self->length - 1; i >= 0; --i)
398
- {
399
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
400
- AnyValue kVal = AnyValue::make_number(i);
401
- const AnyValue cbArgs[] = {element, kVal, thisVal};
402
-
403
- if (is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
404
- return element;
405
- }
406
- }
407
- return Constants::UNDEFINED; },
408
- "findLast");
409
- return fn;
410
- }
411
-
412
- inline AnyValue &get_findLastIndex_fn()
413
- {
414
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
415
- {
416
- auto self = thisVal.as_array();
417
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
418
- auto callback = args[0].as_function();
419
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
420
-
421
- for (int64_t i = self->length - 1; i >= 0; --i)
422
- {
423
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
424
- AnyValue kVal = AnyValue::make_number(i);
425
- const AnyValue cbArgs[] = {element, kVal, thisVal};
426
-
427
- if (is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
428
- return AnyValue::make_number(i);
429
- }
430
- }
431
- return AnyValue::make_number(-1); },
432
- "findLastIndex");
433
- return fn;
434
- }
435
-
436
- inline AnyValue &get_values_fn()
437
- {
438
- static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> _) -> jspp::JsIterator<jspp::AnyValue>
439
- {
440
- auto arr = thisVal.as_array();
441
- for (uint64_t idx = 0; idx < arr->length; ++idx)
442
- {
443
- co_yield arr->get_property(static_cast<uint32_t>(idx));
444
- }
445
- co_return Constants::UNDEFINED; },
446
- "values");
447
- return fn;
448
- }
449
-
450
- inline AnyValue &get_keys_fn()
451
- {
452
- static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> _) -> jspp::JsIterator<jspp::AnyValue>
453
- {
454
- auto self = thisVal.as_array();
455
- for (uint64_t i = 0; i < self->length; ++i) {
456
- co_yield AnyValue::make_number(i);
457
- }
458
- co_return Constants::UNDEFINED; },
459
- "keys");
460
- return fn;
461
- }
462
-
463
- inline AnyValue &get_entries_fn()
464
- {
465
- static AnyValue fn = AnyValue::make_generator([](AnyValue thisVal, std::vector<AnyValue> _) -> jspp::JsIterator<jspp::AnyValue>
466
- {
467
- auto self = thisVal.as_array();
468
- for (uint64_t i = 0; i < self->length; ++i) {
469
- std::vector<AnyValue> entry;
470
- entry.push_back(AnyValue::make_number(i));
471
- entry.push_back(self->get_property(static_cast<uint32_t>(i)));
472
- co_yield AnyValue::make_array(std::move(entry));
473
- }
474
- co_return Constants::UNDEFINED; },
475
- "entries");
476
- return fn;
477
- }
478
-
479
- inline AnyValue &get_map_fn()
480
- {
481
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
482
- {
483
- auto self = thisVal.as_array();
484
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
485
- auto callback = args[0].as_function();
486
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
487
-
488
- std::vector<AnyValue> result;
489
- result.reserve(self->length);
490
-
491
- for (uint64_t i = 0; i < self->length; ++i) {
492
- if (self->has_property(std::to_string(i))) {
493
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
494
- AnyValue kVal = AnyValue::make_number(i);
495
- const AnyValue cbArgs[] = {val, kVal, thisVal};
496
- result.push_back(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)));
497
- } else {
498
- result.push_back(Constants::UNINITIALIZED);
499
- }
500
- }
501
- return AnyValue::make_array(std::move(result)); },
502
- "map");
503
- return fn;
504
- }
505
-
506
- inline AnyValue &get_filter_fn()
507
- {
508
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
509
- {
510
- auto self = thisVal.as_array();
511
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
512
- auto callback = args[0].as_function();
513
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
514
-
515
- std::vector<AnyValue> result;
516
-
517
- for (uint64_t i = 0; i < self->length; ++i) {
518
- if (self->has_property(std::to_string(i))) {
519
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
520
- AnyValue kVal = AnyValue::make_number(i);
521
- const AnyValue cbArgs[] = {val, kVal, thisVal};
522
- if (is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
523
- result.push_back(val);
524
- }
525
- }
526
- }
527
- return AnyValue::make_array(std::move(result)); },
528
- "filter");
529
- return fn;
530
- }
531
-
532
- inline AnyValue &get_every_fn()
533
- {
534
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
535
- {
536
- auto self = thisVal.as_array();
537
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
538
- auto callback = args[0].as_function();
539
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
540
-
541
- for (uint64_t i = 0; i < self->length; ++i) {
542
- if (self->has_property(std::to_string(i))) {
543
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
544
- AnyValue kVal = AnyValue::make_number(i);
545
- const AnyValue cbArgs[] = {val, kVal, thisVal};
546
- if (!is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
547
- return Constants::FALSE;
548
- }
549
- }
550
- }
551
- return Constants::TRUE; },
552
- "every");
553
- return fn;
554
- }
555
-
556
- inline AnyValue &get_some_fn()
557
- {
558
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
559
- {
560
- auto self = thisVal.as_array();
561
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
562
- auto callback = args[0].as_function();
563
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
564
-
565
- for (uint64_t i = 0; i < self->length; ++i) {
566
- if (self->has_property(std::to_string(i))) {
567
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
568
- AnyValue kVal = AnyValue::make_number(i);
569
- const AnyValue cbArgs[] = {val, kVal, thisVal};
570
- if (is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
571
- return Constants::TRUE;
572
- }
573
- }
574
- }
575
- return Constants::FALSE; },
576
- "some");
577
- return fn;
578
- }
579
-
580
- inline AnyValue &get_reduce_fn()
581
- {
582
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
583
- {
584
- auto self = thisVal.as_array();
585
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
586
- auto callback = args[0].as_function();
587
-
588
- uint64_t i = 0;
589
- AnyValue accumulator;
590
-
591
- if (args.size() > 1) {
592
- accumulator = args[1];
593
- } else {
594
- if (self->length == 0) throw Exception::make_exception("Reduce of empty array with no initial value", "TypeError");
595
- bool found = false;
596
- for (; i < self->length; ++i) {
597
- if (self->has_property(std::to_string(i))) {
598
- accumulator = self->get_property(static_cast<uint32_t>(i));
599
- found = true;
600
- i++;
601
- break;
602
- }
603
- }
604
- if (!found) throw Exception::make_exception("Reduce of empty array with no initial value", "TypeError");
605
- }
606
-
607
- for (; i < self->length; ++i) {
608
- if (self->has_property(std::to_string(i))) {
609
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
610
- AnyValue kVal = AnyValue::make_number(i);
611
- const AnyValue cbArgs[] = {accumulator, val, kVal, thisVal};
612
- accumulator = callback->call(Constants::UNDEFINED, std::span<const AnyValue>(cbArgs, 4));
613
- }
614
- }
615
- return accumulator; },
616
- "reduce");
617
- return fn;
618
- }
619
-
620
- inline AnyValue &get_reduceRight_fn()
621
- {
622
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
623
- {
624
- auto self = thisVal.as_array();
625
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
626
- auto callback = args[0].as_function();
627
-
628
- int64_t i = self->length - 1;
629
- AnyValue accumulator;
630
-
631
- if (args.size() > 1) {
632
- accumulator = args[1];
633
- } else {
634
- if (self->length == 0) throw Exception::make_exception("Reduce of empty array with no initial value", "TypeError");
635
- bool found = false;
636
- for (; i >= 0; --i) {
637
- if (self->has_property(std::to_string(i))) {
638
- accumulator = self->get_property(static_cast<uint32_t>(i));
639
- found = true;
640
- i--;
641
- break;
642
- }
643
- }
644
- if (!found) throw Exception::make_exception("Reduce of empty array with no initial value", "TypeError");
645
- }
646
-
647
- for (; i >= 0; --i) {
648
- if (self->has_property(std::to_string(i))) {
649
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
650
- AnyValue kVal = AnyValue::make_number(i);
651
- const AnyValue cbArgs[] = {accumulator, val, kVal, thisVal};
652
- accumulator = callback->call(Constants::UNDEFINED, std::span<const AnyValue>(cbArgs, 4));
653
- }
654
- }
655
- return accumulator; },
656
- "reduceRight");
657
- return fn;
658
- }
659
-
660
- inline AnyValue &get_flat_fn()
661
- {
662
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
663
- {
664
- auto self = thisVal.as_array();
665
- double depthVal = (args.size() > 0 && !args[0].is_undefined()) ? Operators_Private::ToNumber(args[0]) : 1;
666
- int depth = static_cast<int>(depthVal);
667
- if (depth < 0) depth = 0;
668
-
669
- std::vector<AnyValue> result;
670
- std::function<void(const AnyValue&, int)> flatten;
671
- flatten = [&result, &flatten](const AnyValue& item, int d) {
672
- if (d > 0 && item.is_array()) {
673
- auto arr = item.as_array();
674
- for (uint64_t i = 0; i < arr->length; ++i) {
675
- if (arr->has_property(std::to_string(i))) {
676
- flatten(arr->get_property(static_cast<uint32_t>(i)), d - 1);
677
- }
678
- }
679
- } else {
680
- result.push_back(item);
681
- }
682
- };
683
-
684
- for (uint64_t i = 0; i < self->length; ++i) {
685
- if (self->has_property(std::to_string(i))) {
686
- flatten(self->get_property(static_cast<uint32_t>(i)), depth);
687
- }
688
- }
689
- return AnyValue::make_array(std::move(result)); },
690
- "flat");
691
- return fn;
692
- }
693
-
694
- inline AnyValue &get_flatMap_fn()
695
- {
696
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
697
- {
698
- auto self = thisVal.as_array();
699
- if (args.empty() || !args[0].is_function()) throw Exception::make_exception("callback is not a function", "TypeError");
700
- auto callback = args[0].as_function();
701
- auto thisArg = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
702
-
703
- std::vector<AnyValue> result;
704
-
705
- for (uint64_t i = 0; i < self->length; ++i) {
706
- if (self->has_property(std::to_string(i))) {
707
- AnyValue val = self->get_property(static_cast<uint32_t>(i));
708
- AnyValue kVal = AnyValue::make_number(i);
709
- const AnyValue cbArgs[] = {val, kVal, thisVal};
710
- AnyValue mapped = callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3));
711
-
712
- if (mapped.is_array()) {
713
- auto arr = mapped.as_array();
714
- for (uint64_t j = 0; j < arr->length; ++j) {
715
- if (arr->has_property(std::to_string(j))) {
716
- result.push_back(arr->get_property(static_cast<uint32_t>(j)));
717
- }
718
- }
719
- } else {
720
- result.push_back(mapped);
721
- }
722
- }
723
- }
724
- return AnyValue::make_array(std::move(result)); },
725
- "flatMap");
726
- return fn;
727
- }
728
-
729
- inline AnyValue &get_fill_fn()
730
- {
731
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
732
- {
733
- auto self = thisVal.as_array();
734
- AnyValue value = args.empty() ? Constants::UNDEFINED : args[0];
735
- double len = static_cast<double>(self->length);
736
- double start = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : 0;
737
- double end = (args.size() > 2 && !args[2].is_undefined()) ? Operators_Private::ToNumber(args[2]) : len;
738
-
739
- double k;
740
- if (start >= 0) k = start; else k = len + start;
741
- if (k < 0) k = 0;
742
-
743
- double final;
744
- if (end >= 0) final = end; else final = len + end;
745
- if (final > len) final = len;
746
-
747
- for (uint64_t i = static_cast<uint64_t>(k); i < static_cast<uint64_t>(final); ++i) {
748
- self->set_property(static_cast<uint32_t>(i), value);
749
- }
750
- return thisVal; },
751
- "fill");
752
- return fn;
753
- }
754
-
755
- inline AnyValue &get_reverse_fn()
756
- {
757
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
758
- {
759
- auto self = thisVal.as_array();
760
- uint64_t len = self->length;
761
- for (uint64_t i = 0; i < len / 2; ++i) {
762
- uint64_t j = len - 1 - i;
763
- bool hasI = self->has_property(std::to_string(i));
764
- bool hasJ = self->has_property(std::to_string(j));
765
-
766
- if (hasI && hasJ) {
767
- AnyValue valI = self->get_property(static_cast<uint32_t>(i));
768
- AnyValue valJ = self->get_property(static_cast<uint32_t>(j));
769
- self->set_property(static_cast<uint32_t>(i), valJ);
770
- self->set_property(static_cast<uint32_t>(j), valI);
771
- } else if (hasI && !hasJ) {
772
- AnyValue valI = self->get_property(static_cast<uint32_t>(i));
773
- self->set_property(static_cast<uint32_t>(j), valI);
774
- if (i < self->dense.size()) self->dense[i] = Constants::UNINITIALIZED;
775
- else self->sparse.erase(static_cast<uint32_t>(i));
776
- } else if (!hasI && hasJ) {
777
- AnyValue valJ = self->get_property(static_cast<uint32_t>(j));
778
- self->set_property(static_cast<uint32_t>(i), valJ);
779
- if (j < self->dense.size()) self->dense[j] = Constants::UNINITIALIZED;
780
- else self->sparse.erase(static_cast<uint32_t>(j));
781
- }
782
- }
783
- return thisVal; },
784
- "reverse");
785
- return fn;
786
- }
787
-
788
- inline AnyValue &get_sort_fn()
789
- {
790
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
791
- {
792
- auto self = thisVal.as_array();
793
- AnyValue compareFn = args.empty() ? Constants::UNDEFINED : args[0];
794
-
795
- std::vector<AnyValue> items;
796
- for (uint64_t i = 0; i < self->length; ++i) {
797
- if (self->has_property(std::to_string(i))) {
798
- items.push_back(self->get_property(static_cast<uint32_t>(i)));
799
- }
800
- }
801
-
802
- std::sort(items.begin(), items.end(), [&](const AnyValue& a, const AnyValue& b) {
803
- if (a.is_undefined() && b.is_undefined()) return false;
804
- if (a.is_undefined()) return false;
805
- if (b.is_undefined()) return true;
806
-
807
- if (compareFn.is_function()) {
808
- const AnyValue cmpArgs[] = {a, b};
809
- double res = Operators_Private::ToNumber(compareFn.call(Constants::UNDEFINED, std::span<const AnyValue>(cmpArgs, 2)));
810
- return res < 0;
811
- } else {
812
- std::string sA = a.to_std_string();
813
- std::string sB = b.to_std_string();
814
- return sA < sB;
815
- }
816
- });
817
-
818
- for (uint64_t i = 0; i < items.size(); ++i) {
819
- self->set_property(static_cast<uint32_t>(i), items[i]);
820
- }
821
- for (uint64_t i = items.size(); i < self->length; ++i) {
822
- if (i < self->dense.size()) self->dense[i] = Constants::UNINITIALIZED;
823
- else self->sparse.erase(static_cast<uint32_t>(i));
824
- }
825
-
826
- return thisVal; },
827
- "sort");
828
- return fn;
829
- }
830
-
831
- inline AnyValue &get_splice_fn()
832
- {
833
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
834
- {
835
- auto self = thisVal.as_array();
836
- double len = static_cast<double>(self->length);
837
- double start = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
838
- double actualStart = (start < 0) ? std::max(len + start, 0.0) : std::min(start, len);
839
-
840
- uint64_t startIdx = static_cast<uint64_t>(actualStart);
841
- uint64_t deleteCount = 0;
842
- if (args.size() >= 2) {
843
- double dc = Operators_Private::ToNumber(args[1]);
844
- deleteCount = static_cast<uint64_t>(std::max(0.0, std::min(dc, len - startIdx)));
845
- } else if (args.size() == 1) {
846
- deleteCount = len - startIdx;
847
- }
848
-
849
- std::vector<AnyValue> deletedItems;
850
- for (uint64_t i = 0; i < deleteCount; ++i) {
851
- if (self->has_property(std::to_string(startIdx + i))) {
852
- deletedItems.push_back(self->get_property(static_cast<uint32_t>(startIdx + i)));
853
- } else {
854
- deletedItems.push_back(Constants::UNINITIALIZED);
855
- }
856
- }
857
-
858
- std::vector<AnyValue> insertItems;
859
- for (size_t i = 2; i < args.size(); ++i) {
860
- insertItems.push_back(args[i]);
861
- }
862
- uint64_t insertCount = insertItems.size();
863
-
864
- if (insertCount < deleteCount) {
865
- for (uint64_t i = startIdx; i < len - deleteCount; ++i) {
866
- uint64_t from = i + deleteCount;
867
- uint64_t to = i + insertCount;
868
- if (self->has_property(std::to_string(from))) {
869
- self->set_property(static_cast<uint32_t>(to), self->get_property(static_cast<uint32_t>(from)));
870
- } else {
871
- if (to < self->dense.size()) self->dense[to] = Constants::UNINITIALIZED;
872
- else self->sparse.erase(static_cast<uint32_t>(to));
873
- }
874
- }
875
- for (uint64_t i = len; i > len - deleteCount + insertCount; --i) {
876
- uint64_t idx = i - 1;
877
- if (idx < self->dense.size()) self->dense[idx] = Constants::UNINITIALIZED;
878
- else self->sparse.erase(static_cast<uint32_t>(idx));
879
- }
880
- } else if (insertCount > deleteCount) {
881
- for (uint64_t i = len; i > startIdx + deleteCount; --i) {
882
- uint64_t from = i - 1;
883
- uint64_t to = from - deleteCount + insertCount;
884
- if (self->has_property(std::to_string(from))) {
885
- self->set_property(static_cast<uint32_t>(to), self->get_property(static_cast<uint32_t>(from)));
886
- } else {
887
- if (to < self->dense.size()) self->dense[to] = Constants::UNINITIALIZED;
888
- else self->sparse.erase(static_cast<uint32_t>(to));
889
- }
890
- }
891
- }
892
-
893
- for (uint64_t i = 0; i < insertCount; ++i) {
894
- self->set_property(static_cast<uint32_t>(startIdx + i), insertItems[i]);
895
- }
896
-
897
- self->length = len - deleteCount + insertCount;
898
- return AnyValue::make_array(std::move(deletedItems)); },
899
- "splice");
900
- return fn;
901
- }
902
-
903
- inline AnyValue &get_copyWithin_fn()
904
- {
905
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
906
- {
907
- auto self = thisVal.as_array();
908
- double len = static_cast<double>(self->length);
909
- double target = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
910
- double start = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : 0;
911
- double end = (args.size() > 2 && !args[2].is_undefined()) ? Operators_Private::ToNumber(args[2]) : len;
912
-
913
- double to;
914
- if (target >= 0) to = target; else to = len + target;
915
- if (to < 0) to = 0; else if (to > len) to = len;
916
-
917
- double from;
918
- if (start >= 0) from = start; else from = len + start;
919
- if (from < 0) from = 0; else if (from > len) from = len;
920
-
921
- double final;
922
- if (end >= 0) final = end; else final = len + end;
923
- if (final < 0) final = 0; else if (final > len) final = len;
924
-
925
- double count = std::min(final - from, len - to);
926
-
927
- if (from < to && to < from + count) {
928
- for (double i = count - 1; i >= 0; --i) {
929
- uint64_t f = static_cast<uint64_t>(from + i);
930
- uint64_t t = static_cast<uint64_t>(to + i);
931
- if (self->has_property(std::to_string(f))) {
932
- self->set_property(static_cast<uint32_t>(t), self->get_property(static_cast<uint32_t>(f)));
933
- } else {
934
- if (t < self->dense.size()) self->dense[t] = Constants::UNINITIALIZED;
935
- else self->sparse.erase(static_cast<uint32_t>(t));
936
- }
937
- }
938
- } else {
939
- for (double i = 0; i < count; ++i) {
940
- uint64_t f = static_cast<uint64_t>(from + i);
941
- uint64_t t = static_cast<uint64_t>(to + i);
942
- if (self->has_property(std::to_string(f))) {
943
- self->set_property(static_cast<uint32_t>(t), self->get_property(static_cast<uint32_t>(f)));
944
- } else {
945
- if (t < self->dense.size()) self->dense[t] = Constants::UNINITIALIZED;
946
- else self->sparse.erase(static_cast<uint32_t>(t));
947
- }
948
- }
949
- }
950
- return thisVal; },
951
- "copyWithin");
952
- return fn;
953
- }
954
-
955
- inline AnyValue &get_concat_fn()
956
- {
957
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
958
- {
959
- auto self = thisVal.as_array();
960
- std::vector<AnyValue> result;
961
- for (uint64_t i = 0; i < self->length; ++i) {
962
- if (self->has_property(std::to_string(i))) {
963
- result.push_back(self->get_property(static_cast<uint32_t>(i)));
964
- } else {
965
- result.push_back(Constants::UNINITIALIZED);
966
- }
967
- }
968
-
969
- for (const auto& item : args) {
970
- bool spreadable = false;
971
- if (item.is_array()) {
972
- spreadable = true;
973
- auto sym = WellKnownSymbols::isConcatSpreadable;
974
- if (item.has_property(sym->key)) {
975
- spreadable = is_truthy(item.get_property_with_receiver(sym->key, item));
976
- }
977
- } else if (item.is_object()) {
978
- auto sym = WellKnownSymbols::isConcatSpreadable;
979
- if (item.has_property(sym->key)) {
980
- spreadable = is_truthy(item.get_property_with_receiver(sym->key, item));
981
- }
982
- }
983
-
984
- if (spreadable && item.is_array()) {
985
- auto arr = item.as_array();
986
- for (uint64_t i = 0; i < arr->length; ++i) {
987
- if (arr->has_property(std::to_string(i))) {
988
- result.push_back(arr->get_property(static_cast<uint32_t>(i)));
989
- } else {
990
- result.push_back(Constants::UNINITIALIZED);
991
- }
992
- }
993
- } else {
994
- result.push_back(item);
995
- }
996
- }
997
- return AnyValue::make_array(std::move(result)); },
998
- "concat");
999
- return fn;
1000
- }
1001
-
1002
- inline AnyValue &get_slice_fn()
1003
- {
1004
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
1005
- {
1006
- auto self = thisVal.as_array();
1007
- double len = static_cast<double>(self->length);
1008
- double start = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
1009
- double end = (args.size() < 2 || args[1].is_undefined()) ? len : Operators_Private::ToNumber(args[1]);
1010
-
1011
- double k;
1012
- if (start >= 0) k = start; else k = len + start;
1013
- if (k < 0) k = 0;
1014
-
1015
- double final;
1016
- if (end >= 0) final = end; else final = len + end;
1017
- if (final > len) final = len;
1018
-
1019
- if (final < k) final = k;
1020
-
1021
- std::vector<AnyValue> result;
1022
- for (uint64_t i = static_cast<uint64_t>(k); i < static_cast<uint64_t>(final); ++i) {
1023
- if (self->has_property(std::to_string(i))) {
1024
- result.push_back(self->get_property(static_cast<uint32_t>(i)));
1025
- } else {
1026
- result.push_back(Constants::UNINITIALIZED);
1027
- }
1028
- }
1029
- return AnyValue::make_array(std::move(result)); },
1030
- "slice");
1031
- return fn;
1032
- }
1033
-
1034
- inline AnyValue &get_toReversed_fn()
1035
- {
1036
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
1037
- {
1038
- auto copy = thisVal.get_property_with_receiver("slice", thisVal).call(thisVal, {});
1039
- copy.get_own_property("reverse").call(copy, {});
1040
- return copy; },
1041
- "toReversed");
1042
- return fn;
1043
- }
1044
-
1045
- inline AnyValue &get_toSorted_fn()
1046
- {
1047
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
1048
- {
1049
- auto copy = thisVal.get_property_with_receiver("slice", thisVal).call(thisVal, {});
1050
- copy.get_own_property("sort").call(copy, args);
1051
- return copy; },
1052
- "toSorted");
1053
- return fn;
1054
- }
1055
-
1056
- inline AnyValue &get_toSpliced_fn()
1057
- {
1058
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
1059
- {
1060
- auto copy = thisVal.get_property_with_receiver("slice", thisVal).call(thisVal, {});
1061
- copy.get_own_property("splice").call(copy, args);
1062
- return copy; },
1063
- "toSpliced");
1064
- return fn;
1065
- }
1066
-
1067
- inline AnyValue &get_with_fn()
1068
- {
1069
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
1070
- {
1071
- auto self = thisVal.as_array();
1072
- auto copy = thisVal.get_property_with_receiver("slice", thisVal).call(thisVal, {});
1073
-
1074
- double len = static_cast<double>(self->length);
1075
- double idx = args.empty() ? 0 : Operators_Private::ToNumber(args[0]);
1076
- double k;
1077
- if (idx >= 0) k = idx; else k = len + idx;
1078
-
1079
- if (k < 0 || k >= len) throw Exception::make_exception("Invalid index", "RangeError");
1080
-
1081
- AnyValue value = (args.size() > 1) ? args[1] : Constants::UNDEFINED;
1082
- copy.set_own_property(static_cast<uint32_t>(k), value);
1083
- return copy; },
1084
- "with");
1085
- return fn;
1086
- }
1087
-
1088
- inline AnyValue &get_toLocaleString_fn()
1089
- {
1090
- static AnyValue fn = AnyValue::make_function([](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
1091
- {
1092
- auto self = thisVal.as_array();
1093
- std::string result = "";
1094
- for (uint64_t i = 0; i < self->length; ++i) {
1095
- if (i > 0) result += ",";
1096
- AnyValue element = self->get_property(static_cast<uint32_t>(i));
1097
- if (!element.is_null() && !element.is_undefined()) {
1098
- if (element.has_property("toLocaleString")) {
1099
- auto fn = element.get_property_with_receiver("toLocaleString", element);
1100
- if (fn.is_function()) {
1101
- result += fn.call(element, {}).to_std_string();
1102
- continue;
1103
- }
1104
- }
1105
- result += element.to_std_string();
1106
- }
1107
- }
1108
- return AnyValue::make_string(result); },
1109
- "toLocaleString");
1110
- return fn;
1111
- }
1112
-
1113
- inline std::optional<AnyValue> get(const std::string &key)
1114
- {
1115
- // --- toString() method ---
1116
- if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
1117
- {
1118
- return get_toString_fn();
1119
- }
1120
-
1121
- // --- [Symbol.iterator]() method ---
1122
- if (key == WellKnownSymbols::iterator->key)
1123
- {
1124
- return get_iterator_fn();
1125
- }
1126
-
1127
- // --- length property ---
1128
- if (key == "length")
1129
- {
1130
- return get_length_desc();
1131
- }
1132
-
1133
- // --- push() method ---
1134
- if (key == "push")
1135
- {
1136
- return get_push_fn();
1137
- }
1138
-
1139
- // --- pop() method ---
1140
- if (key == "pop")
1141
- {
1142
- return get_pop_fn();
1143
- }
1144
-
1145
- // --- shift() method ---
1146
- if (key == "shift")
1147
- {
1148
- return get_shift_fn();
1149
- }
1150
-
1151
- // --- unshift() method ---
1152
- if (key == "unshift")
1153
- {
1154
- return get_unshift_fn();
1155
- }
1156
-
1157
- // --- join() method ---
1158
- if (key == "join")
1159
- {
1160
- return get_join_fn();
1161
- }
1162
-
1163
- // --- forEach() method ---
1164
- if (key == "forEach")
1165
- {
1166
- return get_forEach_fn();
1167
- }
1168
-
1169
- // --- at(index) ---
1170
- if (key == "at")
1171
- {
1172
- return get_at_fn();
1173
- }
1174
-
1175
- // --- includes(searchElement, fromIndex) ---
1176
- if (key == "includes")
1177
- {
1178
- return get_includes_fn();
1179
- }
1180
-
1181
- // --- indexOf(searchElement, fromIndex) ---
1182
- if (key == "indexOf")
1183
- {
1184
- return get_indexOf_fn();
1185
- }
1186
-
1187
- // --- lastIndexOf(searchElement, fromIndex) ---
1188
- if (key == "lastIndexOf")
1189
- {
1190
- return get_lastIndexOf_fn();
1191
- }
1192
-
1193
- // --- find(callback, thisArg) ---
1194
- if (key == "find")
1195
- {
1196
- return get_find_fn();
1197
- }
1198
-
1199
- // --- findIndex(callback, thisArg) ---
1200
- if (key == "findIndex")
1201
- {
1202
- return get_findIndex_fn();
1203
- }
1204
-
1205
- // --- findLast(callback, thisArg) ---
1206
- if (key == "findLast")
1207
- {
1208
- return get_findLast_fn();
1209
- }
1210
-
1211
- // --- findLastIndex(callback, thisArg) ---
1212
- if (key == "findLastIndex")
1213
- {
1214
- return get_findLastIndex_fn();
1215
- }
1216
-
1217
- // --- values() ---
1218
- if (key == "values")
1219
- {
1220
- return get_values_fn();
1221
- }
1222
-
1223
- // --- keys() ---
1224
- if (key == "keys")
1225
- {
1226
- return get_keys_fn();
1227
- }
1228
-
1229
- // --- entries() ---
1230
- if (key == "entries")
1231
- {
1232
- return get_entries_fn();
1233
- }
1234
-
1235
- // --- map(callback, thisArg) ---
1236
- if (key == "map")
1237
- {
1238
- return get_map_fn();
1239
- }
1240
-
1241
- // --- filter(callback, thisArg) ---
1242
- if (key == "filter")
1243
- {
1244
- return get_filter_fn();
1245
- }
1246
-
1247
- // --- every(callback, thisArg) ---
1248
- if (key == "every")
1249
- {
1250
- return get_every_fn();
1251
- }
1252
-
1253
- // --- some(callback, thisArg) ---
1254
- if (key == "some")
1255
- {
1256
- return get_some_fn();
1257
- }
1258
-
1259
- // --- reduce(callback, initialValue) ---
1260
- if (key == "reduce")
1261
- {
1262
- return get_reduce_fn();
1263
- }
1264
-
1265
- // --- reduceRight(callback, initialValue) ---
1266
- if (key == "reduceRight")
1267
- {
1268
- return get_reduceRight_fn();
1269
- }
1270
-
1271
- // --- flat(depth) ---
1272
- if (key == "flat")
1273
- {
1274
- return get_flat_fn();
1275
- }
1276
-
1277
- // --- flatMap(callback, thisArg) ---
1278
- if (key == "flatMap")
1279
- {
1280
- return get_flatMap_fn();
1281
- }
1282
-
1283
- // --- fill(value, start, end) ---
1284
- if (key == "fill")
1285
- {
1286
- return get_fill_fn();
1287
- }
1288
-
1289
- // --- reverse() ---
1290
- if (key == "reverse")
1291
- {
1292
- return get_reverse_fn();
1293
- }
1294
-
1295
- // --- sort(compareFn) ---
1296
- if (key == "sort")
1297
- {
1298
- return get_sort_fn();
1299
- }
1300
-
1301
- // --- splice(start, deleteCount, ...items) ---
1302
- if (key == "splice")
1303
- {
1304
- return get_splice_fn();
1305
- }
1306
-
1307
- // --- copyWithin(target, start, end) ---
1308
- if (key == "copyWithin")
1309
- {
1310
- return get_copyWithin_fn();
1311
- }
1312
-
1313
- // --- concat(...items) ---
1314
- if (key == "concat")
1315
- {
1316
- return get_concat_fn();
1317
- }
1318
-
1319
- // --- slice(start, end) ---
1320
- if (key == "slice")
1321
- {
1322
- return get_slice_fn();
1323
- }
1324
-
1325
- // --- toReversed() ---
1326
- if (key == "toReversed")
1327
- {
1328
- return get_toReversed_fn();
1329
- }
1330
-
1331
- // --- toSorted(compareFn) ---
1332
- if (key == "toSorted")
1333
- {
1334
- return get_toSorted_fn();
1335
- }
1336
-
1337
- // --- toSpliced(start, deleteCount, ...items) ---
1338
- if (key == "toSpliced")
1339
- {
1340
- return get_toSpliced_fn();
1341
- }
1342
-
1343
- // --- with(index, value) ---
1344
- if (key == "with")
1345
- {
1346
- return get_with_fn();
1347
- }
1348
-
1349
- // --- toLocaleString() ---
1350
- if (key == "toLocaleString")
1351
- {
1352
- return get_toLocaleString_fn();
1353
- }
1354
-
1355
- return std::nullopt;
1356
- }
12
+ AnyValue &get_toString_fn();
13
+ AnyValue &get_iterator_fn();
14
+ AnyValue &get_length_desc();
15
+ AnyValue &get_push_fn();
16
+ AnyValue &get_pop_fn();
17
+ AnyValue &get_shift_fn();
18
+ AnyValue &get_unshift_fn();
19
+ AnyValue &get_join_fn();
20
+ AnyValue &get_forEach_fn();
21
+ AnyValue &get_at_fn();
22
+ AnyValue &get_includes_fn();
23
+ AnyValue &get_indexOf_fn();
24
+ AnyValue &get_lastIndexOf_fn();
25
+ AnyValue &get_find_fn();
26
+ AnyValue &get_findIndex_fn();
27
+ AnyValue &get_findLast_fn();
28
+ AnyValue &get_findLastIndex_fn();
29
+ AnyValue &get_values_fn();
30
+ AnyValue &get_keys_fn();
31
+ AnyValue &get_entries_fn();
32
+ AnyValue &get_map_fn();
33
+ AnyValue &get_filter_fn();
34
+ AnyValue &get_every_fn();
35
+ AnyValue &get_some_fn();
36
+ AnyValue &get_reduce_fn();
37
+ AnyValue &get_reduceRight_fn();
38
+ AnyValue &get_flat_fn();
39
+ AnyValue &get_flatMap_fn();
40
+ AnyValue &get_fill_fn();
41
+ AnyValue &get_reverse_fn();
42
+ AnyValue &get_sort_fn();
43
+ AnyValue &get_splice_fn();
44
+ AnyValue &get_copyWithin_fn();
45
+ AnyValue &get_concat_fn();
46
+ AnyValue &get_slice_fn();
47
+ AnyValue &get_toReversed_fn();
48
+ AnyValue &get_toSorted_fn();
49
+ AnyValue &get_toSpliced_fn();
50
+ AnyValue &get_with_fn();
51
+ AnyValue &get_toLocaleString_fn();
52
+
53
+ std::optional<AnyValue> get(const std::string &key);
54
+ std::optional<AnyValue> get(const AnyValue &key);
1357
55
  }
1358
56
  }