@nocobase/plugin-workflow-javascript 2.1.0-beta.10 → 2.1.0-beta.12

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 (107) hide show
  1. package/dist/externalVersion.js +4 -4
  2. package/dist/node_modules/isolated-vm/.clang-tidy +13 -0
  3. package/dist/node_modules/isolated-vm/.dockerignore +9 -0
  4. package/dist/node_modules/isolated-vm/Dockerfile.alpine +9 -0
  5. package/dist/node_modules/isolated-vm/Dockerfile.debian +12 -0
  6. package/dist/node_modules/isolated-vm/LICENSE +13 -0
  7. package/dist/node_modules/isolated-vm/binding.gyp +120 -0
  8. package/dist/node_modules/isolated-vm/include.js +3 -0
  9. package/dist/node_modules/isolated-vm/inspector-example.js +59 -0
  10. package/dist/node_modules/isolated-vm/isolated-vm.d.ts +820 -0
  11. package/dist/node_modules/isolated-vm/isolated-vm.js +1 -0
  12. package/dist/node_modules/isolated-vm/native-example/binding.gyp +23 -0
  13. package/dist/node_modules/isolated-vm/native-example/example.cc +61 -0
  14. package/dist/node_modules/isolated-vm/native-example/package.json +13 -0
  15. package/dist/node_modules/isolated-vm/native-example/usage.js +35 -0
  16. package/dist/node_modules/isolated-vm/out/isolated_vm.node +0 -0
  17. package/dist/node_modules/isolated-vm/package.json +1 -0
  18. package/dist/node_modules/isolated-vm/src/external_copy/error.h +33 -0
  19. package/dist/node_modules/isolated-vm/src/external_copy/external_copy.cc +509 -0
  20. package/dist/node_modules/isolated-vm/src/external_copy/external_copy.h +117 -0
  21. package/dist/node_modules/isolated-vm/src/external_copy/serializer.cc +85 -0
  22. package/dist/node_modules/isolated-vm/src/external_copy/serializer.h +136 -0
  23. package/dist/node_modules/isolated-vm/src/external_copy/serializer_nortti.cc +73 -0
  24. package/dist/node_modules/isolated-vm/src/external_copy/string.cc +124 -0
  25. package/dist/node_modules/isolated-vm/src/external_copy/string.h +28 -0
  26. package/dist/node_modules/isolated-vm/src/isolate/allocator.h +32 -0
  27. package/dist/node_modules/isolated-vm/src/isolate/allocator_nortti.cc +142 -0
  28. package/dist/node_modules/isolated-vm/src/isolate/class_handle.h +334 -0
  29. package/dist/node_modules/isolated-vm/src/isolate/cpu_profile_manager.cc +220 -0
  30. package/dist/node_modules/isolated-vm/src/isolate/cpu_profile_manager.h +100 -0
  31. package/dist/node_modules/isolated-vm/src/isolate/environment.cc +626 -0
  32. package/dist/node_modules/isolated-vm/src/isolate/environment.h +381 -0
  33. package/dist/node_modules/isolated-vm/src/isolate/executor.cc +198 -0
  34. package/dist/node_modules/isolated-vm/src/isolate/executor.h +183 -0
  35. package/dist/node_modules/isolated-vm/src/isolate/external.h +64 -0
  36. package/dist/node_modules/isolated-vm/src/isolate/functor_runners.h +97 -0
  37. package/dist/node_modules/isolated-vm/src/isolate/generic/array.h +145 -0
  38. package/dist/node_modules/isolated-vm/src/isolate/generic/callbacks.h +272 -0
  39. package/dist/node_modules/isolated-vm/src/isolate/generic/error.h +140 -0
  40. package/dist/node_modules/isolated-vm/src/isolate/generic/extract_params.h +145 -0
  41. package/dist/node_modules/isolated-vm/src/isolate/generic/handle_cast.h +257 -0
  42. package/dist/node_modules/isolated-vm/src/isolate/generic/read_option.h +47 -0
  43. package/dist/node_modules/isolated-vm/src/isolate/holder.cc +88 -0
  44. package/dist/node_modules/isolated-vm/src/isolate/holder.h +63 -0
  45. package/dist/node_modules/isolated-vm/src/isolate/inspector.cc +200 -0
  46. package/dist/node_modules/isolated-vm/src/isolate/inspector.h +70 -0
  47. package/dist/node_modules/isolated-vm/src/isolate/node_wrapper.h +15 -0
  48. package/dist/node_modules/isolated-vm/src/isolate/platform_delegate.cc +22 -0
  49. package/dist/node_modules/isolated-vm/src/isolate/platform_delegate.h +46 -0
  50. package/dist/node_modules/isolated-vm/src/isolate/remote_handle.h +164 -0
  51. package/dist/node_modules/isolated-vm/src/isolate/run_with_timeout.h +171 -0
  52. package/dist/node_modules/isolated-vm/src/isolate/runnable.h +29 -0
  53. package/dist/node_modules/isolated-vm/src/isolate/scheduler.cc +191 -0
  54. package/dist/node_modules/isolated-vm/src/isolate/scheduler.h +165 -0
  55. package/dist/node_modules/isolated-vm/src/isolate/specific.h +35 -0
  56. package/dist/node_modules/isolated-vm/src/isolate/stack_trace.cc +219 -0
  57. package/dist/node_modules/isolated-vm/src/isolate/stack_trace.h +24 -0
  58. package/dist/node_modules/isolated-vm/src/isolate/strings.h +127 -0
  59. package/dist/node_modules/isolated-vm/src/isolate/three_phase_task.cc +385 -0
  60. package/dist/node_modules/isolated-vm/src/isolate/three_phase_task.h +136 -0
  61. package/dist/node_modules/isolated-vm/src/isolate/transferable.h +15 -0
  62. package/dist/node_modules/isolated-vm/src/isolate/util.h +45 -0
  63. package/dist/node_modules/isolated-vm/src/isolate/v8_inspector_wrapper.h +12 -0
  64. package/dist/node_modules/isolated-vm/src/isolate/v8_version.h +12 -0
  65. package/dist/node_modules/isolated-vm/src/isolated_vm.h +71 -0
  66. package/dist/node_modules/isolated-vm/src/lib/covariant.h +50 -0
  67. package/dist/node_modules/isolated-vm/src/lib/lockable.h +178 -0
  68. package/dist/node_modules/isolated-vm/src/lib/suspend.h +106 -0
  69. package/dist/node_modules/isolated-vm/src/lib/thread_pool.cc +98 -0
  70. package/dist/node_modules/isolated-vm/src/lib/thread_pool.h +45 -0
  71. package/dist/node_modules/isolated-vm/src/lib/timer.cc +233 -0
  72. package/dist/node_modules/isolated-vm/src/lib/timer.h +36 -0
  73. package/dist/node_modules/isolated-vm/src/module/callback.cc +151 -0
  74. package/dist/node_modules/isolated-vm/src/module/callback.h +64 -0
  75. package/dist/node_modules/isolated-vm/src/module/context_handle.cc +241 -0
  76. package/dist/node_modules/isolated-vm/src/module/context_handle.h +35 -0
  77. package/dist/node_modules/isolated-vm/src/module/evaluation.cc +109 -0
  78. package/dist/node_modules/isolated-vm/src/module/evaluation.h +99 -0
  79. package/dist/node_modules/isolated-vm/src/module/external_copy_handle.cc +119 -0
  80. package/dist/node_modules/isolated-vm/src/module/external_copy_handle.h +64 -0
  81. package/dist/node_modules/isolated-vm/src/module/isolate.cc +136 -0
  82. package/dist/node_modules/isolated-vm/src/module/isolate_handle.cc +611 -0
  83. package/dist/node_modules/isolated-vm/src/module/isolate_handle.h +47 -0
  84. package/dist/node_modules/isolated-vm/src/module/lib_handle.cc +77 -0
  85. package/dist/node_modules/isolated-vm/src/module/lib_handle.h +28 -0
  86. package/dist/node_modules/isolated-vm/src/module/module_handle.cc +475 -0
  87. package/dist/node_modules/isolated-vm/src/module/module_handle.h +68 -0
  88. package/dist/node_modules/isolated-vm/src/module/native_module_handle.cc +104 -0
  89. package/dist/node_modules/isolated-vm/src/module/native_module_handle.h +49 -0
  90. package/dist/node_modules/isolated-vm/src/module/reference_handle.cc +636 -0
  91. package/dist/node_modules/isolated-vm/src/module/reference_handle.h +106 -0
  92. package/dist/node_modules/isolated-vm/src/module/script_handle.cc +107 -0
  93. package/dist/node_modules/isolated-vm/src/module/script_handle.h +37 -0
  94. package/dist/node_modules/isolated-vm/src/module/session_handle.cc +173 -0
  95. package/dist/node_modules/isolated-vm/src/module/session_handle.h +31 -0
  96. package/dist/node_modules/isolated-vm/src/module/transferable.cc +268 -0
  97. package/dist/node_modules/isolated-vm/src/module/transferable.h +42 -0
  98. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v18.0.0.h +360 -0
  99. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v18.3.0.h +376 -0
  100. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v20.0.0.h +397 -0
  101. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v22.0.0.h +419 -0
  102. package/dist/node_modules/winston-transport/package.json +1 -1
  103. package/dist/server/IsolatedVm.js +75 -0
  104. package/dist/server/ScriptInstruction.d.ts +6 -0
  105. package/dist/server/ScriptInstruction.js +11 -1
  106. package/dist/server/Vm.js +42 -27
  107. package/package.json +3 -2
