@ugo-studio/jspp 0.2.7 → 0.2.9

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 (41) hide show
  1. package/dist/analysis/typeAnalyzer.js +42 -27
  2. package/dist/core/codegen/class-handlers.js +2 -2
  3. package/dist/core/codegen/control-flow-handlers.js +4 -4
  4. package/dist/core/codegen/declaration-handlers.js +21 -3
  5. package/dist/core/codegen/destructuring-handlers.js +187 -0
  6. package/dist/core/codegen/expression-handlers.js +7 -0
  7. package/dist/core/codegen/function-handlers.js +58 -36
  8. package/dist/core/codegen/helpers.js +288 -52
  9. package/dist/core/codegen/index.js +7 -4
  10. package/dist/core/codegen/statement-handlers.js +42 -22
  11. package/package.json +1 -1
  12. package/scripts/precompile-headers.ts +19 -4
  13. package/src/prelude/any_value.hpp +26 -25
  14. package/src/prelude/any_value_access.hpp +7 -7
  15. package/src/prelude/any_value_defines.hpp +17 -17
  16. package/src/prelude/any_value_helpers.hpp +16 -7
  17. package/src/prelude/library/array.hpp +7 -7
  18. package/src/prelude/library/console.hpp +5 -5
  19. package/src/prelude/library/error.hpp +3 -3
  20. package/src/prelude/library/function.hpp +1 -1
  21. package/src/prelude/library/math.hpp +38 -38
  22. package/src/prelude/library/object.hpp +16 -16
  23. package/src/prelude/library/performance.hpp +1 -1
  24. package/src/prelude/library/process.hpp +1 -1
  25. package/src/prelude/library/promise.hpp +8 -8
  26. package/src/prelude/library/symbol.hpp +3 -3
  27. package/src/prelude/library/timer.hpp +4 -4
  28. package/src/prelude/types.hpp +4 -4
  29. package/src/prelude/utils/access.hpp +24 -6
  30. package/src/prelude/utils/operators.hpp +7 -0
  31. package/src/prelude/values/async_iterator.hpp +5 -3
  32. package/src/prelude/values/function.hpp +3 -3
  33. package/src/prelude/values/helpers/async_iterator.hpp +7 -3
  34. package/src/prelude/values/helpers/function.hpp +10 -10
  35. package/src/prelude/values/helpers/iterator.hpp +39 -2
  36. package/src/prelude/values/helpers/promise.hpp +9 -9
  37. package/src/prelude/values/helpers/string.hpp +17 -3
  38. package/src/prelude/values/iterator.hpp +32 -5
  39. package/src/prelude/values/promise.hpp +7 -7
  40. package/src/prelude/values/prototypes/array.hpp +41 -41
  41. package/src/prelude/values/prototypes/iterator.hpp +128 -1
@@ -327,4 +327,11 @@ namespace jspp
327
327
  lhs = rhs;
328
328
  return lhs;
329
329
  }
330
+
331
+ inline AnyValue undefined_coalesce(const AnyValue &lhs, const AnyValue &rhs)
332
+ {
333
+ if (!lhs.is_undefined())
334
+ return lhs;
335
+ return rhs;
336
+ }
330
337
  }
@@ -56,7 +56,9 @@ namespace jspp
56
56
  handle_type handle;
57
57
 
58
58
  explicit JsAsyncIterator(handle_type h) : handle(h) {}
59
- JsAsyncIterator(JsAsyncIterator &&other) noexcept : handle(std::exchange(other.handle, nullptr)) {}
59
+ JsAsyncIterator(JsAsyncIterator &&other) noexcept
60
+ : handle(std::exchange(other.handle, nullptr)),
61
+ props(std::move(other.props)) {}
60
62
 
61
63
  JsAsyncIterator(const JsAsyncIterator &) = delete;
62
64
  JsAsyncIterator &operator=(const JsAsyncIterator &) = delete;
@@ -73,8 +75,8 @@ namespace jspp
73
75
 
74
76
  JsPromise next(const T &val = T());
75
77
 
76
- AnyValue get_property(const std::string &key, const AnyValue &thisVal);
77
- AnyValue set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal);
78
+ AnyValue get_property(const std::string &key, AnyValue thisVal);
79
+ AnyValue set_property(const std::string &key, AnyValue value, AnyValue thisVal);
78
80
 
79
81
  void resume_next();
80
82
  };
@@ -73,10 +73,10 @@ namespace jspp
73
73
  JsType get_heap_type() const override { return JsType::Function; }
