@ugo-studio/jspp 0.3.1 → 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/dist/cli/args.js +22 -0
- package/dist/cli/compiler.js +53 -0
- package/dist/cli/index.js +43 -117
- 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 +25 -27
- package/dist/cli/wasm.js +70 -0
- package/dist/index.js +17 -6
- package/dist/{analysis → interpreter/analysis}/scope.js +34 -1
- package/dist/{analysis → interpreter/analysis}/typeAnalyzer.js +542 -3
- package/dist/{core → interpreter/core}/codegen/class-handlers.js +1 -1
- package/dist/{core → interpreter/core}/codegen/control-flow-handlers.js +2 -2
- package/dist/{core → interpreter/core}/codegen/declaration-handlers.js +21 -9
- package/dist/{core → interpreter/core}/codegen/destructuring-handlers.js +3 -3
- package/dist/{core → interpreter/core}/codegen/expression-handlers.js +44 -61
- package/dist/{core → interpreter/core}/codegen/function-handlers.js +108 -61
- package/dist/{core → interpreter/core}/codegen/helpers.js +79 -11
- 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 +39 -1
- package/package.json +6 -4
- package/scripts/precompile-headers.ts +63 -19
- package/scripts/setup-emsdk.ts +114 -0
- package/src/prelude/any_value.cpp +851 -599
- package/src/prelude/any_value.hpp +28 -30
- package/src/prelude/jspp.hpp +3 -1
- package/src/prelude/library/boolean.cpp +30 -0
- package/src/prelude/library/boolean.hpp +14 -0
- package/src/prelude/library/error.cpp +2 -2
- package/src/prelude/library/global.cpp +2 -0
- package/src/prelude/library/math.cpp +46 -43
- package/src/prelude/library/math.hpp +2 -0
- package/src/prelude/library/object.cpp +1 -1
- package/src/prelude/types.hpp +10 -9
- package/src/prelude/utils/access.hpp +2 -2
- package/src/prelude/utils/assignment_operators.hpp +40 -20
- package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
- package/src/prelude/utils/log_any_value/primitives.hpp +1 -1
- package/src/prelude/utils/operators.hpp +87 -87
- package/src/prelude/utils/operators_native.hpp +349 -0
- package/src/prelude/utils/well_known_symbols.hpp +13 -13
- package/src/prelude/values/array.cpp +3 -3
- package/src/prelude/values/boolean.cpp +64 -0
- package/src/prelude/values/number.cpp +137 -92
- package/src/prelude/values/object.cpp +163 -122
- package/src/prelude/values/prototypes/boolean.hpp +24 -0
- package/src/prelude/values/prototypes/number.hpp +8 -1
- 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 -88
- package/src/prelude/utils/operators_primitive.hpp +0 -337
- /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
|
@@ -11,626 +11,878 @@
|
|
|
11
11
|
#include "values/descriptors.hpp"
|
|
12
12
|
#include "exception.hpp"
|
|
13
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
|
|
14
|
+
namespace jspp
|
|
43
15
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
AnyValue AnyValue::
|
|
79
|
-
{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
AnyValue AnyValue::
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
AnyValue AnyValue::
|
|
95
|
-
{
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
AnyValue AnyValue::
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
AnyValue AnyValue::
|
|
111
|
-
{
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
{
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
AnyValue AnyValue::
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
AnyValue AnyValue::
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
16
|
+
|
|
17
|
+
// --- AnyValue methods that were in any_value_helpers.hpp ---
|
|
18
|
+
|
|
19
|
+
bool AnyValue::operator==(const AnyValue &other) const noexcept
|
|
20
|
+
{
|
|
21
|
+
return storage == other.storage;
|
|
22
|
+
}
|
|
23
|
+
bool AnyValue::operator==(const std::string &other) const noexcept
|
|
24
|
+
{
|
|
25
|
+
if (!is_string())
|
|
26
|
+
return false;
|
|
27
|
+
return as_string()->value == other;
|
|
28
|
+
}
|
|
29
|
+
bool AnyValue::operator<(const AnyValue &other) const noexcept
|
|
30
|
+
{
|
|
31
|
+
return storage < other.storage;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
JsString *AnyValue::as_string() const noexcept { return static_cast<JsString *>(get_ptr()); }
|
|
35
|
+
JsObject *AnyValue::as_object() const noexcept { return static_cast<JsObject *>(get_ptr()); }
|
|
36
|
+
JsArray *AnyValue::as_array() const noexcept { return static_cast<JsArray *>(get_ptr()); }
|
|
37
|
+
JsFunction *AnyValue::as_function() const noexcept { return static_cast<JsFunction *>(get_ptr()); }
|
|
38
|
+
JsSymbol *AnyValue::as_symbol() const noexcept { return static_cast<JsSymbol *>(get_ptr()); }
|
|
39
|
+
JsPromise *AnyValue::as_promise() const noexcept { return static_cast<JsPromise *>(get_ptr()); }
|
|
40
|
+
DataDescriptor *AnyValue::as_data_descriptor() const noexcept { return static_cast<DataDescriptor *>(get_ptr()); }
|
|
41
|
+
AccessorDescriptor *AnyValue::as_accessor_descriptor() const noexcept { return static_cast<AccessorDescriptor *>(get_ptr()); }
|
|
42
|
+
|
|
43
|
+
bool AnyValue::is_generator() const noexcept { return is_function() && as_function()->is_generator; }
|
|
44
|
+
|
|
45
|
+
// --- AnyValue FACTORIES ---
|
|
46
|
+
AnyValue AnyValue::make_string(const std::string &raw_s) noexcept
|
|
47
|
+
{
|
|
48
|
+
return from_ptr(new JsString(raw_s));
|
|
49
|
+
}
|
|
50
|
+
AnyValue AnyValue::make_object(std::initializer_list<std::pair<std::string, AnyValue>> props) noexcept
|
|
51
|
+
{
|
|
52
|
+
return from_ptr(new JsObject(props, make_null()));
|
|
53
|
+
}
|
|
54
|
+
AnyValue AnyValue::make_object(const std::map<std::string, AnyValue> &props) noexcept
|
|
55
|
+
{
|
|
56
|
+
return from_ptr(new JsObject(props, make_null()));
|
|
57
|
+
}
|
|
58
|
+
AnyValue AnyValue::make_array(std::span<const AnyValue> dense) noexcept
|
|
59
|
+
{
|
|
60
|
+
std::vector<AnyValue> vec;
|
|
61
|
+
vec.reserve(dense.size());
|
|
62
|
+
for (const auto &item : dense)
|
|
63
|
+
vec.push_back(item);
|
|
64
|
+
return from_ptr(new JsArray(std::move(vec)));
|
|
65
|
+
}
|
|
66
|
+
AnyValue AnyValue::make_array(const std::vector<AnyValue> &dense) noexcept
|
|
67
|
+
{
|
|
68
|
+
return from_ptr(new JsArray(dense));
|
|
69
|
+
}
|
|
70
|
+
AnyValue AnyValue::make_array(std::vector<AnyValue> &&dense) noexcept
|
|
71
|
+
{
|
|
72
|
+
return from_ptr(new JsArray(std::move(dense)));
|
|
73
|
+
}
|
|
74
|
+
AnyValue AnyValue::make_function(const JsFunctionCallable &call, const std::optional<std::string> &name, bool is_constructor) noexcept
|
|
75
|
+
{
|
|
76
|
+
auto v = from_ptr(new JsFunction(call, name, {}, {}, false, is_constructor));
|
|
77
|
+
auto proto = make_object({});
|
|
78
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
79
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
80
|
+
return v;
|
|
81
|
+
}
|
|
82
|
+
AnyValue AnyValue::make_class(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
83
|
+
{
|
|
84
|
+
auto v = from_ptr(new JsFunction(call, name, {}, {}, true));
|
|
85
|
+
auto proto = make_object({});
|
|
86
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
87
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
88
|
+
return v;
|
|
89
|
+
}
|
|
90
|
+
AnyValue AnyValue::make_generator(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
91
|
+
{
|
|
92
|
+
auto v = from_ptr(new JsFunction(call, true, name, {}, {}, false));
|
|
93
|
+
auto proto = make_object({});
|
|
94
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
95
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
96
|
+
return v;
|
|
97
|
+
}
|
|
98
|
+
AnyValue AnyValue::make_async_function(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
99
|
+
{
|
|
100
|
+
auto v = from_ptr(new JsFunction(call, false, true, name, {}, {}, false));
|
|
101
|
+
auto proto = make_object({});
|
|
102
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
103
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
104
|
+
return v;
|
|
105
|
+
}
|
|
106
|
+
AnyValue AnyValue::make_async_generator(const JsFunctionCallable &call, const std::optional<std::string> &name) noexcept
|
|
107
|
+
{
|
|
108
|
+
auto v = from_ptr(new JsFunction(call, true, true, name, {}, {}, false));
|
|
109
|
+
auto proto = make_object({});
|
|
110
|
+
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
111
|
+
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
112
|
+
return v;
|
|
113
|
+
}
|
|
114
|
+
AnyValue AnyValue::make_symbol(const std::string &description) noexcept
|
|
115
|
+
{
|
|
116
|
+
return from_ptr(new JsSymbol(description));
|
|
117
|
+
}
|
|
118
|
+
AnyValue AnyValue::make_promise(const JsPromise &promise) noexcept
|
|
119
|
+
{
|
|
120
|
+
auto p = new JsPromise();
|
|
121
|
+
*p = promise;
|
|
122
|
+
return from_ptr(p);
|
|
123
|
+
}
|
|
124
|
+
AnyValue AnyValue::make_data_descriptor(AnyValue value, bool writable, bool enumerable, bool configurable) noexcept
|
|
125
|
+
{
|
|
126
|
+
return from_ptr(new DataDescriptor(value, writable, enumerable, configurable));
|
|
127
|
+
}
|
|
128
|
+
AnyValue AnyValue::make_accessor_descriptor(const std::optional<std::function<AnyValue(AnyValue, std::span<const AnyValue>)>> &get,
|
|
129
|
+
const std::optional<std::function<AnyValue(AnyValue, std::span<const AnyValue>)>> &set,
|
|
130
|
+
bool enumerable,
|
|
131
|
+
bool configurable) noexcept
|
|
132
|
+
{
|
|
133
|
+
return from_ptr(new AccessorDescriptor(get, set, enumerable, configurable));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
AnyValue AnyValue::from_symbol(JsSymbol *sym) noexcept
|
|
137
|
+
{
|
|
138
|
+
return from_ptr(sym);
|
|
139
|
+
}
|
|
140
|
+
AnyValue AnyValue::from_string(JsString *str) noexcept
|
|
141
|
+
{
|
|
142
|
+
return from_ptr(str);
|
|
143
|
+
}
|
|
144
|
+
AnyValue AnyValue::from_promise(JsPromise &&promise) noexcept
|
|
145
|
+
{
|
|
146
|
+
auto it = new JsPromise(std::move(promise));
|
|
147
|
+
return from_ptr(it);
|
|
148
|
+
}
|
|
149
|
+
AnyValue AnyValue::from_iterator(JsIterator<AnyValue> &&iterator) noexcept
|
|
150
|
+
{
|
|
151
|
+
auto it = new JsIterator<AnyValue>(std::move(iterator));
|
|
152
|
+
return from_ptr(it);
|
|
153
|
+
}
|
|
154
|
+
AnyValue AnyValue::from_iterator_ref(JsIterator<AnyValue> *iterator) noexcept
|
|
155
|
+
{
|
|
156
|
+
return from_ptr(iterator);
|
|
157
|
+
}
|
|
158
|
+
AnyValue AnyValue::from_async_iterator(JsAsyncIterator<AnyValue> &&iterator) noexcept
|
|
159
|
+
{
|
|
160
|
+
auto it = new JsAsyncIterator<AnyValue>(std::move(iterator));
|
|
161
|
+
return from_ptr(it);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
AnyValue AnyValue::resolve_property_for_read(const AnyValue &val, AnyValue thisVal, const std::string &propName) noexcept
|
|
165
|
+
{
|
|
166
|
+
if (val.is_data_descriptor())
|
|
167
|
+
{
|
|
168
|
+
return val.as_data_descriptor()->value;
|
|
169
|
+
}
|
|
170
|
+
if (val.is_accessor_descriptor())
|
|
171
|
+
{
|
|
172
|
+
auto accessor = val.as_accessor_descriptor();
|
|
173
|
+
if (accessor->get.has_value())
|
|
174
|
+
return accessor->get.value()(thisVal, std::span<const AnyValue>{});
|
|
175
|
+
else
|
|
176
|
+
{
|
|
177
|
+
return Constants::UNDEFINED;
|
|
178
|
+
}
|
|
164
179
|
}
|
|
180
|
+
return val;
|
|
165
181
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
|
182
|
+
|
|
183
|
+
AnyValue AnyValue::resolve_property_for_write(AnyValue &val, AnyValue thisVal, const AnyValue &new_val, const std::string &propName)
|
|
184
|
+
{
|
|
185
|
+
if (val.is_data_descriptor())
|
|
186
|
+
{
|
|
187
|
+
auto data = val.as_data_descriptor();
|
|
188
|
+
if (data->writable)
|
|
189
|
+
{
|
|
190
|
+
data->value = new_val;
|
|
191
|
+
return new_val;
|
|
192
|
+
}
|
|
193
|
+
else
|
|
194
|
+
{
|
|
195
|
+
throw Exception::make_exception("Cannot assign to read only property '" + propName + "'", "TypeError");
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (val.is_accessor_descriptor())
|
|
199
|
+
{
|
|
200
|
+
auto accessor = val.as_accessor_descriptor();
|
|
201
|
+
if (accessor->set.has_value())
|
|
202
|
+
{
|
|
203
|
+
const AnyValue args[] = {new_val};
|
|
204
|
+
accessor->set.value()(thisVal, std::span<const AnyValue>(args, 1));
|
|
205
|
+
return new_val;
|
|
206
|
+
}
|
|
207
|
+
else
|
|
208
|
+
{
|
|
209
|
+
throw Exception::make_exception("Cannot set property of #<Object> which has only a getter", "TypeError");
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
val = new_val;
|
|
213
|
+
return new_val;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
std::string AnyValue::to_std_string() const
|
|
217
|
+
{
|
|
218
|
+
switch (get_type())
|
|
219
|
+
{
|
|
220
|
+
case JsType::Undefined:
|
|
211
221
|
return "undefined";
|
|
222
|
+
case JsType::Null:
|
|
223
|
+
return "null";
|
|
224
|
+
case JsType::Boolean:
|
|
225
|
+
return JsBoolean::to_std_string(as_boolean());
|
|
226
|
+
case JsType::String:
|
|
227
|
+
return as_string()->to_std_string();
|
|
228
|
+
case JsType::Object:
|
|
229
|
+
return as_object()->to_std_string();
|
|
230
|
+
case JsType::Array:
|
|
231
|
+
return as_array()->to_std_string();
|
|
232
|
+
case JsType::Function:
|
|
233
|
+
return as_function()->to_std_string();
|
|
234
|
+
case JsType::Iterator:
|
|
235
|
+
return as_iterator()->to_std_string();
|
|
236
|
+
case JsType::AsyncIterator:
|
|
237
|
+
return as_async_iterator()->to_std_string();
|
|
238
|
+
case JsType::Promise:
|
|
239
|
+
return as_promise()->to_std_string();
|
|
240
|
+
case JsType::Symbol:
|
|
241
|
+
return as_symbol()->to_std_string();
|
|
242
|
+
case JsType::DataDescriptor:
|
|
243
|
+
return as_data_descriptor()->value.to_std_string();
|
|
244
|
+
case JsType::AccessorDescriptor:
|
|
245
|
+
{
|
|
246
|
+
if (as_accessor_descriptor()->get.has_value())
|
|
247
|
+
return as_accessor_descriptor()->get.value()(*this, {}).to_std_string();
|
|
248
|
+
else
|
|
249
|
+
return "undefined";
|
|
250
|
+
}
|
|
251
|
+
case JsType::Number:
|
|
252
|
+
return JsNumber::to_std_string(as_double());
|
|
253
|
+
case JsType::Uninitialized:
|
|
254
|
+
Exception::throw_uninitialized_reference("#<Object>");
|
|
255
|
+
default:
|
|
256
|
+
return "";
|
|
257
|
+
}
|
|
212
258
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if (
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
AnyValue
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
259
|
+
|
|
260
|
+
AnyValue &AnyValue::set_prototype(AnyValue proto)
|
|
261
|
+
{
|
|
262
|
+
if (is_object())
|
|
263
|
+
as_object()->proto = proto;
|
|
264
|
+
else if (is_array())
|
|
265
|
+
as_array()->proto = proto;
|
|
266
|
+
else if (is_function())
|
|
267
|
+
as_function()->proto = proto;
|
|
268
|
+
else if (is_uninitialized())
|
|
269
|
+
Exception::throw_uninitialized_reference("#<Object>");
|
|
270
|
+
return *this;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
AnyValue AnyValue::call(AnyValue thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr) const
|
|
274
|
+
{
|
|
275
|
+
if (!is_function())
|
|
276
|
+
throw Exception::make_exception(expr.value_or(to_std_string()) + " is not a function", "TypeError");
|
|
277
|
+
return as_function()->call(thisVal, args);
|
|
278
|
+
}
|
|
279
|
+
AnyValue AnyValue::optional_call(AnyValue thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr) const
|
|
280
|
+
{
|
|
281
|
+
if (is_null() || is_undefined())
|
|
282
|
+
return Constants::UNDEFINED;
|
|
283
|
+
return as_function()->call(thisVal, args);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
AnyValue AnyValue::construct(std::span<const AnyValue> args, const std::optional<std::string> &name) const
|
|
287
|
+
{
|
|
288
|
+
if (!is_function() || !as_function()->is_constructor)
|
|
289
|
+
{
|
|
290
|
+
throw Exception::make_exception(name.value_or(to_std_string()) + " is not a constructor", "TypeError");
|
|
291
|
+
}
|
|
292
|
+
AnyValue proto = get_own_property("prototype");
|
|
293
|
+
if (!proto.is_object())
|
|
294
|
+
proto = AnyValue::make_object({});
|
|
295
|
+
AnyValue instance = AnyValue::make_object({}).set_prototype(proto);
|
|
296
|
+
AnyValue result = call(instance, args);
|
|
297
|
+
if (result.is_object() || result.is_function() || result.is_array() || result.is_promise())
|
|
298
|
+
return result;
|
|
299
|
+
return instance;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// --- AnyValue methods that were in any_value_access.hpp ---
|
|
303
|
+
|
|
304
|
+
AnyValue AnyValue::get_own_property(const std::string &key) const
|
|
305
|
+
{
|
|
306
|
+
return get_property_with_receiver(key, *this);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
AnyValue AnyValue::get_own_property_descriptor(const AnyValue &key) const
|
|
310
|
+
{
|
|
311
|
+
if (key.is_symbol())
|
|
312
|
+
{
|
|
313
|
+
switch (get_type())
|
|
314
|
+
{
|
|
315
|
+
case JsType::Object:
|
|
316
|
+
{
|
|
317
|
+
auto obj = as_object();
|
|
318
|
+
auto it = obj->symbol_props.find(key);
|
|
319
|
+
if (it != obj->symbol_props.end())
|
|
320
|
+
return it->second;
|
|
321
|
+
return Constants::UNDEFINED;
|
|
322
|
+
}
|
|
323
|
+
case JsType::Array:
|
|
324
|
+
{
|
|
325
|
+
auto arr = as_array();
|
|
326
|
+
auto it = arr->symbol_props.find(key);
|
|
327
|
+
if (it != arr->symbol_props.end())
|
|
328
|
+
return it->second;
|
|
329
|
+
return Constants::UNDEFINED;
|
|
330
|
+
}
|
|
331
|
+
case JsType::Function:
|
|
332
|
+
{
|
|
333
|
+
auto func = as_function();
|
|
334
|
+
auto it = func->symbol_props.find(key);
|
|
335
|
+
if (it != func->symbol_props.end())
|
|
336
|
+
return it->second;
|
|
337
|
+
return Constants::UNDEFINED;
|
|
338
|
+
}
|
|
339
|
+
default:
|
|
340
|
+
return Constants::UNDEFINED;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
std::string key_str = key.to_std_string();
|
|
345
|
+
switch (get_type())
|
|
346
|
+
{
|
|
347
|
+
case JsType::Object:
|
|
348
|
+
{
|
|
279
349
|
auto obj = as_object();
|
|
280
|
-
|
|
281
|
-
|
|
350
|
+
if (obj->deleted_keys.count(key_str))
|
|
351
|
+
return Constants::UNDEFINED;
|
|
352
|
+
auto offset = obj->shape->get_offset(key_str);
|
|
353
|
+
if (offset.has_value())
|
|
354
|
+
return obj->storage[offset.value()];
|
|
282
355
|
return Constants::UNDEFINED;
|
|
283
356
|
}
|
|
284
|
-
case JsType::Array:
|
|
357
|
+
case JsType::Array:
|
|
358
|
+
{
|
|
285
359
|
auto arr = as_array();
|
|
286
|
-
|
|
287
|
-
|
|
360
|
+
if (key_str == "length")
|
|
361
|
+
return AnyValue::make_number(arr->length);
|
|
362
|
+
if (JsArray::is_array_index(key_str))
|
|
363
|
+
{
|
|
364
|
+
uint32_t idx = static_cast<uint32_t>(std::stoull(key_str));
|
|
365
|
+
if (idx < arr->dense.size() && !arr->dense[idx].is_uninitialized())
|
|
366
|
+
return arr->dense[idx];
|
|
367
|
+
if (arr->sparse.count(idx))
|
|
368
|
+
return arr->sparse[idx];
|
|
369
|
+
}
|
|
370
|
+
if (arr->props.count(key_str))
|
|
371
|
+
return arr->props.at(key_str);
|
|
288
372
|
return Constants::UNDEFINED;
|
|
289
373
|
}
|
|
290
|
-
case JsType::Function:
|
|
374
|
+
case JsType::Function:
|
|
375
|
+
{
|
|
291
376
|
auto func = as_function();
|
|
292
|
-
|
|
293
|
-
|
|
377
|
+
if (func->props.count(key_str))
|
|
378
|
+
return func->props.at(key_str);
|
|
379
|
+
return Constants::UNDEFINED;
|
|
380
|
+
}
|
|
381
|
+
case JsType::String:
|
|
382
|
+
{
|
|
383
|
+
auto str = as_string();
|
|
384
|
+
if (key_str == "length")
|
|
385
|
+
return AnyValue::make_number(str->value.length());
|
|
386
|
+
if (JsArray::is_array_index(key_str))
|
|
387
|
+
{
|
|
388
|
+
uint32_t idx = static_cast<uint32_t>(std::stoull(key_str));
|
|
389
|
+
if (idx < str->value.length())
|
|
390
|
+
return AnyValue::make_string(std::string(1, str->value[idx]));
|
|
391
|
+
}
|
|
392
|
+
return Constants::UNDEFINED;
|
|
393
|
+
}
|
|
394
|
+
default:
|
|
395
|
+
return Constants::UNDEFINED;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
bool AnyValue::has_property(const std::string &key) const
|
|
400
|
+
{
|
|
401
|
+
switch (get_type())
|
|
402
|
+
{
|
|
403
|
+
case JsType::Object:
|
|
404
|
+
return as_object()->has_property(key);
|
|
405
|
+
case JsType::Array:
|
|
406
|
+
return as_array()->has_property(key);
|
|
407
|
+
case JsType::Function:
|
|
408
|
+
return as_function()->has_property(key);
|
|
409
|
+
case JsType::Promise:
|
|
410
|
+
return as_promise()->get_property(key, *this).is_undefined() == false;
|
|
411
|
+
case JsType::Iterator:
|
|
412
|
+
return static_cast<JsIterator<AnyValue> *>(get_ptr())->get_property(key, *this).is_undefined() == false;
|
|
413
|
+
case JsType::AsyncIterator:
|
|
414
|
+
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->get_property(key, *this).is_undefined() == false;
|
|
415
|
+
case JsType::Symbol:
|
|
416
|
+
return SymbolPrototypes::get(key).has_value();
|
|
417
|
+
case JsType::String:
|
|
418
|
+
if (key == "length")
|
|
419
|
+
return true;
|
|
420
|
+
if (JsArray::is_array_index(key))
|
|
421
|
+
{
|
|
422
|
+
uint32_t idx = static_cast<uint32_t>(std::stoull(key));
|
|
423
|
+
return idx < as_string()->value.length();
|
|
424
|
+
}
|
|
425
|
+
return StringPrototypes::get(key).has_value();
|
|
426
|
+
case JsType::Number:
|
|
427
|
+
return NumberPrototypes::get(key).has_value();
|
|
428
|
+
case JsType::Uninitialized:
|
|
429
|
+
Exception::throw_uninitialized_reference("#<Object>");
|
|
430
|
+
return false;
|
|
431
|
+
default:
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
bool AnyValue::has_property(const AnyValue &key) const
|
|
437
|
+
{
|
|
438
|
+
if (key.is_symbol())
|
|
439
|
+
{
|
|
440
|
+
switch (get_type())
|
|
441
|
+
{
|
|
442
|
+
case JsType::Object:
|
|
443
|
+
return as_object()->has_symbol_property(key);
|
|
444
|
+
case JsType::Array:
|
|
445
|
+
return as_array()->has_symbol_property(key);
|
|
446
|
+
case JsType::Function:
|
|
447
|
+
return as_function()->has_symbol_property(key);
|
|
448
|
+
case JsType::Promise:
|
|
449
|
+
return as_promise()->has_symbol_property(key);
|
|
450
|
+
case JsType::Iterator:
|
|
451
|
+
return static_cast<JsIterator<AnyValue> *>(get_ptr())->has_symbol_property(key);
|
|
452
|
+
case JsType::AsyncIterator:
|
|
453
|
+
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->has_symbol_property(key);
|
|
454
|
+
default:
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return has_property(key.to_std_string());
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
AnyValue AnyValue::get_own_property(uint32_t idx) const
|
|
462
|
+
{
|
|
463
|
+
if (is_array())
|
|
464
|
+
return as_array()->get_property(idx);
|
|
465
|
+
if (is_string())
|
|
466
|
+
return as_string()->get_property(idx);
|
|
467
|
+
return get_own_property(std::to_string(idx));
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
AnyValue AnyValue::get_own_property(const AnyValue &key) const
|
|
471
|
+
{
|
|
472
|
+
if (key.is_number() && is_array())
|
|
473
|
+
return as_array()->get_property(key.as_double());
|
|
474
|
+
if (key.is_number() && is_string())
|
|
475
|
+
return as_string()->get_property(key.as_double());
|
|
476
|
+
if (key.is_symbol())
|
|
477
|
+
return get_own_symbol_property(key);
|
|
478
|
+
return get_own_property(key.to_std_string());
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
AnyValue AnyValue::get_own_symbol_property(const AnyValue &key) const
|
|
482
|
+
{
|
|
483
|
+
return get_symbol_property_with_receiver(key, *this);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
AnyValue AnyValue::get_property_with_receiver(const std::string &key, AnyValue receiver) const
|
|
487
|
+
{
|
|
488
|
+
switch (get_type())
|
|
489
|
+
{
|
|
490
|
+
case JsType::Object:
|
|
491
|
+
return as_object()->get_property(key, receiver);
|
|
492
|
+
case JsType::Array:
|
|
493
|
+
return as_array()->get_property(key, receiver);
|
|
494
|
+
case JsType::Function:
|
|
495
|
+
return as_function()->get_property(key, receiver);
|
|
496
|
+
case JsType::Promise:
|
|
497
|
+
return as_promise()->get_property(key, receiver);
|
|
498
|
+
case JsType::Iterator:
|
|
499
|
+
return static_cast<JsIterator<AnyValue> *>(get_ptr())->get_property(key, receiver);
|
|
500
|
+
case JsType::AsyncIterator:
|
|
501
|
+
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->get_property(key, receiver);
|
|
502
|
+
case JsType::Symbol:
|
|
503
|
+
return as_symbol()->get_property(key, receiver);
|
|
504
|
+
case JsType::String:
|
|
505
|
+
return as_string()->get_property(key, receiver);
|
|
506
|
+
case JsType::Number:
|
|
507
|
+
{
|
|
508
|
+
auto proto_it = NumberPrototypes::get(key);
|
|
509
|
+
if (proto_it.has_value())
|
|
510
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key);
|
|
511
|
+
return Constants::UNDEFINED;
|
|
512
|
+
}
|
|
513
|
+
case JsType::Boolean:
|
|
514
|
+
{
|
|
515
|
+
auto proto_it = BooleanPrototypes::get(key);
|
|
516
|
+
if (proto_it.has_value())
|
|
517
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key);
|
|
518
|
+
return Constants::UNDEFINED;
|
|
519
|
+
}
|
|
520
|
+
case JsType::Undefined:
|
|
521
|
+
throw Exception::make_exception("Cannot read properties of undefined (reading '" + key + "')", "TypeError");
|
|
522
|
+
case JsType::Null:
|
|
523
|
+
throw Exception::make_exception("Cannot read properties of null (reading '" + key + "')", "TypeError");
|
|
524
|
+
case JsType::Uninitialized:
|
|
525
|
+
Exception::throw_uninitialized_reference("#<Object>");
|
|
526
|
+
default:
|
|
527
|
+
return Constants::UNDEFINED;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
AnyValue AnyValue::get_symbol_property_with_receiver(const AnyValue &key, AnyValue receiver) const
|
|
532
|
+
{
|
|
533
|
+
switch (get_type())
|
|
534
|
+
{
|
|
535
|
+
case JsType::Object:
|
|
536
|
+
return as_object()->get_symbol_property(key, receiver);
|
|
537
|
+
case JsType::Array:
|
|
538
|
+
return as_array()->get_symbol_property(key, receiver);
|
|
539
|
+
case JsType::Function:
|
|
540
|
+
return as_function()->get_symbol_property(key, receiver);
|
|
541
|
+
case JsType::Promise:
|
|
542
|
+
return as_promise()->get_symbol_property(key, receiver);
|
|
543
|
+
case JsType::Iterator:
|
|
544
|
+
return static_cast<JsIterator<AnyValue> *>(get_ptr())->get_symbol_property(key, receiver);
|
|
545
|
+
case JsType::AsyncIterator:
|
|
546
|
+
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->get_symbol_property(key, receiver);
|
|
547
|
+
case JsType::Symbol:
|
|
548
|
+
{
|
|
549
|
+
auto proto_it = SymbolPrototypes::get(key);
|
|
550
|
+
if (proto_it.has_value())
|
|
551
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key.to_std_string());
|
|
552
|
+
return Constants::UNDEFINED;
|
|
553
|
+
}
|
|
554
|
+
case JsType::String:
|
|
555
|
+
{
|
|
556
|
+
auto proto_it = StringPrototypes::get(key);
|
|
557
|
+
if (proto_it.has_value())
|
|
558
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key.to_std_string());
|
|
559
|
+
return Constants::UNDEFINED;
|
|
560
|
+
}
|
|
561
|
+
case JsType::Number:
|
|
562
|
+
{
|
|
563
|
+
auto proto_it = NumberPrototypes::get(key);
|
|
564
|
+
if (proto_it.has_value())
|
|
565
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key.to_std_string());
|
|
566
|
+
return Constants::UNDEFINED;
|
|
567
|
+
}
|
|
568
|
+
case JsType::Boolean:
|
|
569
|
+
{
|
|
570
|
+
auto proto_it = BooleanPrototypes::get(key);
|
|
571
|
+
if (proto_it.has_value())
|
|
572
|
+
return AnyValue::resolve_property_for_read(proto_it.value(), receiver, key.to_std_string());
|
|
573
|
+
return Constants::UNDEFINED;
|
|
574
|
+
}
|
|
575
|
+
case JsType::Undefined:
|
|
576
|
+
throw Exception::make_exception("Cannot read properties of undefined (reading Symbol)", "TypeError");
|
|
577
|
+
case JsType::Null:
|
|
578
|
+
throw Exception::make_exception("Cannot read properties of null (reading Symbol)", "TypeError");
|
|
579
|
+
case JsType::Uninitialized:
|
|
580
|
+
Exception::throw_uninitialized_reference("#<Object>");
|
|
581
|
+
default:
|
|
294
582
|
return Constants::UNDEFINED;
|
|
295
583
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
return
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
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);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
AnyValue AnyValue::set_own_property(const std::string &key, AnyValue value) const
|
|
587
|
+
{
|
|
588
|
+
switch (get_type())
|
|
589
|
+
{
|
|
590
|
+
case JsType::Object:
|
|
591
|
+
return as_object()->set_property(key, value, *this);
|
|
592
|
+
case JsType::Array:
|
|
593
|
+
return as_array()->set_property(key, value, *this);
|
|
594
|
+
case JsType::Function:
|
|
595
|
+
return as_function()->set_property(key, value, *this);
|
|
596
|
+
case JsType::Promise:
|
|
597
|
+
return as_promise()->set_property(key, value, *this);
|
|
598
|
+
case JsType::Undefined:
|
|
599
|
+
throw Exception::make_exception("Cannot set properties of undefined (setting '" + key + "')", "TypeError");
|
|
600
|
+
case JsType::Null:
|
|
601
|
+
throw Exception::make_exception("Cannot set properties of null (setting '" + key + "')", "TypeError");
|
|
602
|
+
default:
|
|
603
|
+
return value;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
AnyValue AnyValue::set_own_property(uint32_t idx, AnyValue value) const
|
|
608
|
+
{
|
|
609
|
+
if (is_array())
|
|
610
|
+
return as_array()->set_property(idx, value);
|
|
611
|
+
return set_own_property(std::to_string(idx), value);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
AnyValue AnyValue::set_own_property(const AnyValue &key, AnyValue value) const
|
|
615
|
+
{
|
|
616
|
+
if (key.is_number() && is_array())
|
|
617
|
+
return as_array()->set_property(key.as_double(), value);
|
|
618
|
+
if (key.is_symbol())
|
|
619
|
+
return set_own_symbol_property(key, value);
|
|
620
|
+
return set_own_property(key.to_std_string(), value);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
AnyValue AnyValue::set_own_symbol_property(const AnyValue &key, AnyValue value) const
|
|
624
|
+
{
|
|
625
|
+
switch (get_type())
|
|
626
|
+
{
|
|
627
|
+
case JsType::Object:
|
|
628
|
+
return as_object()->set_symbol_property(key, value, *this);
|
|
629
|
+
case JsType::Array:
|
|
630
|
+
return as_array()->set_symbol_property(key, value, *this);
|
|
631
|
+
case JsType::Function:
|
|
632
|
+
return as_function()->set_symbol_property(key, value, *this);
|
|
633
|
+
case JsType::Promise:
|
|
634
|
+
return as_promise()->set_symbol_property(key, value, *this);
|
|
635
|
+
case JsType::Iterator:
|
|
636
|
+
return static_cast<JsIterator<AnyValue> *>(get_ptr())->set_symbol_property(key, value, *this);
|
|
637
|
+
case JsType::AsyncIterator:
|
|
638
|
+
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr())->set_symbol_property(key, value, *this);
|
|
639
|
+
case JsType::Undefined:
|
|
640
|
+
throw Exception::make_exception("Cannot set properties of undefined (setting Symbol)", "TypeError");
|
|
641
|
+
case JsType::Null:
|
|
642
|
+
throw Exception::make_exception("Cannot set properties of null (setting Symbol)", "TypeError");
|
|
643
|
+
default:
|
|
644
|
+
return value;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
AnyValue AnyValue::call_own_property(const std::string &key, std::span<const AnyValue> args) const
|
|
649
|
+
{
|
|
650
|
+
return get_own_property(key).call((*this), args, key);
|
|
651
|
+
}
|
|
652
|
+
AnyValue AnyValue::call_own_property(uint32_t idx, std::span<const AnyValue> args) const
|
|
653
|
+
{
|
|
654
|
+
if (is_array())
|
|
655
|
+
return as_array()->get_property(idx).call((*this), args, "[" + std::to_string(idx) + "]");
|
|
656
|
+
if (is_string())
|
|
657
|
+
return as_string()->get_property(idx).call((*this), args, "[" + std::to_string(idx) + "]");
|
|
658
|
+
return call_own_property(std::to_string(idx), args);
|
|
659
|
+
}
|
|
660
|
+
AnyValue AnyValue::call_own_property(const AnyValue &key, std::span<const AnyValue> args) const
|
|
661
|
+
{
|
|
662
|
+
if (key.is_number() && is_array())
|
|
663
|
+
return as_array()->get_property(key.as_double()).call((*this), args, "[" + key.to_std_string() + "]");
|
|
664
|
+
if (key.is_number() && is_string())
|
|
665
|
+
return as_string()->get_property(key.as_double()).call((*this), args, "[" + key.to_std_string() + "]");
|
|
666
|
+
if (key.is_symbol())
|
|
667
|
+
return get_own_symbol_property(key).call((*this), args, key.to_std_string());
|
|
668
|
+
return call_own_property(key.to_std_string(), args);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// --- AnyValue methods that were in any_value_defines.hpp ---
|
|
672
|
+
|
|
673
|
+
void AnyValue::define_data_property(const std::string &key, AnyValue value)
|
|
674
|
+
{
|
|
675
|
+
if (is_object())
|
|
676
|
+
{
|
|
677
|
+
auto obj = as_object();
|
|
678
|
+
auto offset = obj->shape->get_offset(key);
|
|
679
|
+
if (offset.has_value())
|
|
680
|
+
obj->storage[offset.value()] = value;
|
|
681
|
+
else
|
|
682
|
+
{
|
|
683
|
+
obj->shape = obj->shape->transition(key);
|
|
684
|
+
obj->storage.push_back(value);
|
|
533
685
|
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
void AnyValue::define_data_property(const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
686
|
+
}
|
|
687
|
+
else if (is_function())
|
|
688
|
+
as_function()->props[key] = value;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
void AnyValue::define_data_property(const AnyValue &key, AnyValue value)
|
|
692
|
+
{
|
|
693
|
+
if (key.is_symbol())
|
|
694
|
+
{
|
|
695
|
+
if (is_object())
|
|
696
|
+
as_object()->symbol_props[key] = value;
|
|
697
|
+
else if (is_function())
|
|
698
|
+
as_function()->symbol_props[key] = value;
|
|
699
|
+
}
|
|
700
|
+
else
|
|
701
|
+
define_data_property(key.to_std_string(), value);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
void AnyValue::define_data_property(const std::string &key, AnyValue value, bool writable, bool enumerable, bool configurable)
|
|
705
|
+
{
|
|
706
|
+
define_data_property(key, AnyValue::make_data_descriptor(value, writable, enumerable, configurable));
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
void AnyValue::define_getter(const std::string &key, AnyValue getter)
|
|
710
|
+
{
|
|
711
|
+
if (is_object())
|
|
712
|
+
{
|
|
713
|
+
auto obj = as_object();
|
|
714
|
+
auto offset = obj->shape->get_offset(key);
|
|
715
|
+
if (offset.has_value())
|
|
716
|
+
{
|
|
717
|
+
auto &val = obj->storage[offset.value()];
|
|
718
|
+
if (val.is_accessor_descriptor())
|
|
719
|
+
{
|
|
720
|
+
auto desc = val.as_accessor_descriptor();
|
|
721
|
+
desc->get = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
722
|
+
{ return getter.call(thisVal, args); };
|
|
723
|
+
}
|
|
724
|
+
else
|
|
725
|
+
{
|
|
726
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
727
|
+
{ return getter.call(thisVal, args); };
|
|
728
|
+
obj->storage[offset.value()] = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
else
|
|
732
|
+
{
|
|
733
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
734
|
+
{ return getter.call(thisVal, args); };
|
|
735
|
+
obj->shape = obj->shape->transition(key);
|
|
736
|
+
obj->storage.push_back(AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true));
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
else if (is_function())
|
|
740
|
+
{
|
|
741
|
+
auto &props = as_function()->props;
|
|
742
|
+
auto it = props.find(key);
|
|
743
|
+
if (it != props.end() && it->second.is_accessor_descriptor())
|
|
744
|
+
{
|
|
745
|
+
auto desc = it->second.as_accessor_descriptor();
|
|
746
|
+
desc->get = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
747
|
+
{ return getter.call(thisVal, args); };
|
|
748
|
+
}
|
|
749
|
+
else
|
|
750
|
+
{
|
|
751
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
752
|
+
{ return getter.call(thisVal, args); };
|
|
753
|
+
props[key] = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
void AnyValue::define_data_property(const AnyValue &key, AnyValue value, bool writable, bool enumerable, bool configurable)
|
|
759
|
+
{
|
|
760
|
+
if (key.is_symbol())
|
|
761
|
+
{
|
|
762
|
+
auto desc = AnyValue::make_data_descriptor(value, writable, enumerable, configurable);
|
|
763
|
+
if (is_object())
|
|
764
|
+
as_object()->symbol_props[key] = desc;
|
|
765
|
+
else if (is_function())
|
|
766
|
+
as_function()->symbol_props[key] = desc;
|
|
767
|
+
}
|
|
768
|
+
else
|
|
769
|
+
define_data_property(key.to_std_string(), value, writable, enumerable, configurable);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
void AnyValue::define_getter(const AnyValue &key, AnyValue getter)
|
|
773
|
+
{
|
|
774
|
+
if (key.is_symbol())
|
|
775
|
+
{
|
|
776
|
+
auto getFunc = [getter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
777
|
+
{ return getter.call(thisVal, args); };
|
|
778
|
+
auto desc = AnyValue::make_accessor_descriptor(getFunc, std::nullopt, true, true);
|
|
779
|
+
if (is_object())
|
|
780
|
+
as_object()->symbol_props[key] = desc;
|
|
781
|
+
else if (is_function())
|
|
782
|
+
as_function()->symbol_props[key] = desc;
|
|
783
|
+
}
|
|
784
|
+
else
|
|
785
|
+
define_getter(key.to_std_string(), getter);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
void AnyValue::define_setter(const std::string &key, AnyValue setter)
|
|
789
|
+
{
|
|
790
|
+
if (is_object())
|
|
791
|
+
{
|
|
792
|
+
auto obj = as_object();
|
|
793
|
+
auto offset = obj->shape->get_offset(key);
|
|
794
|
+
if (offset.has_value())
|
|
795
|
+
{
|
|
796
|
+
auto &val = obj->storage[offset.value()];
|
|
797
|
+
if (val.is_accessor_descriptor())
|
|
798
|
+
{
|
|
799
|
+
auto desc = val.as_accessor_descriptor();
|
|
800
|
+
desc->set = [setter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
801
|
+
{
|
|
802
|
+
if (args.empty())
|
|
803
|
+
return Constants::UNDEFINED;
|
|
804
|
+
return setter.call(thisVal, args);
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
else
|
|
808
|
+
{
|
|
809
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
810
|
+
{
|
|
811
|
+
if (args.empty())
|
|
812
|
+
return jspp::Constants::UNDEFINED;
|
|
813
|
+
return setter.call(thisVal, args);
|
|
814
|
+
};
|
|
815
|
+
obj->storage[offset.value()] = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
else
|
|
819
|
+
{
|
|
820
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
821
|
+
{
|
|
822
|
+
if (args.empty())
|
|
823
|
+
return jspp::Constants::UNDEFINED;
|
|
579
824
|
return setter.call(thisVal, args);
|
|
580
825
|
};
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
826
|
+
obj->shape = obj->shape->transition(key);
|
|
827
|
+
obj->storage.push_back(AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true));
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
else if (is_function())
|
|
831
|
+
{
|
|
832
|
+
auto &props = as_function()->props;
|
|
833
|
+
auto it = props.find(key);
|
|
834
|
+
if (it != props.end() && it->second.is_accessor_descriptor())
|
|
835
|
+
{
|
|
836
|
+
auto desc = it->second.as_accessor_descriptor();
|
|
837
|
+
desc->set = [setter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
838
|
+
{
|
|
839
|
+
if (args.empty())
|
|
840
|
+
return Constants::UNDEFINED;
|
|
584
841
|
return setter.call(thisVal, args);
|
|
585
842
|
};
|
|
586
|
-
obj->storage[offset.value()] = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
|
|
587
843
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
if (args.empty())
|
|
844
|
+
else
|
|
845
|
+
{
|
|
846
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
847
|
+
{
|
|
848
|
+
if (args.empty())
|
|
849
|
+
return jspp::Constants::UNDEFINED;
|
|
850
|
+
return setter.call(thisVal, args);
|
|
851
|
+
};
|
|
852
|
+
props[key] = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
void AnyValue::define_setter(const AnyValue &key, AnyValue setter)
|
|
858
|
+
{
|
|
859
|
+
if (key.is_symbol())
|
|
860
|
+
{
|
|
861
|
+
auto setFunc = [setter](AnyValue thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
862
|
+
{
|
|
863
|
+
if (args.empty())
|
|
864
|
+
return Constants::UNDEFINED;
|
|
608
865
|
return setter.call(thisVal, args);
|
|
609
866
|
};
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
JsAsyncIterator<AnyValue>* AnyValue::as_async_iterator() const noexcept {
|
|
633
|
-
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr());
|
|
634
|
-
}
|
|
867
|
+
auto desc = AnyValue::make_accessor_descriptor(std::nullopt, setFunc, true, true);
|
|
868
|
+
if (is_object())
|
|
869
|
+
as_object()->symbol_props[key] = desc;
|
|
870
|
+
else if (is_function())
|
|
871
|
+
as_function()->symbol_props[key] = desc;
|
|
872
|
+
}
|
|
873
|
+
else
|
|
874
|
+
define_setter(key.to_std_string(), setter);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// AnyValue iterator methods from runtime.cpp
|
|
878
|
+
JsIterator<AnyValue> *AnyValue::as_iterator() const noexcept
|
|
879
|
+
{
|
|
880
|
+
return static_cast<JsIterator<AnyValue> *>(get_ptr());
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
JsAsyncIterator<AnyValue> *AnyValue::as_async_iterator() const noexcept
|
|
884
|
+
{
|
|
885
|
+
return static_cast<JsAsyncIterator<AnyValue> *>(get_ptr());
|
|
886
|
+
}
|
|
635
887
|
|
|
636
888
|
} // namespace jspp
|