@nocobase/plugin-workflow-javascript 2.1.0-beta.26 → 2.1.0-beta.29

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 (139) hide show
  1. package/dist/externalVersion.js +4 -4
  2. package/dist/node_modules/joi/package.json +1 -1
  3. package/dist/node_modules/quickjs-emscripten/017c8a1a1898bfe7b7ae.wasm +0 -0
  4. package/dist/node_modules/quickjs-emscripten/161.index.js +50 -0
  5. package/dist/node_modules/quickjs-emscripten/277.index.js +27 -0
  6. package/dist/node_modules/quickjs-emscripten/302.index.js +55 -0
  7. package/dist/node_modules/quickjs-emscripten/45d53437811cf6eec760.wasm +0 -0
  8. package/dist/node_modules/quickjs-emscripten/712.index.js +5566 -0
  9. package/dist/node_modules/quickjs-emscripten/96b24985ab62871ec2a0.wasm +0 -0
  10. package/dist/node_modules/quickjs-emscripten/9a4b9654a8a7f4d515ba.wasm +0 -0
  11. package/dist/node_modules/quickjs-emscripten/LICENSE +21 -0
  12. package/dist/node_modules/quickjs-emscripten/dist/index.d.mts +57 -0
  13. package/dist/node_modules/quickjs-emscripten/dist/index.d.ts +57 -0
  14. package/dist/node_modules/quickjs-emscripten/dist/index.global.js +7309 -0
  15. package/dist/node_modules/quickjs-emscripten/dist/index.js +1 -0
  16. package/dist/node_modules/quickjs-emscripten/dist/variants.d.mts +39 -0
  17. package/dist/node_modules/quickjs-emscripten/dist/variants.d.ts +39 -0
  18. package/dist/node_modules/quickjs-emscripten/dist/variants.js +2 -0
  19. package/dist/node_modules/quickjs-emscripten/package.json +1 -0
  20. package/dist/node_modules/winston-transport/package.json +1 -1
  21. package/dist/server/QuickJs.js +135 -0
  22. package/dist/server/ScriptInstruction.d.ts +1 -1
  23. package/dist/server/ScriptInstruction.js +2 -2
  24. package/package.json +3 -8
  25. package/dist/node_modules/isolated-vm/.clang-tidy +0 -13
  26. package/dist/node_modules/isolated-vm/.dockerignore +0 -9
  27. package/dist/node_modules/isolated-vm/Dockerfile.alpine +0 -9
  28. package/dist/node_modules/isolated-vm/Dockerfile.debian +0 -12
  29. package/dist/node_modules/isolated-vm/LICENSE +0 -13
  30. package/dist/node_modules/isolated-vm/binding.gyp +0 -120
  31. package/dist/node_modules/isolated-vm/include.js +0 -3
  32. package/dist/node_modules/isolated-vm/inspector-example.js +0 -59
  33. package/dist/node_modules/isolated-vm/isolated-vm-6.1.2.tgz +0 -0
  34. package/dist/node_modules/isolated-vm/isolated-vm.d.ts +0 -820
  35. package/dist/node_modules/isolated-vm/isolated-vm.js +0 -1
  36. package/dist/node_modules/isolated-vm/native-example/binding.gyp +0 -23
  37. package/dist/node_modules/isolated-vm/native-example/example.cc +0 -61
  38. package/dist/node_modules/isolated-vm/native-example/package.json +0 -13
  39. package/dist/node_modules/isolated-vm/native-example/usage.js +0 -35
  40. package/dist/node_modules/isolated-vm/package.json +0 -1
  41. package/dist/node_modules/isolated-vm/prebuilds/darwin-arm64/isolated-vm.abi127.node +0 -0
  42. package/dist/node_modules/isolated-vm/prebuilds/darwin-arm64/isolated-vm.abi137.node +0 -0
  43. package/dist/node_modules/isolated-vm/prebuilds/linux-arm64/isolated-vm.abi127.glibc.node +0 -0
  44. package/dist/node_modules/isolated-vm/prebuilds/linux-arm64/isolated-vm.abi127.musl.node +0 -0
  45. package/dist/node_modules/isolated-vm/prebuilds/linux-arm64/isolated-vm.abi137.glibc.node +0 -0
  46. package/dist/node_modules/isolated-vm/prebuilds/linux-arm64/isolated-vm.abi137.musl.node +0 -0
  47. package/dist/node_modules/isolated-vm/prebuilds/linux-x64/isolated-vm.abi127.glibc.node +0 -0
  48. package/dist/node_modules/isolated-vm/prebuilds/linux-x64/isolated-vm.abi127.musl.node +0 -0
  49. package/dist/node_modules/isolated-vm/prebuilds/linux-x64/isolated-vm.abi137.glibc.node +0 -0
  50. package/dist/node_modules/isolated-vm/prebuilds/linux-x64/isolated-vm.abi137.musl.node +0 -0
  51. package/dist/node_modules/isolated-vm/prebuilds/win32-x64/isolated-vm.abi127.node +0 -0
  52. package/dist/node_modules/isolated-vm/prebuilds/win32-x64/isolated-vm.abi137.node +0 -0
  53. package/dist/node_modules/isolated-vm/scripts/run-prebuild.js +0 -33
  54. package/dist/node_modules/isolated-vm/src/external_copy/error.h +0 -33
  55. package/dist/node_modules/isolated-vm/src/external_copy/external_copy.cc +0 -509
  56. package/dist/node_modules/isolated-vm/src/external_copy/external_copy.h +0 -117
  57. package/dist/node_modules/isolated-vm/src/external_copy/serializer.cc +0 -85
  58. package/dist/node_modules/isolated-vm/src/external_copy/serializer.h +0 -136
  59. package/dist/node_modules/isolated-vm/src/external_copy/serializer_nortti.cc +0 -73
  60. package/dist/node_modules/isolated-vm/src/external_copy/string.cc +0 -124
  61. package/dist/node_modules/isolated-vm/src/external_copy/string.h +0 -28
  62. package/dist/node_modules/isolated-vm/src/isolate/allocator.h +0 -30
  63. package/dist/node_modules/isolated-vm/src/isolate/allocator_nortti.cc +0 -131
  64. package/dist/node_modules/isolated-vm/src/isolate/class_handle.h +0 -338
  65. package/dist/node_modules/isolated-vm/src/isolate/cpu_profile_manager.cc +0 -220
  66. package/dist/node_modules/isolated-vm/src/isolate/cpu_profile_manager.h +0 -100
  67. package/dist/node_modules/isolated-vm/src/isolate/environment.cc +0 -627
  68. package/dist/node_modules/isolated-vm/src/isolate/environment.h +0 -381
  69. package/dist/node_modules/isolated-vm/src/isolate/executor.cc +0 -198
  70. package/dist/node_modules/isolated-vm/src/isolate/executor.h +0 -183
  71. package/dist/node_modules/isolated-vm/src/isolate/external.h +0 -64
  72. package/dist/node_modules/isolated-vm/src/isolate/functor_runners.h +0 -97
  73. package/dist/node_modules/isolated-vm/src/isolate/generic/array.h +0 -145
  74. package/dist/node_modules/isolated-vm/src/isolate/generic/callbacks.h +0 -264
  75. package/dist/node_modules/isolated-vm/src/isolate/generic/error.h +0 -140
  76. package/dist/node_modules/isolated-vm/src/isolate/generic/extract_params.h +0 -145
  77. package/dist/node_modules/isolated-vm/src/isolate/generic/handle_cast.h +0 -257
  78. package/dist/node_modules/isolated-vm/src/isolate/generic/read_option.h +0 -47
  79. package/dist/node_modules/isolated-vm/src/isolate/holder.cc +0 -88
  80. package/dist/node_modules/isolated-vm/src/isolate/holder.h +0 -69
  81. package/dist/node_modules/isolated-vm/src/isolate/inspector.cc +0 -200
  82. package/dist/node_modules/isolated-vm/src/isolate/inspector.h +0 -70
  83. package/dist/node_modules/isolated-vm/src/isolate/node_wrapper.h +0 -15
  84. package/dist/node_modules/isolated-vm/src/isolate/platform_delegate.cc +0 -22
  85. package/dist/node_modules/isolated-vm/src/isolate/platform_delegate.h +0 -46
  86. package/dist/node_modules/isolated-vm/src/isolate/remote_handle.h +0 -164
  87. package/dist/node_modules/isolated-vm/src/isolate/run_with_timeout.h +0 -171
  88. package/dist/node_modules/isolated-vm/src/isolate/runnable.h +0 -29
  89. package/dist/node_modules/isolated-vm/src/isolate/scheduler.cc +0 -191
  90. package/dist/node_modules/isolated-vm/src/isolate/scheduler.h +0 -165
  91. package/dist/node_modules/isolated-vm/src/isolate/specific.h +0 -35
  92. package/dist/node_modules/isolated-vm/src/isolate/stack_trace.cc +0 -218
  93. package/dist/node_modules/isolated-vm/src/isolate/stack_trace.h +0 -24
  94. package/dist/node_modules/isolated-vm/src/isolate/strings.h +0 -127
  95. package/dist/node_modules/isolated-vm/src/isolate/three_phase_task.cc +0 -385
  96. package/dist/node_modules/isolated-vm/src/isolate/three_phase_task.h +0 -136
  97. package/dist/node_modules/isolated-vm/src/isolate/transferable.h +0 -15
  98. package/dist/node_modules/isolated-vm/src/isolate/util.h +0 -45
  99. package/dist/node_modules/isolated-vm/src/isolate/v8_inspector_wrapper.h +0 -14
  100. package/dist/node_modules/isolated-vm/src/isolate/v8_version.h +0 -12
  101. package/dist/node_modules/isolated-vm/src/isolated_vm.h +0 -71
  102. package/dist/node_modules/isolated-vm/src/lib/covariant.h +0 -50
  103. package/dist/node_modules/isolated-vm/src/lib/lockable.h +0 -178
  104. package/dist/node_modules/isolated-vm/src/lib/suspend.h +0 -106
  105. package/dist/node_modules/isolated-vm/src/lib/thread_pool.cc +0 -98
  106. package/dist/node_modules/isolated-vm/src/lib/thread_pool.h +0 -45
  107. package/dist/node_modules/isolated-vm/src/lib/timer.cc +0 -233
  108. package/dist/node_modules/isolated-vm/src/lib/timer.h +0 -36
  109. package/dist/node_modules/isolated-vm/src/module/callback.cc +0 -155
  110. package/dist/node_modules/isolated-vm/src/module/callback.h +0 -64
  111. package/dist/node_modules/isolated-vm/src/module/context_handle.cc +0 -241
  112. package/dist/node_modules/isolated-vm/src/module/context_handle.h +0 -35
  113. package/dist/node_modules/isolated-vm/src/module/evaluation.cc +0 -108
  114. package/dist/node_modules/isolated-vm/src/module/evaluation.h +0 -99
  115. package/dist/node_modules/isolated-vm/src/module/external_copy_handle.cc +0 -125
  116. package/dist/node_modules/isolated-vm/src/module/external_copy_handle.h +0 -64
  117. package/dist/node_modules/isolated-vm/src/module/isolate.cc +0 -136
  118. package/dist/node_modules/isolated-vm/src/module/isolate_handle.cc +0 -623
  119. package/dist/node_modules/isolated-vm/src/module/isolate_handle.h +0 -47
  120. package/dist/node_modules/isolated-vm/src/module/lib_handle.cc +0 -77
  121. package/dist/node_modules/isolated-vm/src/module/lib_handle.h +0 -28
  122. package/dist/node_modules/isolated-vm/src/module/module_handle.cc +0 -475
  123. package/dist/node_modules/isolated-vm/src/module/module_handle.h +0 -68
  124. package/dist/node_modules/isolated-vm/src/module/native_module_handle.cc +0 -108
  125. package/dist/node_modules/isolated-vm/src/module/native_module_handle.h +0 -49
  126. package/dist/node_modules/isolated-vm/src/module/reference_handle.cc +0 -640
  127. package/dist/node_modules/isolated-vm/src/module/reference_handle.h +0 -106
  128. package/dist/node_modules/isolated-vm/src/module/script_handle.cc +0 -107
  129. package/dist/node_modules/isolated-vm/src/module/script_handle.h +0 -37
  130. package/dist/node_modules/isolated-vm/src/module/session_handle.cc +0 -173
  131. package/dist/node_modules/isolated-vm/src/module/session_handle.h +0 -31
  132. package/dist/node_modules/isolated-vm/src/module/transferable.cc +0 -268
  133. package/dist/node_modules/isolated-vm/src/module/transferable.h +0 -42
  134. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v18.0.0.h +0 -360
  135. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v18.3.0.h +0 -376
  136. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v20.0.0.h +0 -397
  137. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v22.0.0.h +0 -419
  138. package/dist/node_modules/isolated-vm/vendor/v8_inspector/nodejs_v24.0.0.h +0 -426
  139. package/dist/server/IsolatedVm.js +0 -75
