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