@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.
- package/dist/externalVersion.js +4 -4
- package/dist/node_modules/isolated-vm/.clang-tidy +13 -0
- package/dist/node_modules/isolated-vm/.dockerignore +9 -0
- package/dist/node_modules/isolated-vm/Dockerfile.alpine +9 -0
- package/dist/node_modules/isolated-vm/Dockerfile.debian +12 -0
- package/dist/node_modules/isolated-vm/LICENSE +13 -0
- package/dist/node_modules/isolated-vm/binding.gyp +120 -0
- package/dist/node_modules/isolated-vm/include.js +3 -0
- package/dist/node_modules/isolated-vm/inspector-example.js +59 -0
- package/dist/node_modules/isolated-vm/isolated-vm.d.ts +820 -0
- package/dist/node_modules/isolated-vm/isolated-vm.js +1 -0
- package/dist/node_modules/isolated-vm/native-example/binding.gyp +23 -0
- package/dist/node_modules/isolated-vm/native-example/example.cc +61 -0
- package/dist/node_modules/isolated-vm/native-example/package.json +13 -0
- package/dist/node_modules/isolated-vm/native-example/usage.js +35 -0
- package/dist/node_modules/isolated-vm/out/isolated_vm.node +0 -0
- package/dist/node_modules/isolated-vm/package.json +1 -0
- package/dist/node_modules/isolated-vm/src/external_copy/error.h +33 -0
- package/dist/node_modules/isolated-vm/src/external_copy/external_copy.cc +509 -0
- package/dist/node_modules/isolated-vm/src/external_copy/external_copy.h +117 -0
- package/dist/node_modules/isolated-vm/src/external_copy/serializer.cc +85 -0
- package/dist/node_modules/isolated-vm/src/external_copy/serializer.h +136 -0
- package/dist/node_modules/isolated-vm/src/external_copy/serializer_nortti.cc +73 -0
- package/dist/node_modules/isolated-vm/src/external_copy/string.cc +124 -0
- package/dist/node_modules/isolated-vm/src/external_copy/string.h +28 -0
- package/dist/node_modules/isolated-vm/src/isolate/allocator.h +32 -0
- package/dist/node_modules/isolated-vm/src/isolate/allocator_nortti.cc +142 -0
- package/dist/node_modules/isolated-vm/src/isolate/class_handle.h +334 -0
- package/dist/node_modules/isolated-vm/src/isolate/cpu_profile_manager.cc +220 -0
- package/dist/node_modules/isolated-vm/src/isolate/cpu_profile_manager.h +100 -0
- package/dist/node_modules/isolated-vm/src/isolate/environment.cc +626 -0
- package/dist/node_modules/isolated-vm/src/isolate/environment.h +381 -0
- package/dist/node_modules/isolated-vm/src/isolate/executor.cc +198 -0
- package/dist/node_modules/isolated-vm/src/isolate/executor.h +183 -0
- package/dist/node_modules/isolated-vm/src/isolate/external.h +64 -0
- package/dist/node_modules/isolated-vm/src/isolate/functor_runners.h +97 -0
- package/dist/node_modules/isolated-vm/src/isolate/generic/array.h +145 -0
- package/dist/node_modules/isolated-vm/src/isolate/generic/callbacks.h +272 -0
- package/dist/node_modules/isolated-vm/src/isolate/generic/error.h +140 -0
- package/dist/node_modules/isolated-vm/src/isolate/generic/extract_params.h +145 -0
- package/dist/node_modules/isolated-vm/src/isolate/generic/handle_cast.h +257 -0
- package/dist/node_modules/isolated-vm/src/isolate/generic/read_option.h +47 -0
- package/dist/node_modules/isolated-vm/src/isolate/holder.cc +88 -0
- package/dist/node_modules/isolated-vm/src/isolate/holder.h +63 -0
- package/dist/node_modules/isolated-vm/src/isolate/inspector.cc +200 -0
- package/dist/node_modules/isolated-vm/src/isolate/inspector.h +70 -0
- package/dist/node_modules/isolated-vm/src/isolate/node_wrapper.h +15 -0
- package/dist/node_modules/isolated-vm/src/isolate/platform_delegate.cc +22 -0
- package/dist/node_modules/isolated-vm/src/isolate/platform_delegate.h +46 -0
- package/dist/node_modules/isolated-vm/src/isolate/remote_handle.h +164 -0
- package/dist/node_modules/isolated-vm/src/isolate/run_with_timeout.h +171 -0
- package/dist/node_modules/isolated-vm/src/isolate/runnable.h +29 -0
- package/dist/node_modules/isolated-vm/src/isolate/scheduler.cc +191 -0
- package/dist/node_modules/isolated-vm/src/isolate/scheduler.h +165 -0
- package/dist/node_modules/isolated-vm/src/isolate/specific.h +35 -0
- package/dist/node_modules/isolated-vm/src/isolate/stack_trace.cc +219 -0
- package/dist/node_modules/isolated-vm/src/isolate/stack_trace.h +24 -0
- package/dist/node_modules/isolated-vm/src/isolate/strings.h +127 -0
- package/dist/node_modules/isolated-vm/src/isolate/three_phase_task.cc +385 -0
- package/dist/node_modules/isolated-vm/src/isolate/three_phase_task.h +136 -0
- package/dist/node_modules/isolated-vm/src/isolate/transferable.h +15 -0
- package/dist/node_modules/isolated-vm/src/isolate/util.h +45 -0
- package/dist/node_modules/isolated-vm/src/isolate/v8_inspector_wrapper.h +12 -0
- package/dist/node_modules/isolated-vm/src/isolate/v8_version.h +12 -0
- package/dist/node_modules/isolated-vm/src/isolated_vm.h +71 -0
- package/dist/node_modules/isolated-vm/src/lib/covariant.h +50 -0
- package/dist/node_modules/isolated-vm/src/lib/lockable.h +178 -0
- package/dist/node_modules/isolated-vm/src/lib/suspend.h +106 -0
- package/dist/node_modules/isolated-vm/src/lib/thread_pool.cc +98 -0
- package/dist/node_modules/isolated-vm/src/lib/thread_pool.h +45 -0
- package/dist/node_modules/isolated-vm/src/lib/timer.cc +233 -0
- package/dist/node_modules/isolated-vm/src/lib/timer.h +36 -0
- package/dist/node_modules/isolated-vm/src/module/callback.cc +151 -0
- package/dist/node_modules/isolated-vm/src/module/callback.h +64 -0
- package/dist/node_modules/isolated-vm/src/module/context_handle.cc +241 -0
- package/dist/node_modules/isolated-vm/src/module/context_handle.h +35 -0
- package/dist/node_modules/isolated-vm/src/module/evaluation.cc +109 -0
- package/dist/node_modules/isolated-vm/src/module/evaluation.h +99 -0
- package/dist/node_modules/isolated-vm/src/module/external_copy_handle.cc +119 -0
- package/dist/node_modules/isolated-vm/src/module/external_copy_handle.h +64 -0
- package/dist/node_modules/isolated-vm/src/module/isolate.cc +136 -0
- package/dist/node_modules/isolated-vm/src/module/isolate_handle.cc +611 -0
- package/dist/node_modules/isolated-vm/src/module/isolate_handle.h +47 -0
- package/dist/node_modules/isolated-vm/src/module/lib_handle.cc +77 -0
- package/dist/node_modules/isolated-vm/src/module/lib_handle.h +28 -0
- package/dist/node_modules/isolated-vm/src/module/module_handle.cc +475 -0
- package/dist/node_modules/isolated-vm/src/module/module_handle.h +68 -0
- package/dist/node_modules/isolated-vm/src/module/native_module_handle.cc +104 -0
- package/dist/node_modules/isolated-vm/src/module/native_module_handle.h +49 -0
- package/dist/node_modules/isolated-vm/src/module/reference_handle.cc +636 -0
- package/dist/node_modules/isolated-vm/src/module/reference_handle.h +106 -0
- package/dist/node_modules/isolated-vm/src/module/script_handle.cc +107 -0
- package/dist/node_modules/isolated-vm/src/module/script_handle.h +37 -0
- package/dist/node_modules/isolated-vm/src/module/session_handle.cc +173 -0
- package/dist/node_modules/isolated-vm/src/module/session_handle.h +31 -0
- package/dist/node_modules/isolated-vm/src/module/transferable.cc +268 -0
- package/dist/node_modules/isolated-vm/src/module/transferable.h +42 -0
- package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v18.0.0.h +360 -0
- package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v18.3.0.h +376 -0
- package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v20.0.0.h +397 -0
- package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v22.0.0.h +419 -0
- package/dist/node_modules/winston-transport/package.json +1 -1
- package/dist/server/IsolatedVm.js +75 -0
- package/dist/server/ScriptInstruction.d.ts +6 -0
- package/dist/server/ScriptInstruction.js +11 -1
- package/dist/server/Vm.js +42 -27
- 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 : ¤t_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
|