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