@ugo-studio/jspp 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +25 -25
- package/README.md +20 -12
- package/dist/analysis/scope.js +5 -3
- package/dist/analysis/typeAnalyzer.js +21 -25
- package/dist/cli/index.js +14 -4
- package/dist/cli/utils.js +61 -0
- package/dist/core/codegen/control-flow-handlers.js +10 -9
- package/dist/core/codegen/declaration-handlers.js +10 -3
- package/dist/core/codegen/destructuring-handlers.js +9 -4
- package/dist/core/codegen/expression-handlers.js +40 -29
- package/dist/core/codegen/function-handlers.js +78 -12
- package/dist/core/codegen/helpers.js +91 -14
- package/dist/core/codegen/index.js +4 -2
- package/dist/core/codegen/statement-handlers.js +8 -6
- package/package.json +2 -2
- package/scripts/precompile-headers.ts +249 -50
- package/scripts/setup-compiler.ts +63 -63
- package/src/prelude/any_value.cpp +636 -0
- package/src/prelude/any_value.hpp +23 -16
- 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} +10 -16
- package/src/prelude/library/array.cpp +191 -0
- package/src/prelude/library/array.hpp +5 -178
- 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 +96 -0
- package/src/prelude/library/global.hpp +12 -28
- package/src/prelude/library/global_usings.hpp +15 -0
- package/src/prelude/library/math.cpp +258 -0
- package/src/prelude/library/math.hpp +6 -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 +17 -12
- package/src/prelude/utils/access.hpp +122 -31
- package/src/prelude/utils/assignment_operators.hpp +99 -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/object.hpp +60 -3
- package/src/prelude/utils/operators.hpp +25 -10
- package/src/prelude/utils/operators_primitive.hpp +336 -336
- 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/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 +176 -0
- package/src/prelude/values/object.cpp +159 -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/function.hpp +7 -46
- package/src/prelude/values/prototypes/iterator.hpp +15 -191
- package/src/prelude/values/prototypes/number.hpp +23 -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/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/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
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "any_value.hpp"
|
|
3
|
+
#include "values/iterator.hpp"
|
|
4
|
+
#include "values/async_iterator.hpp"
|
|
5
|
+
#include "values/string.hpp"
|
|
6
|
+
#include "values/object.hpp"
|
|
7
|
+
#include "values/array.hpp"
|
|
8
|
+
#include "values/function.hpp"
|
|
9
|
+
#include "values/promise.hpp"
|
|
10
|
+
#include "values/symbol.hpp"
|
|
11
|
+
#include "values/descriptors.hpp"
|
|
12
|
+
#include "exception.hpp"
|
|
13
|
+
|
|
14
|
+
namespace jspp {
|
|
15
|
+
|
|
16
|
+
// --- AnyValue methods that were in any_value_helpers.hpp ---
|
|
17
|
+
|
|
18
|
+
bool AnyValue::operator==(const AnyValue &other) const noexcept {
|
|
19
|
+
return storage == other.storage;
|
|
20
|
+
}
|
|
21
|
+
bool AnyValue::operator==(const std::string &other) const noexcept {
|
|
22
|
+
if (!is_string())
|
|
23
|
+
return false;
|
|
24
|
+
return as_string()->value == other;
|
|
25
|
+
}
|
|
26
|
+
bool AnyValue::operator<(const AnyValue &other) const noexcept {
|
|
27
|
+
return storage < other.storage;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
JsString *AnyValue::as_string() const noexcept { return static_cast<JsString *>(get_ptr()); }
|
|
31
|
+
JsObject *AnyValue::as_object() const noexcept { return static_cast<JsObject *>(get_ptr()); }
|
|
32
|
+
JsArray *AnyValue::as_array() const noexcept { return static_cast<JsArray *>(get_ptr()); }
|
|
33
|
+
JsFunction *AnyValue::as_function() const noexcept { return static_cast<JsFunction *>(get_ptr()); }
|
|
34
|
+
JsSymbol *AnyValue::as_symbol() const noexcept { return static_cast<JsSymbol *>(get_ptr()); }
|
|
35
|
+
JsPromise *AnyValue::as_promise() const noexcept { return static_cast<JsPromise *>(get_ptr()); }
|
|
36
|
+
DataDescriptor *AnyValue::as_data_descriptor() const noexcept { return static_cast<DataDescriptor *>(get_ptr()); }
|
|
37
|
+
AccessorDescriptor *AnyValue::as_accessor_descriptor() const noexcept { return static_cast<AccessorDescriptor *>(get_ptr()); }
|
|
38
|
+
|
|
39
|
+
bool AnyValue::is_generator() const noexcept { return is_function() && as_function()->is_generator; }
|
|
40
|
+
|
|
41
|
+
// --- AnyValue FACTORIES ---
|
|
42
|
+
AnyValue AnyValue::make_string(const std::string &raw_s) noexcept
|
|
43
|
+
{
|
|
44
|
+
return from_ptr(new JsString(raw_s));
|
|
45
|
+
}
|
|
46
|
+
AnyValue AnyValue::make_object(std::initializer_list<std::pair<std::string, AnyValue>> props) noexcept
|
|
47
|
+
{
|
|
48
|
+
return from_ptr(new JsObject(props, make_null()));
|
|
49
|
+
}
|
|
50
|
+
AnyValue AnyValue::make_object(const std::map<std::string, AnyValue> &props) noexcept
|
|
51
|
+
{
|
|
52
|
+
return from_ptr(new JsObject(props, make_null()));
|
|
53
|
+
}
|
|
54
|
+
AnyValue AnyValue::make_array(std::span<const AnyValue> dense) noexcept
|
|
55
|
+
{
|
|
56
|
+
std::vector<AnyValue> vec;
|
|
57
|
+
vec.reserve(dense.size());
|
|
58
|
+
for (const auto &item : dense)
|
|
59
|
+
vec.push_back(item);
|
|
60
|
+
return from_ptr(new JsArray(std::move(vec)));
|
|
61
|
+
}
|
|
62
|
+
AnyValue AnyValue::make_array(const std::vector<AnyValue> &dense) noexcept
|
|
63
|
+
{
|
|
64
|
+
return from_ptr(new JsArray(dense));
|
|
65
|
+
}
|
|
66
|
+
AnyValue AnyValue::make_array(std::vector<AnyValue> &&dense) noexcept
|
|
67
|
+
{
|
|
68
|
+
return from_ptr(new JsArray(std::move(dense)));
|
|
69
|
+
}
|
|
70
|
+
AnyValue AnyValue::make_function(const JsFunctionCallable &call, const std::optional<std::string> &name, bool is_constructor) noexcept
|
|
71
|
+
{
|
|
72
|
+
auto v = from_ptr(new JsFunction(call, name, {}, {}, false, is_constructor));
|
|
73
|
+
auto proto = make_object({});
|
|
74
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
75
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
76
|
+
return v;
|
|
77
|
+
}
|
|
78
|
+
AnyValue AnyValue::make_class(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
79
|
+
{
|
|
80
|
+
auto v = from_ptr(new JsFunction(call, name, {}, {}, true));
|
|
81
|
+
auto proto = make_object({});
|
|
82
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
83
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
84
|
+
return v;
|
|
85
|
+
}
|
|
86
|
+
AnyValue AnyValue::make_generator(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
87
|
+
{
|
|
88
|
+
auto v = from_ptr(new JsFunction(call, true, name, {}, {}, false));
|
|
89
|
+
auto proto = make_object({});
|
|
90
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
91
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
92
|
+
return v;
|
|
93
|
+
}
|
|
94
|
+
AnyValue AnyValue::make_async_function(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
95
|
+
{
|
|
96
|
+
auto v = from_ptr(new JsFunction(call, false, true, name, {}, {}, false));
|
|
97
|
+
auto proto = make_object({});
|
|
98
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
99
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
100
|
+
return v;
|
|
101
|
+
}
|
|
102
|
+
AnyValue AnyValue::make_async_generator(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
103
|
+
{
|
|
104
|
+
auto v = from_ptr(new JsFunction(call, true, true, name, {}, {}, false));
|
|
105
|
+
auto proto = make_object({});
|
|
106
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
107
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
108
|
+
return v;
|
|
109
|
+
}
|
|
110
|
+
AnyValue AnyValue::make_symbol(const std::string &description) noexcept
|
|
111
|
+
{
|
|
112
|
+
return from_ptr(new JsSymbol(description));
|
|
113
|
+
}
|
|
114
|
+
AnyValue AnyValue::make_promise(const JsPromise &promise) noexcept
|
|
115
|
+
{
|
|
116
|
+
auto p = new JsPromise();
|
|
117
|
+
*p = promise;
|
|
118
|
+
return from_ptr(p);
|
|
119
|
+
}
|
|
120
|
+
AnyValue AnyValue::make_data_descriptor(AnyValue value, bool writable, bool enumerable, bool configurable) noexcept
|
|
121
|
+
{
|
|
122
|
+
return from_ptr(new DataDescriptor(value, writable, enumerable, configurable));
|
|
123
|
+
}
|
|
124
|
+
AnyValue AnyValue::make_accessor_descriptor(const std::optional<std::function<AnyValue(AnyValue, std::span<const AnyValue>)>> &get,
|
|
125
|
+
const std::optional<std::function<AnyValue(AnyValue, std::span<const AnyValue>)>> &set,
|
|
126
|
+
bool enumerable,
|
|
127
|
+
bool configurable) noexcept
|
|
128
|
+
{
|
|
129
|
+
return from_ptr(new AccessorDescriptor(get, set, enumerable, configurable));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
AnyValue AnyValue::from_symbol(JsSymbol *sym) noexcept {
|
|
133
|
+
return from_ptr(sym);
|
|
134
|
+
}
|
|
135
|
+
AnyValue AnyValue::from_string(JsString *str) noexcept {
|
|
136
|
+
return from_ptr(str);
|
|
137
|
+
}
|
|
138
|
+
AnyValue AnyValue::from_promise(JsPromise &&promise) noexcept {
|
|
139
|
+
auto it = new JsPromise(std::move(promise));
|
|
140
|
+
return from_ptr(it);
|
|
141
|
+
}
|
|
142
|
+
AnyValue AnyValue::from_iterator(JsIterator<AnyValue> &&iterator) noexcept {
|
|
143
|
+
auto it = new JsIterator<AnyValue>(std::move(iterator));
|
|
144
|
+
return from_ptr(it);
|
|
145
|
+
}
|
|
146
|
+
AnyValue AnyValue::from_iterator_ref(JsIterator<AnyValue> *iterator) noexcept {
|
|
147
|
+
return from_ptr(iterator);
|
|
148
|
+
}
|
|
149
|
+
AnyValue AnyValue::from_async_iterator(JsAsyncIterator<AnyValue> &&iterator) noexcept {
|
|
150
|
+
auto it = new JsAsyncIterator<AnyValue>(std::move(iterator));
|
|
151
|
+
return from_ptr(it);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
AnyValue AnyValue::resolve_property_for_read(const AnyValue &val, AnyValue thisVal, const std::string &propName) noexcept {
|
|
155
|
+
if (val.is_data_descriptor()) {
|
|
156
|
+
return val.as_data_descriptor()->value;
|
|
157
|
+
}
|
|
158
|
+
if (val.is_accessor_descriptor()) {
|
|
159
|
+
auto accessor = val.as_accessor_descriptor();
|
|
160
|
+
if (accessor->get.has_value())
|
|
161
|
+
return accessor->get.value()(thisVal, std::span<const AnyValue>{});
|
|
162
|
+
else {
|
|
163
|
+
return Constants::UNDEFINED;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return val;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
AnyValue AnyValue::resolve_property_for_write(AnyValue &val, AnyValue thisVal, const AnyValue &new_val, const std::string &propName) {
|
|
170
|
+
if (val.is_data_descriptor()) {
|
|
171
|
+
auto data = val.as_data_descriptor();
|
|
172
|
+
if (data->writable) {
|
|
173
|
+
data->value = new_val;
|
|
174
|
+
return new_val;
|
|
175
|
+
} else {
|
|
176
|
+
throw Exception::make_exception("Cannot assign to read only property '" + propName + "' of object '#<Object>'", "TypeError");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (val.is_accessor_descriptor()) {
|
|
180
|
+
auto accessor = val.as_accessor_descriptor();
|
|
181
|
+
if (accessor->set.has_value()) {
|
|
182
|
+
const AnyValue args[] = {new_val};
|
|
183
|
+
accessor->set.value()(thisVal, std::span<const AnyValue>(args, 1));
|
|
184
|
+
return new_val;
|
|
185
|
+
} else {
|
|
186
|
+
throw Exception::make_exception("Cannot set property of #<Object> which has only a getter", "TypeError");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
val = new_val;
|
|
190
|
+
return new_val;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
std::string AnyValue::to_std_string() const {
|
|
194
|
+
switch (get_type()) {
|
|
195
|
+
case JsType::Undefined: return "undefined";
|
|
196
|
+
case JsType::Null: return "null";
|
|
197
|
+
case JsType::Boolean: return as_boolean() ? "true" : "false";
|
|
198
|
+
case JsType::String: return as_string()->to_std_string();
|
|
199
|
+
case JsType::Object: return as_object()->to_std_string();
|
|
200
|
+
case JsType::Array: return as_array()->to_std_string();
|
|
201
|
+
case JsType::Function: return as_function()->to_std_string();
|
|
202
|
+
case JsType::Iterator: return as_iterator()->to_std_string();
|
|
203
|
+
case JsType::AsyncIterator: return as_async_iterator()->to_std_string();
|
|
204
|
+
case JsType::Promise: return as_promise()->to_std_string();
|
|
205
|
+
case JsType::Symbol: return as_symbol()->to_std_string();
|
|
206
|
+
case JsType::DataDescriptor: return as_data_descriptor()->value.to_std_string();
|
|
207
|
+
case JsType::AccessorDescriptor: {
|
|
208
|
+
if (as_accessor_descriptor()->get.has_value())
|
|
209
|
+
return as_accessor_descriptor()->get.value()(*this, {}).to_std_string();
|
|
210
|
+
else
|
|
211
|
+
return "undefined";
|
|
212
|
+
}
|
|
213
|
+
case JsType::Number: {
|
|
214
|
+
double num = as_double();
|
|
215
|
+
if (std::isnan(num)) return "NaN";
|
|
216
|
+
if (std::abs(num) >= 1e21 || (std::abs(num) > 0 && std::abs(num) < 1e-6)) {
|
|
217
|
+
std::ostringstream oss;
|
|
218
|
+
oss << std::scientific << std::setprecision(4) << num;
|
|
219
|
+
return oss.str();
|
|
220
|
+
} else {
|
|
221
|
+
std::ostringstream oss;
|
|
222
|
+
oss << std::setprecision(6) << std::fixed << num;
|
|
223
|
+
std::string s = oss.str();
|
|
224
|
+
s.erase(s.find_last_not_of('0') + 1, std::string::npos);
|
|
225
|
+
if (!s.empty() && s.back() == '.') s.pop_back();
|
|
226
|
+
return s;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
case JsType::Uninitialized: Exception::throw_uninitialized_reference("#<Object>");
|
|
230
|
+
default: return "";
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
std::string AnyValue::to_property_key() const {
|
|
235
|
+
if (is_symbol()) return as_symbol()->key;
|
|
236
|
+
return to_std_string();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
AnyValue &AnyValue::set_prototype(AnyValue proto) {
|
|
240
|
+
if (is_object()) as_object()->proto = proto;
|
|
241
|
+
else if (is_array()) as_array()->proto = proto;
|
|
242
|
+
else if (is_function()) as_function()->proto = proto;
|
|
243
|
+
else if (is_uninitialized()) Exception::throw_uninitialized_reference("#<Object>");
|
|
244
|
+
return *this;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
AnyValue AnyValue::call(AnyValue thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr) const {
|
|
248
|
+
if (!is_function())
|
|
249
|
+
throw Exception::make_exception(expr.value_or(to_std_string()) + " is not a function", "TypeError");
|
|
250
|
+
return as_function()->call(thisVal, args);
|
|
251
|
+
}
|
|
252
|
+
AnyValue AnyValue::optional_call(AnyValue thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr) const {
|
|
253
|
+
if (is_null() || is_undefined()) return Constants::UNDEFINED;
|
|
254
|
+
return as_function()->call(thisVal, args);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
AnyValue AnyValue::construct(std::span<const AnyValue> args, const std::optional<std::string> &name) const {
|
|
258
|
+
if (!is_function() || !as_function()->is_constructor) {
|
|
259
|
+
throw Exception::make_exception(name.value_or(to_std_string()) + " is not a constructor", "TypeError");
|
|
260
|
+
}
|
|
261
|
+
AnyValue proto = get_own_property("prototype");
|
|
262
|
+
if (!proto.is_object()) proto = AnyValue::make_object({});
|
|
263
|
+
AnyValue instance = AnyValue::make_object({}).set_prototype(proto);
|
|
264
|
+
AnyValue result = call(instance, args);
|
|
265
|
+
if (result.is_object() || result.is_function() || result.is_array() || result.is_promise()) return result;
|
|
266
|
+
return instance;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// --- AnyValue methods that were in any_value_access.hpp ---
|
|
270
|
+
|
|
271
|
+
AnyValue AnyValue::get_own_property(const std::string &key) const {
|
|
272
|
+
return get_property_with_receiver(key, *this);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
AnyValue AnyValue::get_own_property_descriptor(const AnyValue &key) const {
|
|
276
|
+
if (key.is_symbol()) {
|
|
277
|
+
switch (get_type()) {
|
|
278
|
+
case JsType::Object: {
|
|
279
|
+
auto obj = as_object();
|
|
280
|
+
auto it = obj->symbol_props.find(key);
|
|
281
|
+
if (it != obj->symbol_props.end()) return it->second;
|
|
282
|
+
return Constants::UNDEFINED;
|
|
283
|
+
}
|
|
284
|
+
case JsType::Array: {
|
|
285
|
+
auto arr = as_array();
|
|
286
|
+
auto it = arr->symbol_props.find(key);
|
|
287
|
+
if (it != arr->symbol_props.end()) return it->second;
|
|
288
|
+
return Constants::UNDEFINED;
|
|
289
|
+
}
|
|
290
|
+
case JsType::Function: {
|
|
291
|
+
auto func = as_function();
|
|
292
|
+
auto it = func->symbol_props.find(key);
|
|
293
|
+
if (it != func->symbol_props.end()) return it->second;
|
|
294
|
+
return Constants::UNDEFINED;
|
|
295
|
+
}
|
|
296
|
+
default: return Constants::UNDEFINED;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
std::string key_str = key.to_std_string();
|
|
301
|
+
switch (get_type()) {
|
|
302
|
+
case JsType::Object: {
|
|
303
|
+
auto obj = as_object();
|
|
304
|
+
if (obj->deleted_keys.count(key_str)) return Constants::UNDEFINED;
|
|
305
|
+
auto offset = obj->shape->get_offset(key_str);
|
|
306
|
+
if (offset.has_value()) return obj->storage[offset.value()];
|
|
307
|
+
return Constants::UNDEFINED;
|
|
308
|
+
}
|
|
309
|
+
case JsType::Array: {
|
|
310
|
+
auto arr = as_array();
|
|
311
|
+
if (key_str == "length") return AnyValue::make_number(arr->length);
|
|
312
|
+
if (JsArray::is_array_index(key_str)) {
|
|
313
|
+
uint32_t idx = static_cast<uint32_t>(std::stoull(key_str));
|
|
314
|
+
if (idx < arr->dense.size() && !arr->dense[idx].is_uninitialized()) return arr->dense[idx];
|
|
315
|
+
if (arr->sparse.count(idx)) return arr->sparse[idx];
|
|
316
|
+
}
|
|
317
|
+
if (arr->props.count(key_str)) return arr->props.at(key_str);
|
|
318
|
+
return Constants::UNDEFINED;
|
|
319
|
+
}
|
|
320
|
+
case JsType::Function: {
|
|
321
|
+
auto func = as_function();
|
|
322
|
+
if (func->props.count(key_str)) return func->props.at(key_str);
|
|
323
|
+
return Constants::UNDEFINED;
|
|
324
|
+
}
|
|
325
|
+
case JsType::String: {
|
|
326
|
+
auto str = as_string();
|
|
327
|
+
if (key_str == "length") return AnyValue::make_number(str->value.length());
|
|
328
|
+
if (JsArray::is_array_index(key_str)) {
|
|
329
|
+
uint32_t idx = static_cast<uint32_t>(std::stoull(key_str));
|
|
330
|
+
if (idx < str->value.length()) return AnyValue::make_string(std::string(1, str->value[idx]));
|
|
331
|
+
}
|
|
332
|
+
return Constants::UNDEFINED;
|
|
333
|
+
}
|
|
334
|
+
default: return Constants::UNDEFINED;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
bool AnyValue::has_property(const std::string &key) const {
|
|
339
|
+
switch (get_type()) {
|
|
340
|
+
case JsType::Object: return as_object()->has_property(key);
|
|
341
|
+
case JsType::Array: return as_array()->has_property(key);
|
|
342
|
+
case JsType::Function: return as_function()->has_property(key);
|
|
343
|
+
case JsType::Promise: return as_promise()->get_property(key, *this).is_undefined() == false;
|
|
344
|
+
case JsType::Iterator: return static_cast<JsIterator<AnyValue> *>(get_ptr())->get_property(key, *this).is_undefined() == false;
|
|
345
|
+
case JsType::AsyncIterator: return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->get_property(key, *this).is_undefined() == false;
|
|
346
|
+
case JsType::Symbol: return SymbolPrototypes::get(key).has_value();
|
|
347
|
+
case JsType::String:
|
|
348
|
+
if (key == "length") return true;
|
|
349
|
+
if (JsArray::is_array_index(key)) {
|
|
350
|
+
uint32_t idx = static_cast<uint32_t>(std::stoull(key));
|
|
351
|
+
return idx < as_string()->value.length();
|
|
352
|
+
}
|
|
353
|
+
return StringPrototypes::get(key).has_value();
|
|
354
|
+
case JsType::Number: return NumberPrototypes::get(key).has_value();
|
|
355
|
+
case JsType::Uninitialized: Exception::throw_uninitialized_reference("#<Object>"); return false;
|
|
356
|
+
default: return false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
bool AnyValue::has_property(const AnyValue &key) const {
|
|
361
|
+
if (key.is_symbol()) {
|
|
362
|
+
switch (get_type()) {
|
|
363
|
+
case JsType::Object: return as_object()->has_symbol_property(key);
|
|
364
|
+
case JsType::Array: return as_array()->has_symbol_property(key);
|
|
365
|
+
case JsType::Function: return as_function()->has_symbol_property(key);
|
|
366
|
+
case JsType::Promise: return as_promise()->has_symbol_property(key);
|
|
367
|
+
case JsType::Iterator: return static_cast<JsIterator<AnyValue> *>(get_ptr())->has_symbol_property(key);
|
|
368
|
+
case JsType::AsyncIterator: return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->has_symbol_property(key);
|
|
369
|
+
default: return false;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return has_property(key.to_std_string());
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
AnyValue AnyValue::get_own_property(uint32_t idx) const {
|
|
376
|
+
if (is_array()) return as_array()->get_property(idx);
|
|
377
|
+
if (is_string()) return as_string()->get_property(idx);
|
|
378
|
+
return get_own_property(std::to_string(idx));
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
AnyValue AnyValue::get_own_property(const AnyValue &key) const {
|
|
382
|
+
if (key.is_number() && is_array()) return as_array()->get_property(key.as_double());
|
|
383
|
+
if (key.is_number() && is_string()) return as_string()->get_property(key.as_double());
|
|
384
|
+
if (key.is_symbol()) return get_own_symbol_property(key);
|
|
385
|
+
return get_own_property(key.to_std_string());
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
AnyValue AnyValue::get_own_symbol_property(const AnyValue &key) const {
|
|
389
|
+
return get_symbol_property_with_receiver(key, *this);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
AnyValue AnyValue::get_property_with_receiver(const std::string &key, AnyValue receiver) const {
|
|
393
|
+
switch (get_type()) {
|
|
394
|
+
case JsType::Object: return as_object()->get_property(key, receiver);
|
|
395
|
+
case JsType::Array: return as_array()->get_property(key, receiver);
|
|
396
|
+
case JsType::Function: return as_function()->get_property(key, receiver);
|
|
397
|
+
case JsType::Promise: return as_promise()->get_property(key, receiver);
|
|
398
|
+
case JsType::Iterator: return static_cast<JsIterator<AnyValue> *>(get_ptr())->get_property(key, receiver);
|
|
399
|
+
case JsType::AsyncIterator: return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->get_property(key, receiver);
|
|
400
|
+
case JsType::Symbol: return as_symbol()->get_property(key, receiver);
|
|
401
|
+
case JsType::String: return as_string()->get_property(key, receiver);
|
|
402
|
+
case JsType::Number: {
|
|
403
|
+
auto proto_it = NumberPrototypes::get(key);
|
|
404
|
+
if (proto_it.has_value()) return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key);
|
|
405
|
+
return Constants::UNDEFINED;
|
|
406
|
+
}
|
|
407
|
+
case JsType::Undefined: throw Exception::make_exception("Cannot read properties of undefined (reading '" + key + "')", "TypeError");
|
|
408
|
+
case JsType::Null: throw Exception::make_exception("Cannot read properties of null (reading '" + key + "')", "TypeError");
|
|
409
|
+
case JsType::Uninitialized: Exception::throw_uninitialized_reference("#<Object>");
|
|
410
|
+
default: return Constants::UNDEFINED;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
AnyValue AnyValue::get_symbol_property_with_receiver(const AnyValue &key, AnyValue receiver) const {
|
|
415
|
+
switch (get_type()) {
|
|
416
|
+
case JsType::Object: return as_object()->get_symbol_property(key, receiver);
|
|
417
|
+
case JsType::Array: return as_array()->get_symbol_property(key, receiver);
|
|
418
|
+
case JsType::Function: return as_function()->get_symbol_property(key, receiver);
|
|
419
|
+
case JsType::Promise: return as_promise()->get_symbol_property(key, receiver);
|
|
420
|
+
case JsType::Iterator: return static_cast<JsIterator<AnyValue> *>(get_ptr())->get_symbol_property(key, receiver);
|
|
421
|
+
case JsType::AsyncIterator: return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->get_symbol_property(key, receiver);
|
|
422
|
+
case JsType::Symbol: {
|
|
423
|
+
auto proto_it = SymbolPrototypes::get(key);
|
|
424
|
+
if (proto_it.has_value()) return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key.to_std_string());
|
|
425
|
+
return Constants::UNDEFINED;
|
|
426
|
+
}
|
|
427
|
+
case JsType::String: {
|
|
428
|
+
auto proto_it = StringPrototypes::get(key);
|
|
429
|
+
if (proto_it.has_value()) return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key.to_std_string());
|
|
430
|
+
return Constants::UNDEFINED;
|
|
431
|
+
}
|
|
432
|
+
case JsType::Number: {
|
|
433
|
+
auto proto_it = NumberPrototypes::get(key);
|
|
434
|
+
if (proto_it.has_value()) return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key.to_std_string());
|
|
435
|
+
return Constants::UNDEFINED;
|
|
436
|
+
}
|
|
437
|
+
case JsType::Undefined: throw Exception::make_exception("Cannot read properties of undefined (reading Symbol)", "TypeError");
|
|
438
|
+
case JsType::Null: throw Exception::make_exception("Cannot read properties of null (reading Symbol)", "TypeError");
|
|
439
|
+
case JsType::Uninitialized: Exception::throw_uninitialized_reference("#<Object>");
|
|
440
|
+
default: return Constants::UNDEFINED;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
AnyValue AnyValue::set_own_property(const std::string &key, AnyValue value) const {
|
|
445
|
+
switch (get_type()) {
|
|
446
|
+
case JsType::Object: return as_object()->set_property(key, value, *this);
|
|
447
|
+
case JsType::Array: return as_array()->set_property(key, value, *this);
|
|
448
|
+
case JsType::Function: return as_function()->set_property(key, value, *this);
|
|
449
|
+
case JsType::Promise: return as_promise()->set_property(key, value, *this);
|
|
450
|
+
case JsType::Undefined: throw Exception::make_exception("Cannot set properties of undefined (setting '" + key + "')", "TypeError");
|
|
451
|
+
case JsType::Null: throw Exception::make_exception("Cannot set properties of null (setting '" + key + "')", "TypeError");
|
|
452
|
+
default: return value;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
AnyValue AnyValue::set_own_property(uint32_t idx, AnyValue value) const {
|
|
457
|
+
if (is_array()) return as_array()->set_property(idx, value);
|
|
458
|
+
return set_own_property(std::to_string(idx), value);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
AnyValue AnyValue::set_own_property(const AnyValue &key, AnyValue value) const {
|
|
462
|
+
if (key.is_number() && is_array()) return as_array()->set_property(key.as_double(), value);
|
|
463
|
+
if (key.is_symbol()) return set_own_symbol_property(key, value);
|
|
464
|
+
return set_own_property(key.to_std_string(), value);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
AnyValue AnyValue::set_own_symbol_property(const AnyValue &key, AnyValue value) const {
|
|
468
|
+
switch (get_type()) {
|
|
469
|
+
case JsType::Object: return as_object()->set_symbol_property(key, value, *this);
|
|
470
|
+
case JsType::Array: return as_array()->set_symbol_property(key, value, *this);
|
|
471
|
+
case JsType::Function: return as_function()->set_symbol_property(key, value, *this);
|
|
472
|
+
case JsType::Promise: return as_promise()->set_symbol_property(key, value, *this);
|
|
473
|
+
case JsType::Iterator: return static_cast<JsIterator<AnyValue> *>(get_ptr())->set_symbol_property(key, value, *this);
|
|
474
|
+
case JsType::AsyncIterator: return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->set_symbol_property(key, value, *this);
|
|
475
|
+
case JsType::Undefined: throw Exception::make_exception("Cannot set properties of undefined (setting Symbol)", "TypeError");
|
|
476
|
+
case JsType::Null: throw Exception::make_exception("Cannot set properties of null (setting Symbol)", "TypeError");
|
|
477
|
+
default: return value;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
AnyValue AnyValue::call_own_property(const std::string &key, std::span<const AnyValue> args) const {
|
|
482
|
+
return get_own_property(key).call((*this), args, key);
|
|
483
|
+
}
|
|
484
|
+
AnyValue AnyValue::call_own_property(uint32_t idx, std::span<const AnyValue> args) const {
|
|
485
|
+
if (is_array()) return as_array()->get_property(idx).call((*this), args, "[" + std::to_string(idx) + "]");
|
|
486
|
+
if (is_string()) return as_string()->get_property(idx).call((*this), args, "[" + std::to_string(idx) + "]");
|
|
487
|
+
return call_own_property(std::to_string(idx), args);
|
|
488
|
+
}
|
|
489
|
+
AnyValue AnyValue::call_own_property(const AnyValue &key, std::span<const AnyValue> args) const {
|
|
490
|
+
if (key.is_number() && is_array()) return as_array()->get_property(key.as_double()).call((*this), args, "[" + key.to_std_string() + "]");
|
|
491
|
+
if (key.is_number() && is_string()) return as_string()->get_property(key.as_double()).call((*this), args, "[" + key.to_std_string() + "]");
|
|
492
|
+
if (key.is_symbol()) return get_own_symbol_property(key).call((*this), args, key.to_std_string());
|
|
493
|
+
return call_own_property(key.to_std_string(), args);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// --- AnyValue methods that were in any_value_defines.hpp ---
|
|
497
|
+
|
|
498
|
+
void AnyValue::define_data_property(const std::string &key, AnyValue value) {
|
|
499
|
+
if (is_object()) {
|
|
500
|
+
auto obj = as_object();
|
|
501
|
+
auto offset = obj->shape->get_offset(key);
|
|
502
|
+
if (offset.has_value()) obj->storage[offset.value()] = value;
|
|
503
|
+
else {
|
|
504
|
+
obj->shape = obj->shape->transition(key);
|
|
505
|
+
obj->storage.push_back(value);
|
|
506
|
+
}
|
|
507
|
+
} else if (is_function()) as_function()->props[key] = value;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
void AnyValue::define_data_property(const AnyValue &key, AnyValue value) {
|
|
511
|
+
if (key.is_symbol()) {
|
|
512
|
+
if (is_object()) as_object()->symbol_props[key] = value;
|
|
513
|
+
else if (is_function()) as_function()->symbol_props[key] = value;
|
|
514
|
+
} else define_data_property(key.to_std_string(), value);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
void AnyValue::define_data_property(const std::string &key, AnyValue value, bool writable, bool enumerable, bool configurable) {
|
|
518
|
+
define_data_property(key, AnyValue::make_data_descriptor(value, writable, enumerable, configurable));
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
void AnyValue::define_getter(const std::string &key, AnyValue getter) {
|
|
522
|
+
if (is_object()) {
|
|
523
|
+
auto obj = as_object();
|
|
524
|
+
auto offset = obj->shape->get_offset(key);
|
|
525
|
+
if (offset.has_value()) {
|
|
526
|
+
auto &val = obj->storage[offset.value()];
|
|
527
|
+
if (val.is_accessor_descriptor()) {
|
|
528
|
+
auto desc = val.as_accessor_descriptor();
|
|
529
|
+
desc->get = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue { return getter.call(thisVal, args); };
|
|
530
|
+
} else {
|
|
531
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue { return getter.call(thisVal, args); };
|
|
532
|
+
obj->storage[offset.value()] = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
|
|
533
|
+
}
|
|
534
|
+
} else {
|
|
535
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue { return getter.call(thisVal, args); };
|
|
536
|
+
obj->shape = obj->shape->transition(key);
|
|
537
|
+
obj->storage.push_back(AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true));
|
|
538
|
+
}
|
|
539
|
+
} else if (is_function()) {
|
|
540
|
+
auto &props = as_function()->props;
|
|
541
|
+
auto it = props.find(key);
|
|
542
|
+
if (it != props.end() && it->second.is_accessor_descriptor()) {
|
|
543
|
+
auto desc = it->second.as_accessor_descriptor();
|
|
544
|
+
desc->get = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue { return getter.call(thisVal, args); };
|
|
545
|
+
} else {
|
|
546
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue { return getter.call(thisVal, args); };
|
|
547
|
+
props[key] = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
void AnyValue::define_data_property(const AnyValue &key, AnyValue value, bool writable, bool enumerable, bool configurable) {
|
|
553
|
+
if (key.is_symbol()) {
|
|
554
|
+
auto desc = AnyValue::make_data_descriptor(value, writable, enumerable, configurable);
|
|
555
|
+
if (is_object()) as_object()->symbol_props[key] = desc;
|
|
556
|
+
else if (is_function()) as_function()->symbol_props[key] = desc;
|
|
557
|
+
} else define_data_property(key.to_std_string(), value, writable, enumerable, configurable);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
void AnyValue::define_getter(const AnyValue &key, AnyValue getter) {
|
|
561
|
+
if (key.is_symbol()) {
|
|
562
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue { return getter.call(thisVal, args); };
|
|
563
|
+
auto desc = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
|
|
564
|
+
if (is_object()) as_object()->symbol_props[key] = desc;
|
|
565
|
+
else if (is_function()) as_function()->symbol_props[key] = desc;
|
|
566
|
+
} else define_getter(key.to_std_string(), getter);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
void AnyValue::define_setter(const std::string &key, AnyValue setter) {
|
|
570
|
+
if (is_object()) {
|
|
571
|
+
auto obj = as_object();
|
|
572
|
+
auto offset = obj->shape->get_offset(key);
|
|
573
|
+
if (offset.has_value()) {
|
|
574
|
+
auto &val = obj->storage[offset.value()];
|
|
575
|
+
if (val.is_accessor_descriptor()) {
|
|
576
|
+
auto desc = val.as_accessor_descriptor();
|
|
577
|
+
desc->set = [setter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue {
|
|
578
|
+
if (args.empty()) return Constants::UNDEFINED;
|
|
579
|
+
return setter.call(thisVal, args);
|
|
580
|
+
};
|
|
581
|
+
} else {
|
|
582
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
|
|
583
|
+
if (args.empty()) return jspp::Constants::UNDEFINED;
|
|
584
|
+
return setter.call(thisVal, args);
|
|
585
|
+
};
|
|
586
|
+
obj->storage[offset.value()] = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
|
|
587
|
+
}
|
|
588
|
+
} else {
|
|
589
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
|
|
590
|
+
if (args.empty()) return jspp::Constants::UNDEFINED;
|
|
591
|
+
return setter.call(thisVal, args);
|
|
592
|
+
};
|
|
593
|
+
obj->shape = obj->shape->transition(key);
|
|
594
|
+
obj->storage.push_back(AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true));
|
|
595
|
+
}
|
|
596
|
+
} else if (is_function()) {
|
|
597
|
+
auto &props = as_function()->props;
|
|
598
|
+
auto it = props.find(key);
|
|
599
|
+
if (it != props.end() && it->second.is_accessor_descriptor()) {
|
|
600
|
+
auto desc = it->second.as_accessor_descriptor();
|
|
601
|
+
desc->set = [setter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue {
|
|
602
|
+
if (args.empty()) return Constants::UNDEFINED;
|
|
603
|
+
return setter.call(thisVal, args);
|
|
604
|
+
};
|
|
605
|
+
} else {
|
|
606
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
|
|
607
|
+
if (args.empty()) return jspp::Constants::UNDEFINED;
|
|
608
|
+
return setter.call(thisVal, args);
|
|
609
|
+
};
|
|
610
|
+
props[key] = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
void AnyValue::define_setter(const AnyValue &key, AnyValue setter) {
|
|
616
|
+
if (key.is_symbol()) {
|
|
617
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue {
|
|
618
|
+
if (args.empty()) return Constants::UNDEFINED;
|
|
619
|
+
return setter.call(thisVal, args);
|
|
620
|
+
};
|
|
621
|
+
auto desc = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
|
|
622
|
+
if (is_object()) as_object()->symbol_props[key] = desc;
|
|
623
|
+
else if (is_function()) as_function()->symbol_props[key] = desc;
|
|
624
|
+
} else define_setter(key.to_std_string(), setter);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// AnyValue iterator methods from runtime.cpp
|
|
628
|
+
JsIterator<AnyValue>* AnyValue::as_iterator() const noexcept {
|
|
629
|
+
return static_cast<JsIterator<AnyValue> *>(get_ptr());
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
JsAsyncIterator<AnyValue>* AnyValue::as_async_iterator() const noexcept {
|
|
633
|
+
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr());
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
} // namespace jspp
|