@ugo-studio/jspp 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/LICENSE +25 -25
  2. package/README.md +20 -12
  3. package/dist/cli/args.js +22 -0
  4. package/dist/cli/compiler.js +53 -0
  5. package/dist/cli/index.js +43 -107
  6. package/dist/cli/pch.js +71 -0
  7. package/dist/cli/runner.js +23 -0
  8. package/dist/cli/spinner.js +27 -11
  9. package/dist/cli/transpiler.js +20 -0
  10. package/dist/cli/utils.js +59 -0
  11. package/dist/cli/wasm.js +70 -0
  12. package/dist/index.js +17 -6
  13. package/dist/{analysis → interpreter/analysis}/scope.js +38 -3
  14. package/dist/{analysis → interpreter/analysis}/typeAnalyzer.js +563 -28
  15. package/dist/{core → interpreter/core}/codegen/class-handlers.js +1 -1
  16. package/dist/{core → interpreter/core}/codegen/control-flow-handlers.js +12 -11
  17. package/dist/{core → interpreter/core}/codegen/declaration-handlers.js +28 -9
  18. package/dist/{core → interpreter/core}/codegen/destructuring-handlers.js +9 -4
  19. package/dist/{core → interpreter/core}/codegen/expression-handlers.js +82 -88
  20. package/dist/{core → interpreter/core}/codegen/function-handlers.js +159 -46
  21. package/dist/{core → interpreter/core}/codegen/helpers.js +170 -25
  22. package/dist/interpreter/core/codegen/index.js +156 -0
  23. package/dist/{core → interpreter/core}/codegen/literal-handlers.js +9 -0
  24. package/dist/{core → interpreter/core}/codegen/statement-handlers.js +47 -7
  25. package/package.json +6 -4
  26. package/scripts/precompile-headers.ts +293 -50
  27. package/scripts/setup-compiler.ts +63 -63
  28. package/scripts/setup-emsdk.ts +114 -0
  29. package/src/prelude/any_value.cpp +888 -0
  30. package/src/prelude/any_value.hpp +29 -24
  31. package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
  32. package/src/prelude/exception.hpp +27 -27
  33. package/src/prelude/iterator_instantiations.hpp +10 -0
  34. package/src/prelude/{index.hpp → jspp.hpp} +13 -17
  35. package/src/prelude/library/array.cpp +191 -0
  36. package/src/prelude/library/array.hpp +5 -178
  37. package/src/prelude/library/boolean.cpp +30 -0
  38. package/src/prelude/library/boolean.hpp +14 -0
  39. package/src/prelude/library/console.cpp +125 -0
  40. package/src/prelude/library/console.hpp +9 -97
  41. package/src/prelude/library/error.cpp +100 -0
  42. package/src/prelude/library/error.hpp +8 -108
  43. package/src/prelude/library/function.cpp +69 -0
  44. package/src/prelude/library/function.hpp +6 -5
  45. package/src/prelude/library/global.cpp +98 -0
  46. package/src/prelude/library/global.hpp +12 -28
  47. package/src/prelude/library/global_usings.hpp +15 -0
  48. package/src/prelude/library/math.cpp +261 -0
  49. package/src/prelude/library/math.hpp +8 -288
  50. package/src/prelude/library/object.cpp +379 -0
  51. package/src/prelude/library/object.hpp +5 -267
  52. package/src/prelude/library/performance.cpp +21 -0
  53. package/src/prelude/library/performance.hpp +5 -20
  54. package/src/prelude/library/process.cpp +38 -0
  55. package/src/prelude/library/process.hpp +3 -31
  56. package/src/prelude/library/promise.cpp +131 -0
  57. package/src/prelude/library/promise.hpp +5 -116
  58. package/src/prelude/library/symbol.cpp +56 -0
  59. package/src/prelude/library/symbol.hpp +5 -46
  60. package/src/prelude/library/timer.cpp +88 -0
  61. package/src/prelude/library/timer.hpp +11 -87
  62. package/src/prelude/runtime.cpp +19 -0
  63. package/src/prelude/types.hpp +26 -20
  64. package/src/prelude/utils/access.hpp +123 -32
  65. package/src/prelude/utils/assignment_operators.hpp +119 -99
  66. package/src/prelude/utils/log_any_value/array.hpp +61 -40
  67. package/src/prelude/utils/log_any_value/function.hpp +39 -39
  68. package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
  69. package/src/prelude/utils/log_any_value/object.hpp +60 -3
  70. package/src/prelude/utils/log_any_value/primitives.hpp +1 -1
  71. package/src/prelude/utils/operators.hpp +109 -94
  72. package/src/prelude/utils/operators_native.hpp +349 -0
  73. package/src/prelude/utils/well_known_symbols.hpp +24 -24
  74. package/src/prelude/values/array.cpp +1399 -0
  75. package/src/prelude/values/array.hpp +4 -0
  76. package/src/prelude/values/async_iterator.cpp +251 -0
  77. package/src/prelude/values/async_iterator.hpp +60 -32
  78. package/src/prelude/values/boolean.cpp +64 -0
  79. package/src/prelude/values/function.cpp +262 -0
  80. package/src/prelude/values/function.hpp +10 -30
  81. package/src/prelude/values/iterator.cpp +309 -0
  82. package/src/prelude/values/iterator.hpp +33 -64
  83. package/src/prelude/values/number.cpp +221 -0
  84. package/src/prelude/values/object.cpp +200 -0
  85. package/src/prelude/values/object.hpp +4 -0
  86. package/src/prelude/values/promise.cpp +479 -0
  87. package/src/prelude/values/promise.hpp +9 -2
  88. package/src/prelude/values/prototypes/array.hpp +46 -1348
  89. package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
  90. package/src/prelude/values/prototypes/boolean.hpp +24 -0
  91. package/src/prelude/values/prototypes/function.hpp +7 -46
  92. package/src/prelude/values/prototypes/iterator.hpp +15 -191
  93. package/src/prelude/values/prototypes/number.hpp +30 -210
  94. package/src/prelude/values/prototypes/object.hpp +7 -23
  95. package/src/prelude/values/prototypes/promise.hpp +8 -186
  96. package/src/prelude/values/prototypes/string.hpp +28 -553
  97. package/src/prelude/values/prototypes/symbol.hpp +9 -70
  98. package/src/prelude/values/shape.hpp +52 -52
  99. package/src/prelude/values/string.cpp +485 -0
  100. package/src/prelude/values/symbol.cpp +89 -0
  101. package/src/prelude/values/symbol.hpp +101 -101
  102. package/dist/cli/file-utils.js +0 -20
  103. package/dist/cli-utils/args.js +0 -59
  104. package/dist/cli-utils/colors.js +0 -9
  105. package/dist/cli-utils/file-utils.js +0 -20
  106. package/dist/cli-utils/spinner.js +0 -55
  107. package/dist/cli.js +0 -153
  108. package/dist/core/codegen/index.js +0 -86
  109. package/src/prelude/any_value_access.hpp +0 -170
  110. package/src/prelude/any_value_defines.hpp +0 -190
  111. package/src/prelude/any_value_helpers.hpp +0 -374
  112. package/src/prelude/utils/operators_primitive.hpp +0 -337
  113. package/src/prelude/values/helpers/array.hpp +0 -199
  114. package/src/prelude/values/helpers/async_iterator.hpp +0 -275
  115. package/src/prelude/values/helpers/function.hpp +0 -109
  116. package/src/prelude/values/helpers/iterator.hpp +0 -145
  117. package/src/prelude/values/helpers/object.hpp +0 -104
  118. package/src/prelude/values/helpers/promise.hpp +0 -254
  119. package/src/prelude/values/helpers/string.hpp +0 -37
  120. package/src/prelude/values/helpers/symbol.hpp +0 -21
  121. /package/dist/{ast → interpreter/ast}/symbols.js +0 -0
  122. /package/dist/{ast → interpreter/ast}/types.js +0 -0
  123. /package/dist/{core → interpreter/core}/codegen/visitor.js +0 -0
  124. /package/dist/{core → interpreter/core}/constants.js +0 -0
  125. /package/dist/{core → interpreter/core}/error.js +0 -0
  126. /package/dist/{core → interpreter/core}/parser.js +0 -0
  127. /package/dist/{core → interpreter/core}/traverser.js +0 -0