74
74
 
75
75
  std::string to_std_string() const;
76
- AnyValue call(const AnyValue &thisVal, std::span<const AnyValue> args);
76
+ AnyValue call(AnyValue thisVal, std::span<const AnyValue> args);
77
77
 
78
78
  bool has_property(const std::string &key) const;
79
- AnyValue get_property(const std::string &key, const AnyValue &thisVal);
80
- AnyValue set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal);
79
+ AnyValue get_property(const std::string &key, AnyValue thisVal);
80
+ AnyValue set_property(const std::string &key, AnyValue value, AnyValue thisVal);
81
81
  };
82
82
  }
@@ -14,7 +14,7 @@ std::string jspp::JsAsyncIterator<T>::to_std_string() const
14
14
  }
15
15
 
16
16
  template <typename T>
17
- jspp::AnyValue jspp::JsAsyncIterator<T>::get_property(const std::string &key, const AnyValue &thisVal)
17
+ jspp::AnyValue jspp::JsAsyncIterator<T>::get_property(const std::string &key, AnyValue thisVal)
18
18
  {
19
19
  auto it = props.find(key);
20
20
  if (it == props.end())
@@ -33,7 +33,7 @@ jspp::AnyValue jspp::JsAsyncIterator<T>::get_property(const std::string &key, co
33
33
  }
34
34
 
35
35
  template <typename T>
36
- jspp::AnyValue jspp::JsAsyncIterator<T>::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal)
36
+ jspp::AnyValue jspp::JsAsyncIterator<T>::set_property(const std::string &key, AnyValue value, AnyValue thisVal)
37
37
  {
38
38
  if constexpr (std::is_same_v<T, AnyValue>)
39
39
  {
@@ -87,8 +87,12 @@ void jspp::JsAsyncIterator<T>::resume_next()
87
87
  // After yield/return, if more calls are pending, handle them.
88
88
  if (!p.pending_calls.empty() && !p.is_awaiting && !handle.done())
89
89
  {
90
+ this->ref();
90
91
  Scheduler::instance().enqueue([this]()
91
- { this->resume_next(); });
92
+ {
93
+ this->resume_next();
94
+ this->deref();
95
+ });
92
96
  }
93
97
  }
94
98
 
@@ -18,23 +18,23 @@ namespace jspp
18
18
  return type_part + " " + name_part + "() { [native code] }";
19
19
  }
20
20
 
21
- inline AnyValue JsFunction::call(const AnyValue &thisVal, std::span<const AnyValue> args)
21
+ inline AnyValue JsFunction::call(AnyValue thisVal, std::span<const AnyValue> args)
22
22
  {
23
- if (std::function<AnyValue(const AnyValue &, std::span<const AnyValue>)> *func = std::get_if<0>(&callable))
23
+ if (std::function<AnyValue(AnyValue, std::span<const AnyValue>)> *func = std::get_if<0>(&callable))
24
24
  {
25
25
  return (*func)(thisVal, args);
26
26
  }
27
- else if (std::function<jspp::JsIterator<jspp::AnyValue>(const AnyValue &, std::span<const AnyValue>)> *func = std::get_if<1>(&callable))
27
+ else if (std::function<jspp::JsIterator<jspp::AnyValue>(AnyValue, std::vector<AnyValue>)> *func = std::get_if<1>(&callable))
28
28
  {
29
- return AnyValue::from_iterator((*func)(thisVal, args));
29
+ return AnyValue::from_iterator((*func)(thisVal, std::vector<AnyValue>(args.begin(), args.end())));
30
30
  }
31
- else if (std::function<jspp::JsPromise(const AnyValue &, std::span<const AnyValue>)> *func = std::get_if<2>(&callable))
31
+ else if (std::function<jspp::JsPromise(AnyValue, std::vector<AnyValue>)> *func = std::get_if<2>(&callable))
32
32
  {
33
- return AnyValue::make_promise((*func)(thisVal, args));
33
+ return AnyValue::make_promise((*func)(thisVal, std::vector<AnyValue>(args.begin(), args.end())));
34
34
  }
35
- else if (std::function<jspp::JsAsyncIterator<jspp::AnyValue>(const AnyValue &, std::span<const AnyValue>)> *func = std::get_if<3>(&callable))
35
+ else if (std::function<jspp::JsAsyncIterator<jspp::AnyValue>(AnyValue, std::vector<AnyValue>)> *func = std::get_if<3>(&callable))
36
36
  {
37
- return AnyValue::from_async_iterator((*func)(thisVal, args));
37
+ return AnyValue::from_async_iterator((*func)(thisVal, std::vector<AnyValue>(args.begin(), args.end())));
38
38
  }
39
39
  else
40
40
  {
@@ -56,7 +56,7 @@ namespace jspp
56
56
  return false;
57
57
  }
58
58
 
59
- inline AnyValue JsFunction::get_property(const std::string &key, const AnyValue &thisVal)
59
+ inline AnyValue JsFunction::get_property(const std::string &key, AnyValue thisVal)
60
60
  {
61
61
  auto it = props.find(key);
62
62
  if (it == props.end())
@@ -79,7 +79,7 @@ namespace jspp
79
79
  return AnyValue::resolve_property_for_read(it->second, thisVal, key);
80
80
  }
81
81
 
82
- inline AnyValue JsFunction::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal)
82
+ inline AnyValue JsFunction::set_property(const std::string &key, AnyValue value, AnyValue thisVal)
83
83
  {
84
84
  auto proto_it = FunctionPrototypes::get(key);
85
85
  if (proto_it.has_value())
@@ -35,6 +35,43 @@ typename jspp::JsIterator<T>::NextResult jspp::JsIterator<T>::next(const T &val)
35
35
  return {handle.promise().current_value, is_done};
36
36
  }
