@ugo-studio/jspp 0.1.8 → 0.2.0
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 +1 -1
- package/package.json +3 -2
- package/scripts/precompile-headers.ts +110 -0
- package/scripts/setup-compiler.ts +63 -0
- 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 +9 -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
|
@@ -42,7 +42,7 @@ namespace jspp
|
|
|
42
42
|
{
|
|
43
43
|
if (args.empty())
|
|
44
44
|
{
|
|
45
|
-
return
|
|
45
|
+
return Constants::UNDEFINED;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
const auto &new_len_val = args[0];
|
|
@@ -103,7 +103,7 @@ namespace jspp
|
|
|
103
103
|
{
|
|
104
104
|
if (self->length == 0)
|
|
105
105
|
{
|
|
106
|
-
return
|
|
106
|
+
return Constants::UNDEFINED;
|
|
107
107
|
}
|
|
108
108
|
uint64_t last_idx = self->length - 1;
|
|
109
109
|
AnyValue last_val = self->get_property(static_cast<uint32_t>(last_idx));
|
|
@@ -128,7 +128,7 @@ namespace jspp
|
|
|
128
128
|
{
|
|
129
129
|
if (self->length == 0)
|
|
130
130
|
{
|
|
131
|
-
return
|
|
131
|
+
return Constants::UNDEFINED;
|
|
132
132
|
}
|
|
133
133
|
AnyValue first_val = self->get_property(0u);
|
|
134
134
|
|
|
@@ -227,7 +227,7 @@ namespace jspp
|
|
|
227
227
|
callback->call(thisVal, cbArgs);
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
|
-
return
|
|
230
|
+
return Constants::UNDEFINED; },
|
|
231
231
|
key);
|
|
232
232
|
}
|
|
233
233
|
|
|
@@ -241,7 +241,7 @@ namespace jspp
|
|
|
241
241
|
double k;
|
|
242
242
|
if (relativeIndex >= 0) k = relativeIndex;
|
|
243
243
|
else k = len + relativeIndex;
|
|
244
|
-
if (k < 0 || k >= len) return
|
|
244
|
+
if (k < 0 || k >= len) return Constants::UNDEFINED;
|
|
245
245
|
return self->get_property(static_cast<uint32_t>(k)); },
|
|
246
246
|
key);
|
|
247
247
|
}
|
|
@@ -251,9 +251,9 @@ namespace jspp
|
|
|
251
251
|
{
|
|
252
252
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
253
253
|
{
|
|
254
|
-
AnyValue searchElement = args.empty() ?
|
|
254
|
+
AnyValue searchElement = args.empty() ? Constants::UNDEFINED : args[0];
|
|
255
255
|
double len = static_cast<double>(self->length);
|
|
256
|
-
if (len == 0) return
|
|
256
|
+
if (len == 0) return Constants::FALSE;
|
|
257
257
|
double n = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : 0;
|
|
258
258
|
double k;
|
|
259
259
|
if (n >= 0) k = n;
|
|
@@ -264,10 +264,10 @@ namespace jspp
|
|
|
264
264
|
{
|
|
265
265
|
AnyValue element = self->get_property(static_cast<uint32_t>(i));
|
|
266
266
|
// SameValueZero algorithm (includes handles NaN)
|
|
267
|
-
if (element.is_number() && searchElement.is_number() && std::isnan(element.as_double()) && std::isnan(searchElement.as_double())) return
|
|
268
|
-
if (is_strictly_equal_to_primitive(element, searchElement)) return
|
|
267
|
+
if (element.is_number() && searchElement.is_number() && std::isnan(element.as_double()) && std::isnan(searchElement.as_double())) return Constants::TRUE;
|
|
268
|
+
if (is_strictly_equal_to_primitive(element, searchElement)) return Constants::TRUE;
|
|
269
269
|
}
|
|
270
|
-
return
|
|
270
|
+
return Constants::FALSE; },
|
|
271
271
|
key);
|
|
272
272
|
}
|
|
273
273
|
|
|
@@ -276,7 +276,7 @@ namespace jspp
|
|
|
276
276
|
{
|
|
277
277
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
278
278
|
{
|
|
279
|
-
AnyValue searchElement = args.empty() ?
|
|
279
|
+
AnyValue searchElement = args.empty() ? Constants::UNDEFINED : args[0];
|
|
280
280
|
double len = static_cast<double>(self->length);
|
|
281
281
|
if (len == 0) return AnyValue::make_number(-1);
|
|
282
282
|
double n = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : 0;
|
|
@@ -301,7 +301,7 @@ namespace jspp
|
|
|
301
301
|
{
|
|
302
302
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
303
303
|
{
|
|
304
|
-
AnyValue searchElement = args.empty() ?
|
|
304
|
+
AnyValue searchElement = args.empty() ? Constants::UNDEFINED : args[0];
|
|
305
305
|
double len = static_cast<double>(self->length);
|
|
306
306
|
if (len == 0) return AnyValue::make_number(-1);
|
|
307
307
|
double n = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : len - 1;
|
|
@@ -341,7 +341,7 @@ namespace jspp
|
|
|
341
341
|
return element;
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
|
-
return
|
|
344
|
+
return Constants::UNDEFINED; },
|
|
345
345
|
key);
|
|
346
346
|
}
|
|
347
347
|
|
|
@@ -387,7 +387,7 @@ namespace jspp
|
|
|
387
387
|
return element;
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
|
-
return
|
|
390
|
+
return Constants::UNDEFINED; },
|
|
391
391
|
key);
|
|
392
392
|
}
|
|
393
393
|
|
|
@@ -431,7 +431,7 @@ namespace jspp
|
|
|
431
431
|
for (uint64_t i = 0; i < self->length; ++i) {
|
|
432
432
|
co_yield AnyValue::make_number(i);
|
|
433
433
|
}
|
|
434
|
-
co_return
|
|
434
|
+
co_return Constants::UNDEFINED; },
|
|
435
435
|
key);
|
|
436
436
|
}
|
|
437
437
|
|
|
@@ -447,7 +447,7 @@ namespace jspp
|
|
|
447
447
|
entry.push_back(self->get_property(static_cast<uint32_t>(i)));
|
|
448
448
|
co_yield AnyValue::make_array(std::move(entry));
|
|
449
449
|
}
|
|
450
|
-
co_return
|
|
450
|
+
co_return Constants::UNDEFINED; },
|
|
451
451
|
key);
|
|
452
452
|
}
|
|
453
453
|
|
|
@@ -517,11 +517,11 @@ namespace jspp
|
|
|
517
517
|
AnyValue kVal = AnyValue::make_number(i);
|
|
518
518
|
const AnyValue cbArgs[] = {val, kVal, thisVal};
|
|
519
519
|
if (!is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
|
|
520
|
-
return
|
|
520
|
+
return Constants::FALSE;
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
523
|
}
|
|
524
|
-
return
|
|
524
|
+
return Constants::TRUE; },
|
|
525
525
|
key);
|
|
526
526
|
}
|
|
527
527
|
|
|
@@ -540,11 +540,11 @@ namespace jspp
|
|
|
540
540
|
AnyValue kVal = AnyValue::make_number(i);
|
|
541
541
|
const AnyValue cbArgs[] = {val, kVal, thisVal};
|
|
542
542
|
if (is_truthy(callback->call(thisArg, std::span<const AnyValue>(cbArgs, 3)))) {
|
|
543
|
-
return
|
|
543
|
+
return Constants::TRUE;
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
546
|
}
|
|
547
|
-
return
|
|
547
|
+
return Constants::FALSE; },
|
|
548
548
|
key);
|
|
549
549
|
}
|
|
550
550
|
|
|
@@ -698,7 +698,7 @@ namespace jspp
|
|
|
698
698
|
{
|
|
699
699
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
700
700
|
{
|
|
701
|
-
AnyValue value = args.empty() ?
|
|
701
|
+
AnyValue value = args.empty() ? Constants::UNDEFINED : args[0];
|
|
702
702
|
double len = static_cast<double>(self->length);
|
|
703
703
|
double start = (args.size() > 1) ? Operators_Private::ToNumber(args[1]) : 0;
|
|
704
704
|
double end = (args.size() > 2 && !args[2].is_undefined()) ? Operators_Private::ToNumber(args[2]) : len;
|
|
@@ -755,7 +755,7 @@ namespace jspp
|
|
|
755
755
|
{
|
|
756
756
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
757
757
|
{
|
|
758
|
-
AnyValue compareFn = args.empty() ?
|
|
758
|
+
AnyValue compareFn = args.empty() ? Constants::UNDEFINED : args[0];
|
|
759
759
|
|
|
760
760
|
std::vector<AnyValue> items;
|
|
761
761
|
for (uint64_t i = 0; i < self->length; ++i) {
|
|
@@ -20,17 +20,10 @@ namespace jspp
|
|
|
20
20
|
key);
|
|
21
21
|
}
|
|
22
22
|
// --- [Symbol.asyncIterator]() method ---
|
|
23
|
-
// For async iterators, the async iterator is itself (similar to sync iterators)
|
|
24
23
|
if (key == WellKnownSymbols::asyncIterator->key)
|
|
25
24
|
{
|
|
26
|
-
// We return 'this'. Since we can't easily create a shared_ptr from raw pointer,
|
|
27
|
-
// we rely on the context to hold the reference or implement better shared_from_this strategy.
|
|
28
|
-
// For now, assume it works like Iterator.
|
|
29
25
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
30
|
-
{
|
|
31
|
-
// This is slightly dangerous as we create a new shared_ptr from raw.
|
|
32
|
-
// TODO: fix lifetime management
|
|
33
|
-
return thisVal; },
|
|
26
|
+
{ return thisVal; },
|
|
34
27
|
key);
|
|
35
28
|
}
|
|
36
29
|
// --- next() method ---
|
|
@@ -38,7 +31,7 @@ namespace jspp
|
|
|
38
31
|
{
|
|
39
32
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
40
33
|
{
|
|
41
|
-
AnyValue val = args.empty() ?
|
|
34
|
+
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
42
35
|
auto res = self->next(val);
|
|
43
36
|
return AnyValue::make_promise(res); },
|
|
44
37
|
key);
|
|
@@ -47,4 +40,4 @@ namespace jspp
|
|
|
47
40
|
return std::nullopt;
|
|
48
41
|
}
|
|
49
42
|
}
|
|
50
|
-
}
|
|
43
|
+
}
|
|
@@ -1,58 +1,51 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include "types.hpp"
|
|
4
|
-
#include "values/iterator.hpp"
|
|
5
|
-
#include "any_value.hpp"
|
|
6
|
-
#include "exception.hpp"
|
|
7
|
-
#include "utils/operators.hpp"
|
|
8
|
-
|
|
9
|
-
namespace jspp
|
|
10
|
-
{
|
|
11
|
-
namespace IteratorPrototypes
|
|
12
|
-
{
|
|
13
|
-
inline std::optional<AnyValue> get(const std::string &key, JsIterator<AnyValue> *self)
|
|
14
|
-
{
|
|
15
|
-
// --- toString() method ---
|
|
16
|
-
if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
|
|
17
|
-
{
|
|
18
|
-
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
19
|
-
{ return AnyValue::make_string(self->to_std_string()); },
|
|
20
|
-
key);
|
|
21
|
-
}
|
|
22
|
-
// --- [Symbol.iterator]() method ---
|
|
23
|
-
if (key == WellKnownSymbols::iterator->key)
|
|
24
|
-
{
|
|
25
|
-
return AnyValue::make_generator([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
key);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
key);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return std::nullopt;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "types.hpp"
|
|
4
|
+
#include "values/iterator.hpp"
|
|
5
|
+
#include "any_value.hpp"
|
|
6
|
+
#include "exception.hpp"
|
|
7
|
+
#include "utils/operators.hpp"
|
|
8
|
+
|
|
9
|
+
namespace jspp
|
|
10
|
+
{
|
|
11
|
+
namespace IteratorPrototypes
|
|
12
|
+
{
|
|
13
|
+
inline std::optional<AnyValue> get(const std::string &key, JsIterator<AnyValue> *self)
|
|
14
|
+
{
|
|
15
|
+
// --- toString() method ---
|
|
16
|
+
if (key == "toString" || key == WellKnownSymbols::toStringTag->key)
|
|
17
|
+
{
|
|
18
|
+
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
19
|
+
{ return AnyValue::make_string(self->to_std_string()); },
|
|
20
|
+
key);
|
|
21
|
+
}
|
|
22
|
+
// --- [Symbol.iterator]() method ---
|
|
23
|
+
if (key == WellKnownSymbols::iterator->key)
|
|
24
|
+
{
|
|
25
|
+
return AnyValue::make_generator([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
26
|
+
{
|
|
27
|
+
return thisVal; },
|
|
28
|
+
key);
|
|
29
|
+
}
|
|
30
|
+
// --- next() method ---
|
|
31
|
+
if (key == "next")
|
|
32
|
+
{
|
|
33
|
+
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
34
|
+
{
|
|
35
|
+
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
36
|
+
auto res = self->next(val);
|
|
37
|
+
return AnyValue::make_object({{"value",res.value.value_or(Constants::UNDEFINED)},{"done",AnyValue::make_boolean(res.done)},}); },
|
|
38
|
+
key);
|
|
39
|
+
}
|
|
40
|
+
// --- toArray() method ---
|
|
41
|
+
if (key == "toArray")
|
|
42
|
+
{
|
|
43
|
+
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
44
|
+
{ return AnyValue::make_array(self->to_vector()); },
|
|
45
|
+
key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return std::nullopt;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -15,23 +15,32 @@ namespace jspp
|
|
|
15
15
|
{
|
|
16
16
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
17
17
|
{
|
|
18
|
-
AnyValue onFulfilled = (args.size() > 0 && args[0].is_function()) ? args[0] :
|
|
19
|
-
AnyValue onRejected = (args.size() > 1 && args[1].is_function()) ? args[1] :
|
|
18
|
+
AnyValue onFulfilled = (args.size() > 0 && args[0].is_function()) ? args[0] : Constants::UNDEFINED;
|
|
19
|
+
AnyValue onRejected = (args.size() > 1 && args[1].is_function()) ? args[1] : Constants::UNDEFINED;
|
|
20
20
|
|
|
21
21
|
// "then" returns a new Promise
|
|
22
22
|
JsPromise newPromise;
|
|
23
23
|
AnyValue newPromiseVal = AnyValue::make_promise(newPromise);
|
|
24
24
|
|
|
25
|
-
// Capture shared pointer to the new promise's state to keep it alive and modify it
|
|
26
25
|
auto newPromiseState = newPromise.state;
|
|
27
|
-
// Helper wrapper to interact with state
|
|
28
26
|
auto resolveNew = [newPromiseState](const AnyValue& v) {
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
// Manual state resolution to avoid HeapObject management issues here
|
|
28
|
+
if (newPromiseState->status != PromiseStatus::Pending) return;
|
|
29
|
+
newPromiseState->status = PromiseStatus::Fulfilled;
|
|
30
|
+
newPromiseState->result = v;
|
|
31
|
+
auto callbacks = newPromiseState->onFulfilled;
|
|
32
|
+
newPromiseState->onFulfilled.clear();
|
|
33
|
+
newPromiseState->onRejected.clear();
|
|
34
|
+
for (auto& cb : callbacks) jspp::Scheduler::instance().enqueue([cb, v]() { cb(v); });
|
|
31
35
|
};
|
|
32
36
|
auto rejectNew = [newPromiseState](const AnyValue& r) {
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
if (newPromiseState->status != PromiseStatus::Pending) return;
|
|
38
|
+
newPromiseState->status = PromiseStatus::Rejected;
|
|
39
|
+
newPromiseState->result = r;
|
|
40
|
+
auto callbacks = newPromiseState->onRejected;
|
|
41
|
+
newPromiseState->onFulfilled.clear();
|
|
42
|
+
newPromiseState->onRejected.clear();
|
|
43
|
+
for (auto& cb : callbacks) jspp::Scheduler::instance().enqueue([cb, r]() { cb(r); });
|
|
35
44
|
};
|
|
36
45
|
|
|
37
46
|
|
|
@@ -40,9 +49,8 @@ namespace jspp
|
|
|
40
49
|
if (onFulfilled.is_function()) {
|
|
41
50
|
try {
|
|
42
51
|
const AnyValue cbArgs[] = {val};
|
|
43
|
-
auto res = onFulfilled.call(
|
|
52
|
+
auto res = onFulfilled.call(Constants::UNDEFINED, cbArgs, "onFulfilled");
|
|
44
53
|
if (res.is_promise()) {
|
|
45
|
-
// Chaining: newPromise follows res
|
|
46
54
|
auto chained = res.as_promise();
|
|
47
55
|
chained->then(
|
|
48
56
|
[resolveNew](const AnyValue& v) { resolveNew(v); },
|
|
@@ -52,12 +60,12 @@ namespace jspp
|
|
|
52
60
|
resolveNew(res);
|
|
53
61
|
}
|
|
54
62
|
} catch (const Exception& e) {
|
|
55
|
-
rejectNew(
|
|
63
|
+
rejectNew(e.data);
|
|
56
64
|
} catch (...) {
|
|
57
65
|
rejectNew(AnyValue::make_string("Unknown error"));
|
|
58
66
|
}
|
|
59
67
|
} else {
|
|
60
|
-
resolveNew(val);
|
|
68
|
+
resolveNew(val);
|
|
61
69
|
}
|
|
62
70
|
};
|
|
63
71
|
|
|
@@ -66,7 +74,7 @@ namespace jspp
|
|
|
66
74
|
if (onRejected.is_function()) {
|
|
67
75
|
try {
|
|
68
76
|
const AnyValue cbArgs[] = {reason};
|
|
69
|
-
auto res = onRejected.call(
|
|
77
|
+
auto res = onRejected.call(Constants::UNDEFINED, cbArgs,"onRejected");
|
|
70
78
|
if (res.is_promise()) {
|
|
71
79
|
auto chained = res.as_promise();
|
|
72
80
|
chained->then(
|
|
@@ -74,15 +82,15 @@ namespace jspp
|
|
|
74
82
|
[rejectNew](const AnyValue& e) { rejectNew(e); }
|
|
75
83
|
);
|
|
76
84
|
} else {
|
|
77
|
-
resolveNew(res);
|
|
85
|
+
resolveNew(res);
|
|
78
86
|
}
|
|
79
87
|
} catch (const Exception& e) {
|
|
80
|
-
rejectNew(
|
|
88
|
+
rejectNew(e.data);
|
|
81
89
|
} catch (...) {
|
|
82
90
|
rejectNew(AnyValue::make_string("Unknown error"));
|
|
83
91
|
}
|
|
84
92
|
} else {
|
|
85
|
-
rejectNew(reason);
|
|
93
|
+
rejectNew(reason);
|
|
86
94
|
}
|
|
87
95
|
};
|
|
88
96
|
|
|
@@ -94,9 +102,8 @@ namespace jspp
|
|
|
94
102
|
{
|
|
95
103
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
96
104
|
{
|
|
97
|
-
|
|
98
|
-
AnyValue
|
|
99
|
-
const AnyValue thenArgs[] = {AnyValue::make_undefined(), onRejected};
|
|
105
|
+
AnyValue onRejected = (args.size() > 0 && args[0].is_function()) ? args[0] : Constants::UNDEFINED;
|
|
106
|
+
const AnyValue thenArgs[] = {Constants::UNDEFINED, onRejected};
|
|
100
107
|
return thisVal.get_own_property("then").call(thisVal, thenArgs,"then"); }, "catch");
|
|
101
108
|
}
|
|
102
109
|
|
|
@@ -104,23 +111,20 @@ namespace jspp
|
|
|
104
111
|
{
|
|
105
112
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
106
113
|
{
|
|
107
|
-
AnyValue onFinally = (args.size() > 0 && args[0].is_function()) ? args[0] :
|
|
108
|
-
|
|
109
|
-
// finally(onFinally) returns a promise that passes through value/reason,
|
|
110
|
-
// but executes onFinally first.
|
|
114
|
+
AnyValue onFinally = (args.size() > 0 && args[0].is_function()) ? args[0] : Constants::UNDEFINED;
|
|
111
115
|
|
|
112
116
|
const AnyValue thenArgs[] = {
|
|
113
117
|
AnyValue::make_function([onFinally](const AnyValue&, std::span<const AnyValue> args) -> AnyValue {
|
|
114
|
-
AnyValue val = args.empty() ?
|
|
118
|
+
AnyValue val = args.empty() ? Constants::UNDEFINED : args[0];
|
|
115
119
|
if (onFinally.is_function()) {
|
|
116
|
-
onFinally.call(
|
|
120
|
+
onFinally.call(Constants::UNDEFINED, {}, "onFinally");
|
|
117
121
|
}
|
|
118
122
|
return val;
|
|
119
123
|
}, ""),
|
|
120
124
|
AnyValue::make_function([onFinally](const AnyValue&, std::span<const AnyValue> args) -> AnyValue {
|
|
121
|
-
AnyValue reason = args.empty() ?
|
|
125
|
+
AnyValue reason = args.empty() ? Constants::UNDEFINED : args[0];
|
|
122
126
|
if (onFinally.is_function()) {
|
|
123
|
-
onFinally.call(
|
|
127
|
+
onFinally.call(Constants::UNDEFINED, {}, "onFinally");
|
|
124
128
|
}
|
|
125
129
|
throw Exception(reason);
|
|
126
130
|
}, "")
|
|
@@ -131,4 +135,4 @@ namespace jspp
|
|
|
131
135
|
return std::nullopt;
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
|
-
}
|
|
138
|
+
}
|
|
@@ -40,7 +40,7 @@ namespace jspp
|
|
|
40
40
|
return AnyValue::make_accessor_descriptor([self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
41
41
|
{ return AnyValue::make_number(self->value.length()); },
|
|
42
42
|
[self](const AnyValue &thisVal, std::span<const AnyValue>) -> AnyValue
|
|
43
|
-
{ return
|
|
43
|
+
{ return Constants::UNDEFINED; },
|
|
44
44
|
false,
|
|
45
45
|
false);
|
|
46
46
|
}
|
|
@@ -78,12 +78,12 @@ namespace jspp
|
|
|
78
78
|
{
|
|
79
79
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
80
80
|
{
|
|
81
|
-
if(args.empty()) return
|
|
81
|
+
if(args.empty()) return Constants::FALSE;
|
|
82
82
|
std::string search = args[0].to_std_string();
|
|
83
83
|
size_t end_pos = (args.size() > 1 && !args[1].is_undefined()) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : self->value.length();
|
|
84
84
|
|
|
85
85
|
if (end_pos > self->value.length()) end_pos = self->value.length();
|
|
86
|
-
if (search.length() > end_pos) return
|
|
86
|
+
if (search.length() > end_pos) return Constants::FALSE;
|
|
87
87
|
|
|
88
88
|
return AnyValue::make_boolean(self->value.substr(end_pos - search.length(), search.length()) == search); },
|
|
89
89
|
key);
|
|
@@ -94,7 +94,7 @@ namespace jspp
|
|
|
94
94
|
{
|
|
95
95
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
96
96
|
{
|
|
97
|
-
if(args.empty()) return
|
|
97
|
+
if(args.empty()) return Constants::FALSE;
|
|
98
98
|
std::string search = args[0].to_std_string();
|
|
99
99
|
size_t pos = (args.size() > 1) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : 0;
|
|
100
100
|
|
|
@@ -269,7 +269,7 @@ namespace jspp
|
|
|
269
269
|
{
|
|
270
270
|
return AnyValue::make_function([self](const AnyValue &thisVal, std::span<const AnyValue> args) -> AnyValue
|
|
271
271
|
{
|
|
272
|
-
if(args.empty()) return
|
|
272
|
+
if(args.empty()) return Constants::FALSE;
|
|
273
273
|
std::string search = args[0].to_std_string();
|
|
274
274
|
size_t pos = (args.size() > 1) ? static_cast<size_t>(Operators_Private::ToNumber(args[1])) : 0;
|
|
275
275
|
if (pos > self->value.length()) pos = self->value.length();
|
|
@@ -9,13 +9,15 @@ namespace jspp
|
|
|
9
9
|
// Forward declaration of AnyValue
|
|
10
10
|
class AnyValue;
|
|
11
11
|
|
|
12
|
-
struct JsString
|
|
12
|
+
struct JsString : HeapObject
|
|
13
13
|
{
|
|
14
14
|
std::string value;
|
|
15
15
|
|
|
16
16
|
JsString() = default;
|
|
17
17
|
explicit JsString(const std::string &s) : value(s) {}
|
|
18
18
|
|
|
19
|
+
JsType get_heap_type() const override { return JsType::String; }
|
|
20
|
+
|
|
19
21
|
std::string to_std_string() const;
|
|
20
22
|
JsIterator<AnyValue> get_iterator();
|
|
21
23
|
|