@@ -2,91 +2,15 @@
2
2
 
3
3
  #include "types.hpp"
4
4
  #include "any_value.hpp"
5
- #include "scheduler.hpp"
6
- #include "values/function.hpp"
7
- #include "exception.hpp"
8
5
 
9
- // setTimeout(callback, delay, ...args)
10
- inline auto setTimeout = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
11
- if (args.empty() || !args[0].is_function()) {
12
- throw jspp::Exception::make_exception("Callback must be a function", "TypeError");
13
- }
14
-
15
- auto callback = args[0];
16
- double delay = 0;
17
- if (args.size() > 1 && args[1].is_number()) {
18
- delay = args[1].as_double();
19
- }
20
-
21
- // Capture arguments
22
- std::vector<jspp::AnyValue> callArgs;
23
- for (size_t i = 2; i < args.size(); ++i) {
24
- callArgs.push_back(args[i]);
25
- }
26
-
27
- auto task = [callback, callArgs]() {
28
- try {
29
- callback.call(jspp::Constants::UNDEFINED, std::span<const jspp::AnyValue>(callArgs));
30
- } catch (const jspp::Exception& e) {
31
- std::cerr << "Uncaught exception in setTimeout: " << e.what() << "\n";
32
- } catch (const std::exception& e) {
33
- std::cerr << "Uncaught exception in setTimeout: " << e.what() << "\n";
34
- } catch (...) {
35
- std::cerr << "Uncaught unknown exception in setTimeout\n";
36
- }
37
- };
38
-
39
- size_t id = jspp::Scheduler::instance().set_timeout(task, static_cast<size_t>(delay));
40
- return jspp::AnyValue::make_number(static_cast<double>(id));
41
- }, "setTimeout");
42
-
43
- // clearTimeout(id)
44
- inline auto clearTimeout = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
45
- if (!args.empty() && args[0].is_number()) {
46
- size_t id = static_cast<size_t>(args[0].as_double());
47
- jspp::Scheduler::instance().clear_timer(id);
48
- }
49
- return jspp::Constants::UNDEFINED;
50
- }, "clearTimeout");
51
-
52
- // setInterval(callback, delay, ...args)
53
- inline auto setInterval = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
54
- if (args.empty() || !args[0].is_function()) {
55
- throw jspp::Exception::make_exception("Callback must be a function", "TypeError");
56
- }
57
-
58
- auto callback = args[0];
59
- double delay = 0;
60
- if (args.size() > 1 && args[1].is_number()) {
61
- delay = args[1].as_double();
62
- }
63
-
64
- std::vector<jspp::AnyValue> callArgs;
65
- for (size_t i = 2; i < args.size(); ++i) {
66
- callArgs.push_back(args[i]);
67
- }
68
-
69
- auto task = [callback, callArgs]() {
70
- try {
71
- callback.call(jspp::Constants::UNDEFINED, std::span<const jspp::AnyValue>(callArgs));
72
- } catch (const jspp::Exception& e) {
73
- std::cerr << "Uncaught exception in setInterval: " << e.what() << "\n";
74
- } catch (const std::exception& e) {
75
- std::cerr << "Uncaught exception in setInterval: " << e.what() << "\n";
76
- } catch (...) {
77
- std::cerr << "Uncaught unknown exception in setInterval\n";
78
- }
79
- };
80
-
81
- size_t id = jspp::Scheduler::instance().set_interval(task, static_cast<size_t>(delay));
82
- return jspp::AnyValue::make_number(static_cast<double>(id));
83
- }, "setInterval");
84
-
85
- // clearInterval(id)
86
- inline auto clearInterval = jspp::AnyValue::make_function([](jspp::AnyValue thisVal, std::span<const jspp::AnyValue> args) -> jspp::AnyValue {
87
- if (!args.empty() && args[0].is_number()) {
88
- size_t id = static_cast<size_t>(args[0].as_double());
89
- jspp::Scheduler::instance().clear_timer(id);
90
- }
91
- return jspp::Constants::UNDEFINED;
92
- }, "clearInterval");
6
+ namespace jspp {
7
+ extern AnyValue setTimeout;
8
+ extern AnyValue clearTimeout;
9
+ extern AnyValue setInterval;
10
+ extern AnyValue clearInterval;
11
+ }
12
+
13
+ using jspp::setTimeout;
14
+ using jspp::clearTimeout;
15
+ using jspp::setInterval;
16
+ using jspp::clearInterval;
@@ -0,0 +1,19 @@
1
+ #include "jspp.hpp"
2
+
3
+ // Include core headers
4
+ #include "values/iterator.hpp"
5
+ #include "values/async_iterator.hpp"
6
+ #include "values/string.hpp"
7
+ #include "values/object.hpp"
8
+ #include "values/array.hpp"
9
+ #include "values/function.hpp"
10
+ #include "values/promise.hpp"
11
+ #include "values/symbol.hpp"
12
+ #include "values/descriptors.hpp"
13
+ #include "exception.hpp"
14
+
15
+ namespace jspp {
16
+ // Explicit template instantiation definitions
17
+ template class JsIterator<AnyValue>;
18
+ template class JsAsyncIterator<AnyValue>;
19
+ }
@@ -1,6 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  #include <iostream>
4
+ #include <exception>
4
5
  #include <string>
