@ugo-studio/jspp 0.2.5 → 0.2.7

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