@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,241 @@
1
+ #include "isolate/run_with_timeout.h"
2
+ #include "isolate/three_phase_task.h"
3
+ #include "module/evaluation.h"
4
+ #include "context_handle.h"
5
+ #include "reference_handle.h"
6
+ #include "transferable.h"
7
+
8
+ using namespace v8;
9
+
10
+ namespace ivm {
11
+ namespace {
12
+
13
+ /**
14
+ * Instances of this turn into a ContextHandle when they are transferred in
15
+ */
16
+ class ContextHandleTransferable : public Transferable {
17
+ public:
18
+ ContextHandleTransferable(RemoteHandle<Context> context, RemoteHandle<Value> global) :
19
+ context{std::move(context)}, global{std::move(global)} {}
20
+
21
+ auto TransferIn() -> Local<Value> final {
22
+ return ClassHandle::NewInstance<ContextHandle>(std::move(context), std::move(global));
23
+ }
24
+
25
+ private:
26
+ RemoteHandle<v8::Context> context;
27
+ RemoteHandle<v8::Value> global;
28
+ };
29
+
30
+ } // anonymous namespace
31
+
32
+ /**
33
+ * ContextHandle implementation
34
+ */
35
+ ContextHandle::ContextHandle(RemoteHandle<Context> context, RemoteHandle<Value> global) :
36
+ context{std::move(context)}, global{std::move(global)} {}
37
+
38
+ auto ContextHandle::Definition() -> Local<FunctionTemplate> {
39
+ return Inherit<TransferableHandle>(MakeClass(
40
+ "Context", nullptr,
41
+ "eval", MemberFunction<decltype(&ContextHandle::Eval<1>), &ContextHandle::Eval<1>>{},
42
+ "evalIgnored", MemberFunction<decltype(&ContextHandle::Eval<2>), &ContextHandle::Eval<2>>{},
43
+ "evalSync", MemberFunction<decltype(&ContextHandle::Eval<0>), &ContextHandle::Eval<0>>{},
44
+ "evalClosure", MemberFunction<decltype(&ContextHandle::EvalClosure<1>), &ContextHandle::EvalClosure<1>>{},
45
+ "evalClosureIgnored", MemberFunction<decltype(&ContextHandle::EvalClosure<2>), &ContextHandle::EvalClosure<2>>{},
46
+ "evalClosureSync", MemberFunction<decltype(&ContextHandle::EvalClosure<0>), &ContextHandle::EvalClosure<0>>{},
47
+ "global", MemberAccessor<decltype(&ContextHandle::GlobalGetter), &ContextHandle::GlobalGetter>{},
48
+ "release", MemberFunction<decltype(&ContextHandle::Release), &ContextHandle::Release>{}
49
+ ));
50
+ }
51
+
52
+ auto ContextHandle::TransferOut() -> std::unique_ptr<Transferable> {
53
+ return std::make_unique<ContextHandleTransferable>(context, global);
54
+ }
55
+
56
+ auto ContextHandle::GetContext() const -> RemoteHandle<v8::Context> {
57
+ if (!context) {
58
+ throw RuntimeGenericError("Context is released");
59
+ }
60
+ return context;
61
+ }
62
+
63
+ auto ContextHandle::GlobalGetter() -> Local<Value> {
64
+ Isolate* isolate = Isolate::GetCurrent();
65
+ if (!context) {
66
+ return Undefined(isolate);
67
+ }
68
+ Local<Object> ref;
69
+ if (global_reference) {
70
+ ref = Deref(global_reference);
71
+ } else {
72
+ ref = ClassHandle::NewInstance<ReferenceHandle>(global.GetSharedIsolateHolder(), global, context, ReferenceHandle::TypeOf::Object, false, false);
73
+ global_reference = RemoteHandle<v8::Object>(ref);
74
+ }
75
+ Unmaybe(This()->CreateDataProperty(isolate->GetCurrentContext(), StringTable::Get().global, ref));
76
+ return ref;
77
+ }
78
+
79
+ auto ContextHandle::Release() -> Local<Value> {
80
+ return Boolean::New(Isolate::GetCurrent(), [&]() {
81
+ if (context) {
82
+ context = {};
83
+ global = {};
84
+ if (global_reference) {
85
+ ClassHandle::Unwrap<ReferenceHandle>(Deref(global_reference))->Release();
86
+ global_reference = {};
87
+ }
88
+ return true;
89
+ } else {
90
+ return false;
91
+ }
92
+ }());
93
+ }
94
+
95
+ /*
96
+ * Compiles and immediately executes a given script
97
+ */
98
+ class EvalRunner : public CodeCompilerHolder, public ThreePhaseTask {
99
+ public:
100
+ explicit EvalRunner(
101
+ RemoteHandle<Context> context,
102
+ Local<String> code,
103
+ MaybeLocal<Object> maybe_options
104
+ ) :
105
+ CodeCompilerHolder{code, maybe_options},
106
+ transfer_options{maybe_options},
107
+ context{std::move(context)} {
108
+ if (!this->context) {
109
+ throw RuntimeGenericError("Context is released");
110
+ }
111
+ timeout_ms = ReadOption<int32_t>(maybe_options, StringTable::Get().timeout, timeout_ms);
112
+ }
113
+
114
+ void Phase2() final {
115
+ // Load script in and compile
116
+ auto& isolate = IsolateEnvironment::GetCurrent();
117
+ auto context = this->context.Deref();
118
+ Context::Scope context_scope{context};
119
+ IsolateEnvironment::HeapCheck heap_check{isolate, true};
120
+ auto source = GetSource();
121
+ auto script = RunWithAnnotatedErrors([&]() {
122
+ return Unmaybe(ScriptCompiler::Compile(context, source.get()));
123
+ });
124
+
125
+ // Execute script and transfer out
126
+ Local<Value> script_result = RunWithTimeout(timeout_ms, [&]() {
127
+ return script->Run(context);
128
+ });
129
+ result = OptionalTransferOut(script_result, transfer_options);
130
+ heap_check.Epilogue();
131
+ }
132
+
133
+ auto Phase3() -> Local<Value> final {
134
+ return result ? result->TransferIn() : Undefined(Isolate::GetCurrent()).As<Value>();
135
+ }
136
+
137
+ private:
138
+ TransferOptions transfer_options;
139
+ RemoteHandle<Context> context;
140
+ std::unique_ptr<Transferable> result;
141
+ int32_t timeout_ms = 0;
142
+ };
143
+
144
+ template <int Async>
145
+ auto ContextHandle::Eval(Local<String> code, MaybeLocal<Object> maybe_options) -> Local<Value> {
146
+ return ThreePhaseTask::Run<Async, EvalRunner>(*context.GetIsolateHolder(), context, code, maybe_options);
147
+ }
148
+
149
+ /*
150
+ * Compiles a script as a function body and immediately invokes it
151
+ */
152
+ class EvalClosureRunner : public CodeCompilerHolder, public ThreePhaseTask {
153
+ public:
154
+ explicit EvalClosureRunner(
155
+ RemoteHandle<Context> context,
156
+ Local<String> code,
157
+ Maybe<ArrayRange> maybe_arguments,
158
+ MaybeLocal<Object> maybe_options
159
+ ) :
160
+ CodeCompilerHolder{code, maybe_options},
161
+ transfer_options{ReadOption<MaybeLocal<Object>>(maybe_options, StringTable::Get().result, {})},
162
+ argv{[&]() {
163
+ // Transfer arguments out of isolate
164
+ std::vector<std::unique_ptr<Transferable>> argv;
165
+ TransferOptions transfer_options{ReadOption<MaybeLocal<Object>>(maybe_options, StringTable::Get().arguments, {})};
166
+ ArrayRange arguments;
167
+ if (maybe_arguments.To(&arguments)) {
168
+ argv.reserve(std::distance(arguments.begin(), arguments.end()));
169
+ for (auto value : arguments) {
170
+ argv.push_back(TransferOut(value, transfer_options));
171
+ }
172
+ }
173
+ return argv;
174
+ }()},
175
+ context{std::move(context)} {
176
+ if (!this->context) {
177
+ throw RuntimeGenericError("Context is released");
178
+ }
179
+ timeout_ms = ReadOption<int32_t>(maybe_options, StringTable::Get().timeout, timeout_ms);
180
+ }
181
+
182
+ void Phase2() final {
183
+ // Setup isolate's context
184
+ auto& isolate = IsolateEnvironment::GetCurrent();
185
+ auto context = this->context.Deref();
186
+ Context::Scope context_scope{context};
187
+ IsolateEnvironment::HeapCheck heap_check{isolate, true};
188
+
189
+ // Generate $0 ... $N argument names
190
+ std::vector<Local<String>> argument_names;
191
+ size_t argc = argv.size();
192
+ argument_names.reserve(argc + 1);
193
+ for (size_t ii = 0; ii < argc; ++ii) {
194
+ argument_names.emplace_back(HandleCast<Local<String>>(std::string{"$"}+ std::to_string(ii)));
195
+ }
196
+
197
+ // Invoke `new Function` to compile script
198
+ auto source = GetSource();
199
+ auto function = RunWithAnnotatedErrors([&]() {
200
+ return Unmaybe(ScriptCompiler::CompileFunction(
201
+ context, source.get(),
202
+ argument_names.size(), argument_names.empty() ? nullptr : &argument_names[0],
203
+ 0, nullptr
204
+ ));
205
+ });
206
+
207
+ // Transfer arguments into this isolate
208
+ std::vector<Local<Value>> argv_transferred;
209
+ argv_transferred.reserve(argc);
210
+ for (size_t ii = 0; ii < argc; ++ii) {
211
+ argv_transferred.emplace_back(argv[ii]->TransferIn());
212
+ }
213
+
214
+ // Execute script and transfer out
215
+ Local<Value> script_result = RunWithTimeout(timeout_ms, [&]() {
216
+ return function->Call(
217
+ context, context->Global(),
218
+ argv_transferred.size(), argv_transferred.empty() ? nullptr : &argv_transferred[0]);
219
+ });
220
+ result = TransferOut(script_result, transfer_options);
221
+ heap_check.Epilogue();
222
+ }
223
+
224
+ auto Phase3() -> Local<Value> final {
225
+ return result ? result->TransferIn() : Undefined(Isolate::GetCurrent()).As<Value>();
226
+ }
227
+
228
+ private:
229
+ TransferOptions transfer_options;
230
+ std::vector<std::unique_ptr<Transferable>> argv;
231
+ RemoteHandle<Context> context;
232
+ std::unique_ptr<Transferable> result;
233
+ int32_t timeout_ms = 0;
234
+ };
235
+
236
+ template <int Async>
237
+ auto ContextHandle::EvalClosure(Local<String> code, Maybe<ArrayRange> maybe_arguments, MaybeLocal<Object> maybe_options) -> Local<Value> {
238
+ return ThreePhaseTask::Run<Async, EvalClosureRunner>(*context.GetIsolateHolder(), context, code, maybe_arguments, maybe_options);
239
+ }
240
+
241
+ } // namespace ivm
@@ -0,0 +1,35 @@
1
+ #pragma once
2
+ #include "isolate/remote_handle.h"
3
+ #include "transferable.h"
4
+ #include <v8.h>
5
+ #include <memory>
6
+
7
+ namespace ivm {
8
+
9
+ class ContextHandle : public TransferableHandle {
10
+ public:
11
+ ContextHandle(RemoteHandle<v8::Context> context, RemoteHandle<v8::Value> global);
12
+ static auto Definition() -> v8::Local<v8::FunctionTemplate>;
13
+ auto TransferOut() -> std::unique_ptr<Transferable> final;
14
+
15
+ auto GetContext() const -> RemoteHandle<v8::Context>;
16
+ auto GlobalGetter() -> v8::Local<v8::Value>;
17
+ auto Release() -> v8::Local<v8::Value>;
18
+
19
+ template <int Async>
20
+ auto Eval(v8::Local<v8::String> code, v8::MaybeLocal<v8::Object> maybe_options) -> v8::Local<v8::Value>;
21
+
22
+ template <int Async>
23
+ auto EvalClosure(
24
+ v8::Local<v8::String> code,
25
+ v8::Maybe<ArrayRange> maybe_arguments,
26
+ v8::MaybeLocal<v8::Object> maybe_options
27
+ ) -> v8::Local<v8::Value>;
28
+
29
+ private:
30
+ RemoteHandle<v8::Context> context;
31
+ RemoteHandle<v8::Value> global;
32
+ RemoteHandle<v8::Object> global_reference;
33
+ };
34
+
35
+ } // namespace ivm
@@ -0,0 +1,109 @@
1
+ #include "isolate/class_handle.h"
2
+ #include "isolate/generic/read_option.h"
3
+ #include "external_copy_handle.h"
4
+ #include "evaluation.h"
5
+
6
+ using namespace v8;
7
+ namespace ivm {
8
+
9
+ /**
10
+ * ScriptOriginHolder implementation
11
+ */
12
+ ScriptOriginHolder::ScriptOriginHolder(MaybeLocal<Object> maybe_options, bool is_module) :
13
+ is_module{is_module} {
14
+ Local<Object> options;
15
+ if (maybe_options.ToLocal(&options)) {
16
+ filename = ReadOption<std::string>(options, StringTable::Get().filename, filename);
17
+ column_offset = ReadOption<int32_t>(options, StringTable::Get().columnOffset, column_offset);
18
+ line_offset = ReadOption<int32_t>(options, StringTable::Get().lineOffset, line_offset);
19
+ }
20
+ }
21
+
22
+ ScriptOriginHolder::operator ScriptOrigin() const {
23
+ return ScriptOrigin{
24
+ Isolate::GetCurrent(),
25
+ HandleCast<Local<String>>(filename),
26
+ line_offset,
27
+ column_offset,
28
+ false, // resource_is_shared_cross_origin
29
+ -1, // script_id
30
+ {}, // source_map_url
31
+ false, // resource_is_opaque
32
+ false, // is_wasm
33
+ is_module
34
+ };
35
+ }
36
+
37
+ /**
38
+ * CodeCompilerHolder implementation
39
+ */
40
+ CodeCompilerHolder::CodeCompilerHolder(Local<String> code_handle, MaybeLocal<Object> maybe_options, bool is_module) :
41
+ script_origin_holder{maybe_options, is_module},
42
+ code_string{ExternalCopyString{code_handle}},
43
+ produce_cached_data{ReadOption<bool>(maybe_options, StringTable::Get().produceCachedData, {})} {
44
+ // Read `cachedData`
45
+ auto maybe_cached_data = ReadOption<MaybeLocal<Object>>(maybe_options, StringTable::Get().cachedData, {});
46
+ Local<Object> cached_data;
47
+ if (maybe_cached_data.ToLocal(&cached_data)) {
48
+ auto* copy_handle = ClassHandle::Unwrap<ExternalCopyHandle>(cached_data);
49
+ if (copy_handle != nullptr) {
50
+ ExternalCopyArrayBuffer* copy_ptr = dynamic_cast<ExternalCopyArrayBuffer*>(copy_handle->GetValue().get());
51
+ if (copy_ptr != nullptr) {
52
+ supplied_cached_data = true;
53
+ cached_data_in = copy_ptr->Acquire();
54
+ cached_data_in_size = cached_data_in->ByteLength();
55
+ }
56
+ }
57
+ if (!cached_data_in) {
58
+ throw RuntimeTypeError("`cachedData` must be an ExternalCopy to ArrayBuffer");
59
+ }
60
+ }
61
+ }
62
+
63
+ auto CodeCompilerHolder::GetCachedData() const -> std::unique_ptr<ScriptCompiler::CachedData> {
64
+ if (cached_data_in) {
65
+ return std::make_unique<ScriptCompiler::CachedData>(reinterpret_cast<const uint8_t*>(cached_data_in->Data()), cached_data_in_size);
66
+ }
67
+ return {};
68
+ }
69
+
70
+ auto CodeCompilerHolder::GetSource() -> std::unique_ptr<ScriptCompiler::Source> {
71
+ return std::make_unique<ScriptCompiler::Source>(
72
+ GetSourceString(),
73
+ ScriptOrigin{script_origin_holder},
74
+ GetCachedData().release()
75
+ );
76
+ }
77
+
78
+ auto CodeCompilerHolder::GetSourceString() -> v8::Local<v8::String> {
79
+ if (code_string_handle.IsEmpty()) {
80
+ code_string_handle = code_string.CopyIntoCheckHeap().As<String>();
81
+ }
82
+ return code_string_handle;
83
+ }
84
+
85
+ void CodeCompilerHolder::ResetSource() {
86
+ cached_data_in.reset();
87
+ code_string = {};
88
+ }
89
+
90
+ void CodeCompilerHolder::SaveCachedData(ScriptCompiler::CachedData* cached_data) {
91
+ if (cached_data != nullptr) {
92
+ cached_data_out = std::make_shared<ExternalCopyArrayBuffer>((void*)cached_data->data, cached_data->length);
93
+ cached_data->buffer_policy = ScriptCompiler::CachedData::BufferNotOwned;
94
+ delete cached_data;
95
+ }
96
+ }
97
+
98
+ void CodeCompilerHolder::WriteCompileResults(Local<Object> handle) {
99
+ Isolate* isolate = Isolate::GetCurrent();
100
+ Local<Context> context = isolate->GetCurrentContext();
101
+ if (DidSupplyCachedData()) {
102
+ Unmaybe(handle->Set(context, StringTable::Get().cachedDataRejected, Boolean::New(isolate, cached_data_rejected)));
103
+ }
104
+ if (cached_data_out) {
105
+ Unmaybe(handle->Set(context, StringTable::Get().cachedData, ClassHandle::NewInstance<ExternalCopyHandle>(std::move(cached_data_out))));
106
+ }
107
+ }
108
+
109
+ } // namespace ivm
@@ -0,0 +1,99 @@
1
+ #pragma once
2
+ #include "isolate/generic/error.h"
3
+ #include "isolate/generic/handle_cast.h"
4
+ #include "external_copy/external_copy.h"
5
+ #include "external_copy/string.h"
6
+ #include <v8.h>
7
+ #include <memory>
8
+ #include <string>
9
+
10
+ namespace ivm {
11
+
12
+ /**
13
+ * Parses script origin information from an option object and returns a non-v8 holder for the
14
+ * information which can then be converted to a ScriptOrigin, perhaps in a different isolate from
15
+ * the one it was read in.
16
+ */
17
+ class ScriptOriginHolder {
18
+ public:
19
+ explicit ScriptOriginHolder(v8::MaybeLocal<v8::Object> maybe_options, bool is_module = false);
20
+ explicit operator v8::ScriptOrigin() const;
21
+
22
+ private:
23
+ std::string filename = "<isolated-vm>";
24
+ int32_t column_offset = 0;
25
+ int32_t line_offset = 0;
26
+ bool is_module;
27
+ };
28
+
29
+ /**
30
+ * Parser and holder for all common v8 compilation information like code string, cached data, script
31
+ * origin, etc.
32
+ */
33
+ class CodeCompilerHolder {
34
+ public:
35
+ CodeCompilerHolder(
36
+ v8::Local<v8::String> code_handle, v8::MaybeLocal<v8::Object> maybe_options, bool is_module = false);
37
+ auto DidSupplyCachedData() const { return supplied_cached_data; }
38
+ auto GetSource() -> std::unique_ptr<v8::ScriptCompiler::Source>;
39
+ auto GetSourceString() -> v8::Local<v8::String>;
40
+ void ResetSource();
41
+ void SaveCachedData(v8::ScriptCompiler::CachedData* cached_data);
42
+ void SetCachedDataRejected(bool rejected) { cached_data_rejected = rejected; }
43
+ auto ShouldProduceCachedData() const { return produce_cached_data && (!supplied_cached_data || cached_data_rejected); }
44
+ void WriteCompileResults(v8::Local<v8::Object> handle);
45
+
46
+ private:
47
+ auto GetCachedData() const -> std::unique_ptr<v8::ScriptCompiler::CachedData>;
48
+
49
+ ScriptOriginHolder script_origin_holder;
50
+ ExternalCopyString code_string;
51
+ std::shared_ptr<ExternalCopyArrayBuffer> cached_data_out;
52
+ std::shared_ptr<v8::BackingStore> cached_data_in;
53
+ mutable v8::Local<v8::String> code_string_handle;
54
+ size_t cached_data_in_size = 0;
55
+ bool cached_data_rejected = false;
56
+ bool produce_cached_data = false;
57
+ bool supplied_cached_data = false;
58
+ };
59
+
60
+ /**
61
+ * Run a lambda which invokes the v8 compiler and annotate the exception with source / line number
62
+ * if it throws.
63
+ */
64
+ template <class Function>
65
+ auto RunWithAnnotatedErrors(Function fn) {
66
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
67
+ v8::TryCatch try_catch{isolate};
68
+ try {
69
+ return fn();
70
+ } catch (const detail::RuntimeErrorWithMessage& cc_error) {
71
+ throw std::logic_error("Invalid error thrown by RunWithAnnotatedErrors");
72
+ } catch (const RuntimeError& cc_error) {
73
+ try {
74
+ assert(try_catch.HasCaught());
75
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
76
+ v8::Local<v8::Value> error = try_catch.Exception();
77
+ v8::Local<v8::Message> message = try_catch.Message();
78
+ assert(error->IsObject());
79
+ int linenum = Unmaybe(message->GetLineNumber(context));
80
+ int start_column = Unmaybe(message->GetStartColumn(context));
81
+ auto name = message->GetScriptResourceName();
82
+ std::string decorator =
83
+ (name->IsString() ?
84
+ HandleCast<std::string>(message->GetScriptResourceName()) : "<isolated-vm>") +
85
+ ":" + std::to_string(linenum) +
86
+ ":" + std::to_string(start_column + 1);
87
+ auto message_key = HandleCast<v8::Local<v8::String>>("message");
88
+ std::string message_str = HandleCast<std::string>(Unmaybe(error.As<v8::Object>()->Get(context, message_key)));
89
+ Unmaybe(error.As<v8::Object>()->Set(context, message_key, HandleCast<v8::Local<v8::String>>(message_str + " [" + decorator + "]")));
90
+ isolate->ThrowException(error);
91
+ throw RuntimeError();
92
+ } catch (const RuntimeError& cc_error) {
93
+ try_catch.ReThrow();
94
+ throw RuntimeError();
95
+ }
96
+ }
97
+ }
98
+
99
+ } // namespace ivm
@@ -0,0 +1,119 @@
1
+ #include "external_copy_handle.h"
2
+ #include "external_copy/external_copy.h"
3
+
4
+ using namespace v8;
5
+ using std::shared_ptr;
6
+ using std::unique_ptr;
7
+
8
+ namespace ivm {
9
+
10
+ /**
11
+ * Transferable wrapper
12
+ */
13
+ ExternalCopyHandle::ExternalCopyTransferable::ExternalCopyTransferable(std::shared_ptr<ExternalCopy> value) : value(std::move(value)) {}
14
+
15
+ auto ExternalCopyHandle::ExternalCopyTransferable::TransferIn() -> Local<Value> {
16
+ return ClassHandle::NewInstance<ExternalCopyHandle>(value);
17
+ }
18
+
19
+ /**
20
+ * ExternalCopyHandle implementation
21
+ */
22
+ ExternalCopyHandle::ExternalCopyHandle(shared_ptr<ExternalCopy> value) : value(std::move(value)), size{this->value->Size()} {
23
+ Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size);
24
+ }
25
+
26
+ ExternalCopyHandle::~ExternalCopyHandle() {
27
+ Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-size);
28
+ }
29
+
30
+ auto ExternalCopyHandle::Definition() -> Local<FunctionTemplate> {
31
+ return Inherit<TransferableHandle>(MakeClass(
32
+ "ExternalCopy", ConstructorFunction<decltype(&New), &New>{},
33
+ "totalExternalSize", StaticAccessor<decltype(&ExternalCopyHandle::TotalExternalSizeGetter), &ExternalCopyHandle::TotalExternalSizeGetter>{},
34
+ "copy", MemberFunction<decltype(&ExternalCopyHandle::Copy), &ExternalCopyHandle::Copy>{},
35
+ "copyInto", MemberFunction<decltype(&ExternalCopyHandle::CopyInto), &ExternalCopyHandle::CopyInto>{},
36
+ "release", MemberFunction<decltype(&ExternalCopyHandle::Release), &ExternalCopyHandle::Release>{}
37
+ ));
38
+ }
39
+
40
+ auto ExternalCopyHandle::TransferOut() -> unique_ptr<Transferable> {
41
+ return std::make_unique<ExternalCopyTransferable>(value);
42
+ }
43
+
44
+ auto ExternalCopyHandle::New(Local<Value> value, MaybeLocal<Object> maybe_options) -> unique_ptr<ExternalCopyHandle> {
45
+ Local<Object> options;
46
+ bool transfer_out = false;
47
+ ArrayRange transfer_list;
48
+ if (maybe_options.ToLocal(&options)) {
49
+ transfer_out = ReadOption<bool>(options, StringTable::Get().transferOut, false);
50
+ transfer_list = ReadOption<ArrayRange>(options, StringTable::Get().transferList, {});
51
+ }
52
+ return std::make_unique<ExternalCopyHandle>(shared_ptr<ExternalCopy>(ExternalCopy::Copy(value, transfer_out, transfer_list)));
53
+ }
54
+
55
+ void ExternalCopyHandle::CheckDisposed() const {
56
+ if (!value) {
57
+ throw RuntimeGenericError("Copy has been released");
58
+ }
59
+ }
60
+
61
+ /**
62
+ * JS API functions
63
+ */
64
+ auto ExternalCopyHandle::TotalExternalSizeGetter() -> Local<Value> {
65
+ return Number::New(Isolate::GetCurrent(), ExternalCopy::TotalExternalSize());
66
+ }
67
+
68
+ auto ExternalCopyHandle::Copy(MaybeLocal<Object> maybe_options) -> Local<Value> {
69
+ CheckDisposed();
70
+ bool release = ReadOption<bool>(maybe_options, StringTable::Get().release, false);
71
+ bool transfer_in = ReadOption<bool>(maybe_options, StringTable::Get().transferIn, false);
72
+ Local<Value> ret = value->CopyIntoCheckHeap(transfer_in);
73
+ if (release) {
74
+ Release();
75
+ }
76
+ return ret;
77
+ }
78
+
79
+ auto ExternalCopyHandle::CopyInto(MaybeLocal<Object> maybe_options) -> Local<Value> {
80
+ CheckDisposed();
81
+ bool release = ReadOption<bool>(maybe_options, StringTable::Get().release, false);
82
+ bool transfer_in = ReadOption<bool>(maybe_options, StringTable::Get().transferIn, false);
83
+ Local<Value> ret = ClassHandle::NewInstance<ExternalCopyIntoHandle>(value, transfer_in);
84
+ if (release) {
85
+ Release();
86
+ }
87
+ return ret;
88
+ }
89
+
90
+ auto ExternalCopyHandle::Release() -> Local<Value> {
91
+ CheckDisposed();
92
+ Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-std::exchange(size, 0));
93
+ value.reset();
94
+ return Undefined(Isolate::GetCurrent());
95
+ }
96
+
97
+ /**
98
+ * ExternalCopyIntoHandle implementation
99
+ */
100
+ ExternalCopyIntoHandle::ExternalCopyIntoTransferable::ExternalCopyIntoTransferable(shared_ptr<ExternalCopy> value, bool transfer_in) : value(std::move(value)), transfer_in(transfer_in) {}
101
+
102
+ auto ExternalCopyIntoHandle::ExternalCopyIntoTransferable::TransferIn() -> Local<Value> {
103
+ return value->CopyIntoCheckHeap(transfer_in);
104
+ }
105
+
106
+ ExternalCopyIntoHandle::ExternalCopyIntoHandle(shared_ptr<ExternalCopy> value, bool transfer_in) : value(std::move(value)), transfer_in(transfer_in) {}
107
+
108
+ auto ExternalCopyIntoHandle::Definition() -> Local<FunctionTemplate> {
109
+ return Inherit<TransferableHandle>(MakeClass("ExternalCopyInto", nullptr));
110
+ }
111
+
112
+ auto ExternalCopyIntoHandle::TransferOut() -> unique_ptr<Transferable> {
113
+ if (!value) {
114
+ throw RuntimeGenericError("The return value of `copyInto()` should only be used once");
115
+ }
116
+ return std::make_unique<ExternalCopyIntoTransferable>(std::move(value), transfer_in);
117
+ }
118
+
119
+ } // namespace ivm
@@ -0,0 +1,64 @@
1
+ #pragma once
2
+ #include <v8.h>
3
+ #include "transferable.h"
4
+ #include <memory>
5
+
6
+ namespace ivm {
7
+
8
+ class ExternalCopy;
9
+
10
+ class ExternalCopyHandle final : public TransferableHandle {
11
+ public:
12
+ class ExternalCopyTransferable : public Transferable {
13
+ private:
14
+ std::shared_ptr<ExternalCopy> value;
15
+
16
+ public:
17
+ explicit ExternalCopyTransferable(std::shared_ptr<ExternalCopy> value);
18
+ auto TransferIn() -> v8::Local<v8::Value> final;
19
+ };
20
+
21
+ std::shared_ptr<ExternalCopy> value;
22
+
23
+ void CheckDisposed() const;
24
+
25
+ explicit ExternalCopyHandle(std::shared_ptr<ExternalCopy> value);
26
+ ExternalCopyHandle(const ExternalCopyHandle&) = delete;
27
+ auto operator= (const ExternalCopyHandle&) -> ExternalCopyHandle& = delete;
28
+ ~ExternalCopyHandle() final;
29
+ static auto Definition() -> v8::Local<v8::FunctionTemplate>;
30
+ auto TransferOut() -> std::unique_ptr<Transferable> final;
31
+
32
+ static auto New(v8::Local<v8::Value> value, v8::MaybeLocal<v8::Object> maybe_options) -> std::unique_ptr<ExternalCopyHandle>;
33
+ static auto TotalExternalSizeGetter() -> v8::Local<v8::Value>;
34
+ auto Copy(v8::MaybeLocal<v8::Object> maybe_options) -> v8::Local<v8::Value>;
35
+ auto CopyInto(v8::MaybeLocal<v8::Object> maybe_options) -> v8::Local<v8::Value>;
36
+ auto Release() -> v8::Local<v8::Value>;
37
+ auto GetValue() const -> std::shared_ptr<ExternalCopy> { return value; }
38
+
39
+ private:
40
+ int size = 0;
41
+ };
42
+
43
+ class ExternalCopyIntoHandle : public TransferableHandle {
44
+ private:
45
+ class ExternalCopyIntoTransferable : public Transferable {
46
+ private:
47
+ std::shared_ptr<ExternalCopy> value;
48
+ bool transfer_in;
49
+
50
+ public:
51
+ explicit ExternalCopyIntoTransferable(std::shared_ptr<ExternalCopy> value, bool transfer_in);
52
+ auto TransferIn() -> v8::Local<v8::Value> final;
53
+ };
54
+
55
+ std::shared_ptr<ExternalCopy> value;
56
+ bool transfer_in;
57
+
58
+ public:
59
+ explicit ExternalCopyIntoHandle(std::shared_ptr<ExternalCopy> value, bool transfer_in);
60
+ static auto Definition() -> v8::Local<v8::FunctionTemplate>;
61
+ auto TransferOut() -> std::unique_ptr<Transferable> final;
62
+ };
63
+
64
+ } // namespace ivm