5
6
  #include <vector>
6
7
  #include <variant>
@@ -94,24 +95,21 @@ namespace jspp
94
95
  std::function<JsPromise(AnyValue, std::vector<AnyValue>)>,
95
96
  std::function<JsAsyncIterator<AnyValue>(AnyValue, std::vector<AnyValue>)>>;
96
97
 
97
- // Awaiter for AnyValue
98
- struct AnyValueAwaiter;
99
-
100
98
  // Truthiness checker
101
99
  const bool is_truthy(const double &val) noexcept;
102
100
  const bool is_truthy(const std::string &val) noexcept;
103
101
  const bool is_truthy(const AnyValue &val) noexcept;
104
102
 
105
103
  // Basic equality operators
106
- inline const bool is_strictly_equal_to_primitive(const AnyValue &lhs, const double &rhs) noexcept;
107
- inline const bool is_strictly_equal_to_primitive(const double &lhs, const AnyValue &rhs) noexcept;
108
- inline const bool is_strictly_equal_to_primitive(const double &lhs, const double &rhs) noexcept;
109
- inline const bool is_strictly_equal_to_primitive(const AnyValue &lhs, const AnyValue &rhs) noexcept;
104
+ inline const bool is_strictly_equal_to_native(const AnyValue &lhs, const double &rhs) noexcept;
105
+ inline const bool is_strictly_equal_to_native(const double &lhs, const AnyValue &rhs) noexcept;
106
+ inline const bool is_strictly_equal_to_native(const double &lhs, const double &rhs) noexcept;
107
+ inline const bool is_strictly_equal_to_native(const AnyValue &lhs, const AnyValue &rhs) noexcept;
110
108
 