@@ -0,0 +1,183 @@
1
+ #pragma once
2
+ #include <v8.h>
3
+ #include <chrono>
4
+ #include <mutex>
5
+ #include <thread>
6
+ #include "holder.h"
7
+ #include "v8-profiler.h"
8
+
9
+ namespace ivm {
10
+ class InspectorAgent;
11
+ class IsolateEnvironment;
12
+ class Scheduler;
13
+
14
+ /**
15
+ * Executor class handles v8 locking while C++ code is running. Thread syncronization is handled
16
+ * by v8::Locker. This also enters the isolate and sets up a handle scope.
17
+ */
18
+ class Executor { // "En taro adun"
19
+ friend InspectorAgent;
20
+ friend IsolateEnvironment;
21
+ public:
22
+ explicit Executor(IsolateEnvironment& env);
23
+ Executor(const Executor&) = delete;
24
+ ~Executor();
25
+ auto operator= (const Executor&) = delete;
26
+
27
+ static auto GetCurrentEnvironment() -> IsolateEnvironment*;
28
+ static auto GetDefaultEnvironment() -> IsolateEnvironment&;
29
+ static auto IsDefaultThread() -> bool;
30
+ static auto MayRunInlineTasks(IsolateEnvironment& env) -> bool;
31
+
32
+ private:
33
+ class CpuTimer {
34
+ public:
35
+ explicit CpuTimer(Executor& executor);
36
+ CpuTimer(const CpuTimer&) = delete;
37
+ ~CpuTimer();
38
+ auto operator= (const CpuTimer&) = delete;
39
+
40
+ using TimePoint = std::chrono::time_point<std::chrono::steady_clock, std::chrono::nanoseconds>;
41
+ auto Delta(const std::lock_guard<std::mutex>& /*lock*/) const -> std::chrono::nanoseconds;
42
+ void Pause();
43
+ void Resume();
44
+ static auto Now() -> TimePoint;
45
+
46
+ private:
47
+ Executor& executor;
48
+ CpuTimer* last;
49
+ TimePoint time;
50
+ #if USE_CLOCK_THREAD_CPUTIME_ID
51
+ std::chrono::time_point<std::chrono::steady_clock> steady_time;
52
+ #endif
53
+ };
54
+
55
+ // WallTimer is also responsible for pausing the current CpuTimer before we attempt to
56
+ // acquire the v8::Locker, because that could block in which case CPU shouldn't be counted.
57
+ class WallTimer {
58
+ public:
59
+ explicit WallTimer(Executor& executor);
60
+ WallTimer(const WallTimer&) = delete;
61
+ ~WallTimer();
62
+ auto operator= (const WallTimer&) = delete;
63
+
64
+ auto Delta(const std::lock_guard<std::mutex>& /*lock*/) const -> std::chrono::nanoseconds;
65
+
66
+ private:
67
+ Executor& executor;
68
+ CpuTimer* cpu_timer;
69
+ std::chrono::time_point<std::chrono::steady_clock> time;
70
+ };
71
+
72
+ public:
73
+ // Pauses CpuTimer
74
+ class UnpauseScope;
75
+ class PauseScope {
76
+ friend UnpauseScope;
77
+ public:
78
+ explicit PauseScope(CpuTimer* timer) : timer{timer} { timer->Pause(); }
79
+ PauseScope(const PauseScope&) = delete;
80
+ ~PauseScope() { timer->Resume(); }
81
+ auto operator=(const PauseScope&) = delete;
82
+
83
+ private:
84
+ CpuTimer* timer;
85
+ };
86
+
87
+ // Unpauses CpuTimer
88
+ class UnpauseScope {
89
+ public:
90
+ explicit UnpauseScope(PauseScope& pause) : timer{pause.timer} { timer->Resume(); }
91
+ UnpauseScope(const UnpauseScope&) = delete;
92
+ ~UnpauseScope() { timer->Pause(); }
93
+ auto operator=(const UnpauseScope&) = delete;
94
+
95
+ CpuTimer* timer;
96
+ };
97
+
98
+ // A scope sets the current environment without locking v8
99
+ class Scope {
100
+ public:
101
+ explicit Scope(IsolateEnvironment& env);
102
+ Scope(const Scope&) = delete;
103
+ ~Scope();
104
+ auto operator= (const Scope&) = delete;
105
+
106
+ private:
107
+ Executor* last;
108
+ };
109
+
110
+ class Profiler {
111
+ public:
112
+ explicit Profiler(IsolateEnvironment& env);
113
+ Profiler(const Profiler&) = delete;
114
+ ~Profiler();
115
+ auto operator= (const Profiler&) = delete;
116
+ private:
117
+ IsolateEnvironment* environment;
118
+ Executor* executor;
119
+ v8::CpuProfiler* profiler;
120
+ v8::Isolate* isolate;
121
+ };
122
+
123
+ // Locks this environment for execution. Implies `Scope` as well.
124
+ class Lock {
125
+ public:
126
+ explicit Lock(IsolateEnvironment& env);
127
+ Lock(const Lock&) = delete;
128
+ ~Lock() = default;
129
+ auto operator= (const Lock&) = delete;
130
+
131
+ private:
132
+ // These need to be separate from `Executor::current_executor` because the default isolate
133
+ // doesn't actually get a lock.
134
+ Scope scope;
135
+ WallTimer wall_timer;
136
+ v8::Locker locker;
137
+ CpuTimer cpu_timer;
138
+ v8::Isolate::Scope isolate_scope;
139
+ v8::HandleScope handle_scope;
140
+ Profiler profiler;
141
+ };
142
+
143
+ class Unlock {
144
+ public:
145
+ explicit Unlock(IsolateEnvironment& env);
146
+ Unlock(const Unlock&) = delete;
147
+ ~Unlock() = default;
148
+ auto operator= (const Unlock&) = delete;
149
+
150
+ private:
151
+ PauseScope pause_scope;
152
+ v8::Unlocker unlocker;
153
+ };
154
+
155
+ private:
156
+ IsolateEnvironment& env;
157
+ Executor& default_executor;
158
+ std::thread::id default_thread;
159
+ Lock* current_lock = nullptr;
160
+ CpuTimer* cpu_timer = nullptr;
161
+ WallTimer* wall_timer = nullptr;
162
+ int depth = 0;
163
+ std::mutex timer_mutex;
164
+ std::chrono::nanoseconds cpu_time{};
165
+ std::chrono::nanoseconds wall_time{};
166
+
167
+ static thread_local CpuTimer* cpu_timer_thread;
168
+ static thread_local Executor* current_executor;
169
+ };
170
+
171
+ inline auto Executor::GetCurrentEnvironment() -> IsolateEnvironment* {
172
+ return current_executor == nullptr ? nullptr : &current_executor->env;
173
+ }
174
+
175
+ inline auto Executor::GetDefaultEnvironment() -> IsolateEnvironment& {
176
+ return current_executor->default_executor.env;
177
+ }
178
+
179
+ inline auto Executor::IsDefaultThread() -> bool {
180
+ return std::this_thread::get_id() == current_executor->default_thread;
181
+ };
182
+
183
+ } // namespace ivm
@@ -0,0 +1,64 @@
1
+ #pragma once
2
+ #include "environment.h"
3
+ #include "util.h"
4
+ #include <v8.h>
5
+ #include <memory>
6
+ #include <utility>
7
+
8
+ namespace ivm {
9
+ namespace detail {
10
+
11
+ template <class Type>
12
+ class ExternalHolder {
13
+ public:
14
+ ExternalHolder(const ExternalHolder&) = delete;
15
+ ~ExternalHolder() = default;
16
+ auto operator=(const ExternalHolder&) = delete;
17
+
18
+ template <class ...Args>
19
+ static auto New(Args&&... args) {
20
+ // Allocate heap memory for ExternalHolder (don't construct)
21
+ ExternalHolder* that = std::allocator<ExternalHolder>{}.allocate(1);
22
+ // Create a new v8::External referencing the unconstructed holder
23
+ auto external = v8::External::New(v8::Isolate::GetCurrent(), &that->data);
24
+ // Construct the holder in-place
25
+ new(that) ExternalHolder(external, std::forward<Args>(args)...);
26
+ // Setup weak callbacks (technically could throw)
27
+ that->handle.SetWeak(reinterpret_cast<void*>(that), WeakCallbackV8, v8::WeakCallbackType::kParameter);
28
+ IsolateEnvironment::GetCurrent().AddWeakCallback(&that->handle, WeakCallback, that);
29
+ // Return local external handle
30
+ return external;
31
+ }
32
+
33
+ private:
34
+ template <class ...Args>
35
+ explicit ExternalHolder(v8::Local<v8::External> handle, Args&&... args) :
36
+ handle{v8::Isolate::GetCurrent(), handle}, data{std::forward<Args>(args)...} {}
37
+
38
+ static void WeakCallback(void* param) {
39
+ auto* that = static_cast<ExternalHolder*>(param);
40
+ auto& isolate = IsolateEnvironment::GetCurrent();
41
+ isolate.RemoveWeakCallback(&that->handle);
42
+ that->handle.Reset();
43
+ delete that;
44
+ }
45
+
46
+ static void WeakCallbackV8(const v8::WeakCallbackInfo<void>& info) {
47
+ WeakCallback(info.GetParameter());
48
+ }
49
+
50
+ v8::Persistent<v8::Value> handle;
51
+ Type data;
52
+ };
53
+
54
+ } // namespace detail
55
+
56
+ /**
57
+ * Returns a v8::External with attached handle deletion
58
+ */
59
+ template <class Type, class ...Args>
60
+ auto MakeExternal(Args&&... args) {
61
+ return detail::ExternalHolder<Type>::New(std::forward<Args>(args)...);
62
+ }
63
+
64
+ }
@@ -0,0 +1,97 @@
1
+ #pragma once
2
+ #include "util.h"
3
+ #include "external_copy/error.h"
4
+ #include "generic/error.h"
5
+
6
+ namespace ivm {
7
+
8
+ /**
9
+ * Helpers to run a function and catch the various exceptions defined above
10
+ */
11
+ namespace FunctorRunners {
12
+
13
+ template <typename F, typename T>
14
+ inline void RunCallback(T& info, F fn) {
15
+ // This function is used when C++ code is invoked from a JS callback. We are given an instance of
16
+ // `FunctionCallbackInfo`, or `PropertyCallbackInfo` which is used to give the return value to v8.
17
+ // C++ exceptions will be caught, converted to JS exceptions, and then thrown back to JS.
18
+ try {
19
+ v8::Local<v8::Value> result = fn();
20
+ if (result.IsEmpty()) {
21
+ throw std::logic_error("Callback returned empty Local<> but did not set exception");
22
+ }
23
+ info.GetReturnValue().Set(result);
24
+ } catch (const detail::RuntimeErrorConstructible& cc_error) {
25
+ v8::Local<v8::Value> error = cc_error.ConstructError();
26
+ if (!error.IsEmpty()) {
27
+ v8::Isolate::GetCurrent()->ThrowException(error);
28
+ }
29
+ } catch (const RuntimeError& err) {
30
+ }
31
+ }
32
+
33
+ template <typename F1, typename F2>
34
+ inline void RunCatchExternal(v8::Local<v8::Context> default_context, F1 fn1, F2 fn2) {
35
+ // This function will call `fn1()` and if that fails it will convert the caught error to an
36
+ // `ExternalCopy` and call `fn2(err)`
37
+ auto* isolate = v8::Isolate::GetCurrent();
38
+ v8::TryCatch try_catch{isolate};
39
+ try {
40
+ try {
41
+ fn1();
42
+ } catch (const RuntimeTypeError& cc_error) {
43
+ // The following errors are just various C++ strings with an error type
44
+ fn2(std::make_unique<ExternalCopyError>(ExternalCopyError::ErrorType::TypeError, cc_error.GetMessage().c_str(), cc_error.GetStackTrace()));
45
+ } catch (const RuntimeRangeError& cc_error) {
46
+ fn2(std::make_unique<ExternalCopyError>(ExternalCopyError::ErrorType::RangeError, cc_error.GetMessage().c_str(), cc_error.GetStackTrace()));
47
+ } catch (const RuntimeGenericError& cc_error) {
48
+ fn2(std::make_unique<ExternalCopyError>(ExternalCopyError::ErrorType::Error, cc_error.GetMessage().c_str(), cc_error.GetStackTrace()));
49
+ } catch (const detail::RuntimeErrorWithMessage& cc_error) {
50
+ fn2(std::make_unique<ExternalCopyError>(ExternalCopyError::ErrorType::Error, cc_error.GetMessage().c_str()));
51
+ } catch (const RuntimeError& cc_error) {
52
+ // If this is caught it means the error needs to be copied out of v8
53
+ assert(try_catch.HasCaught());
54
+ v8::Context::Scope context_scope{default_context};
55
+ fn2(ExternalCopy::CopyThrownValue(try_catch.Exception()));
56
+ }
57
+ } catch (...) {
58
+ if (try_catch.HasCaught()) {
59
+ try_catch.ReThrow();
60
+ }
61
+ throw;
62
+ }
63
+ }
64
+
65
+ template <typename F1, typename F2>
66
+ inline void RunCatchValue(F1 fn1, F2 fn2) {
67
+ // This function will call `fn1()` and if that fails it will convert the caught error to a v8
68
+ // value and pass it to fn3().
69
+ //
70
+ // *Fatal errors are swallowed*
71
+ //
72
+ v8::TryCatch try_catch(v8::Isolate::GetCurrent());
73
+ try {
74
+ try {
75
+ fn1();
76
+ } catch (const FatalRuntimeError& cc_error) {
77
+ return;
78
+ } catch (const detail::RuntimeErrorConstructible& cc_error) {
79
+ // A C++ error thrown and needs to be internalized into v8
80
+ fn2(cc_error.ConstructError());
81
+ } catch (const RuntimeError& cc_error) {
82
+ // A JS error is waiting in the isolate
83
+ assert(try_catch.HasCaught());
84
+ v8::Local<v8::Value> error = try_catch.Exception();
85
+ try_catch.Reset();
86
+ fn2(error);
87
+ }
88
+ } catch (...) {
89
+ if (try_catch.HasCaught()) {
90
+ try_catch.ReThrow();
91
+ }
92
+ throw;
93
+ }
94
+ }
95
+
96
+ }; // namespace FunctorRunners
97
+ }; // namespace ivm
@@ -0,0 +1,145 @@
1
+ #pragma once
2
+ #include "error.h"
3
+ #include "handle_cast.h"
4
+ #include <v8.h>
5
+ #include <cstdint>
6
+
7
+ namespace ivm {
8
+
9
+ class ArrayRange {
10
+ public:
11
+ ArrayRange() = default;
12
+ ArrayRange(const ArrayRange&) = default;
13
+ ArrayRange(v8::Local<v8::Array> array, v8::Local<v8::Context> context) :
14
+ array{array}, context{context}, length{array->Length()} {}
15
+ ~ArrayRange() = default;
16
+ auto operator=(const ArrayRange&) -> ArrayRange& = default;
17
+
18
+ auto begin() const {
19
+ return iterator{array, context, 0};
20
+ }
21
+
22
+ auto end() const {
23
+ return iterator{array, context, length};
24
+ }
25
+
26
+ class iterator {
27
+ public:
28
+ using iterator_category = std::random_access_iterator_tag;
29
+ using difference_type = int32_t;
30
+ using pointer = void;
31
+ using value_type = v8::Local<v8::Value>;
32
+ using reference = value_type;
33
+
34
+ iterator() = default;
35
+ iterator(const iterator&) = default;
36
+ iterator(v8::Local<v8::Array> array, v8::Local<v8::Context> context, uint32_t index) :
37
+ array{array}, context{context}, index{index} {}
38
+ ~iterator() = default;
39
+ auto operator=(const iterator&) -> iterator& = default;
40
+
41
+ auto operator*() const {
42
+ return Unmaybe(array->Get(context, index));
43
+ }
44
+
45
+ auto operator==(const iterator& rhs) const {
46
+ return index == rhs.index;
47
+ }
48
+
49
+ auto operator<(const iterator& rhs) const {
50
+ return index < rhs.index;
51
+ }
52
+
53
+ auto operator-(const iterator& rhs) const -> difference_type {
54
+ return index - rhs.index;
55
+ }
56
+
57
+ auto operator+=(int val) -> iterator& {
58
+ index += val;
59
+ return *this;
60
+ }
61
+
62
+ // The following methods are boiler plate which invoke the above methods
63
+ decltype(auto) operator[](int index) const {
64
+ return *(*this + index);
65
+ }
66
+
67
+ auto operator!=(const iterator& rhs) const {
68
+ return !(*this == rhs);
69
+ }
70
+
71
+ auto operator>(const iterator& rhs) const {
72
+ return rhs < *this;
73
+ }
74
+
75
+ auto operator<=(const iterator& rhs) const {
76
+ return !(*this > rhs);
77
+ }
78
+
79
+ auto operator>=(const iterator& rhs) const {
80
+ return !(*this < rhs);
81
+ }
82
+
83
+ auto operator+(difference_type val) const -> iterator {
84
+ iterator copy{*this};
85
+ copy += val;
86
+ return copy;
87
+ }
88
+
89
+ auto operator-(difference_type val) const -> iterator {
90
+ return *this + -val;
91
+ }
92
+
93
+ auto operator++() -> iterator& {
94
+ return *this += 1;
95
+ }
96
+
97
+ auto operator-=(difference_type val) -> iterator& {
98
+ return *this += -val;
99
+ }
100
+
101
+ auto operator--() -> iterator& {
102
+ return *this -= 1;
103
+ }
104
+
105
+ auto operator++(int) -> iterator {
106
+ iterator copy{*this};
107
+ *this += 1;
108
+ return copy;
109
+ }
110
+
111
+ auto operator--(int) -> iterator {
112
+ iterator copy{*this};
113
+ *this -= 1;
114
+ return copy;
115
+ }
116
+
117
+ private:
118
+ v8::Local<v8::Array> array;
119
+ v8::Local<v8::Context> context;
120
+ uint32_t index = 0;
121
+ };
122
+
123
+ private:
124
+ v8::Local<v8::Array> array;
125
+ v8::Local<v8::Context> context;
126
+ uint32_t length = 0;
127
+ };
128
+
129
+ inline auto HandleCastImpl(v8::Local<v8::Value> value, const HandleCastArguments& arguments, HandleCastTag<ArrayRange> /*tag*/) {
130
+ if (value->IsArray()) {
131
+ return ArrayRange{value.As<v8::Array>(), arguments.context};
132
+ }
133
+ ParamIncorrect::Throw("an array");
134
+ }
135
+
136
+ inline auto HandleCastImpl(v8::Local<v8::Value> value, const HandleCastArguments& arguments, HandleCastTag<v8::Maybe<ArrayRange>> /*tag*/) -> v8::Maybe<ArrayRange> {
137
+ if (value->IsNullOrUndefined()) {
138
+ return v8::Nothing<ArrayRange>();
139
+ } else if (value->IsArray()) {
140
+ return v8::Just<ArrayRange>(ArrayRange{value.As<v8::Array>(), arguments.context});
141
+ }
142
+ ParamIncorrect::Throw("an array");
143
+ }
144
+
145
+ } // namespace ivm