37
37
 
38
+ template <typename T>
39
+ typename jspp::JsIterator<T>::NextResult jspp::JsIterator<T>::return_(const T &val)
40
+ {
41
+ if (!handle || handle.done())
42
+ return {val, true};
43
+
44
+ handle.promise().pending_return = true;
45
+ handle.promise().current_value = val;
46
+ handle.resume();
47
+
48
+ if (handle.promise().exception_)
49
+ {
50
+ std::rethrow_exception(handle.promise().exception_);
51
+ }
52
+
53
+ return {handle.promise().current_value, true};
54
+ }
55
+
56
+ template <typename T>
57
+ typename jspp::JsIterator<T>::NextResult jspp::JsIterator<T>::throw_(const AnyValue &err)
58
+ {
59
+ if (!handle || handle.done()) {
60
+ throw Exception(err);
61
+ }
62
+
63
+ handle.promise().pending_exception = std::make_exception_ptr(Exception(err));
64
+ handle.resume();
65
+
66
+ if (handle.promise().exception_)
67
+ {
68
+ std::rethrow_exception(handle.promise().exception_);
69
+ }
70
+
71
+ bool is_done = handle.done();
72
+ return {handle.promise().current_value, is_done};
73
+ }
74
+
38
75
  template <typename T>
39
76
  std::vector<T> jspp::JsIterator<T>::to_vector()
40
77
  {
@@ -52,7 +89,7 @@ std::vector<T> jspp::JsIterator<T>::to_vector()
52
89
  }
53
90
 
54
91
  template <typename T>