111
- inline const bool is_equal_to_primitive(const AnyValue &lhs, const double &rhs) noexcept;
112
- inline const bool is_equal_to_primitive(const double &lhs, const AnyValue &rhs) noexcept;
113
- inline const bool is_equal_to_primitive(const double &lhs, const double &rhs) noexcept;
114
- inline const bool is_equal_to_primitive(const AnyValue &lhs, const AnyValue &rhs) noexcept;
109
+ inline const bool is_equal_to_native(const AnyValue &lhs, const double &rhs) noexcept;
110
+ inline const bool is_equal_to_native(const double &lhs, const AnyValue &rhs) noexcept;
111
+ inline const bool is_equal_to_native(const double &lhs, const double &rhs) noexcept;
112
+ inline const bool is_equal_to_native(const AnyValue &lhs, const AnyValue &rhs) noexcept;
115
113
 
116
114
  inline const AnyValue is_strictly_equal_to(const AnyValue &lhs, const double &rhs) noexcept;
117
115
  inline const AnyValue is_strictly_equal_to(const double &lhs, const AnyValue &rhs) noexcept;
@@ -146,34 +144,42 @@ namespace jspp
146
144
  // AnyValue prototypes
147
145
  namespace ObjectPrototypes
148
146
  {
149
- inline std::optional<AnyValue> get(const std::string &key);
147
+ std::optional<AnyValue> get(const std::string &key);
148
+ std::optional<AnyValue> get(const AnyValue &key);
150
149
  }
151
150
  namespace StringPrototypes
152
151
  {
153
- inline std::optional<AnyValue> get(const std::string &key);
152
+ std::optional<AnyValue> get(const std::string &key);
153
+ std::optional<AnyValue> get(const AnyValue &key);
154
154
  }
155
155
  namespace NumberPrototypes
156
156
  {
157
- inline std::optional<AnyValue> get(const std::string &key);
157
+ std::optional<AnyValue> get(const std::string &key);
158
+ std::optional<AnyValue> get(const AnyValue &key);
158
159
  }
159
160
  namespace ArrayPrototypes
160
161
  {
161
- inline std::optional<AnyValue> get(const std::string &key);
162
+ std::optional<AnyValue> get(const std::string &key);
163
+ std::optional<AnyValue> get(const AnyValue &key);
162
164
  }
