@ugo-studio/jspp 0.1.4 → 0.1.5
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/analysis/scope.js +17 -0
- package/dist/analysis/typeAnalyzer.js +7 -1
- package/dist/ast/symbols.js +29 -0
- package/dist/ast/types.js +0 -6
- package/dist/cli-utils/args.js +57 -0
- package/dist/cli-utils/colors.js +9 -0
- package/dist/cli-utils/file-utils.js +20 -0
- package/dist/cli-utils/spinner.js +55 -0
- package/dist/cli.js +105 -30
- package/dist/core/codegen/class-handlers.js +10 -6
- package/dist/core/codegen/control-flow-handlers.js +31 -21
- package/dist/core/codegen/declaration-handlers.js +10 -6
- package/dist/core/codegen/expression-handlers.js +202 -60
- package/dist/core/codegen/function-handlers.js +179 -70
- package/dist/core/codegen/helpers.js +107 -17
- package/dist/core/codegen/index.js +9 -8
- package/dist/core/codegen/literal-handlers.js +15 -6
- package/dist/core/codegen/statement-handlers.js +67 -53
- package/dist/core/codegen/visitor.js +3 -1
- package/package.json +1 -1
- package/src/prelude/any_value.hpp +195 -342
- package/src/prelude/any_value_access.hpp +78 -30
- package/src/prelude/any_value_defines.hpp +74 -35
- package/src/prelude/any_value_helpers.hpp +73 -180
- package/src/prelude/exception.hpp +1 -0
- package/src/prelude/exception_helpers.hpp +4 -4
- package/src/prelude/index.hpp +9 -2
- package/src/prelude/library/array.hpp +190 -0
- package/src/prelude/library/console.hpp +6 -5
- package/src/prelude/library/error.hpp +10 -8
- package/src/prelude/library/function.hpp +10 -0
- package/src/prelude/library/global.hpp +20 -0
- package/src/prelude/library/math.hpp +308 -0
- package/src/prelude/library/object.hpp +288 -0
- package/src/prelude/library/performance.hpp +1 -1
- package/src/prelude/library/process.hpp +39 -0
- package/src/prelude/library/promise.hpp +53 -43
- package/src/prelude/library/symbol.hpp +45 -57
- package/src/prelude/library/timer.hpp +6 -6
- package/src/prelude/types.hpp +48 -0
- package/src/prelude/utils/access.hpp +182 -11
- package/src/prelude/utils/assignment_operators.hpp +99 -0
- package/src/prelude/utils/log_any_value/array.hpp +8 -8
- package/src/prelude/utils/log_any_value/function.hpp +6 -4
- package/src/prelude/utils/log_any_value/object.hpp +41 -24
- package/src/prelude/utils/log_any_value/primitives.hpp +3 -1
- package/src/prelude/utils/operators.hpp +750 -274
- package/src/prelude/utils/well_known_symbols.hpp +12 -0
- package/src/prelude/values/array.hpp +8 -6
- package/src/prelude/values/descriptors.hpp +2 -2
- package/src/prelude/values/function.hpp +71 -62
- package/src/prelude/values/helpers/array.hpp +64 -28
- package/src/prelude/values/helpers/function.hpp +77 -92
- package/src/prelude/values/helpers/iterator.hpp +3 -3
- package/src/prelude/values/helpers/object.hpp +54 -9
- package/src/prelude/values/helpers/promise.hpp +3 -3
- package/src/prelude/values/iterator.hpp +1 -1
- package/src/prelude/values/object.hpp +10 -3
- package/src/prelude/values/promise.hpp +3 -3
- package/src/prelude/values/prototypes/array.hpp +851 -12
- package/src/prelude/values/prototypes/function.hpp +2 -2
- package/src/prelude/values/prototypes/iterator.hpp +5 -5
- package/src/prelude/values/prototypes/number.hpp +153 -0
- package/src/prelude/values/prototypes/object.hpp +2 -2
- package/src/prelude/values/prototypes/promise.hpp +40 -30
- package/src/prelude/values/prototypes/string.hpp +28 -28
- package/src/prelude/values/prototypes/symbol.hpp +20 -3
- package/src/prelude/values/shape.hpp +52 -0
|
@@ -12,10 +12,10 @@ const char *jspp::Exception::what() const noexcept
|
|
|
12
12
|
jspp::Exception jspp::Exception::make_exception(const std::string &message, const std::string &name = "Error")
|
|
13
13
|
{
|
|
14
14
|
// Use the global Error object to construct the exception
|
|
15
|
-
std::vector<AnyValue> args = {
|
|
16
|
-
AnyValue errorObj = ::Error.construct(args);
|
|
17
|
-
errorObj.define_data_property("name", AnyValue::make_string(name));
|
|
18
|
-
|
|
15
|
+
std::vector<AnyValue> args = {AnyValue::make_string(message)};
|
|
16
|
+
AnyValue errorObj = ::Error.construct(args, name);
|
|
17
|
+
errorObj.define_data_property("name", AnyValue::make_string(name), true, false, true);
|
|
18
|
+
|
|
19
19
|
return Exception(errorObj);
|
|
20
20
|
}
|
|
21
21
|
jspp::AnyValue jspp::Exception::exception_to_any_value(const std::exception &ex)
|
package/src/prelude/index.hpp
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include "utils/well_known_symbols.hpp"
|
|
5
5
|
|
|
6
6
|
// values
|
|
7
|
+
#include "values/shape.hpp"
|
|
7
8
|
#include "values/symbol.hpp"
|
|
8
9
|
#include "values/non_values.hpp"
|
|
9
10
|
#include "values/object.hpp"
|
|
@@ -13,9 +14,8 @@
|
|
|
13
14
|
#include "values/promise.hpp"
|
|
14
15
|
#include "values/string.hpp"
|
|
15
16
|
|
|
16
|
-
#include "exception.hpp"
|
|
17
|
-
#include "values/descriptors.hpp"
|
|
18
17
|
#include "any_value.hpp"
|
|
18
|
+
#include "values/descriptors.hpp"
|
|
19
19
|
#include "any_value_helpers.hpp"
|
|
20
20
|
#include "any_value_access.hpp"
|
|
21
21
|
#include "any_value_defines.hpp"
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
#include "values/prototypes/iterator.hpp"
|
|
31
31
|
#include "values/prototypes/promise.hpp"
|
|
32
32
|
#include "values/prototypes/string.hpp"
|
|
33
|
+
#include "values/prototypes/number.hpp"
|
|
33
34
|
|
|
34
35
|
#include "values/helpers/symbol.hpp"
|
|
35
36
|
#include "values/helpers/object.hpp"
|
|
@@ -41,12 +42,18 @@
|
|
|
41
42
|
|
|
42
43
|
// utilities
|
|
43
44
|
#include "utils/operators.hpp"
|
|
45
|
+
#include "utils/assignment_operators.hpp"
|
|
44
46
|
#include "utils/access.hpp"
|
|
45
47
|
#include "utils/log_any_value/log_any_value.hpp"
|
|
46
48
|
|
|
47
49
|
// js standard libraries
|
|
48
50
|
#include "library/symbol.hpp"
|
|
51
|
+
#include "library/process.hpp"
|
|
52
|
+
#include "library/function.hpp"
|
|
49
53
|
#include "library/console.hpp"
|
|
50
54
|
#include "library/performance.hpp"
|
|
51
55
|
#include "library/promise.hpp"
|
|
56
|
+
#include "library/math.hpp"
|
|
57
|
+
#include "library/object.hpp"
|
|
58
|
+
#include "library/array.hpp"
|
|
52
59
|
#include "library/global.hpp"
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "types.hpp"
|
|
4
|
+
#include "any_value.hpp"
|
|
5
|
+
#include "utils/operators.hpp"
|
|
6
|
+
#include "utils/access.hpp"
|
|
7
|
+
|
|
8
|
+
inline auto Array = jspp::AnyValue::make_class([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
9
|
+
{
|
|
10
|
+
if (args.size() == 1 && args[0].is_number()) {
|
|
11
|
+
double len = args[0].as_double();
|
|
12
|
+
if (len < 0 || len > 4294967295.0) { // Max uint32
|
|
13
|
+
throw jspp::Exception::make_exception("Invalid array length", "RangeError");
|
|
14
|
+
}
|
|
15
|
+
auto arr = jspp::AnyValue::make_array(std::vector<jspp::AnyValue>());
|
|
16
|
+
arr.as_array()->length = static_cast<uint64_t>(len);
|
|
17
|
+
arr.as_array()->dense.resize(static_cast<size_t>(len), jspp::AnyValue::make_uninitialized());
|
|
18
|
+
return arr;
|
|
19
|
+
}
|
|
20
|
+
std::vector<jspp::AnyValue> elements;
|
|
21
|
+
for(const auto& arg : args) {
|
|
22
|
+
elements.push_back(arg);
|
|
23
|
+
}
|
|
24
|
+
return jspp::AnyValue::make_array(std::move(elements)); }, "Array");
|
|
25
|
+
|
|
26
|
+
struct ArrayInit
|
|
27
|
+
{
|
|
28
|
+
ArrayInit()
|
|
29
|
+
{
|
|
30
|
+
// Set Array.prototype.proto to Object.prototype
|
|
31
|
+
// Array.get_own_property("prototype").set_prototype(::Object.get_own_property("prototype"));
|
|
32
|
+
|
|
33
|
+
// Array.isArray(value)
|
|
34
|
+
Array.define_data_property("isArray", jspp::AnyValue::make_function([](const jspp::AnyValue &, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
35
|
+
{
|
|
36
|
+
if (args.empty()) return jspp::Constants::FALSE;
|
|
37
|
+
return jspp::AnyValue::make_boolean(args[0].is_array()); }, "isArray"));
|
|
38
|
+
|
|
39
|
+
// Array.of(...elements)
|
|
40
|
+
Array.define_data_property("of", jspp::AnyValue::make_function([](const jspp::AnyValue &, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
41
|
+
{
|
|
42
|
+
std::vector<jspp::AnyValue> elements;
|
|
43
|
+
for(const auto& arg : args) {
|
|
44
|
+
elements.push_back(arg);
|
|
45
|
+
}
|
|
46
|
+
return jspp::AnyValue::make_array(std::move(elements)); }, "of"));
|
|
47
|
+
|
|
48
|
+
// Array.from(arrayLike, mapFn?, thisArg?)
|
|
49
|
+
Array.define_data_property("from", jspp::AnyValue::make_function([](const jspp::AnyValue &, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
50
|
+
{
|
|
51
|
+
if (args.empty() || args[0].is_null() || args[0].is_undefined()) {
|
|
52
|
+
throw jspp::Exception::make_exception("Array.from requires an array-like object", "TypeError");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const auto& items = args[0];
|
|
56
|
+
const auto& mapFn = (args.size() > 1 && args[1].is_function()) ? args[1] : jspp::Constants::UNDEFINED;
|
|
57
|
+
const auto& thisArg = (args.size() > 2) ? args[2] : jspp::Constants::UNDEFINED;
|
|
58
|
+
|
|
59
|
+
std::vector<jspp::AnyValue> result;
|
|
60
|
+
|
|
61
|
+
// Check if iterable
|
|
62
|
+
// Simple check: does it have [Symbol.iterator]?
|
|
63
|
+
auto iteratorSym = jspp::WellKnownSymbols::iterator;
|
|
64
|
+
if (items.has_property(iteratorSym->key)) {
|
|
65
|
+
auto iter = jspp::Access::get_object_value_iterator(items, "Array.from source");
|
|
66
|
+
auto nextFn = iter.get_own_property("next");
|
|
67
|
+
|
|
68
|
+
size_t k = 0;
|
|
69
|
+
while (true) {
|
|
70
|
+
auto nextRes = nextFn.call(iter, std::span<const jspp::AnyValue>{}, "next");
|
|
71
|
+
if (jspp::is_truthy(nextRes.get_own_property("done"))) break;
|
|
72
|
+
|
|
73
|
+
auto val = nextRes.get_own_property("value");
|
|
74
|
+
if (mapFn.is_function()) {
|
|
75
|
+
jspp::AnyValue kVal = jspp::AnyValue::make_number(k);
|
|
76
|
+
const jspp::AnyValue mapArgs[] = {val, kVal};
|
|
77
|
+
val = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
78
|
+
}
|
|
79
|
+
result.push_back(val);
|
|
80
|
+
k++;
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
// Array-like (length property)
|
|
84
|
+
auto lenVal = items.get_property_with_receiver("length", items);
|
|
85
|
+
size_t len = static_cast<size_t>(jspp::Operators_Private::ToUint32(lenVal));
|
|
86
|
+
|
|
87
|
+
for (size_t k = 0; k < len; ++k) {
|
|
88
|
+
auto kVal = items.get_property_with_receiver(std::to_string(k), items);
|
|
89
|
+
if (mapFn.is_function()) {
|
|
90
|
+
jspp::AnyValue kNum = jspp::AnyValue::make_number(k);
|
|
91
|
+
const jspp::AnyValue mapArgs[] = {kVal, kNum};
|
|
92
|
+
kVal = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
93
|
+
}
|
|
94
|
+
result.push_back(kVal);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return jspp::AnyValue::make_array(std::move(result)); }, "from"));
|
|
99
|
+
|
|
100
|
+
// Array.fromAsync(iterableOrArrayLike, mapFn?, thisArg?)
|
|
101
|
+
Array.define_data_property("fromAsync", jspp::AnyValue::make_async_function([](const jspp::AnyValue &, std::span<const jspp::AnyValue> args) -> jspp::JsPromise
|
|
102
|
+
{
|
|
103
|
+
if (args.empty() || args[0].is_null() || args[0].is_undefined()) {
|
|
104
|
+
throw jspp::Exception::make_exception("Array.fromAsync requires an iterable or array-like object", "TypeError");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const auto& items = args[0];
|
|
108
|
+
const auto& mapFn = (args.size() > 1 && args[1].is_function()) ? args[1] : jspp::Constants::UNDEFINED;
|
|
109
|
+
const auto& thisArg = (args.size() > 2) ? args[2] : jspp::Constants::UNDEFINED;
|
|
110
|
+
|
|
111
|
+
std::vector<jspp::AnyValue> result;
|
|
112
|
+
|
|
113
|
+
bool isAsync = false;
|
|
114
|
+
jspp::AnyValue iter;
|
|
115
|
+
jspp::AnyValue nextFn;
|
|
116
|
+
|
|
117
|
+
if (items.has_property(jspp::WellKnownSymbols::asyncIterator->key)) {
|
|
118
|
+
auto method = items.get_property_with_receiver(jspp::WellKnownSymbols::asyncIterator->key, items);
|
|
119
|
+
if (method.is_function()) {
|
|
120
|
+
iter = method.call(items, {});
|
|
121
|
+
nextFn = iter.get_own_property("next");
|
|
122
|
+
isAsync = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!isAsync && items.has_property(jspp::WellKnownSymbols::iterator->key)) {
|
|
127
|
+
auto method = items.get_property_with_receiver(jspp::WellKnownSymbols::iterator->key, items);
|
|
128
|
+
if (method.is_function()) {
|
|
129
|
+
iter = method.call(items, {});
|
|
130
|
+
nextFn = iter.get_own_property("next");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (!iter.is_undefined()) {
|
|
135
|
+
size_t k = 0;
|
|
136
|
+
while (true) {
|
|
137
|
+
auto nextRes = nextFn.call(iter, {});
|
|
138
|
+
|
|
139
|
+
if (nextRes.is_promise()) {
|
|
140
|
+
nextRes = co_await nextRes;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (jspp::is_truthy(nextRes.get_own_property("done"))) break;
|
|
144
|
+
|
|
145
|
+
auto val = nextRes.get_own_property("value");
|
|
146
|
+
|
|
147
|
+
if (mapFn.is_function()) {
|
|
148
|
+
jspp::AnyValue kVal = jspp::AnyValue::make_number(k);
|
|
149
|
+
const jspp::AnyValue mapArgs[] = {val, kVal};
|
|
150
|
+
auto mapRes = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
151
|
+
if (mapRes.is_promise()) {
|
|
152
|
+
val = co_await mapRes;
|
|
153
|
+
} else {
|
|
154
|
+
val = mapRes;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
result.push_back(val);
|
|
158
|
+
k++;
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
auto lenVal = items.get_property_with_receiver("length", items);
|
|
162
|
+
size_t len = static_cast<size_t>(jspp::Operators_Private::ToUint32(lenVal));
|
|
163
|
+
|
|
164
|
+
for (size_t k = 0; k < len; ++k) {
|
|
165
|
+
auto kVal = items.get_property_with_receiver(std::to_string(k), items);
|
|
166
|
+
if (kVal.is_promise()) {
|
|
167
|
+
kVal = co_await kVal;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (mapFn.is_function()) {
|
|
171
|
+
jspp::AnyValue kNum = jspp::AnyValue::make_number(k);
|
|
172
|
+
const jspp::AnyValue mapArgs[] = {kVal, kNum};
|
|
173
|
+
auto mapRes = mapFn.call(thisArg, std::span<const jspp::AnyValue>(mapArgs, 2));
|
|
174
|
+
if (mapRes.is_promise()) {
|
|
175
|
+
kVal = co_await mapRes;
|
|
176
|
+
} else {
|
|
177
|
+
kVal = mapRes;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
result.push_back(kVal);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
co_return jspp::AnyValue::make_array(std::move(result)); }, "fromAsync"));
|
|
185
|
+
|
|
186
|
+
// Array[Symbol.species]
|
|
187
|
+
Array.define_getter(jspp::AnyValue::from_symbol(jspp::WellKnownSymbols::species), jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
188
|
+
{ return thisVal; }, "get [Symbol.species]"));
|
|
189
|
+
}
|
|
190
|
+
} arrayInit;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#include "values/object.hpp"
|
|
7
7
|
#include "values/function.hpp"
|
|
8
8
|
#include "utils/operators.hpp"
|
|
9
|
+
#include "exception.hpp"
|
|
9
10
|
#include "utils/log_any_value/log_any_value.hpp"
|
|
10
11
|
|
|
11
12
|
#include <cmath>
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
|
|
15
16
|
static std::map<std::string, std::chrono::steady_clock::time_point> timers = {};
|
|
16
17
|
|
|
17
|
-
auto logFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal,
|
|
18
|
+
auto logFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args)
|
|
18
19
|
{
|
|
19
20
|
for (size_t i = 0; i < args.size(); ++i)
|
|
20
21
|
{
|
|
@@ -24,7 +25,7 @@ auto logFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, con
|
|
|
24
25
|
}
|
|
25
26
|
std::cout << "\n" << std::flush;
|
|
26
27
|
return jspp::AnyValue::make_undefined(); }, "log");
|
|
27
|
-
auto warnFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal,
|
|
28
|
+
auto warnFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args)
|
|
28
29
|
{
|
|
29
30
|
std::cerr << "\033[33m";
|
|
30
31
|
for (size_t i = 0; i < args.size(); ++i)
|
|
@@ -35,7 +36,7 @@ auto warnFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, co
|
|
|
35
36
|
}
|
|
36
37
|
std::cerr << "\033[0m" << "\n" << std::flush; // reset
|
|
37
38
|
return jspp::AnyValue::make_undefined(); }, "warn");
|
|
38
|
-
auto errorFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal,
|
|
39
|
+
auto errorFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args)
|
|
39
40
|
{
|
|
40
41
|
std::cerr << "\033[31m";
|
|
41
42
|
for (size_t i = 0; i < args.size(); ++i)
|
|
@@ -46,7 +47,7 @@ auto errorFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, c
|
|
|
46
47
|
}
|
|
47
48
|
std::cerr << "\033[0m" << "\n" << std::flush; // reset
|
|
48
49
|
return jspp::AnyValue::make_undefined(); }, "error");
|
|
49
|
-
auto timeFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal,
|
|
50
|
+
auto timeFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args)
|
|
50
51
|
{
|
|
51
52
|
auto start = std::chrono::steady_clock::now(); // capture immediately
|
|
52
53
|
auto key_str = args.size() > 0 ? args[0].to_std_string() : "default";
|
|
@@ -83,7 +84,7 @@ static auto format_duration = [](double ms) -> std::string
|
|
|
83
84
|
return ss.str();
|
|
84
85
|
};
|
|
85
86
|
|
|
86
|
-
auto timeEndFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal,
|
|
87
|
+
auto timeEndFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args)
|
|
87
88
|
{
|
|
88
89
|
auto end = std::chrono::steady_clock::now(); // capture immediately
|
|
89
90
|
auto key_str = args.size() > 0 ? args[0].to_std_string() : "default";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
inline jspp::AnyValue Error;
|
|
8
8
|
|
|
9
9
|
// Constructor logic
|
|
10
|
-
inline auto errorConstructor = [](const jspp::AnyValue &thisVal,
|
|
10
|
+
inline auto errorConstructor = [](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
11
11
|
{
|
|
12
12
|
// Access global Error to get prototype
|
|
13
13
|
jspp::AnyValue proto = Error.get_own_property("prototype");
|
|
@@ -18,7 +18,7 @@ inline auto errorConstructor = [](const jspp::AnyValue &thisVal, const std::vect
|
|
|
18
18
|
if (target.is_object())
|
|
19
19
|
{
|
|
20
20
|
auto obj = target.as_object();
|
|
21
|
-
if (obj->proto && (*obj->proto)
|
|
21
|
+
if (obj->proto && is_strictly_equal_to_primitive((*obj->proto), proto))
|
|
22
22
|
{
|
|
23
23
|
is_construct_call = true;
|
|
24
24
|
}
|
|
@@ -29,6 +29,7 @@ inline auto errorConstructor = [](const jspp::AnyValue &thisVal, const std::vect
|
|
|
29
29
|
target = jspp::AnyValue::make_object_with_proto({}, proto);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
std::string name = "Error";
|
|
32
33
|
std::string message = "";
|
|
33
34
|
if (!args.empty() && !args[0].is_undefined())
|
|
34
35
|
{
|
|
@@ -36,8 +37,8 @@ inline auto errorConstructor = [](const jspp::AnyValue &thisVal, const std::vect
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
target.define_data_property("message", jspp::AnyValue::make_string(message), true, false, true);
|
|
39
|
-
target.define_data_property("name", jspp::AnyValue::make_string(
|
|
40
|
-
target.define_data_property("stack", jspp::AnyValue::make_string("
|
|
40
|
+
target.define_data_property("name", jspp::AnyValue::make_string(name), true, false, true);
|
|
41
|
+
target.define_data_property("stack", jspp::AnyValue::make_string(name + ": " + message + "\n at <unknown>"), true, false, true);
|
|
41
42
|
|
|
42
43
|
if (args.size() > 1 && args[1].is_object())
|
|
43
44
|
{
|
|
@@ -52,7 +53,7 @@ inline auto errorConstructor = [](const jspp::AnyValue &thisVal, const std::vect
|
|
|
52
53
|
};
|
|
53
54
|
|
|
54
55
|
// Static Error.isError(val) implementation
|
|
55
|
-
inline auto isErrorFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal,
|
|
56
|
+
inline auto isErrorFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
56
57
|
{
|
|
57
58
|
if (args.empty()) return jspp::AnyValue::make_boolean(false);
|
|
58
59
|
|
|
@@ -67,7 +68,7 @@ inline auto isErrorFn = jspp::AnyValue::make_function([](const jspp::AnyValue &t
|
|
|
67
68
|
if (val.is_object()) {
|
|
68
69
|
auto current = val.as_object()->proto;
|
|
69
70
|
while (current && !(*current).is_null()) {
|
|
70
|
-
if ((*current)
|
|
71
|
+
if (is_strictly_equal_to_primitive((*current),proto)) return jspp::AnyValue::make_boolean(true);
|
|
71
72
|
if ((*current).is_object()) current = (*current).as_object()->proto;
|
|
72
73
|
else break;
|
|
73
74
|
}
|
|
@@ -76,7 +77,7 @@ inline auto isErrorFn = jspp::AnyValue::make_function([](const jspp::AnyValue &t
|
|
|
76
77
|
return jspp::AnyValue::make_boolean(false); }, "isError");
|
|
77
78
|
|
|
78
79
|
// toString method for Error.prototype
|
|
79
|
-
inline auto errorToStringFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal,
|
|
80
|
+
inline auto errorToStringFn = jspp::AnyValue::make_function([](const jspp::AnyValue &thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue
|
|
80
81
|
{
|
|
81
82
|
std::string name = "Error";
|
|
82
83
|
std::string msg = "";
|
|
@@ -104,8 +105,9 @@ struct ErrorInit
|
|
|
104
105
|
// Define Error.prototype.toString
|
|
105
106
|
auto proto = Error.get_own_property("prototype");
|
|
106
107
|
proto.define_data_property("toString", errorToStringFn, true, false, true);
|
|
108
|
+
proto.define_data_property(jspp::WellKnownSymbols::toStringTag->key, errorToStringFn, true, false, true);
|
|
107
109
|
|
|
108
110
|
// Define static Error.isError
|
|
109
|
-
Error.define_data_property("isError", isErrorFn,true
|
|
111
|
+
Error.define_data_property("isError", isErrorFn, true, false, true);
|
|
110
112
|
}
|
|
111
113
|
} errorInit;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "types.hpp"
|
|
4
|
+
#include "any_value.hpp"
|
|
5
|
+
|
|
6
|
+
// Define Function constructor
|
|
7
|
+
// In a full implementation, this would support 'new Function(args, body)'
|
|
8
|
+
inline auto Function = jspp::AnyValue::make_class([](const jspp::AnyValue& thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
|
|
9
|
+
return jspp::Constants::UNDEFINED;
|
|
10
|
+
}, "Function");
|
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
#include "library/promise.hpp"
|
|
10
10
|
#include "library/timer.hpp"
|
|
11
|
+
#include "library/math.hpp"
|
|
11
12
|
|
|
12
13
|
inline auto global = jspp::AnyValue::make_object({
|
|
14
|
+
{"Symbol", Symbol},
|
|
15
|
+
{"process", process},
|
|
16
|
+
{"Function", Function},
|
|
13
17
|
{"console", console},
|
|
14
18
|
{"performance", performance},
|
|
15
19
|
{"Error", Error},
|
|
@@ -18,4 +22,20 @@ inline auto global = jspp::AnyValue::make_object({
|
|
|
18
22
|
{"clearTimeout", clearTimeout},
|
|
19
23
|
{"setInterval", setInterval},
|
|
20
24
|
{"clearInterval", clearInterval},
|
|
25
|
+
{"Math", Math},
|
|
26
|
+
{"Object", Object},
|
|
27
|
+
{"Array", Array},
|
|
21
28
|
});
|
|
29
|
+
|
|
30
|
+
struct GlobalInit {
|
|
31
|
+
GlobalInit() {
|
|
32
|
+
auto objectProto = ::Object.get_own_property("prototype");
|
|
33
|
+
|
|
34
|
+
// Tie built-in prototypes to Object.prototype
|
|
35
|
+
::Array.get_own_property("prototype").set_prototype(objectProto);
|
|
36
|
+
::Function.get_own_property("prototype").set_prototype(objectProto);
|
|
37
|
+
::Error.get_own_property("prototype").set_prototype(objectProto);
|
|
38
|
+
::Promise.get_own_property("prototype").set_prototype(objectProto);
|
|
39
|
+
::Symbol.get_own_property("prototype").set_prototype(objectProto);
|
|
40
|
+
}
|
|
41
|
+
} globalInit;
|