@ugo-studio/jspp 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +25 -25
- package/README.md +20 -12
- package/dist/analysis/scope.js +5 -3
- package/dist/analysis/typeAnalyzer.js +21 -25
- package/dist/cli/index.js +14 -4
- package/dist/cli/utils.js +61 -0
- package/dist/core/codegen/control-flow-handlers.js +10 -9
- package/dist/core/codegen/declaration-handlers.js +10 -3
- package/dist/core/codegen/destructuring-handlers.js +9 -4
- package/dist/core/codegen/expression-handlers.js +40 -29
- package/dist/core/codegen/function-handlers.js +78 -12
- package/dist/core/codegen/helpers.js +91 -14
- package/dist/core/codegen/index.js +4 -2
- package/dist/core/codegen/statement-handlers.js +8 -6
- package/package.json +2 -2
- package/scripts/precompile-headers.ts +249 -50
- package/scripts/setup-compiler.ts +63 -63
- package/src/prelude/any_value.cpp +636 -0
- package/src/prelude/any_value.hpp +23 -16
- package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
- package/src/prelude/exception.hpp +27 -27
- package/src/prelude/iterator_instantiations.hpp +10 -0
- package/src/prelude/{index.hpp → jspp.hpp} +10 -16
- package/src/prelude/library/array.cpp +191 -0
- package/src/prelude/library/array.hpp +5 -178
- package/src/prelude/library/console.cpp +125 -0
- package/src/prelude/library/console.hpp +9 -97
- package/src/prelude/library/error.cpp +100 -0
- package/src/prelude/library/error.hpp +8 -108
- package/src/prelude/library/function.cpp +69 -0
- package/src/prelude/library/function.hpp +6 -5
- package/src/prelude/library/global.cpp +96 -0
- package/src/prelude/library/global.hpp +12 -28
- package/src/prelude/library/global_usings.hpp +15 -0
- package/src/prelude/library/math.cpp +258 -0
- package/src/prelude/library/math.hpp +6 -288
- package/src/prelude/library/object.cpp +379 -0
- package/src/prelude/library/object.hpp +5 -267
- package/src/prelude/library/performance.cpp +21 -0
- package/src/prelude/library/performance.hpp +5 -20
- package/src/prelude/library/process.cpp +38 -0
- package/src/prelude/library/process.hpp +3 -31
- package/src/prelude/library/promise.cpp +131 -0
- package/src/prelude/library/promise.hpp +5 -116
- package/src/prelude/library/symbol.cpp +56 -0
- package/src/prelude/library/symbol.hpp +5 -46
- package/src/prelude/library/timer.cpp +88 -0
- package/src/prelude/library/timer.hpp +11 -87
- package/src/prelude/runtime.cpp +19 -0
- package/src/prelude/types.hpp +17 -12
- package/src/prelude/utils/access.hpp +122 -31
- package/src/prelude/utils/assignment_operators.hpp +99 -99
- package/src/prelude/utils/log_any_value/array.hpp +61 -40
- package/src/prelude/utils/log_any_value/function.hpp +39 -39
- package/src/prelude/utils/log_any_value/object.hpp +60 -3
- package/src/prelude/utils/operators.hpp +25 -10
- package/src/prelude/utils/operators_primitive.hpp +336 -336
- package/src/prelude/utils/well_known_symbols.hpp +24 -24
- package/src/prelude/values/array.cpp +1399 -0
- package/src/prelude/values/array.hpp +4 -0
- package/src/prelude/values/async_iterator.cpp +251 -0
- package/src/prelude/values/async_iterator.hpp +60 -32
- package/src/prelude/values/function.cpp +262 -0
- package/src/prelude/values/function.hpp +10 -30
- package/src/prelude/values/iterator.cpp +309 -0
- package/src/prelude/values/iterator.hpp +33 -64
- package/src/prelude/values/number.cpp +176 -0
- package/src/prelude/values/object.cpp +159 -0
- package/src/prelude/values/object.hpp +4 -0
- package/src/prelude/values/promise.cpp +479 -0
- package/src/prelude/values/promise.hpp +9 -2
- package/src/prelude/values/prototypes/array.hpp +46 -1348
- package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
- package/src/prelude/values/prototypes/function.hpp +7 -46
- package/src/prelude/values/prototypes/iterator.hpp +15 -191
- package/src/prelude/values/prototypes/number.hpp +23 -210
- package/src/prelude/values/prototypes/object.hpp +7 -23
- package/src/prelude/values/prototypes/promise.hpp +8 -186
- package/src/prelude/values/prototypes/string.hpp +28 -553
- package/src/prelude/values/prototypes/symbol.hpp +9 -70
- package/src/prelude/values/shape.hpp +52 -52
- package/src/prelude/values/string.cpp +485 -0
- package/src/prelude/values/symbol.cpp +89 -0
- package/src/prelude/values/symbol.hpp +101 -101
- package/src/prelude/any_value_access.hpp +0 -170
- package/src/prelude/any_value_defines.hpp +0 -190
- package/src/prelude/any_value_helpers.hpp +0 -374
- package/src/prelude/values/helpers/array.hpp +0 -199
- package/src/prelude/values/helpers/async_iterator.hpp +0 -275
- package/src/prelude/values/helpers/function.hpp +0 -109
- package/src/prelude/values/helpers/iterator.hpp +0 -145
- package/src/prelude/values/helpers/object.hpp +0 -104
- package/src/prelude/values/helpers/promise.hpp +0 -254
- package/src/prelude/values/helpers/string.hpp +0 -37
- package/src/prelude/values/helpers/symbol.hpp +0 -21
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "library/performance.hpp"
|
|
3
|
+
#include <chrono>
|
|
4
|
+
|
|
5
|
+
namespace jspp
|
|
6
|
+
{
|
|
7
|
+
|
|
8
|
+
AnyValue performance = jspp::AnyValue::make_object({
|
|
9
|
+
{"now",
|
|
10
|
+
jspp::AnyValue::make_function(
|
|
11
|
+
[startTime = std::chrono::steady_clock::now()](jspp::AnyValue, std::span<const jspp::AnyValue>)
|
|
12
|
+
{
|
|
13
|
+
std::chrono::duration<double, std::milli> duration =
|
|
14
|
+
std::chrono::steady_clock::now() - startTime;
|
|
15
|
+
|
|
16
|
+
return jspp::AnyValue::make_number(duration.count());
|
|
17
|
+
},
|
|
18
|
+
"now")},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
} // namespace jspp
|
|
@@ -1,25 +1,10 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
-
#include <chrono>
|
|
4
3
|
#include "types.hpp"
|
|
5
|
-
#include "
|
|
6
|
-
#include "values/object.hpp"
|
|
7
|
-
#include "values/function.hpp"
|
|
8
|
-
#include "utils/operators.hpp"
|
|
4
|
+
#include "any_value.hpp"
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// [C++14 Feature] Generalized Lambda Capture
|
|
14
|
-
// We initialize 'startTime' RIGHT HERE inside the [].
|
|
15
|
-
// It acts like a private variable stored inside this specific function.
|
|
16
|
-
[startTime = std::chrono::steady_clock::now()](jspp::AnyValue, std::span<const jspp::AnyValue>)
|
|
17
|
-
{
|
|
18
|
-
// We calculate the diff against the captured startTime
|
|
19
|
-
std::chrono::duration<double, std::milli> duration =
|
|
20
|
-
std::chrono::steady_clock::now() - startTime;
|
|
6
|
+
namespace jspp {
|
|
7
|
+
extern AnyValue performance;
|
|
8
|
+
}
|
|
21
9
|
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
"now")},
|
|
25
|
-
});
|
|
10
|
+
using jspp::performance;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "library/process.hpp"
|
|
3
|
+
|
|
4
|
+
#ifdef _WIN32
|
|
5
|
+
#define JSPP_PLATFORM "win32"
|
|
6
|
+
#else
|
|
7
|
+
#define JSPP_PLATFORM "linux"
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
namespace jspp {
|
|
11
|
+
|
|
12
|
+
AnyValue process = jspp::AnyValue::make_object({
|
|
13
|
+
{"argv", jspp::AnyValue::make_array(std::vector<jspp::AnyValue>{})},
|
|
14
|
+
{"env", jspp::AnyValue::make_object({})},
|
|
15
|
+
{"platform", jspp::AnyValue::make_string(JSPP_PLATFORM)},
|
|
16
|
+
{"exit", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
|
|
17
|
+
int code = 0;
|
|
18
|
+
if (!args.empty() && args[0].is_number()) {
|
|
19
|
+
code = static_cast<int>(args[0].as_double());
|
|
20
|
+
}
|
|
21
|
+
std::exit(code);
|
|
22
|
+
return jspp::Constants::UNDEFINED;
|
|
23
|
+
}, "exit")}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
void setup_process_argv(int argc, char** argv) {
|
|
27
|
+
std::vector<jspp::AnyValue> args;
|
|
28
|
+
if (argc > 0) {
|
|
29
|
+
args.push_back(jspp::AnyValue::make_string(argv[0]));
|
|
30
|
+
args.push_back(jspp::AnyValue::make_string("index.js"));
|
|
31
|
+
for (int i = 1; i < argc; ++i) {
|
|
32
|
+
args.push_back(jspp::AnyValue::make_string(argv[i]));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
process.set_own_property("argv", jspp::AnyValue::make_array(std::move(args)));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
} // namespace jspp
|
|
@@ -3,37 +3,9 @@
|
|
|
3
3
|
#include "types.hpp"
|
|
4
4
|
#include "any_value.hpp"
|
|
5
5
|
|
|
6
|
-
#ifdef _WIN32
|
|
7
|
-
#define JSPP_PLATFORM "win32"
|
|
8
|
-
#else
|
|
9
|
-
#define JSPP_PLATFORM "linux"
|
|
10
|
-
#endif
|
|
11
|
-
|
|
12
|
-
inline auto process = jspp::AnyValue::make_object({
|
|
13
|
-
{"argv", jspp::AnyValue::make_array(std::vector<jspp::AnyValue>{})},
|
|
14
|
-
{"env", jspp::AnyValue::make_object({})},
|
|
15
|
-
{"platform", jspp::AnyValue::make_string(JSPP_PLATFORM)},
|
|
16
|
-
{"exit", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
|
|
17
|
-
int code = 0;
|
|
18
|
-
if (!args.empty() && args[0].is_number()) {
|
|
19
|
-
code = static_cast<int>(args[0].as_double());
|
|
20
|
-
}
|
|
21
|
-
std::exit(code);
|
|
22
|
-
return jspp::Constants::UNDEFINED;
|
|
23
|
-
}, "exit")}
|
|
24
|
-
});
|
|
25
|
-
|
|
26
6
|
namespace jspp {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (argc > 0) {
|
|
30
|
-
args.push_back(jspp::AnyValue::make_string(argv[0]));
|
|
31
|
-
args.push_back(jspp::AnyValue::make_string("index.js"));
|
|
32
|
-
for (int i = 1; i < argc; ++i) {
|
|
33
|
-
args.push_back(jspp::AnyValue::make_string(argv[i]));
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
process.set_own_property("argv", jspp::AnyValue::make_array(std::move(args)));
|
|
37
|
-
}
|
|
7
|
+
extern AnyValue process;
|
|
8
|
+
void setup_process_argv(int argc, char** argv);
|
|
38
9
|
}
|
|
39
10
|
|
|
11
|
+
using jspp::process;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "library/promise.hpp"
|
|
3
|
+
|
|
4
|
+
namespace jspp
|
|
5
|
+
{
|
|
6
|
+
jspp::AnyValue Promise = jspp::AnyValue::make_function(
|
|
7
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
8
|
+
{
|
|
9
|
+
if (args.empty() || !args[0].is_function())
|
|
10
|
+
{
|
|
11
|
+
throw jspp::Exception::make_exception("Promise resolver undefined is not a function", "TypeError");
|
|
12
|
+
}
|
|
13
|
+
auto executor = args[0].as_function();
|
|
14
|
+
|
|
15
|
+
jspp::JsPromise promise;
|
|
16
|
+
auto state = promise.state; // Share state
|
|
17
|
+
|
|
18
|
+
// resolve function
|
|
19
|
+
auto resolveFn = jspp::AnyValue::make_function(
|
|
20
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([state](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
21
|
+
{
|
|
22
|
+
jspp::JsPromise p; p.state = state;
|
|
23
|
+
p.resolve(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
24
|
+
return jspp::Constants::UNDEFINED;
|
|
25
|
+
}), "resolve");
|
|
26
|
+
|
|
27
|
+
// reject function
|
|
28
|
+
auto rejectFn = jspp::AnyValue::make_function(
|
|
29
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([state](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
30
|
+
{
|
|
31
|
+
jspp::JsPromise p; p.state = state;
|
|
32
|
+
p.reject(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
33
|
+
return jspp::Constants::UNDEFINED;
|
|
34
|
+
}), "reject");
|
|
35
|
+
|
|
36
|
+
try
|
|
37
|
+
{
|
|
38
|
+
const jspp::AnyValue executorArgs[] = {resolveFn, rejectFn};
|
|
39
|
+
executor->call(jspp::Constants::UNDEFINED, std::span<const jspp::AnyValue>(executorArgs, 2));
|
|
40
|
+
}
|
|
41
|
+
catch (const jspp::Exception &e)
|
|
42
|
+
{
|
|
43
|
+
promise.reject(e.data);
|
|
44
|
+
}
|
|
45
|
+
catch (...)
|
|
46
|
+
{
|
|
47
|
+
promise.reject(jspp::AnyValue::make_string("Unknown error during Promise execution"));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return jspp::AnyValue::make_promise(promise); }),
|
|
51
|
+
"Promise");
|
|
52
|
+
|
|
53
|
+
struct PromiseInit
|
|
54
|
+
{
|
|
55
|
+
PromiseInit()
|
|
56
|
+
{
|
|
57
|
+
Promise.define_data_property("resolve", jspp::AnyValue::make_function(
|
|
58
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
59
|
+
{
|
|
60
|
+
jspp::JsPromise p;
|
|
61
|
+
p.resolve(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
62
|
+
return jspp::AnyValue::make_promise(p); }),
|
|
63
|
+
"resolve"));
|
|
64
|
+
|
|
65
|
+
Promise.define_data_property("reject", jspp::AnyValue::make_function(
|
|
66
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
67
|
+
{
|
|
68
|
+
jspp::JsPromise p;
|
|
69
|
+
p.reject(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
70
|
+
return jspp::AnyValue::make_promise(p); }),
|
|
71
|
+
"reject"));
|
|
72
|
+
|
|
73
|
+
Promise.define_data_property("all", jspp::AnyValue::make_function(
|
|
74
|
+
std::function<AnyValue(AnyValue, std::span<const AnyValue>)>([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
75
|
+
{
|
|
76
|
+
if (args.empty() || !args[0].is_array()) {
|
|
77
|
+
jspp::JsPromise p; p.reject(jspp::AnyValue::make_string("Promise.all argument must be an array"));
|
|
78
|
+
return jspp::AnyValue::make_promise(p);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
auto arr = args[0].as_array();
|
|
82
|
+
size_t len = static_cast<size_t>(arr->length);
|
|
83
|
+
if (len == 0) {
|
|
84
|
+
jspp::JsPromise p; p.resolve(jspp::AnyValue::make_array(std::vector<jspp::AnyValue>()));
|
|
85
|
+
return jspp::AnyValue::make_promise(p);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
jspp::JsPromise masterPromise;
|
|
89
|
+
auto masterState = masterPromise.state;
|
|
90
|
+
|
|
91
|
+
auto results = std::make_shared<std::vector<jspp::AnyValue>>(len, jspp::Constants::UNDEFINED);
|
|
92
|
+
auto count = std::make_shared<size_t>(len);
|
|
93
|
+
auto rejected = std::make_shared<bool>(false);
|
|
94
|
+
|
|
95
|
+
for (size_t i = 0; i < len; ++i) {
|
|
96
|
+
jspp::AnyValue item = arr->get_property(static_cast<uint32_t>(i));
|
|
97
|
+
|
|
98
|
+
auto handleResult = [masterState, results, count, i, rejected](jspp::AnyValue res) {
|
|
99
|
+
if (*rejected) return;
|
|
100
|
+
(*results)[i] = res;
|
|
101
|
+
(*count)--;
|
|
102
|
+
if (*count == 0) {
|
|
103
|
+
jspp::JsPromise p; p.state = masterState;
|
|
104
|
+
p.resolve(jspp::AnyValue::make_array(std::move(*results)));
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
auto handleReject = [masterState, rejected](jspp::AnyValue reason) {
|
|
109
|
+
if (*rejected) return;
|
|
110
|
+
*rejected = true;
|
|
111
|
+
jspp::JsPromise p; p.state = masterState;
|
|
112
|
+
masterState->status = jspp::PromiseStatus::Rejected;
|
|
113
|
+
p.reject(reason);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
if (item.is_promise()) {
|
|
117
|
+
item.as_promise()->then(handleResult, handleReject);
|
|
118
|
+
} else {
|
|
119
|
+
handleResult(item);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return jspp::AnyValue::make_promise(masterPromise); }),
|
|
124
|
+
"all"));
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
void init_promise()
|
|
128
|
+
{
|
|
129
|
+
static PromiseInit promiseInit;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -1,123 +1,12 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include "types.hpp"
|
|
4
|
-
#include "values/promise.hpp"
|
|
5
4
|
#include "any_value.hpp"
|
|
6
|
-
#include "exception.hpp"
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
if (args.empty() || !args[0].is_function())
|
|
11
|
-
{
|
|
12
|
-
throw jspp::Exception::make_exception("Promise resolver undefined is not a function", "TypeError");
|
|
13
|
-
}
|
|
14
|
-
auto executor = args[0].as_function();
|
|
15
|
-
|
|
16
|
-
jspp::JsPromise promise;
|
|
17
|
-
auto state = promise.state; // Share state
|
|
18
|
-
|
|
19
|
-
// resolve function
|
|
20
|
-
auto resolveFn = jspp::AnyValue::make_function([state](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
21
|
-
{
|
|
22
|
-
jspp::JsPromise p; p.state = state;
|
|
23
|
-
p.resolve(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
24
|
-
return jspp::Constants::UNDEFINED; }, "resolve");
|
|
25
|
-
|
|
26
|
-
// reject function
|
|
27
|
-
auto rejectFn = jspp::AnyValue::make_function([state](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
28
|
-
{
|
|
29
|
-
jspp::JsPromise p; p.state = state;
|
|
30
|
-
p.reject(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
31
|
-
return jspp::Constants::UNDEFINED; }, "reject");
|
|
32
|
-
|
|
33
|
-
try
|
|
34
|
-
{
|
|
35
|
-
const jspp::AnyValue executorArgs[] = {resolveFn, rejectFn};
|
|
36
|
-
executor->call(jspp::Constants::UNDEFINED, std::span<const jspp::AnyValue>(executorArgs, 2));
|
|
37
|
-
}
|
|
38
|
-
catch (const jspp::Exception &e)
|
|
39
|
-
{
|
|
40
|
-
promise.reject(e.data);
|
|
41
|
-
}
|
|
42
|
-
catch (...)
|
|
43
|
-
{
|
|
44
|
-
promise.reject(jspp::AnyValue::make_string("Unknown error during Promise execution"));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return jspp::AnyValue::make_promise(promise); },
|
|
48
|
-
"Promise");
|
|
49
|
-
|
|
50
|
-
struct PromiseInit
|
|
6
|
+
namespace jspp
|
|
51
7
|
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Promise.define_data_property("resolve", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
56
|
-
{
|
|
57
|
-
jspp::JsPromise p;
|
|
58
|
-
p.resolve(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
59
|
-
return jspp::AnyValue::make_promise(p); }, "resolve"));
|
|
60
|
-
|
|
61
|
-
// Promise.reject(reason)
|
|
62
|
-
Promise.define_data_property("reject", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
63
|
-
{
|
|
64
|
-
jspp::JsPromise p;
|
|
65
|
-
p.reject(args.empty() ? jspp::Constants::UNDEFINED : args[0]);
|
|
66
|
-
return jspp::AnyValue::make_promise(p); }, "reject"));
|
|
67
|
-
|
|
68
|
-
// Promise.all(iterable)
|
|
69
|
-
Promise.define_data_property("all", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
70
|
-
{
|
|
71
|
-
// Handle non-array iterable or empty args
|
|
72
|
-
if (args.empty() || !args[0].is_array()) {
|
|
73
|
-
jspp::JsPromise p; p.reject(jspp::AnyValue::make_string("Promise.all argument must be an array"));
|
|
74
|
-
return jspp::AnyValue::make_promise(p);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
auto arr = args[0].as_array();
|
|
78
|
-
size_t len = static_cast<size_t>(arr->length);
|
|
79
|
-
if (len == 0) {
|
|
80
|
-
jspp::JsPromise p; p.resolve(jspp::AnyValue::make_array(std::vector<jspp::AnyValue>()));
|
|
81
|
-
return jspp::AnyValue::make_promise(p);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
jspp::JsPromise masterPromise;
|
|
85
|
-
auto masterState = masterPromise.state;
|
|
86
|
-
|
|
87
|
-
auto results = std::make_shared<std::vector<jspp::AnyValue>>(len, jspp::Constants::UNDEFINED);
|
|
88
|
-
auto count = std::make_shared<size_t>(len);
|
|
89
|
-
|
|
90
|
-
// Check if already rejected to avoid further processing
|
|
91
|
-
auto rejected = std::make_shared<bool>(false);
|
|
92
|
-
|
|
93
|
-
for (size_t i = 0; i < len; ++i) {
|
|
94
|
-
jspp::AnyValue item = arr->get_property(static_cast<uint32_t>(i));
|
|
95
|
-
|
|
96
|
-
auto handleResult = [masterState, results, count, i, rejected](jspp::AnyValue res) {
|
|
97
|
-
if (*rejected) return;
|
|
98
|
-
(*results)[i] = res;
|
|
99
|
-
(*count)--;
|
|
100
|
-
if (*count == 0) {
|
|
101
|
-
jspp::JsPromise p; p.state = masterState;
|
|
102
|
-
p.resolve(jspp::AnyValue::make_array(std::move(*results)));
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
auto handleReject = [masterState, rejected](jspp::AnyValue reason) {
|
|
107
|
-
if (*rejected) return;
|
|
108
|
-
*rejected = true;
|
|
109
|
-
jspp::JsPromise p; p.state = masterState;
|
|
110
|
-
masterState->status =jspp::PromiseStatus::Rejected; // ensure master state updated
|
|
111
|
-
p.reject(reason);
|
|
112
|
-
};
|
|
8
|
+
extern AnyValue Promise;
|
|
9
|
+
void init_promise();
|
|
10
|
+
}
|
|
113
11
|
|
|
114
|
-
|
|
115
|
-
item.as_promise()->then(handleResult, handleReject);
|
|
116
|
-
} else {
|
|
117
|
-
handleResult(item);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return jspp::AnyValue::make_promise(masterPromise); }, "all"));
|
|
122
|
-
}
|
|
123
|
-
} promiseInit;
|
|
12
|
+
using jspp::Promise;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "library/symbol.hpp"
|
|
3
|
+
|
|
4
|
+
namespace jspp
|
|
5
|
+
{
|
|
6
|
+
|
|
7
|
+
AnyValue Symbol = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
8
|
+
{
|
|
9
|
+
std::string description = "";
|
|
10
|
+
if (!args.empty() && !args[0].is_undefined()) {
|
|
11
|
+
description = args[0].to_std_string();
|
|
12
|
+
}
|
|
13
|
+
return jspp::AnyValue::make_symbol(description); }, "Symbol", false);
|
|
14
|
+
|
|
15
|
+
struct SymbolInit
|
|
16
|
+
{
|
|
17
|
+
SymbolInit()
|
|
18
|
+
{
|
|
19
|
+
// Static methods
|
|
20
|
+
Symbol.define_data_property("for", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
21
|
+
{
|
|
22
|
+
std::string key = "";
|
|
23
|
+
if (!args.empty()) key = args[0].to_std_string();
|
|
24
|
+
return jspp::AnyValue::from_symbol(jspp::JsSymbol::for_global(key)); }, "for"));
|
|
25
|
+
|
|
26
|
+
Symbol.define_data_property("keyFor", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
27
|
+
{
|
|
28
|
+
if (args.empty() || !args[0].is_symbol()) throw jspp::Exception::make_exception("Symbol.keyFor requires a symbol", "TypeError");
|
|
29
|
+
auto sym = args[0].as_symbol();
|
|
30
|
+
auto key = jspp::JsSymbol::key_for(sym);
|
|
31
|
+
if (key.has_value()) return jspp::AnyValue::make_string(key.value());
|
|
32
|
+
return jspp::Constants::UNDEFINED; }, "keyFor"));
|
|
33
|
+
|
|
34
|
+
// Well-known symbols
|
|
35
|
+
Symbol.define_data_property("iterator", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::iterator), false, false, false);
|
|
36
|
+
Symbol.define_data_property("asyncIterator", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::asyncIterator), false, false, false);
|
|
37
|
+
Symbol.define_data_property("hasInstance", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::hasInstance), false, false, false);
|
|
38
|
+
Symbol.define_data_property("isConcatSpreadable", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::isConcatSpreadable), false, false, false);
|
|
39
|
+
Symbol.define_data_property("match", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::match), false, false, false);
|
|
40
|
+
Symbol.define_data_property("matchAll", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::matchAll), false, false, false);
|
|
41
|
+
Symbol.define_data_property("replace", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::replace), false, false, false);
|
|
42
|
+
Symbol.define_data_property("search", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::search), false, false, false);
|
|
43
|
+
Symbol.define_data_property("species", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::species), false, false, false);
|
|
44
|
+
Symbol.define_data_property("split", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::split), false, false, false);
|
|
45
|
+
Symbol.define_data_property("toPrimitive", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::toPrimitive), false, false, false);
|
|
46
|
+
Symbol.define_data_property("toStringTag", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::toStringTag), false, false, false);
|
|
47
|
+
Symbol.define_data_property("unscopables", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::unscopables), false, false, false);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
void init_symbol()
|
|
52
|
+
{
|
|
53
|
+
static SymbolInit symbolInit;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
} // namespace jspp
|
|
@@ -1,52 +1,11 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
3
|
#include "types.hpp"
|
|
4
|
-
#include "utils/well_known_symbols.hpp"
|
|
5
|
-
#include "values/object.hpp"
|
|
6
4
|
#include "any_value.hpp"
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!args.empty() && !args[0].is_undefined()) {
|
|
13
|
-
description = args[0].to_std_string();
|
|
14
|
-
}
|
|
15
|
-
return jspp::AnyValue::make_symbol(description); }, "Symbol", false);
|
|
6
|
+
namespace jspp {
|
|
7
|
+
extern AnyValue Symbol;
|
|
8
|
+
void init_symbol();
|
|
9
|
+
}
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
struct SymbolInit
|
|
19
|
-
{
|
|
20
|
-
SymbolInit()
|
|
21
|
-
{
|
|
22
|
-
// Static methods
|
|
23
|
-
Symbol.define_data_property("for", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
24
|
-
{
|
|
25
|
-
std::string key = "";
|
|
26
|
-
if (!args.empty()) key = args[0].to_std_string();
|
|
27
|
-
return jspp::AnyValue::from_symbol(jspp::JsSymbol::for_global(key)); }, "for"));
|
|
28
|
-
|
|
29
|
-
Symbol.define_data_property("keyFor", jspp::AnyValue::make_function([](jspp::AnyValue, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
30
|
-
{
|
|
31
|
-
if (args.empty() || !args[0].is_symbol()) throw jspp::Exception::make_exception("Symbol.keyFor requires a symbol", "TypeError");
|
|
32
|
-
auto sym = args[0].as_symbol();
|
|
33
|
-
auto key = jspp::JsSymbol::key_for(sym);
|
|
34
|
-
if (key.has_value()) return jspp::AnyValue::make_string(key.value());
|
|
35
|
-
return jspp::Constants::UNDEFINED; }, "keyFor"));
|
|
36
|
-
|
|
37
|
-
// Well-known symbols
|
|
38
|
-
Symbol.define_data_property("iterator", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::iterator), false, false, false);
|
|
39
|
-
Symbol.define_data_property("asyncIterator", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::asyncIterator), false, false, false);
|
|
40
|
-
Symbol.define_data_property("hasInstance", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::hasInstance), false, false, false);
|
|
41
|
-
Symbol.define_data_property("isConcatSpreadable", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::isConcatSpreadable), false, false, false);
|
|
42
|
-
Symbol.define_data_property("match", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::match), false, false, false);
|
|
43
|
-
Symbol.define_data_property("matchAll", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::matchAll), false, false, false);
|
|
44
|
-
Symbol.define_data_property("replace", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::replace), false, false, false);
|
|
45
|
-
Symbol.define_data_property("search", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::search), false, false, false);
|
|
46
|
-
Symbol.define_data_property("species", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::species), false, false, false);
|
|
47
|
-
Symbol.define_data_property("split", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::split), false, false, false);
|
|
48
|
-
Symbol.define_data_property("toPrimitive", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::toPrimitive), false, false, false);
|
|
49
|
-
Symbol.define_data_property("toStringTag", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::toStringTag), false, false, false);
|
|
50
|
-
Symbol.define_data_property("unscopables", jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::unscopables), false, false, false);
|
|
51
|
-
}
|
|
52
|
-
} symbolInit;
|
|
11
|
+
using jspp::Symbol;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#include "jspp.hpp"
|
|
2
|
+
#include "library/timer.hpp"
|
|
3
|
+
|
|
4
|
+
namespace jspp
|
|
5
|
+
{
|
|
6
|
+
|
|
7
|
+
AnyValue setTimeout = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
8
|
+
{
|
|
9
|
+
if (args.empty() || !args[0].is_function()) {
|
|
10
|
+
throw jspp::Exception::make_exception("Callback must be a function", "TypeError");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
auto callback = args[0];
|
|
14
|
+
double delay = 0;
|
|
15
|
+
if (args.size() > 1 && args[1].is_number()) {
|
|
16
|
+
delay = args[1].as_double();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Capture arguments
|
|
20
|
+
std::vector<jspp::AnyValue> callArgs;
|
|
21
|
+
for (size_t i = 2; i < args.size(); ++i) {
|
|
22
|
+
callArgs.push_back(args[i]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
auto task = [callback, callArgs]() {
|
|
26
|
+
try {
|
|
27
|
+
callback.call(jspp::Constants::UNDEFINED, std::span<const jspp::AnyValue>(callArgs));
|
|
28
|
+
} catch (const jspp::Exception& e) {
|
|
29
|
+
std::cerr << "Uncaught exception in setTimeout: " << e.what() << "\n";
|
|
30
|
+
} catch (const std::exception& e) {
|
|
31
|
+
std::cerr << "Uncaught exception in setTimeout: " << e.what() << "\n";
|
|
32
|
+
} catch (...) {
|
|
33
|
+
std::cerr << "Uncaught unknown exception in setTimeout\n";
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
size_t id = jspp::Scheduler::instance().set_timeout(task, static_cast<size_t>(delay));
|
|
38
|
+
return jspp::AnyValue::make_number(static_cast<double>(id)); }, "setTimeout");
|
|
39
|
+
|
|
40
|
+
AnyValue clearTimeout = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
41
|
+
{
|
|
42
|
+
if (!args.empty() && args[0].is_number()) {
|
|
43
|
+
size_t id = static_cast<size_t>(args[0].as_double());
|
|
44
|
+
jspp::Scheduler::instance().clear_timer(id);
|
|
45
|
+
}
|
|
46
|
+
return jspp::Constants::UNDEFINED; }, "clearTimeout");
|
|
47
|
+
|
|
48
|
+
AnyValue setInterval = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
49
|
+
{
|
|
50
|
+
if (args.empty() || !args[0].is_function()) {
|
|
51
|
+
throw jspp::Exception::make_exception("Callback must be a function", "TypeError");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
auto callback = args[0];
|
|
55
|
+
double delay = 0;
|
|
56
|
+
if (args.size() > 1 && args[1].is_number()) {
|
|
57
|
+
delay = args[1].as_double();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
std::vector<jspp::AnyValue> callArgs;
|
|
61
|
+
for (size_t i = 2; i < args.size(); ++i) {
|
|
62
|
+
callArgs.push_back(args[i]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
auto task = [callback, callArgs]() {
|
|
66
|
+
try {
|
|
67
|
+
callback.call(jspp::Constants::UNDEFINED, std::span<const jspp::AnyValue>(callArgs));
|
|
68
|
+
} catch (const jspp::Exception& e) {
|
|
69
|
+
std::cerr << "Uncaught exception in setInterval: " << e.what() << "\n";
|
|
70
|
+
} catch (const std::exception& e) {
|
|
71
|
+
std::cerr << "Uncaught exception in setInterval: " << e.what() << "\n";
|
|
72
|
+
} catch (...) {
|
|
73
|
+
std::cerr << "Uncaught unknown exception in setInterval\n";
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
size_t id = jspp::Scheduler::instance().set_interval(task, static_cast<size_t>(delay));
|
|
78
|
+
return jspp::AnyValue::make_number(static_cast<double>(id)); }, "setInterval");
|
|
79
|
+
|
|
80
|
+
AnyValue clearInterval = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
81
|
+
{
|
|
82
|
+
if (!args.empty() && args[0].is_number()) {
|
|
83
|
+
size_t id = static_cast<size_t>(args[0].as_double());
|
|
84
|
+
jspp::Scheduler::instance().clear_timer(id);
|
|
85
|
+
}
|
|
86
|
+
return jspp::Constants::UNDEFINED; }, "clearInterval");
|
|
87
|
+
|
|
88
|
+
} // namespace jspp
|