163
165
  namespace FunctionPrototypes
164
166
  {
165
- inline std::optional<AnyValue> get(const std::string &key);
167
+ std::optional<AnyValue> get(const std::string &key);
168
+ std::optional<AnyValue> get(const AnyValue &key);
166
169
  }
167
170
  namespace PromisePrototypes
168
171
  {
169
- inline std::optional<AnyValue> get(const std::string &key);
172
+ std::optional<AnyValue> get(const std::string &key);
173
+ std::optional<AnyValue> get(const AnyValue &key);
170
174
  }
171
175
  namespace IteratorPrototypes
172
176
  {
173
- inline std::optional<AnyValue> get(const std::string &key);
177
+ std::optional<AnyValue> get(const std::string &key);
178
+ std::optional<AnyValue> get(const AnyValue &key);
174
179
  }
175
180
  namespace SymbolPrototypes
176
181
  {
177
- inline std::optional<AnyValue> get(const std::string &key);
182
+ std::optional<AnyValue> get(const std::string &key);
183
+ std::optional<AnyValue> get(const AnyValue &key);
178
184
  }
179
- }
185
+ }
@@ -83,9 +83,9 @@ namespace jspp
83
83
  }
84
84
 
85
85
  // Helper function to get enumerable own property keys/values of an object
86
- inline std::vector<std::string> get_object_keys(const AnyValue &obj, bool include_symbols = false)
86
+ inline std::vector<AnyValue> get_object_keys(const AnyValue &obj, bool include_symbols = false)
87
87
  {
88
- std::vector<std::string> keys;
88
+ std::vector<AnyValue> keys;
89
89
 
90
90
  if (obj.is_object())
91
91
  {
@@ -95,9 +95,6 @@ namespace jspp
95
95
  if (ptr->deleted_keys.count(key))
96
96
  continue;
97
97
 
98
- if (!include_symbols && JsSymbol::is_internal_key(key))
99
- continue;
100
-
101
98
  auto offset_opt = ptr->shape->get_offset(key);
102
99
  if (!offset_opt.has_value())
103
100
  continue;
@@ -107,16 +104,37 @@ namespace jspp
107
104
  if (val.is_data_descriptor())
108
105
  {
109
106
  if (val.as_data_descriptor()->enumerable)
110
- keys.push_back(key);
107
+ keys.push_back(AnyValue::make_string(key));
111
108
  }
112
109
  else if (val.is_accessor_descriptor())
113
110
  {
114
111
  if (val.as_accessor_descriptor()->enumerable)
115
- keys.push_back(key);
112
+ keys.push_back(AnyValue::make_string(key));
116
113
  }
117
114
  else
118
115
  {
119
- keys.push_back(key);
116
+ keys.push_back(AnyValue::make_string(key));
117
+ }
118
+ }
119
+ if (include_symbols)
120
+ {
121
+ for (const auto &pair : ptr->symbol_props)
122
+ {
123
+ const auto &val = pair.second;
124
+ if (val.is_data_descriptor())
125
+ {
126
+ if (val.as_data_descriptor()->enumerable)
127
+ keys.push_back(pair.first);
128
+ }
129
+ else if (val.is_accessor_descriptor())
130
+ {
131
+ if (val.as_accessor_descriptor()->enumerable)
132
+ keys.push_back(pair.first);
133
+ }
134
+ else
135
+ {
136
+ keys.push_back(pair.first);
137
+ }
120
138
  }
121
139
  }
122
140
  }
@@ -125,22 +143,62 @@ namespace jspp
125
143
  auto ptr = obj.as_function();
126
144
  for (const auto &pair : ptr->props)