55
- jspp::AnyValue jspp::JsIterator<T>::get_property(const std::string &key, const AnyValue &thisVal)
92
+ jspp::AnyValue jspp::JsIterator<T>::get_property(const std::string &key, AnyValue thisVal)
56
93
  {
57
94
  auto it = props.find(key);
58
95
  if (it == props.end())
@@ -74,7 +111,7 @@ jspp::AnyValue jspp::JsIterator<T>::get_property(const std::string &key, const A
74
111
  }
75
112
 
76
113
  template <typename T>
77
- jspp::AnyValue jspp::JsIterator<T>::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal)
114
+ jspp::AnyValue jspp::JsIterator<T>::set_property(const std::string &key, AnyValue value, AnyValue thisVal)
78
115
  {
79
116
  // set prototype property if accessor descriptor
80
117
  if constexpr (std::is_same_v<T, AnyValue>)
@@ -12,7 +12,7 @@ namespace jspp
12
12
 
13
13
  inline JsPromise::JsPromise() : state(std::make_shared<PromiseState>()) {}
14
14
 
15
- inline void JsPromise::resolve(const AnyValue &value)
15
+ inline void JsPromise::resolve(AnyValue value)
16
16
  {
17
17
  if (state->status != PromiseStatus::Pending)
18
18
  return;
@@ -29,7 +29,7 @@ namespace jspp
29
29
  auto weak_state = std::weak_ptr<PromiseState>(state);
30
30
 
31
31
  p->then(
32
- [weak_state](const AnyValue &v)
32
+ [weak_state](AnyValue v)
33
33
  {
34
34
  if (auto s = weak_state.lock())
35
35
  {
@@ -49,7 +49,7 @@ namespace jspp
49
49
  { cb(v); });
50
50
  }
51
51
  },
52
- [weak_state](const AnyValue &r)
52
+ [weak_state](AnyValue r)
53
53
  {
54
54
  if (auto s = weak_state.lock())
55
55
  {
@@ -81,7 +81,7 @@ namespace jspp
81
81
  }
82
82
  }
83
83
 
84
- inline void JsPromise::reject(const AnyValue &reason)
84
+ inline void JsPromise::reject(AnyValue reason)
85
85
  {
86
86
  if (state->status != PromiseStatus::Pending)
87
87
  return;
@@ -99,7 +99,7 @@ namespace jspp
99
99
  }
100
100
  }
101
101
 
102
- inline void JsPromise::then(std::function<void(const AnyValue &)> onFulfilled, std::function<void(const AnyValue &)> onRejected)
102
+ inline void JsPromise::then(std::function<void(AnyValue)> onFulfilled, std::function<void(AnyValue)> onRejected)
103
103
  {
104
104
  if (state->status == PromiseStatus::Fulfilled)
105
105
  {
@@ -140,7 +140,7 @@ namespace jspp
140
140
  return "[object Promise]";
141
141
  }
142
142
 
143
- inline AnyValue JsPromise::get_property(const std::string &key, const AnyValue &thisVal)
143
+ inline AnyValue JsPromise::get_property(const std::string &key, AnyValue thisVal)
144
144
  {
145
145
  // Prototype lookup
146
146
  auto proto_it = PromisePrototypes::get(key);
@@ -157,7 +157,7 @@ namespace jspp
157
157
  return Constants::UNDEFINED;
158
158
  }
159
159
 
160
- inline AnyValue JsPromise::set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal)
160
+ inline AnyValue JsPromise::set_property(const std::string &key, AnyValue value, AnyValue thisVal)
161
161
  {
162
162
  auto it = props.find(key);
163
163
  if (it != props.end())
@@ -173,7 +173,7 @@ namespace jspp
173
173
 
174
174
  // --- Coroutine Methods ---
175
175
 
176
- inline void JsPromisePromiseType::return_value(const AnyValue &val)
176
+ inline void JsPromisePromiseType::return_value(AnyValue val)
177
177
  {
178
178
  promise.resolve(val);
179
179
  }
@@ -198,7 +198,7 @@ namespace jspp
198
198
  }
199
199
  }
200
200
 
201
- inline auto JsPromisePromiseType::await_transform(const AnyValue &value)
201
+ inline auto JsPromisePromiseType::await_transform(AnyValue value)
202
202
  {
203
203
  return AnyValueAwaiter{value};
204
204
  }
@@ -14,10 +14,24 @@ inline std::string jspp::JsString::to_std_string() const
14
14
 
15
15
  inline jspp::JsIterator<jspp::AnyValue> jspp::JsString::get_iterator()
16
16
  {
17
- size_t strLength = value.length();
18
- for (size_t idx = 0; idx < strLength; idx++)
17
+ for (size_t i = 0; i < value.length();)
19
18
  {
20
- co_yield AnyValue::make_string(std::string(1, value[idx]));
19
+ unsigned char c = static_cast<unsigned char>(value[i]);
20
+ size_t len = 1;
21
+ if ((c & 0x80) == 0)
22
+ len = 1;
23
+ else if ((c & 0xE0) == 0xC0)
24
+ len = 2;
25
+ else if ((c & 0xF0) == 0xE0)
26
+ len = 3;
27
+ else if ((c & 0xF8) == 0xF0)
28
+ len = 4;
29
+
30
+ if (i + len > value.length())
31
+ len = value.length() - i;
32
+
33
+ co_yield AnyValue::make_string(value.substr(i, len));
34
+ i += len;
21
35
  }
22
36
  co_return AnyValue::make_undefined();
23
37
  }
@@ -12,6 +12,9 @@ namespace jspp
12
12
  // Forward declaration of AnyValue
13
13
  class AnyValue;
14
14
 
15
+ // Special exception to signal a return from a generator
16
+ struct GeneratorReturnException {};
17
+
15
18
  template <typename T>
16
19
  class JsIterator : public HeapObject
