@ugo-studio/jspp 0.1.9 → 0.2.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/README.md +1 -1
- package/dist/cli-utils/args.js +2 -0
- package/dist/cli.js +4 -4
- package/package.json +1 -1
- package/src/prelude/any_value.hpp +185 -391
- package/src/prelude/any_value_access.hpp +170 -190
- package/src/prelude/any_value_defines.hpp +12 -12
- package/src/prelude/any_value_helpers.hpp +208 -26
- package/src/prelude/exception.hpp +27 -31
- package/src/prelude/exception_helpers.hpp +53 -49
- package/src/prelude/index.hpp +4 -4
- package/src/prelude/library/array.hpp +4 -9
- package/src/prelude/library/console.hpp +112 -112
- package/src/prelude/library/error.hpp +8 -8
- package/src/prelude/library/math.hpp +3 -3
- package/src/prelude/library/object.hpp +12 -24
- package/src/prelude/library/promise.hpp +1 -1
- package/src/prelude/library/symbol.hpp +1 -1
- package/src/prelude/library/timer.hpp +3 -3
- package/src/prelude/types.hpp +178 -130
- package/src/prelude/utils/access.hpp +338 -378
- package/src/prelude/utils/log_any_value/function.hpp +39 -39
- package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
- package/src/prelude/utils/operators.hpp +20 -82
- package/src/prelude/utils/well_known_symbols.hpp +14 -15
- package/src/prelude/values/array.hpp +5 -3
- package/src/prelude/values/async_iterator.hpp +3 -1
- package/src/prelude/values/descriptors.hpp +15 -3
- package/src/prelude/values/function.hpp +5 -9
- package/src/prelude/values/helpers/array.hpp +208 -219
- package/src/prelude/values/helpers/async_iterator.hpp +7 -11
- package/src/prelude/values/helpers/function.hpp +12 -17
- package/src/prelude/values/helpers/iterator.hpp +108 -107
- package/src/prelude/values/helpers/object.hpp +104 -109
- package/src/prelude/values/helpers/promise.hpp +185 -119
- package/src/prelude/values/helpers/string.hpp +7 -10
- package/src/prelude/values/helpers/symbol.hpp +21 -23
- package/src/prelude/values/iterator.hpp +4 -1
- package/src/prelude/values/object.hpp +6 -4
- package/src/prelude/values/promise.hpp +5 -2
- package/src/prelude/values/prototypes/array.hpp +22 -22
- package/src/prelude/values/prototypes/async_iterator.hpp +3 -10
- package/src/prelude/values/prototypes/iterator.hpp +51 -58
- package/src/prelude/values/prototypes/promise.hpp +32 -28
- package/src/prelude/values/prototypes/string.hpp +5 -5
- package/src/prelude/values/prototypes/symbol.hpp +1 -1
- package/src/prelude/values/string.hpp +3 -1
- package/src/prelude/values/symbol.hpp +101 -102
|
@@ -17,83 +17,101 @@
|
|
|
17
17
|
#include <cmath>
|
|
18
18
|
#include <optional>
|
|
19
19
|
#include <coroutine>
|
|
20
|
-
#include <variant>
|
|
21
20
|
|
|
22
21
|
#include "types.hpp"
|
|
23
22
|
#include "values/non_values.hpp"
|
|
24
|
-
#include "values/object.hpp"
|
|
25
|
-
#include "values/array.hpp"
|
|
26
|
-
#include "values/function.hpp"
|
|
27
|
-
#include "values/iterator.hpp"
|
|
28
|
-
#include "values/promise.hpp"
|
|
29
|
-
#include "values/symbol.hpp"
|
|
30
|
-
#include "values/string.hpp"
|
|
31
|
-
#include "values/descriptors.hpp"
|
|
32
|
-
#include "exception.hpp"
|
|
33
|
-
#include "utils/well_known_symbols.hpp"
|
|
34
23
|
|
|
35
24
|
namespace jspp
|
|
36
25
|
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Iterator = 9,
|
|
49
|
-
Symbol = 10,
|
|
50
|
-
Promise = 11,
|
|
51
|
-
DataDescriptor = 12,
|
|
52
|
-
AccessorDescriptor = 13,
|
|
53
|
-
AsyncIterator = 14,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// The variant order MUST match JsType
|
|
57
|
-
using AnyValueVariant = std::variant<
|
|
58
|
-
JsUndefined,
|
|
59
|
-
JsNull,
|
|
60
|
-
JsUninitialized,
|
|
61
|
-
bool,
|
|
62
|
-
double,
|
|
63
|
-
std::shared_ptr<JsString>,
|
|
64
|
-
std::shared_ptr<JsObject>,
|
|
65
|
-
std::shared_ptr<JsArray>,
|
|
66
|
-
std::shared_ptr<JsFunction>,
|
|
67
|
-
std::shared_ptr<JsIterator<AnyValue>>,
|
|
68
|
-
std::shared_ptr<JsSymbol>,
|
|
69
|
-
std::shared_ptr<JsPromise>,
|
|
70
|
-
std::shared_ptr<DataDescriptor>,
|
|
71
|
-
std::shared_ptr<AccessorDescriptor>,
|
|
72
|
-
std::shared_ptr<JsAsyncIterator<AnyValue>>>;
|
|
26
|
+
// NAN BOXING SCHEME (64-bit)
|
|
27
|
+
// -------------------------
|
|
28
|
+
// Any value that is NOT a NaN double or is a "quiet" NaN is stored as a double.
|
|
29
|
+
// We use the top bits of the NaN space for tagging.
|
|
30
|
+
//
|
|
31
|
+
// Any value >= 0xFFFC000000000000 is a special tag.
|
|
32
|
+
//
|
|
33
|
+
// Tagging (bits 48-63):
|
|
34
|
+
// 0xFFFC: Pointer to HeapObject
|
|
35
|
+
// 0xFFFD: Boolean (bit 0 is value)
|
|
36
|
+
// 0xFFFE: Special (Undefined, Null, Uninitialized)
|
|
73
37
|
|
|
74
38
|
class AnyValue
|
|
75
39
|
{
|
|
76
40
|
private:
|
|
77
|
-
|
|
41
|
+
uint64_t storage;
|
|
42
|
+
|
|
43
|
+
static constexpr uint64_t TAG_BASE = 0xFFFC000000000000ULL;
|
|
44
|
+
static constexpr uint64_t TAG_POINTER = 0xFFFC000000000000ULL;
|
|
45
|
+
static constexpr uint64_t TAG_BOOLEAN = 0xFFFD000000000000ULL;
|
|
46
|
+
static constexpr uint64_t TAG_SPECIAL = 0xFFFE000000000000ULL;
|
|
47
|
+
|
|
48
|
+
static constexpr uint64_t VAL_UNDEFINED = 0x1ULL;
|
|
49
|
+
static constexpr uint64_t VAL_NULL = 0x2ULL;
|
|
50
|
+
static constexpr uint64_t VAL_UNINITIALIZED = 0x3ULL;
|
|
51
|
+
|
|
52
|
+
static constexpr uint64_t TAG_MASK = 0xFFFF000000000000ULL;
|
|
53
|
+
static constexpr uint64_t PAYLOAD_MASK = 0x0000FFFFFFFFFFFFULL;
|
|
54
|
+
|
|
55
|
+
inline bool has_tag(uint64_t tag) const noexcept {
|
|
56
|
+
return (storage & TAG_MASK) == tag;
|
|
57
|
+
}
|
|
78
58
|
|
|
79
59
|
public:
|
|
60
|
+
inline HeapObject* get_ptr() const noexcept {
|
|
61
|
+
return reinterpret_cast<HeapObject*>(storage & PAYLOAD_MASK);
|
|
62
|
+
}
|
|
63
|
+
|
|
80
64
|
// default ctor (Undefined)
|
|
81
|
-
AnyValue() noexcept
|
|
65
|
+
AnyValue() noexcept : storage(TAG_SPECIAL | VAL_UNDEFINED) {}
|
|
66
|
+
|
|
67
|
+
explicit AnyValue(double d) noexcept {
|
|
68
|
+
std::memcpy(&storage, &d, 8);
|
|
69
|
+
if (storage >= TAG_BASE) [[unlikely]] {
|
|
70
|
+
storage = 0x7FF8000000000000ULL;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
82
73
|
|
|
83
|
-
|
|
84
|
-
AnyValue(const AnyValue &) = default;
|
|
85
|
-
AnyValue(AnyValue &&) noexcept = default;
|
|
86
|
-
AnyValue &operator=(const AnyValue &) = default;
|
|
87
|
-
AnyValue &operator=(AnyValue &&) noexcept = default;
|
|
74
|
+
explicit AnyValue(bool b) noexcept : storage(TAG_BOOLEAN | (b ? 1 : 0)) {}
|
|
88
75
|
|
|
89
|
-
|
|
76
|
+
AnyValue(const AnyValue &other) noexcept : storage(other.storage) {
|
|
77
|
+
if (is_heap_object()) get_ptr()->ref();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
AnyValue(AnyValue &&other) noexcept : storage(other.storage) {
|
|
81
|
+
other.storage = TAG_SPECIAL | VAL_UNDEFINED;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
AnyValue &operator=(const AnyValue &other) noexcept {
|
|
85
|
+
if (this != &other) {
|
|
86
|
+
if (is_heap_object()) get_ptr()->deref();
|
|
87
|
+
storage = other.storage;
|
|
88
|
+
if (is_heap_object()) get_ptr()->ref();
|
|
89
|
+
}
|
|
90
|
+
return *this;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
AnyValue &operator=(AnyValue &&other) noexcept {
|
|
94
|
+
if (this != &other) {
|
|
95
|
+
if (is_heap_object()) get_ptr()->deref();
|
|
96
|
+
storage = other.storage;
|
|
97
|
+
other.storage = TAG_SPECIAL | VAL_UNDEFINED;
|
|
98
|
+
}
|
|
99
|
+
return *this;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
~AnyValue() {
|
|
103
|
+
if (is_heap_object()) get_ptr()->deref();
|
|
104
|
+
}
|
|
90
105
|
|
|
91
106
|
// Assignments
|
|
92
|
-
AnyValue &operator=(
|
|
93
|
-
|
|
94
|
-
storage
|
|
107
|
+
AnyValue &operator=(double val) noexcept {
|
|
108
|
+
if (is_heap_object()) get_ptr()->deref();
|
|
109
|
+
std::memcpy(&storage, &val, 8);
|
|
110
|
+
if (storage >= TAG_BASE) [[unlikely]] {
|
|
111
|
+
storage = 0x7FF8000000000000ULL;
|
|
112
|
+
}
|
|
95
113
|
return *this;
|
|
96
|
-
}
|
|
114
|
+
}
|
|
97
115
|
|
|
98
116
|
friend void swap(AnyValue &a, AnyValue &b) noexcept
|
|
99
117
|
{
|
|
@@ -114,415 +132,191 @@ namespace jspp
|
|
|
114
132
|
// factories -------------------------------------------------------
|
|
115
133
|
static AnyValue make_number(double d) noexcept
|
|
116
134
|
{
|
|
117
|
-
AnyValue
|
|
118
|
-
v.storage = d;
|
|
119
|
-
return v;
|
|
135
|
+
return AnyValue(d);
|
|
120
136
|
}
|
|
121
137
|
static AnyValue make_nan() noexcept
|
|
122
138
|
{
|
|
123
139
|
AnyValue v;
|
|
124
|
-
v.storage =
|
|
140
|
+
v.storage = 0x7FF8000000000000ULL;
|
|
125
141
|
return v;
|
|
126
142
|
}
|
|
127
143
|
static AnyValue make_uninitialized() noexcept
|
|
128
144
|
{
|
|
129
145
|
AnyValue v;
|
|
130
|
-
v.storage =
|
|
146
|
+
v.storage = TAG_SPECIAL | VAL_UNINITIALIZED;
|
|
131
147
|
return v;
|
|
132
148
|
}
|
|
133
149
|
static AnyValue make_undefined() noexcept
|
|
134
150
|
{
|
|
135
151
|
AnyValue v;
|
|
136
|
-
v.storage =
|
|
152
|
+
v.storage = TAG_SPECIAL | VAL_UNDEFINED;
|
|
137
153
|
return v;
|
|
138
154
|
}
|
|
139
155
|
static AnyValue make_null() noexcept
|
|
140
156
|
{
|
|
141
157
|
AnyValue v;
|
|
142
|
-
v.storage =
|
|
158
|
+
v.storage = TAG_SPECIAL | VAL_NULL;
|
|
143
159
|
return v;
|
|
144
160
|
}
|
|
145
161
|
static AnyValue make_boolean(bool b) noexcept
|
|
146
162
|
{
|
|
147
|
-
AnyValue
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
static AnyValue
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
static AnyValue
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
static AnyValue
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
static AnyValue make_object_with_proto(std::initializer_list<std::pair<std::string, AnyValue>> props, const AnyValue &proto) noexcept
|
|
170
|
-
{
|
|
171
|
-
AnyValue v;
|
|
172
|
-
auto protoPtr = std::make_shared<AnyValue>(proto);
|
|
173
|
-
v.storage = std::make_shared<JsObject>(props, protoPtr);
|
|
174
|
-
return v;
|
|
175
|
-
}
|
|
176
|
-
static AnyValue make_object_with_proto(const std::map<std::string, AnyValue> &props, const AnyValue &proto) noexcept
|
|
177
|
-
{
|
|
178
|
-
AnyValue v;
|
|
179
|
-
auto protoPtr = std::make_shared<AnyValue>(proto);
|
|
180
|
-
v.storage = std::make_shared<JsObject>(props, protoPtr);
|
|
181
|
-
return v;
|
|
182
|
-
}
|
|
183
|
-
static AnyValue make_array(std::span<const AnyValue> dense) noexcept
|
|
184
|
-
{
|
|
185
|
-
AnyValue v;
|
|
186
|
-
std::vector<AnyValue> vec;
|
|
187
|
-
vec.reserve(dense.size());
|
|
188
|
-
for (const auto &item : dense)
|
|
189
|
-
vec.push_back(item);
|
|
190
|
-
v.storage = std::make_shared<JsArray>(std::move(vec));
|
|
191
|
-
return v;
|
|
192
|
-
}
|
|
193
|
-
static AnyValue make_array(const std::vector<AnyValue> &dense) noexcept
|
|
194
|
-
{
|
|
195
|
-
AnyValue v;
|
|
196
|
-
v.storage = std::make_shared<JsArray>(dense);
|
|
197
|
-
return v;
|
|
198
|
-
}
|
|
199
|
-
static AnyValue make_array(std::vector<AnyValue> &&dense) noexcept
|
|
200
|
-
{
|
|
201
|
-
AnyValue v;
|
|
202
|
-
v.storage = std::make_shared<JsArray>(std::move(dense));
|
|
203
|
-
return v;
|
|
204
|
-
}
|
|
205
|
-
static AnyValue make_array_with_proto(std::span<const AnyValue> dense, const AnyValue &proto) noexcept
|
|
206
|
-
{
|
|
207
|
-
AnyValue v;
|
|
208
|
-
std::vector<AnyValue> vec;
|
|
209
|
-
vec.reserve(dense.size());
|
|
210
|
-
for (const auto &item : dense)
|
|
211
|
-
vec.push_back(item);
|
|
212
|
-
v.storage = std::make_shared<JsArray>(std::move(vec));
|
|
213
|
-
std::get<std::shared_ptr<JsArray>>(v.storage)->proto = std::make_shared<AnyValue>(proto);
|
|
214
|
-
return v;
|
|
215
|
-
}
|
|
216
|
-
static AnyValue make_array_with_proto(const std::vector<AnyValue> &dense, const AnyValue &proto) noexcept
|
|
217
|
-
{
|
|
218
|
-
AnyValue v;
|
|
219
|
-
v.storage = std::make_shared<JsArray>(dense);
|
|
220
|
-
std::get<std::shared_ptr<JsArray>>(v.storage)->proto = std::make_shared<AnyValue>(proto);
|
|
221
|
-
return v;
|
|
222
|
-
}
|
|
223
|
-
static AnyValue make_function(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt, bool is_constructor = true) noexcept
|
|
224
|
-
{
|
|
225
|
-
AnyValue v;
|
|
226
|
-
v.storage = std::make_shared<JsFunction>(call, name, std::unordered_map<std::string, AnyValue>{}, false, is_constructor);
|
|
227
|
-
|
|
228
|
-
auto proto = make_object({});
|
|
229
|
-
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
230
|
-
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
231
|
-
|
|
232
|
-
return v;
|
|
233
|
-
}
|
|
234
|
-
static AnyValue make_class(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
235
|
-
{
|
|
236
|
-
AnyValue v;
|
|
237
|
-
// use Constructor A with is_cls = true
|
|
238
|
-
v.storage = std::make_shared<JsFunction>(call, name, std::unordered_map<std::string, AnyValue>{}, true);
|
|
239
|
-
|
|
240
|
-
auto proto = make_object({});
|
|
241
|
-
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
242
|
-
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
243
|
-
|
|
244
|
-
return v;
|
|
245
|
-
}
|
|
246
|
-
static AnyValue make_generator(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
247
|
-
{
|
|
248
|
-
AnyValue v;
|
|
249
|
-
// use Constructor B with is_gen = true
|
|
250
|
-
v.storage = std::make_shared<JsFunction>(call, true, name);
|
|
251
|
-
|
|
252
|
-
auto proto = make_object({});
|
|
253
|
-
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
254
|
-
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
255
|
-
|
|
256
|
-
return v;
|
|
257
|
-
}
|
|
258
|
-
static AnyValue make_async_function(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
259
|
-
{
|
|
260
|
-
AnyValue v;
|
|
261
|
-
// use Constructor C with is_async_func = true
|
|
262
|
-
v.storage = std::make_shared<JsFunction>(call, false, true, name);
|
|
263
|
-
|
|
264
|
-
auto proto = make_object({});
|
|
265
|
-
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
266
|
-
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
267
|
-
|
|
268
|
-
return v;
|
|
269
|
-
}
|
|
270
|
-
static AnyValue make_async_generator(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept
|
|
271
|
-
{
|
|
272
|
-
AnyValue v;
|
|
273
|
-
// use Constructor C with is_gen = true and is_async_func = true
|
|
274
|
-
v.storage = std::make_shared<JsFunction>(call, true, true, name);
|
|
275
|
-
|
|
276
|
-
auto proto = make_object({});
|
|
277
|
-
proto.define_data_property("constructor", AnyValue::make_data_descriptor(v, true, false, false));
|
|
278
|
-
v.define_data_property("prototype", AnyValue::make_data_descriptor(proto, false, false, false));
|
|
279
|
-
|
|
280
|
-
return v;
|
|
281
|
-
}
|
|
282
|
-
static AnyValue make_symbol(const std::string &description = "") noexcept
|
|
283
|
-
{
|
|
284
|
-
AnyValue v;
|
|
285
|
-
v.storage = std::make_shared<JsSymbol>(description);
|
|
286
|
-
return v;
|
|
287
|
-
}
|
|
288
|
-
static AnyValue make_promise(const JsPromise &promise) noexcept
|
|
289
|
-
{
|
|
290
|
-
AnyValue v;
|
|
291
|
-
v.storage = std::make_shared<JsPromise>(promise);
|
|
292
|
-
return v;
|
|
293
|
-
}
|
|
294
|
-
static AnyValue make_data_descriptor(const AnyValue &value, bool writable, bool enumerable, bool configurable) noexcept
|
|
295
|
-
{
|
|
296
|
-
AnyValue v;
|
|
297
|
-
v.storage = std::make_shared<DataDescriptor>(std::make_shared<AnyValue>(value), writable, enumerable, configurable);
|
|
298
|
-
return v;
|
|
299
|
-
}
|
|
163
|
+
return AnyValue(b);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
static AnyValue make_string(const std::string &raw_s) noexcept;
|
|
167
|
+
static AnyValue make_object(std::initializer_list<std::pair<std::string, AnyValue>> props) noexcept;
|
|
168
|
+
static AnyValue make_object(const std::map<std::string, AnyValue> &props) noexcept;
|
|
169
|
+
static AnyValue make_object_with_proto(std::initializer_list<std::pair<std::string, AnyValue>> props, AnyValue proto) noexcept;
|
|
170
|
+
static AnyValue make_object_with_proto(const std::map<std::string, AnyValue> &props, AnyValue proto) noexcept;
|
|
171
|
+
static AnyValue make_array(std::span<const AnyValue> dense) noexcept;
|
|
172
|
+
static AnyValue make_array(const std::vector<AnyValue> &dense) noexcept;
|
|
173
|
+
static AnyValue make_array(std::vector<AnyValue> &&dense) noexcept;
|
|
174
|
+
static AnyValue make_array_with_proto(std::span<const AnyValue> dense, AnyValue proto) noexcept;
|
|
175
|
+
static AnyValue make_array_with_proto(const std::vector<AnyValue> &dense, AnyValue proto) noexcept;
|
|
176
|
+
static AnyValue make_function(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt, bool is_constructor = true) noexcept;
|
|
177
|
+
static AnyValue make_class(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept;
|
|
178
|
+
static AnyValue make_generator(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept;
|
|
179
|
+
static AnyValue make_async_function(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept;
|
|
180
|
+
static AnyValue make_async_generator(const JsFunctionCallable &call, const std::optional<std::string> &name = std::nullopt) noexcept;
|
|
181
|
+
static AnyValue make_symbol(const std::string &description = "") noexcept;
|
|
182
|
+
static AnyValue make_promise(const JsPromise &promise) noexcept;
|
|
183
|
+
static AnyValue make_data_descriptor(AnyValue value, bool writable, bool enumerable, bool configurable) noexcept;
|
|
300
184
|
static AnyValue make_accessor_descriptor(const std::optional<std::function<AnyValue(const AnyValue &, std::span<const AnyValue>)>> &get,
|
|
301
185
|
const std::optional<std::function<AnyValue(const AnyValue &, std::span<const AnyValue>)>> &set,
|
|
302
186
|
bool enumerable,
|
|
303
|
-
bool configurable) noexcept
|
|
304
|
-
{
|
|
305
|
-
AnyValue v;
|
|
306
|
-
v.storage = std::make_shared<AccessorDescriptor>(get, set, enumerable, configurable);
|
|
307
|
-
return v;
|
|
308
|
-
}
|
|
187
|
+
bool configurable) noexcept;
|
|
309
188
|
|
|
310
|
-
static AnyValue from_symbol(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
{
|
|
318
|
-
AnyValue v;
|
|
319
|
-
v.storage = std::move(str);
|
|
320
|
-
return v;
|
|
321
|
-
}
|
|
322
|
-
static AnyValue from_iterator(JsIterator<AnyValue> &&iterator) noexcept
|
|
323
|
-
{
|
|
324
|
-
AnyValue v;
|
|
325
|
-
v.storage = std::make_shared<JsIterator<AnyValue>>(std::move(iterator));
|
|
326
|
-
return v;
|
|
327
|
-
}
|
|
328
|
-
static AnyValue from_iterator_ref(JsIterator<AnyValue> *iterator) noexcept
|
|
329
|
-
{
|
|
330
|
-
AnyValue v;
|
|
331
|
-
v.storage = std::shared_ptr<JsIterator<AnyValue>>(iterator, [](JsIterator<AnyValue> *) {});
|
|
332
|
-
return v;
|
|
333
|
-
}
|
|
334
|
-
static AnyValue from_async_iterator(JsAsyncIterator<AnyValue> &&iterator) noexcept
|
|
335
|
-
{
|
|
189
|
+
static AnyValue from_symbol(JsSymbol *sym) noexcept;
|
|
190
|
+
static AnyValue from_string(JsString *str) noexcept;
|
|
191
|
+
static AnyValue from_iterator(JsIterator<AnyValue> &&iterator) noexcept;
|
|
192
|
+
static AnyValue from_iterator_ref(JsIterator<AnyValue> *iterator) noexcept;
|
|
193
|
+
static AnyValue from_async_iterator(JsAsyncIterator<AnyValue> &&iterator) noexcept;
|
|
194
|
+
|
|
195
|
+
// internal factory for wrapping raw heap object pointers
|
|
196
|
+
static AnyValue from_ptr(HeapObject* ptr) noexcept {
|
|
336
197
|
AnyValue v;
|
|
337
|
-
v.storage =
|
|
198
|
+
v.storage = TAG_POINTER | reinterpret_cast<uint64_t>(ptr);
|
|
199
|
+
ptr->ref();
|
|
338
200
|
return v;
|
|
339
201
|
}
|
|
340
202
|
|
|
341
|
-
|
|
342
|
-
static AnyValue
|
|
343
|
-
{
|
|
344
|
-
switch (val.get_type())
|
|
345
|
-
{
|
|
346
|
-
case JsType::DataDescriptor:
|
|
347
|
-
{
|
|
348
|
-
return *(val.as_data_descriptor()->value);
|
|
349
|
-
}
|
|
350
|
-
case JsType::AccessorDescriptor:
|
|
351
|
-
{
|
|
352
|
-
const auto &accessor = val.as_accessor_descriptor();
|
|
353
|
-
if (accessor->get.has_value())
|
|
354
|
-
return accessor->get.value()(thisVal, std::span<const AnyValue>{});
|
|
355
|
-
else
|
|
356
|
-
{
|
|
357
|
-
static AnyValue undefined = AnyValue{};
|
|
358
|
-
return undefined;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
default:
|
|
362
|
-
{
|
|
363
|
-
return val;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
static AnyValue resolve_property_for_write(AnyValue &val, const AnyValue &thisVal, const AnyValue &new_val, const std::string &propName)
|
|
368
|
-
{
|
|
369
|
-
switch (val.get_type())
|
|
370
|
-
{
|
|
371
|
-
case JsType::DataDescriptor:
|
|
372
|
-
{
|
|
373
|
-
const auto &data = val.as_data_descriptor();
|
|
374
|
-
if (data->writable)
|
|
375
|
-
{
|
|
376
|
-
*(data->value) = new_val;
|
|
377
|
-
return new_val;
|
|
378
|
-
}
|
|
379
|
-
else
|
|
380
|
-
{
|
|
381
|
-
throw Exception::make_exception("Cannot assign to read only property '" + propName + "' of object '#<Object>'", "TypeError");
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
case JsType::AccessorDescriptor:
|
|
385
|
-
{
|
|
386
|
-
const auto &accessor = val.as_accessor_descriptor();
|
|
387
|
-
if (accessor->set.has_value())
|
|
388
|
-
{
|
|
389
|
-
const AnyValue args[] = {new_val};
|
|
390
|
-
accessor->set.value()(thisVal, args);
|
|
391
|
-
return new_val;
|
|
392
|
-
}
|
|
393
|
-
else
|
|
394
|
-
{
|
|
395
|
-
throw Exception::make_exception("Cannot set property of #<Object> which has only a getter", "TypeError");
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
default:
|
|
399
|
-
{
|
|
400
|
-
val = new_val;
|
|
401
|
-
return new_val;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
203
|
+
static AnyValue resolve_property_for_read(const AnyValue &val, const AnyValue &thisVal, const std::string &propName) noexcept;
|
|
204
|
+
static AnyValue resolve_property_for_write(AnyValue &val, const AnyValue &thisVal, const AnyValue &new_val, const std::string &propName);
|
|
405
205
|
|
|
406
206
|
// TYPE CHECKERS AND ACCESSORS ---------------------------------------
|
|
407
|
-
JsType get_type() const noexcept {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
bool
|
|
418
|
-
bool
|
|
419
|
-
bool
|
|
420
|
-
bool
|
|
421
|
-
bool
|
|
422
|
-
bool
|
|
423
|
-
bool
|
|
424
|
-
|
|
425
|
-
|
|
207
|
+
JsType get_type() const noexcept {
|
|
208
|
+
if (is_number()) return JsType::Number;
|
|
209
|
+
if (is_heap_object()) return get_ptr()->get_heap_type();
|
|
210
|
+
if (is_boolean()) return JsType::Boolean;
|
|
211
|
+
if (is_undefined()) return JsType::Undefined;
|
|
212
|
+
if (is_null()) return JsType::Null;
|
|
213
|
+
if (is_uninitialized()) return JsType::Uninitialized;
|
|
214
|
+
return JsType::Undefined;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
inline bool is_number() const noexcept { return storage < TAG_BASE; }
|
|
218
|
+
inline bool is_heap_object() const noexcept { return has_tag(TAG_POINTER); }
|
|
219
|
+
inline bool is_string() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::String; }
|
|
220
|
+
inline bool is_object() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::Object; }
|
|
221
|
+
inline bool is_array() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::Array; }
|
|
222
|
+
inline bool is_function() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::Function; }
|
|
223
|
+
inline bool is_iterator() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::Iterator; }
|
|
224
|
+
inline bool is_boolean() const noexcept { return has_tag(TAG_BOOLEAN); }
|
|
225
|
+
inline bool is_symbol() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::Symbol; }
|
|
226
|
+
inline bool is_promise() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::Promise; }
|
|
227
|
+
inline bool is_null() const noexcept { return storage == (TAG_SPECIAL | VAL_NULL); }
|
|
228
|
+
inline bool is_undefined() const noexcept { return storage == (TAG_SPECIAL | VAL_UNDEFINED); }
|
|
229
|
+
inline bool is_uninitialized() const noexcept { return storage == (TAG_SPECIAL | VAL_UNINITIALIZED); }
|
|
230
|
+
inline bool is_data_descriptor() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::DataDescriptor; }
|
|
231
|
+
inline bool is_accessor_descriptor() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::AccessorDescriptor; }
|
|
232
|
+
inline bool is_async_iterator() const noexcept { return is_heap_object() && get_ptr()->get_heap_type() == JsType::AsyncIterator; }
|
|
233
|
+
|
|
234
|
+
JsString* as_string() const noexcept;
|
|
235
|
+
JsObject* as_object() const noexcept;
|
|
236
|
+
JsArray* as_array() const noexcept;
|
|
237
|
+
JsFunction* as_function() const noexcept;
|
|
238
|
+
JsSymbol* as_symbol() const noexcept;
|
|
239
|
+
JsPromise* as_promise() const noexcept;
|
|
240
|
+
JsIterator<AnyValue>* as_iterator() const noexcept;
|
|
241
|
+
JsAsyncIterator<AnyValue>* as_async_iterator() const noexcept;
|
|
242
|
+
DataDescriptor* as_data_descriptor() const noexcept;
|
|
243
|
+
AccessorDescriptor* as_accessor_descriptor() const noexcept;
|
|
244
|
+
|
|
245
|
+
bool is_generator() const noexcept;
|
|
246
|
+
|
|
426
247
|
double as_double() const noexcept
|
|
427
248
|
{
|
|
428
|
-
|
|
249
|
+
double d;
|
|
250
|
+
std::memcpy(&d, &storage, 8);
|
|
251
|
+
return d;
|
|
429
252
|
}
|
|
430
253
|
bool as_boolean() const noexcept
|
|
431
254
|
{
|
|
432
|
-
return
|
|
433
|
-
}
|
|
434
|
-
JsString *as_string() const noexcept
|
|
435
|
-
{
|
|
436
|
-
return std::get<std::shared_ptr<JsString>>(storage).get();
|
|
437
|
-
}
|
|
438
|
-
JsObject *as_object() const noexcept
|
|
439
|
-
{
|
|
440
|
-
return std::get<std::shared_ptr<JsObject>>(storage).get();
|
|
441
|
-
}
|
|
442
|
-
JsArray *as_array() const noexcept
|
|
443
|
-
{
|
|
444
|
-
return std::get<std::shared_ptr<JsArray>>(storage).get();
|
|
445
|
-
}
|
|
446
|
-
JsFunction *as_function() const noexcept
|
|
447
|
-
{
|
|
448
|
-
return std::get<std::shared_ptr<JsFunction>>(storage).get();
|
|
449
|
-
}
|
|
450
|
-
JsSymbol *as_symbol() const noexcept
|
|
451
|
-
{
|
|
452
|
-
return std::get<std::shared_ptr<JsSymbol>>(storage).get();
|
|
453
|
-
}
|
|
454
|
-
JsPromise *as_promise() const noexcept
|
|
455
|
-
{
|
|
456
|
-
return std::get<std::shared_ptr<JsPromise>>(storage).get();
|
|
457
|
-
}
|
|
458
|
-
std::shared_ptr<JsIterator<AnyValue>> as_iterator() const
|
|
459
|
-
{
|
|
460
|
-
return std::get<std::shared_ptr<JsIterator<AnyValue>>>(storage);
|
|
461
|
-
}
|
|
462
|
-
std::shared_ptr<JsAsyncIterator<AnyValue>> as_async_iterator() const
|
|
463
|
-
{
|
|
464
|
-
return std::get<std::shared_ptr<JsAsyncIterator<AnyValue>>>(storage);
|
|
465
|
-
}
|
|
466
|
-
DataDescriptor *as_data_descriptor() const noexcept
|
|
467
|
-
{
|
|
468
|
-
return std::get<std::shared_ptr<DataDescriptor>>(storage).get();
|
|
469
|
-
}
|
|
470
|
-
AccessorDescriptor *as_accessor_descriptor() const noexcept
|
|
471
|
-
{
|
|
472
|
-
return std::get<std::shared_ptr<AccessorDescriptor>>(storage).get();
|
|
255
|
+
return static_cast<bool>(storage & 1);
|
|
473
256
|
}
|
|
474
257
|
|
|
475
|
-
// --- CO_AWAIT Operator ---
|
|
476
258
|
auto operator co_await() const;
|
|
477
259
|
|
|
478
|
-
// --- PROPERTY ACCESS OPERATORS
|
|
479
260
|
bool has_property(const std::string &key) const;
|
|
261
|
+
bool has_property(const char* key) const { return has_property(std::string(key)); }
|
|
262
|
+
|
|
480
263
|
AnyValue get_own_property(const std::string &key) const;
|
|
264
|
+
AnyValue get_own_property(const char* key) const { return get_own_property(std::string(key)); }
|
|
481
265
|
AnyValue get_own_property(uint32_t idx) const;
|
|
266
|
+
AnyValue get_own_property(int idx) const { return get_own_property(static_cast<uint32_t>(idx)); }
|
|
482
267
|
AnyValue get_own_property(const AnyValue &key) const;
|
|
483
|
-
|
|
268
|
+
|
|
484
269
|
AnyValue get_property_with_receiver(const std::string &key, const AnyValue &receiver) const;
|
|
485
|
-
|
|
270
|
+
AnyValue get_property_with_receiver(const char* key, const AnyValue &receiver) const { return get_property_with_receiver(std::string(key), receiver); }
|
|
271
|
+
|
|
486
272
|
AnyValue set_own_property(const std::string &key, const AnyValue &value) const;
|
|
273
|
+
AnyValue set_own_property(const char* key, const AnyValue &value) const { return set_own_property(std::string(key), value); }
|
|
487
274
|
AnyValue set_own_property(uint32_t idx, const AnyValue &value) const;
|
|
275
|
+
AnyValue set_own_property(int idx, const AnyValue &value) const { return set_own_property(static_cast<uint32_t>(idx), value); }
|
|
488
276
|
AnyValue set_own_property(const AnyValue &key, const AnyValue &value) const;
|
|
489
|
-
|
|
277
|
+
|
|
490
278
|
AnyValue call_own_property(const std::string &key, std::span<const AnyValue> args) const;
|
|
279
|
+
AnyValue call_own_property(const char* key, std::span<const AnyValue> args) const { return call_own_property(std::string(key), args); }
|
|
491
280
|
AnyValue call_own_property(uint32_t idx, std::span<const AnyValue> args) const;
|
|
281
|
+
AnyValue call_own_property(int idx, std::span<const AnyValue> args) const { return call_own_property(static_cast<uint32_t>(idx), args); }
|
|
492
282
|
AnyValue call_own_property(const AnyValue &key, std::span<const AnyValue> args) const;
|
|
493
283
|
|
|
494
|
-
// --- DEFINERS (Object.defineProperty semantics)
|
|
495
284
|
void define_data_property(const std::string &key, const AnyValue &value);
|
|
285
|
+
void define_data_property(const char* key, const AnyValue &value) { define_data_property(std::string(key), value); }
|
|
496
286
|
void define_data_property(const AnyValue &key, const AnyValue &value);
|
|
497
287
|
void define_data_property(const std::string &key, const AnyValue &value, bool writable, bool enumerable, bool configurable);
|
|
288
|
+
void define_data_property(const char* key, const AnyValue &value, bool writable, bool enumerable, bool configurable) { define_data_property(std::string(key), value, writable, enumerable, configurable); }
|
|
289
|
+
|
|
498
290
|
void define_getter(const std::string &key, const AnyValue &getter);
|
|
291
|
+
void define_getter(const char* key, const AnyValue &getter) { define_getter(std::string(key), getter); }
|
|
499
292
|
void define_getter(const AnyValue &key, const AnyValue &getter);
|
|
293
|
+
|
|
500
294
|
void define_setter(const std::string &key, const AnyValue &setter);
|
|
295
|
+
void define_setter(const char* key, const AnyValue &setter) { define_setter(std::string(key), setter); }
|
|
501
296
|
void define_setter(const AnyValue &key, const AnyValue &setter);
|
|
502
297
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const AnyValue construct(std::span<const AnyValue> args, const std::optional<std::string> &name) const;
|
|
298
|
+
AnyValue call(const AnyValue &thisVal, std::span<const AnyValue> args, const std::optional<std::string> &expr = std::nullopt) const;
|
|
299
|
+
AnyValue construct(std::span<const AnyValue> args, const std::optional<std::string> &name = std::nullopt) const;
|
|
506
300
|
void set_prototype(const AnyValue &proto);
|
|
507
301
|
std::string to_std_string() const;
|
|
302
|
+
|
|
303
|
+
inline uint64_t get_storage() const noexcept { return storage; }
|
|
304
|
+
inline void* get_raw_ptr() const noexcept { return reinterpret_cast<void*>(storage & PAYLOAD_MASK); }
|
|
508
305
|
};
|
|
509
306
|
|
|
510
|
-
// Awaiter for AnyValue
|
|
511
307
|
struct AnyValueAwaiter
|
|
512
308
|
{
|
|
513
|
-
AnyValue value;
|
|
309
|
+
AnyValue value;
|
|
514
310
|
bool await_ready();
|
|
515
311
|
void await_suspend(std::coroutine_handle<> h);
|
|
516
312
|
AnyValue await_resume();
|
|
517
313
|
};
|
|
518
314
|
|
|
519
|
-
// Inline implementation of operator co_await
|
|
520
315
|
inline auto AnyValue::operator co_await() const
|
|
521
316
|
{
|
|
522
317
|
return AnyValueAwaiter{*this};
|
|
523
318
|
}
|
|
524
319
|
|
|
525
|
-
// Global Constants for Optimization
|
|
526
320
|
namespace Constants
|
|
527
321
|
{
|
|
528
322
|
inline const AnyValue UNINITIALIZED = AnyValue::make_uninitialized();
|
|
@@ -534,4 +328,4 @@ namespace jspp
|
|
|
534
328
|
inline const AnyValue ZERO = AnyValue::make_number(0.0);
|
|
535
329
|
inline const AnyValue ONE = AnyValue::make_number(1.0);
|
|
536
330
|
}
|
|
537
|
-
}
|
|
331
|
+
}
|