127
145
  {
128
- if (include_symbols || !JsSymbol::is_internal_key(pair.first))
146
+ if (!pair.second.is_data_descriptor() && !pair.second.is_accessor_descriptor())
147
+ keys.push_back(AnyValue::make_string(pair.first));
148
+ else if ((pair.second.is_data_descriptor() && pair.second.as_data_descriptor()->enumerable) ||
149
+ (pair.second.is_accessor_descriptor() && pair.second.as_accessor_descriptor()->enumerable))
150
+ keys.push_back(AnyValue::make_string(pair.first));
151
+ }
152
+ if (include_symbols)
153
+ {
154
+ for (const auto &pair : ptr->symbol_props)
129
155
  {
130
- if (!pair.second.is_data_descriptor() && !pair.second.is_accessor_descriptor())
131
- keys.push_back(pair.first);
132
- else if ((pair.second.is_data_descriptor() && pair.second.as_data_descriptor()->enumerable) ||
133
- (pair.second.is_accessor_descriptor() && pair.second.as_accessor_descriptor()->enumerable))
156
+ const auto &val = pair.second;
157
+ if (val.is_data_descriptor())
158
+ {
159
+ if (val.as_data_descriptor()->enumerable)
160
+ keys.push_back(pair.first);
161
+ }
162
+ else if (val.is_accessor_descriptor())
163
+ {
164
+ if (val.as_accessor_descriptor()->enumerable)
165
+ keys.push_back(pair.first);
166
+ }
167
+ else
168
+ {
134
169
  keys.push_back(pair.first);
170
+ }
135
171
  }
136
172
  }
137
173
  }
138
174
  if (obj.is_array())
139
175
  {
140
- auto len = obj.as_array()->length;
176
+ auto ptr = obj.as_array();
177
+ auto len = ptr->length;
141
178
  for (uint64_t i = 0; i < len; ++i)
142
179
  {
143
- keys.push_back(std::to_string(i));
180
+ keys.push_back(AnyValue::make_string(std::to_string(i)));
181
+ }
182
+ if (include_symbols)
183
+ {
184
+ for (const auto &pair : ptr->symbol_props)
185
+ {
186
+ const auto &val = pair.second;
187
+ if (val.is_data_descriptor())
188
+ {
189
+ if (val.as_data_descriptor()->enumerable)
190
+ keys.push_back(pair.first);
191
+ }
192
+ else if (val.is_accessor_descriptor())
193
+ {
194
+ if (val.as_accessor_descriptor()->enumerable)
195
+ keys.push_back(pair.first);
196
+ }
197
+ else
198
+ {
199
+ keys.push_back(pair.first);
200
+ }
201
+ }
144
202
  }
145
203
  }
146
204
  if (obj.is_string())
@@ -148,24 +206,30 @@ namespace jspp
148
206
  auto len = obj.as_string()->value.length();
149
207
  for (size_t i = 0; i < len; ++i)
150
208
  {
151
- keys.push_back(std::to_string(i));
209
+ keys.push_back(AnyValue::make_string(std::to_string(i)));
152
210
  }
153
211
  }
154
212
 
155
213
  return keys;
156
214
  }
157
215
 
158
- inline AnyValue get_object_iterator(const AnyValue &obj, const std::string &name)
216
+ inline AnyValue get_object_iterator(const AnyValue &obj, const std::optional<std::string> &name = std::nullopt)
159
217
  {
218
+ if (obj.is_null() || obj.is_undefined())
219
+ {
220
+ throw jspp::Exception::make_exception("Cannot read properties of " + obj.to_std_string() + " (reading 'Symbol.iterator')", "TypeError");
221
+ }
222
+
160
223
  if (obj.is_iterator())
161
224
  {
162
225
  return obj;
163
226
  }
164
227
 
165
- auto gen_fn = obj.get_own_property(WellKnownSymbols::iterator->key);
228
+ auto iterSym = AnyValue::from_symbol(WellKnownSymbols::iterator);
229
+ auto gen_fn = obj.get_own_property(iterSym);
166
230
  if (gen_fn.is_function())
167
231
  {
168
- auto iter = gen_fn.call(obj, {}, WellKnownSymbols::iterator->key);
232
+ auto iter = gen_fn.call(obj, {}, iterSym.to_std_string());
169
233
  if (iter.is_iterator())
170
234
  {
171
235
  return iter;
@@ -180,31 +244,38 @@ namespace jspp
180
244
  }
181
245
  }
182
246
 
183
- throw jspp::Exception::make_exception(name + " is not iterable", "TypeError");
247
+ throw jspp::Exception::make_exception(name.value_or(obj.to_std_string()) + " is not iterable", "TypeError");
184
248
  }
185
249
 