17
20
  {
@@ -30,6 +33,9 @@ namespace jspp
30
33
  std::exception_ptr exception_;
31
34
  T input_value;
32
35
 
36
+ std::exception_ptr pending_exception = nullptr;
37
+ bool pending_return = false;
38
+
33
39
  JsIterator get_return_object()
34
40
  {
35
41
  return JsIterator{
@@ -52,7 +58,18 @@ namespace jspp
52
58
  promise_type &p;
53
59
  bool await_ready() { return false; }
54
60
  void await_suspend(std::coroutine_handle<promise_type>) {}
55
- T await_resume() { return p.input_value; }
61
+ T await_resume() {
62
+ if (p.pending_exception) {
63
+ auto ex = p.pending_exception;
64
+ p.pending_exception = nullptr;
65
+ std::rethrow_exception(ex);
66
+ }
67
+ if (p.pending_return) {
68
+ p.pending_return = false;
69
+ throw GeneratorReturnException{};
70
+ }
71
+ return p.input_value;
72
+ }
56
73
  };
57
74
  return Awaiter{*this};
58
75
  }
@@ -68,7 +85,13 @@ namespace jspp
68
85
 
69
86
  void unhandled_exception()
70
87
  {
71
- exception_ = std::current_exception();
88
+ try {
89
+ throw;
90
+ } catch (const GeneratorReturnException&) {
91
+ // Handled return
92
+ } catch (...) {
93
+ exception_ = std::current_exception();
94
+ }
72
95
  }
73
96
  };
74
97
 
@@ -76,7 +99,9 @@ namespace jspp
76
99
  handle_type handle;
77
100
 
78
101
  explicit JsIterator(handle_type h) : handle(h) {}
79
- JsIterator(JsIterator &&other) noexcept : handle(std::exchange(other.handle, nullptr)) {}
102
+ JsIterator(JsIterator &&other) noexcept
103
+ : handle(std::exchange(other.handle, nullptr)),
104
+ props(std::move(other.props)) {}
80
105
 
81
106
  // Delete copy constructor/assignment to ensure unique ownership of the handle
82
107
  JsIterator(const JsIterator &) = delete;
@@ -92,8 +117,10 @@ namespace jspp
92
117
 
93
118
  std::string to_std_string() const;
94
119
  NextResult next(const T &val = T());
120
+ NextResult return_(const T &val = T());
121
+ NextResult throw_(const AnyValue &err);
95
122
  std::vector<T> to_vector();
96
- AnyValue get_property(const std::string &key, const AnyValue &thisVal);
97
- AnyValue set_property(const std::string &key, const AnyValue &value, const AnyValue &thisVal);
123
+ AnyValue get_property(const std::string &key, AnyValue thisVal);
124
+ AnyValue set_property(const std::string &key, AnyValue value, AnyValue thisVal);
98
125
  };
99
126
  }
@@ -41,14 +41,14 @@ namespace jspp
41
41
  JsType get_heap_type() const override { return JsType::Promise; }
42
42
 
43
43
  // --- Promise Logic ---
44
- void resolve(const AnyValue& value);
45
- void reject(const AnyValue& reason);
46
- void then(std::function<void(const AnyValue&)> onFulfilled, std::function<void(const AnyValue&)> onRejected = nullptr);
44
+ void resolve(AnyValue value);
45
+ void reject(AnyValue reason);
46
+ void then(std::function<void(AnyValue)> onFulfilled, std::function<void(AnyValue)> onRejected = nullptr);
47
47
 
48
48
  // --- Methods ---
49
49
  std::string to_std_string() const;
50
- AnyValue get_property(const std::string& key, const AnyValue& thisVal);
51
- AnyValue set_property(const std::string& key, const AnyValue& value, const AnyValue& thisVal);
50
+ AnyValue get_property(const std::string& key, AnyValue thisVal);
51
+ AnyValue set_property(const std::string& key, AnyValue value, AnyValue thisVal);
52
52
 
53
53
  auto operator co_await() const;
54
54
  };
@@ -60,12 +60,12 @@ namespace jspp
60
60
  std::suspend_never initial_suspend() { return {}; }
61
61
  std::suspend_never final_suspend() noexcept { return {}; }
62
62
 
63
- void return_value(const AnyValue& val);
63
+ void return_value(AnyValue val);
64
64
 
65
65
  void unhandled_exception();
66
66
 
67
67
  // await_transform for AnyValue
68
- auto await_transform(const AnyValue& value);
68
+ auto await_transform(AnyValue value);
69
69
  // await_transform for JsPromise
70
70
  auto await_transform(const JsPromise& value);
71
71
  };