@@ -1,627 +0,0 @@
1
- #include "environment.h"
2
- #include "allocator.h"
3
- #include "inspector.h"
4
- #include "isolate/cpu_profile_manager.h"
5
- #include "isolate/generic/error.h"
6
- #include "platform_delegate.h"
7
- #include "runnable.h"
8
- #include "external_copy/external_copy.h"
9
- #include "scheduler.h"
10
- #include "lib/suspend.h"
11
- #include <algorithm>
12
- #include <chrono>
13
- #include <climits>
14
- #include <cmath>
15
- #include <cstdio>
16
- #include <memory>
17
- #include <mutex>
18
- #include <thread>
19
- #include <vector>
20
- #include "v8-platform.h"
21
- #include "v8.h"
22
-
23
- #if USE_CLOCK_THREAD_CPUTIME_ID
24
- #include <time.h>
25
- #endif
26
-
27
- #if defined __APPLE__
28
- #include <pthread.h>
29
- static auto GetStackBase() -> void* {
30
- pthread_t self = pthread_self();
31
- return (void*)((char*)pthread_get_stackaddr_np(self) - pthread_get_stacksize_np(self));
32
- }
33
- #elif defined __OpenBSD__
34
- #include <pthread_np.h>
35
- static auto GetStackBase() -> void* {
36
- pthread_t self = pthread_self();
37
- stack_t ss;
38
- void* base = nullptr;
39
- if (pthread_stackseg_np(self, &ss) == 0) {
40
- base = (void*)((char*)ss.ss_sp - ss.ss_size);
41
- }
42
- return base;
43
- }
44
- #elif defined __FreeBSD__
45
- #include <pthread_np.h>
46
- static auto GetStackBase() -> void* {
47
- pthread_t self = pthread_self();
48
- pthread_attr_t attrs;
49
- void* base = nullptr;
50
- if (pthread_attr_init(&attrs) == 0) {
51
- pthread_attr_get_np(self, &attrs);
52
- size_t size;
53
- pthread_attr_getstack(&attrs, &base, &size);
54
- pthread_attr_destroy(&attrs);
55
- }
56
- return base;
57
- }
58
- #elif defined __unix__
59
- static auto GetStackBase() -> void* {
60
- pthread_t self = pthread_self();
61
- pthread_attr_t attrs;
62
- pthread_getattr_np(self, &attrs);
63
- void* base;
64
- size_t size;
65
- pthread_attr_getstack(&attrs, &base, &size);
66
- return base;
67
- }
68
- #else
69
- static void* GetStackBase() {
70
- return nullptr;
71
- }
72
- #endif
73
-
74
- using namespace v8;
75
- using std::shared_ptr;
76
- using std::unique_ptr;
77
-
78
- namespace ivm {
79
-
80
- std::atomic<size_t> detail::IsolateSpecificSize{0};
81
- thread_suspend_handle::initialize suspend_init{};
82
-
83
- namespace {
84
- std::mutex isolate_allocator_mutex{};
85
- } // anonymous namespace
86
-
87
- /**
88
- * HeapCheck implementation
89
- */
90
- IsolateEnvironment::HeapCheck::HeapCheck(IsolateEnvironment& env, bool force) :
91
- env{env}, extra_size_before{env.extra_allocated_memory}, force{force} {
92
- }
93
-
94
- void IsolateEnvironment::HeapCheck::Epilogue() {
95
- if (!env.nodejs_isolate && (force || env.extra_allocated_memory != extra_size_before)) {
96
- Isolate* isolate = env.GetIsolate();
97
- HeapStatistics heap;
98
- isolate->GetHeapStatistics(&heap);
99
- if (heap.used_heap_size() + env.extra_allocated_memory > env.memory_limit) {
100
- isolate->LowMemoryNotification();
101
- isolate->GetHeapStatistics(&heap);
102
- if (heap.used_heap_size() + env.extra_allocated_memory > env.memory_limit) {
103
- env.hit_memory_limit = true;
104
- env.Terminate();
105
- throw FatalRuntimeError("Isolate was disposed during execution due to memory limit");
106
- }
107
- }
108
- }
109
- }
110
-
111
- /**
112
- * IsolateEnvironment implementation
113
- */
114
- void IsolateEnvironment::OOMErrorCallback(const char* location, bool is_heap_oom) {
115
- if (RaiseCatastrophicError(IsolateEnvironment::GetCurrent().error_handler, "Catastrophic out-of-memory error")) {
116
- while (true) {
117
- using namespace std::chrono_literals;
118
- std::this_thread::sleep_for(100s);
119
- }
120
- }
121
- fprintf(stderr, "%s\nis_heap_oom = %d\n\n\n", location, static_cast<int>(is_heap_oom));
122
- HeapStatistics heap;
123
- Isolate::GetCurrent()->GetHeapStatistics(&heap);
124
- fprintf(stderr,
125
- "<--- Heap statistics --->\n"
126
- "total_heap_size = %zd\n"
127
- "total_heap_size_executable = %zd\n"
128
- "total_physical_size = %zd\n"
129
- "total_available_size = %zd\n"
130
- "used_heap_size = %zd\n"
131
- "heap_size_limit = %zd\n"
132
- "malloced_memory = %zd\n"
133
- "peak_malloced_memory = %zd\n"
134
- "does_zap_garbage = %zd\n",
135
- heap.total_heap_size(),
136
- heap.total_heap_size_executable(),
137
- heap.total_physical_size(),
138
- heap.total_available_size(),
139
- heap.used_heap_size(),
140
- heap.heap_size_limit(),
141
- heap.malloced_memory(),
142
- heap.peak_malloced_memory(),
143
- heap.does_zap_garbage()
144
- );
145
- abort();
146
- }
147
-
148
- void IsolateEnvironment::PromiseRejectCallback(PromiseRejectMessage rejection) {
149
- auto& that = IsolateEnvironment::GetCurrent();
150
- assert(that.isolate == Isolate::GetCurrent());
151
- // TODO: Revisit this in version 4.x?
152
- auto event = rejection.GetEvent();
153
- if (event == kPromiseRejectWithNoHandler) {
154
- that.unhandled_promise_rejections.emplace_back(that.isolate, rejection.GetPromise());
155
- that.unhandled_promise_rejections.back().SetWeak();
156
- } else if (event == kPromiseHandlerAddedAfterReject) {
157
- that.PromiseWasHandled(rejection.GetPromise());
158
- }
159
- }
160
-
161
- void IsolateEnvironment::PromiseWasHandled(v8::Local<v8::Promise> promise) {
162
- for (auto& handle : unhandled_promise_rejections) {
163
- if (handle == promise) {
164
- handle.Reset();
165
- }
166
- }
167
- }
168
-
169
- auto IsolateEnvironment::CodeGenCallback(Local<Context> /*context*/, Local<Value> source) -> ModifyCodeGenerationFromStringsResult {
170
- auto& that = IsolateEnvironment::GetCurrent();
171
- // This heuristic could be improved by looking up how much `timeout` this isolate has left and
172
- // returning early in some cases
173
- ModifyCodeGenerationFromStringsResult result;
174
- if (source->IsString() && static_cast<size_t>(source.As<String>()->Length()) > static_cast<size_t>(that.memory_limit / 8)) {
175
- return result;
176
- }
177
- result.codegen_allowed = true;
178
- return result;
179
- }
180
-
181
- auto IsolateEnvironment::CodeGenCallback2(Local<Context> context, Local<Value> source, bool) -> ModifyCodeGenerationFromStringsResult {
182
- return CodeGenCallback(context, source);
183
- }
184
-
185
- void IsolateEnvironment::MarkSweepCompactEpilogue(Isolate* isolate, GCType /*gc_type*/, GCCallbackFlags gc_flags, void* data) {
186
- auto* that = static_cast<IsolateEnvironment*>(data);
187
- HeapStatistics heap;
188
- that->isolate->GetHeapStatistics(&heap);
189
- size_t total_memory = heap.used_heap_size() + that->extra_allocated_memory;
190
- size_t memory_limit = that->memory_limit + that->misc_memory_size;
191
- if (total_memory > memory_limit) {
192
- if ((gc_flags & (GCCallbackFlags::kGCCallbackFlagCollectAllAvailableGarbage | GCCallbackFlags::kGCCallbackFlagForced)) == 0) {
193
- // Force full garbage collection
194
- that->RequestMemoryPressureNotification(MemoryPressureLevel::kCritical);
195
- } else {
196
- that->Terminate();
197
- that->hit_memory_limit = true;
198
- }
199
- } else if ((gc_flags & GCCallbackFlags::kGCCallbackFlagCollectAllAvailableGarbage) == 0) {
200
- if (that->did_adjust_heap_limit) {
201
- // There is also `AutomaticallyRestoreInitialHeapLimit` introduced in v8 7.3.411 / 93283bf04
202
- // but it seems less effective than this ratcheting strategy.
203
- isolate->RemoveNearHeapLimitCallback(NearHeapLimitCallback, that->memory_limit);
204
- isolate->AddNearHeapLimitCallback(NearHeapLimitCallback, data);
205
- HeapStatistics heap;
206
- that->isolate->GetHeapStatistics(&heap);
207
- if (heap.heap_size_limit() == that->initial_heap_size_limit) {
208
- that->did_adjust_heap_limit = false;
209
- }
210
- }
211
- if (total_memory + total_memory / 4 > memory_limit) {
212
- // Send "moderate" pressure at 80%
213
- that->RequestMemoryPressureNotification(MemoryPressureLevel::kModerate);
214
- } else {
215
- that->RequestMemoryPressureNotification(MemoryPressureLevel::kNone);
216
- }
217
- return;
218
- }
219
- }
220
-
221
- auto IsolateEnvironment::NearHeapLimitCallback(void* data, size_t current_heap_limit, size_t /*initial_heap_limit*/) -> size_t {
222
- // This callback will temporarily give the v8 vm up to an extra 1 GB of memory to prevent the
223
- // application from crashing.
224
- auto* that = static_cast<IsolateEnvironment*>(data);
225
- that->did_adjust_heap_limit = true;
226
- HeapStatistics heap;
227
- that->isolate->GetHeapStatistics(&heap);
228
- if (heap.used_heap_size() + that->extra_allocated_memory > that->memory_limit + that->misc_memory_size) {
229
- that->RequestMemoryPressureNotification(MemoryPressureLevel::kCritical, true);
230
- } else {
231
- that->RequestMemoryPressureNotification(MemoryPressureLevel::kModerate, true);
232
- }
233
- return current_heap_limit + 1024 * 1024 * 1024;
234
- }
235
-
236
- void IsolateEnvironment::RequestMemoryPressureNotification(MemoryPressureLevel memory_pressure, bool as_interrupt) {
237
- this->memory_pressure = memory_pressure;
238
- if (as_interrupt) {
239
- if (memory_pressure > last_memory_pressure) {
240
- isolate->RequestInterrupt(MemoryPressureInterrupt, static_cast<void*>(this));
241
- }
242
- } else {
243
- CheckMemoryPressure();
244
- if (memory_pressure == MemoryPressureLevel::kCritical) {
245
- // Reentrant GC doesn't trigger callbacks
246
- MarkSweepCompactEpilogue(isolate, GCType::kGCTypeMarkSweepCompact, GCCallbackFlags::kGCCallbackFlagForced, reinterpret_cast<void*>(this));
247
- }
248
- }
249
- }
250
-
251
- void IsolateEnvironment::MemoryPressureInterrupt(Isolate* /*isolate*/, void* data) {
252
- static_cast<IsolateEnvironment*>(data)->CheckMemoryPressure();
253
- }
254
-
255
- void IsolateEnvironment::CheckMemoryPressure() {
256
- if (memory_pressure != last_memory_pressure) {
257
- if (memory_pressure > last_memory_pressure) {
258
- isolate->MemoryPressureNotification(memory_pressure);
259
- }
260
- last_memory_pressure = memory_pressure;
261
- }
262
- }
263
-
264
- void IsolateEnvironment::AsyncEntry() {
265
- Executor::Lock lock(*this);
266
- if (!nodejs_isolate) {
267
- // Set v8 stack limit on non-default isolate. This is only needed on non-default threads while
268
- // on OS X because it allocates just 512kb for each pthread stack, instead of 2mb on other
269
- // systems. 512kb is lower than the default v8 stack size so JS stack overflows result in
270
- // segfaults.
271
- thread_local void* stack_base = GetStackBase();
272
- if (stack_base != nullptr) {
273
- // Add 24kb of padding for native code to run
274
- isolate->SetStackLimit(reinterpret_cast<uintptr_t>(reinterpret_cast<char*>(stack_base) + 1024 * 24));
275
- }
276
- }
277
-
278
- while (true) {
279
- std::queue<unique_ptr<Runnable>> tasks;
280
- std::queue<unique_ptr<Runnable>> handle_tasks;
281
- std::queue<unique_ptr<Runnable>> interrupts;
282
- {
283
- // Grab current tasks
284
- auto lock = scheduler->Lock();
285
- tasks = ExchangeDefault(lock->tasks);
286
- handle_tasks = ExchangeDefault(lock->handle_tasks);
287
- interrupts = ExchangeDefault(lock->interrupts);
288
- if (tasks.empty() && handle_tasks.empty() && interrupts.empty()) {
289
- lock->DoneRunning();
290
- return;
291
- }
292
- }
293
-
294
- // Execute interrupt tasks
295
- while (!interrupts.empty()) {
296
- interrupts.front()->Run();
297
- interrupts.pop();
298
- }
299
-
300
- // Execute handle tasks
301
- while (!handle_tasks.empty()) {
302
- handle_tasks.front()->Run();
303
- handle_tasks.pop();
304
- }
305
-
306
- // Execute tasks
307
- while (!tasks.empty()) {
308
- tasks.front()->Run();
309
- tasks.pop();
310
- if (terminated) {
311
- return;
312
- }
313
- CheckMemoryPressure();
314
- }
315
- }
316
- }
317
-
318
- template <std::queue<std::unique_ptr<Runnable>> Scheduler::*Tasks>
319
- void IsolateEnvironment::InterruptEntryImplementation() {
320
- // Executor::Lock is already acquired
321
- while (true) {
322
- auto interrupts = [&]() {
323
- return ExchangeDefault((*scheduler->Lock()).*Tasks);
324
- }();
325
- if (interrupts.empty()) {
326
- return;
327
- }
328
- do {
329
- interrupts.front()->Run();
330
- interrupts.pop();
331
- } while (!interrupts.empty());
332
- }
333
- }
334
-
335
- void IsolateEnvironment::InterruptEntryAsync() {
336
- return InterruptEntryImplementation<&Scheduler::interrupts>();
337
- }
338
-
339
- void IsolateEnvironment::InterruptEntrySync() {
340
- return InterruptEntryImplementation<&Scheduler::sync_interrupts>();
341
- }
342
-
343
- IsolateEnvironment::IsolateEnvironment() :
344
- owned_isolates{std::make_unique<OwnedIsolates>()},
345
- scheduler{in_place<UvScheduler>{}, *this},
346
- executor{*this},
347
- nodejs_isolate{true} {}
348
-
349
-
350
- IsolateEnvironment::IsolateEnvironment(UvScheduler& default_scheduler) :
351
- scheduler{in_place<IsolatedScheduler>{}, *this, default_scheduler},
352
- executor{*this} {}
353
-
354
- void IsolateEnvironment::IsolateCtor(Isolate* isolate, Local<Context> context) {
355
- this->isolate = isolate;
356
- default_context.Reset(isolate, context);
357
- }
358
-
359
- void IsolateEnvironment::IsolateCtor(size_t memory_limit_in_mb, shared_ptr<v8::BackingStore> snapshot_blob, size_t snapshot_length) {
360
- memory_limit = memory_limit_in_mb * 1024 * 1024;
361
- allocator_ptr = std::make_shared<LimitedAllocator>(*this, memory_limit);
362
- snapshot_blob_ptr = std::move(snapshot_blob);
363
-
364
- // Calculate resource constraints
365
- ResourceConstraints rc;
366
- size_t young_space_in_kb = (size_t)std::pow(2, std::min(sizeof(void*) >= 8 ? 4.0 : 3.0, memory_limit_in_mb / 128.0) + 10);
367
- size_t old_generation_size_in_mb = memory_limit_in_mb;
368
- // TODO: Give `ConfigureDefaultsFromHeapSize` a try
369
- rc.set_max_young_generation_size_in_bytes(young_space_in_kb * 1024);
370
- rc.set_max_old_generation_size_in_bytes(old_generation_size_in_mb * 1024 * 1024);
371
-
372
- // Build isolate from create params
373
- Isolate::CreateParams create_params;
374
- create_params.constraints = rc;
375
- create_params.array_buffer_allocator_shared = allocator_ptr;
376
- if (snapshot_blob_ptr) {
377
- create_params.snapshot_blob = &startup_data;
378
- startup_data.data = reinterpret_cast<char*>(snapshot_blob_ptr->Data());
379
- startup_data.raw_size = snapshot_length;
380
- }
381
- task_runner = std::make_shared<IsolateTaskRunner>(holder.lock()->GetIsolate());
382
- {
383
- std::lock_guard allocator_lock{isolate_allocator_mutex};
384
- isolate = Isolate::Allocate();
385
- PlatformDelegate::RegisterIsolate(isolate, &*scheduler);
386
- }
387
- Isolate::Initialize(isolate, create_params);
388
-
389
- // Various callbacks
390
- isolate->SetOOMErrorHandler(OOMErrorCallback);
391
- isolate->SetPromiseRejectCallback(PromiseRejectCallback);
392
- isolate->SetModifyCodeGenerationFromStringsCallback(CodeGenCallback2);
393
-
394
- // Add GC callbacks
395
- isolate->AddGCEpilogueCallback(MarkSweepCompactEpilogue, static_cast<void*>(this), GCType::kGCTypeMarkSweepCompact);
396
- isolate->AddNearHeapLimitCallback(NearHeapLimitCallback, static_cast<void*>(this));
397
-
398
- // Heap statistics crushes down lots of different memory spaces into a single number. We note the
399
- // difference between the requested old space and v8's calculated heap size.
400
- HeapStatistics heap;
401
- isolate->GetHeapStatistics(&heap);
402
- initial_heap_size_limit = heap.heap_size_limit();
403
- misc_memory_size = heap.heap_size_limit() - memory_limit_in_mb * 1024 * 1024;
404
-
405
- // Create a default context for the library to use if needed
406
- {
407
- Locker locker(isolate);
408
- HandleScope handle_scope(isolate);
409
- default_context.Reset(isolate, NewContext());
410
- }
411
-
412
- // There is no asynchronous Isolate ctor so we should throw away thread specifics in case
413
- // the client always uses async methods
414
- isolate->DiscardThreadSpecificMetadata();
415
-
416
- // Save reference to this isolate in the default isolate
417
- Executor::GetDefaultEnvironment().owned_isolates->write()->insert({ dispose_wait, holder });
418
- }
419
-
420
- IsolateEnvironment::~IsolateEnvironment() {
421
- if (nodejs_isolate) {
422
- // Throw away all owned isolates when the root one dies
423
- auto isolates = *owned_isolates->read(); // copy
424
- for (const auto& handle : isolates) {
425
- auto ref = handle.holder.lock();
426
- if (ref) {
427
- ref->Dispose();
428
- }
429
- }
430
- for (const auto& handle : isolates) {
431
- handle.dispose_wait->Join();
432
- }
433
- } else {
434
- {
435
- // Grab local pointer to inspector agent with scheduler lock active
436
- auto agent_ptr = [&]() {
437
- auto lock = scheduler->Lock();
438
- return std::move(inspector_agent);
439
- }();
440
- // Now activate executor lock and invoke inspector agent's dtor
441
- Executor::Lock lock{*this};
442
- agent_ptr.reset();
443
- // Kill all weak persistents
444
- for (auto it = weak_persistents.begin(); it != weak_persistents.end(); ) {
445
- void(*fn)(void*) = it->second.first;
446
- void* param = it->second.second;
447
- ++it;
448
- fn(param);
449
- }
450
- assert(weak_persistents.empty());
451
- unhandled_promise_rejections.clear();
452
- // Destroy outstanding tasks. Do this here while the executor lock is up.
453
- auto scheduler_lock = scheduler->Lock();
454
- ExchangeDefault(scheduler_lock->interrupts);
455
- ExchangeDefault(scheduler_lock->sync_interrupts);
456
- ExchangeDefault(scheduler_lock->handle_tasks);
457
- ExchangeDefault(scheduler_lock->tasks);
458
- }
459
- {
460
- std::lock_guard allocator_lock{isolate_allocator_mutex};
461
- {
462
- // Dispose() will call destructors for external strings and array buffers, so this lock sets the
463
- // "current" isolate for those C++ dtors to function correctly without locking v8
464
- Executor::Scope lock{*this};
465
- isolate->Dispose();
466
- }
467
- // Unregister from Platform
468
- PlatformDelegate::UnregisterIsolate(isolate);
469
- }
470
- // Unreference from default isolate
471
- executor.default_executor.env.owned_isolates->write()->erase({ dispose_wait, holder });
472
- }
473
- // Send notification that this isolate is totally disposed
474
- dispose_wait->IsolateDidDispose();
475
- }
476
-
477
- static void DeserializeInternalFieldsCallback(Local<Object> /*holder*/, int /*index*/, StartupData /*payload*/, void* /*data*/) {
478
- }
479
-
480
- auto IsolateEnvironment::NewContext() -> Local<Context> {
481
- auto context =
482
- Context::New(isolate, nullptr, {}, {}, &DeserializeInternalFieldsCallback);
483
- context->AllowCodeGenerationFromStrings(false);
484
- // TODO (but I'm not going to do it): This causes a DCHECK failure in debug builds. Tested nodejs
485
- // v14.17.3 & v16.5.1.
486
- // context->SetErrorMessageForCodeGenerationFromStrings(StringTable::Get().codeGenerationError);
487
- return context;
488
- }
489
-
490
- auto IsolateEnvironment::TaskEpilogue() -> std::unique_ptr<ExternalCopy> {
491
- isolate->PerformMicrotaskCheckpoint();
492
- CheckMemoryPressure();
493
- if (hit_memory_limit) {
494
- throw FatalRuntimeError("Isolate was disposed during execution due to memory limit");
495
- }
496
- auto rejected_promises = std::exchange(unhandled_promise_rejections, {});
497
- for (auto& handle : rejected_promises) {
498
- if (!handle.IsEmpty()) {
499
- Context::Scope context_scope{DefaultContext()};
500
- return ExternalCopy::CopyThrownValue(Deref(handle)->Result());
501
- }
502
- }
503
- return {};
504
- }
505
-
506
- auto IsolateEnvironment::GetLimitedAllocator() const -> LimitedAllocator* {
507
- if (nodejs_isolate) {
508
- return nullptr;
509
- } else {
510
- return static_cast<LimitedAllocator*>(allocator_ptr.get());
511
- }
512
- }
513
-
514
- void IsolateEnvironment::EnableInspectorAgent() {
515
- inspector_agent = std::make_unique<InspectorAgent>(*this);
516
- }
517
-
518
- auto IsolateEnvironment::GetInspectorAgent() const -> InspectorAgent* {
519
- return inspector_agent.get();
520
- }
521
-
522
- auto IsolateEnvironment::GetCpuProfileManager() -> CpuProfileManager* {
523
- if (!cpu_profile_manager) {
524
- cpu_profile_manager = std::make_shared<CpuProfileManager>();
525
- }
526
- return cpu_profile_manager.get();
527
- }
528
-
529
- auto IsolateEnvironment::GetCpuTime() -> std::chrono::nanoseconds {
530
- std::lock_guard<std::mutex> lock(executor.timer_mutex);
531
- std::chrono::nanoseconds time = executor.cpu_time;
532
- if (executor.cpu_timer != nullptr) {
533
- time += executor.cpu_timer->Delta(lock);
534
- }
535
- return time;
536
- }
537
-
538
- auto IsolateEnvironment::GetWallTime() -> std::chrono::nanoseconds {
539
- std::lock_guard<std::mutex> lock(executor.timer_mutex);
540
- std::chrono::nanoseconds time = executor.wall_time;
541
- if (executor.wall_timer != nullptr) {
542
- time += executor.wall_timer->Delta(lock);
543
- }
544
- return time;
545
- }
546
-
547
- void IsolateEnvironment::Terminate() {
548
- assert(!nodejs_isolate);
549
- terminated = true;
550
-
551
- // Destroy inspector session
552
- {
553
- auto lock = scheduler->Lock();
554
- lock->CancelAsync();
555
- if (inspector_agent) {
556
- inspector_agent->Terminate();
557
- }
558
- }
559
-
560
- // Request interrupt to ensure execution is interrupted in race conditions
561
- isolate->RequestInterrupt([](Isolate* isolate, void* /* param */) {
562
- isolate->AddBeforeCallEnteredCallback([](Isolate* isolate) {
563
- isolate->TerminateExecution();
564
- });
565
- isolate->TerminateExecution();
566
- }, nullptr);
567
-
568
- // Throw away Holder reference
569
- auto ref = holder.lock();
570
- if (ref) {
571
- ref->isolate.write()->reset();
572
- }
573
- }
574
-
575
- void IsolateEnvironment::AddWeakCallback(Persistent<Value>* handle, void(*fn)(void*), void* param) {
576
- if (nodejs_isolate) {
577
- return;
578
- }
579
- auto it = weak_persistents.find(handle);
580
- if (it != weak_persistents.end()) {
581
- throw std::logic_error("Weak callback already added");
582
- }
583
- weak_persistents.insert(std::make_pair(handle, std::make_pair(fn, param)));
584
- }
585
-
586
- void IsolateEnvironment::RemoveWeakCallback(Persistent<Value>* handle) {
587
- if (nodejs_isolate) {
588
- return;
589
- }
590
- auto it = weak_persistents.find(handle);
591
- if (it == weak_persistents.end()) {
592
- throw std::logic_error("Weak callback doesn't exist");
593
- }
594
- weak_persistents.erase(it);
595
- }
596
-
597
- void AdjustRemotes(int delta) {
598
- IsolateEnvironment::GetCurrent().AdjustRemotes(delta);
599
- }
600
-
601
- auto RaiseCatastrophicError(RemoteHandle<Function>& handler, const char* message) -> bool {
602
- if (!handler) {
603
- return false;
604
- }
605
-
606
- class ErrorTask : public Task {
607
- public:
608
- explicit ErrorTask(const char* message, RemoteHandle<Function> handler) :
609
- message{message}, handler{std::move(handler)} {}
610
-
611
- void Run() final {
612
- auto* isolate = Isolate::GetCurrent();
613
- auto context = isolate->GetCurrentContext();
614
- auto fn = handler.Deref();
615
- Local<Value> argv[] = { HandleCast<Local<String>>(message) };
616
- Unmaybe(fn->Call(context, Undefined(isolate), 1, argv));
617
- }
618
-
619
- private:
620
- const char* message;
621
- RemoteHandle<Function> handler;
622
- };
623
- handler.GetIsolateHolder()->ScheduleTask(std::make_unique<ErrorTask>(message, handler), false, true);
624
- return true;
625
- }
626
-
627
- } // namespace ivm