186
- inline AnyValue get_object_async_iterator(const AnyValue &obj, const std::string &name)
250
+ inline AnyValue get_object_async_iterator(const AnyValue &obj, const std::optional<std::string> &name = std::nullopt)
187
251
  {
252
+ if (obj.is_null() || obj.is_undefined())
253
+ {
254
+ throw jspp::Exception::make_exception("Cannot read properties of " + obj.to_std_string() + " (reading 'Symbol.asyncIterator')", "TypeError");
255
+ }
256
+
188
257
  if (obj.is_async_iterator())
189
258
  return obj;
190
259
 
191
- auto method = obj.get_own_property(WellKnownSymbols::asyncIterator->key);
260
+ auto asyncIterSym = AnyValue::from_symbol(WellKnownSymbols::asyncIterator);
261
+ auto method = obj.get_own_property(asyncIterSym);
192
262
  if (method.is_function())
193
263
  {
194
- auto iter = method.call(obj, {}, WellKnownSymbols::asyncIterator->key);
264
+ auto iter = method.call(obj, {}, asyncIterSym.to_std_string());
195
265
  if (iter.is_object() || iter.is_async_iterator() || iter.is_iterator())
196
266
  return iter;
197
267
  }
198
268
 
199
- auto syncMethod = obj.get_own_property(WellKnownSymbols::iterator->key);
269
+ auto iterSym = AnyValue::from_symbol(WellKnownSymbols::iterator);
270
+ auto syncMethod = obj.get_own_property(iterSym);
200
271
  if (syncMethod.is_function())
201
272
  {
202
- auto iter = syncMethod.call(obj, {}, WellKnownSymbols::iterator->key);
273
+ auto iter = syncMethod.call(obj, {}, iterSym.to_std_string());
203
274
  if (iter.is_object() || iter.is_iterator())
204
275
  return iter;
205
276
  }
206
277
 
207
- throw jspp::Exception::make_exception(name + " is not async iterable", "TypeError");
278
+ throw jspp::Exception::make_exception(name.value_or(obj.to_std_string()) + " is not async iterable", "TypeError");
208
279
  }
209
280
 
210
281
  inline AnyValue in(const AnyValue &lhs, const AnyValue &rhs)
@@ -249,6 +320,10 @@ namespace jspp
249
320
  {
250
321
  proto = current.as_function()->proto;
251
322
  }
323
+ else if (current.is_promise())
324
+ {
325
+ proto = current.as_promise()->get_property("__proto__", current); // Fallback for promise if not fully modularized
326
+ }
252
327
  else
253
328
  {
254
329
  break;
@@ -256,7 +331,7 @@ namespace jspp
256
331
 
257
332
  if (proto.is_null() || proto.is_undefined())
258
333
  break;
259
- if (is_strictly_equal_to_primitive(proto, targetProto))
334
+ if (is_strictly_equal_to_native(proto, targetProto))
260
335
  return Constants::TRUE;
261
336
  current = proto;
262
337
  }
@@ -386,24 +461,40 @@ namespace jspp
386
461
  auto keys = get_object_keys(source);
387
462
  for (const auto &key : keys)
388
463
  {
389
- target.set_own_property(key, source.get_property_with_receiver(key, source));
464
+ target.set_own_property(key, source.get_property_with_receiver(key.to_std_string(), source));
390
465
  }
391
466
  }
392
467
 
393
- inline AnyValue get_rest_object(const AnyValue &source, const std::vector<std::string> &excluded_keys)
468
+ inline AnyValue get_rest_object(const AnyValue &source, const std::vector<AnyValue> &excluded_keys)
394
469
  {
395
470
  if (source.is_null() || source.is_undefined())
396
471
  return AnyValue::make_object({});
397
472
 
398
473
  auto result = AnyValue::make_object({});
399
474
  auto keys = get_object_keys(source, true);
400
- std::unordered_set<std::string> excluded(excluded_keys.begin(), excluded_keys.end());
475
+
476
+ auto is_excluded = [&](const AnyValue &key)
477
+ {
478
+ for (const auto &ex : excluded_keys)
479
+ {
480
+ if (is_strictly_equal_to_native(key, ex))
481
+ return true;
482
+ }
483
+ return false;
484
+ };
401
485
 
402
486
  for (const auto &key : keys)
403
487
  {
404
- if (excluded.find(key) == excluded.end())
488
+ if (!is_excluded(key))
405
489
  {
406
- result.set_own_property(key, source.get_property_with_receiver(key, source));
490
+ if (key.is_symbol())
491
+ {
492
+ result.set_own_symbol_property(key, source.get_symbol_property_with_receiver(key, source));
493
+ }
494
+ else
495
+ {
496
+ result.set_own_property(key.to_std_string(), source.get_property_with_receiver(key.to_std_string(), source));
497
+ }
407
498
  }
408
499
  }
409
500
  return result;