@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,117 @@
1
+ #pragma once
2
+ #include <v8.h>
3
+ #include <atomic>
4
+ #include <cstdint>
5
+ #include <cstdlib>
6
+ #include <memory>
7
+ #include <vector>
8
+
9
+ #include "isolate/generic/array.h"
10
+ #include "isolate/allocator.h"
11
+ #include "isolate/transferable.h"
12
+ #include "isolate/util.h"
13
+ #include "lib/lockable.h"
14
+
15
+ namespace ivm {
16
+
17
+ using handle_vector_t = std::vector<v8::Local<v8::Value>>;
18
+ using transferable_vector_t = std::vector<std::unique_ptr<Transferable>>;
19
+ using array_buffer_vector_t = std::vector<std::unique_ptr<class ExternalCopyArrayBuffer>>;
20
+ using shared_buffer_vector_t = std::vector<std::unique_ptr<class ExternalCopySharedArrayBuffer>>;
21
+
22
+ class ExternalCopy : public Transferable {
23
+ public:
24
+ ExternalCopy() = default;
25
+ ExternalCopy(const ExternalCopy&) = delete;
26
+ auto operator= (const ExternalCopy&) = delete;
27
+ ~ExternalCopy() override;
28
+
29
+ /**
30
+ * `Copy` may throw a v8 exception if JSON.stringify(value) throws
31
+ */
32
+ static auto Copy(
33
+ v8::Local<v8::Value> value,
34
+ bool transfer_out = false,
35
+ ArrayRange transfer_list = {}
36
+ ) -> std::unique_ptr<ExternalCopy>;
37
+
38
+ /**
39
+ * If you give this a primitive v8::Value (except Symbol) it will return a ExternalCopy for you.
40
+ * Otherwise it returns nullptr. This is used to automatically move simple values between
41
+ * isolates where it is possible to do so perfectly.
42
+ */
43
+ static auto CopyIfPrimitive(v8::Local<v8::Value> value) -> std::unique_ptr<ExternalCopy>;
44
+ static auto CopyThrownValue(v8::Local<v8::Value> value) -> std::unique_ptr<ExternalCopy>;
45
+
46
+ static auto TotalExternalSize() -> int;
47
+
48
+ auto CopyIntoCheckHeap(bool transfer_in = false) -> v8::Local<v8::Value>;
49
+ virtual auto CopyInto(bool transfer_in = false) -> v8::Local<v8::Value> = 0;
50
+ auto Size() const -> int { return size; }
51
+ auto TransferIn() -> v8::Local<v8::Value> final { return CopyIntoCheckHeap(); }
52
+
53
+ protected:
54
+ explicit ExternalCopy(int size);
55
+ ExternalCopy(ExternalCopy&& that) noexcept;
56
+ auto operator= (ExternalCopy&& that) noexcept -> ExternalCopy&;
57
+
58
+ void UpdateSize(int size);
59
+
60
+ private:
61
+ int size = 0;
62
+ };
63
+
64
+ /**
65
+ * Base class for ArrayBuffer and SharedArrayBuffer
66
+ */
67
+ class ExternalCopyAnyBuffer : public ExternalCopy {
68
+ public:
69
+ explicit ExternalCopyAnyBuffer(std::shared_ptr<v8::BackingStore> backing_store) :
70
+ backing_store{std::move(backing_store)} {}
71
+ auto Acquire() const -> std::shared_ptr<v8::BackingStore> { return *backing_store.read(); }
72
+
73
+ protected:
74
+ lockable_t<std::shared_ptr<v8::BackingStore>> backing_store;
75
+ };
76
+
77
+ /**
78
+ * ArrayBuffer instances
79
+ */
80
+ class ExternalCopyArrayBuffer : public ExternalCopyAnyBuffer {
81
+ public:
82
+ using ExternalCopyAnyBuffer::ExternalCopyAnyBuffer;
83
+ ExternalCopyArrayBuffer(const void* data, size_t length);
84
+ explicit ExternalCopyArrayBuffer(v8::Local<v8::ArrayBuffer> handle);
85
+
86
+ static auto Transfer(v8::Local<v8::ArrayBuffer> handle) -> std::unique_ptr<ExternalCopyArrayBuffer>;
87
+ auto CopyInto(bool transfer_in = false) -> v8::Local<v8::Value> final;
88
+ };
89
+
90
+ /**
91
+ * SharedArrayBuffer instances
92
+ */
93
+ class ExternalCopySharedArrayBuffer : public ExternalCopyAnyBuffer {
94
+ public:
95
+ explicit ExternalCopySharedArrayBuffer(v8::Local<v8::SharedArrayBuffer> handle);
96
+
97
+ auto CopyInto(bool transfer_in = false) -> v8::Local<v8::Value> final;
98
+ };
99
+
100
+ /**
101
+ * All types of TypedArray views w/ underlying buffer handle
102
+ */
103
+ class ExternalCopyArrayBufferView : public ExternalCopy {
104
+ public:
105
+ enum class ViewType { Uint8, Uint8Clamped, Int8, Uint16, Int16, Uint32, Int32, Float32, Float64, BigInt64, BigUint64, DataView };
106
+
107
+ private:
108
+ std::unique_ptr<ExternalCopyAnyBuffer> buffer;
109
+ ViewType type;
110
+ size_t byte_offset, byte_length;
111
+
112
+ public:
113
+ ExternalCopyArrayBufferView(std::unique_ptr<ExternalCopyAnyBuffer> buffer, ViewType type, size_t byte_offset, size_t byte_length);
114
+ auto CopyInto(bool transfer_in = false) -> v8::Local<v8::Value> final;
115
+ };
116
+
117
+ } // namespace ivm
@@ -0,0 +1,85 @@
1
+ #include "serializer.h"
2
+ #include "isolate/allocator.h"
3
+
4
+ using namespace v8;
5
+ namespace ivm {
6
+
7
+ /**
8
+ * ExternalCopySerialized implementation
9
+ */
10
+ ExternalCopySerialized::ExternalCopySerialized(Local<Value> value, ArrayRange transfer_list) :
11
+ BaseSerializer{[&](ValueSerializer& serializer, Local<Context> context) {
12
+ // Mark ArrayBuffers as transferred, but don't actually transfer yet otherwise it will invalidate
13
+ // array views before they are transferred
14
+ int ii = 0;
15
+ for (auto handle : transfer_list) {
16
+ if (handle->IsArrayBuffer()) {
17
+ serializer.TransferArrayBuffer(ii++, handle.As<ArrayBuffer>());
18
+ } else {
19
+ throw RuntimeTypeError("Non-ArrayBuffer passed in `transferList`");
20
+ }
21
+ }
22
+
23
+ // Serialize object and save
24
+ serializer.WriteHeader();
25
+ Unmaybe(serializer.WriteValue(context, value));
26
+ }} {
27
+
28
+ // Transfer ArrayBuffers
29
+ for (auto handle : transfer_list) {
30
+ array_buffers.emplace_back(ExternalCopyArrayBuffer::Transfer(handle.As<ArrayBuffer>()));
31
+ }
32
+ }
33
+
34
+ auto ExternalCopySerialized::CopyInto(bool transfer_in) -> Local<Value> {
35
+ Local<Value> value;
36
+
37
+ Deserialize([&](ValueDeserializer& deserializer, Local<Context> context) {
38
+ // Transfer ArrayBuffers
39
+ for (unsigned ii = 0; ii < array_buffers.size(); ++ii) {
40
+ deserializer.TransferArrayBuffer(ii, array_buffers[ii]->CopyIntoCheckHeap(transfer_in).As<ArrayBuffer>());
41
+ }
42
+
43
+ // Deserialize object
44
+ Unmaybe(deserializer.ReadHeader(context));
45
+ return deserializer.ReadValue(context).ToLocal(&value);
46
+ });
47
+
48
+ return value;
49
+ }
50
+
51
+ /**
52
+ * SerializedVector implementation
53
+ */
54
+ SerializedVector::SerializedVector(const v8::FunctionCallbackInfo<v8::Value>& info) :
55
+ BaseSerializer([&](ValueSerializer& serializer, Local<Context> context) {
56
+ int length = info.Length();
57
+ serializer.WriteUint32(length);
58
+ for (int ii = 0; ii < length; ++ii) {
59
+ Unmaybe(serializer.WriteValue(context, info[ii]));
60
+ }
61
+ }) {}
62
+
63
+ auto SerializedVector::CopyIntoAsVector() -> std::vector<Local<Value>> {
64
+ std::vector<Local<Value>> result;
65
+ Deserialize([&](ValueDeserializer& deserializer, Local<Context> context) {
66
+ // Read length
67
+ uint32_t length;
68
+ Unmaybe(deserializer.ReadHeader(context));
69
+ if (!deserializer.ReadUint32(&length)) {
70
+ throw RuntimeGenericError("Invalid arguments payload");
71
+ }
72
+
73
+ // Read arguments
74
+ result.resize(length);
75
+ for (unsigned ii = 0; ii < length; ++ii) {
76
+ if (!deserializer.ReadValue(context).ToLocal(&result[ii])) {
77
+ return false;
78
+ }
79
+ }
80
+ return true;
81
+ });
82
+ return result;
83
+ }
84
+
85
+ } // namespace ivm
@@ -0,0 +1,136 @@
1
+ #pragma once
2
+ #include "external_copy.h"
3
+ #include "isolate/environment.h"
4
+ #include <deque>
5
+ #include <memory>
6
+ #include <vector>
7
+
8
+ namespace ivm {
9
+ namespace detail {
10
+
11
+ class SerializationDelegateBase {
12
+ public:
13
+ SerializationDelegateBase(
14
+ std::deque<std::unique_ptr<Transferable>>& transferables,
15
+ std::deque<v8::CompiledWasmModule>& wasm_modules
16
+ ) : transferables{transferables}, wasm_modules{wasm_modules} {}
17
+
18
+ protected:
19
+ std::deque<std::unique_ptr<Transferable>>& transferables;
20
+ std::deque<v8::CompiledWasmModule>& wasm_modules;
21
+ };
22
+
23
+ class SerializerDelegate : public SerializationDelegateBase, public v8::ValueSerializer::Delegate {
24
+ public:
25
+ using SerializationDelegateBase::SerializationDelegateBase;
26
+
27
+ void SetSerializer(v8::ValueSerializer* serializer) { this->serializer = serializer; }
28
+ void ThrowDataCloneError(v8::Local<v8::String> message) final;
29
+
30
+ auto GetSharedArrayBufferId(
31
+ v8::Isolate* isolate, v8::Local<v8::SharedArrayBuffer> shared_array_buffer) -> v8::Maybe<uint32_t> final;
32
+ auto GetWasmModuleTransferId(
33
+ v8::Isolate* isolate, v8::Local<v8::WasmModuleObject> module) -> v8::Maybe<uint32_t> final;
34
+ auto WriteHostObject(v8::Isolate* isolate, v8::Local<v8::Object> object) -> v8::Maybe<bool> final;
35
+
36
+ private:
37
+ v8::ValueSerializer* serializer = nullptr;
38
+ };
39
+
40
+ class DeserializerDelegate : public SerializationDelegateBase, public v8::ValueDeserializer::Delegate {
41
+ public:
42
+ using SerializationDelegateBase::SerializationDelegateBase;
43
+
44
+ void SetDeserializer(v8::ValueDeserializer* deserializer) { this->deserializer = deserializer; }
45
+
46
+ auto GetSharedArrayBufferFromId(
47
+ v8::Isolate* isolate, uint32_t clone_id) -> v8::MaybeLocal<v8::SharedArrayBuffer> final;
48
+ auto GetWasmModuleFromId(
49
+ v8::Isolate* isolate, uint32_t transfer_id) -> v8::MaybeLocal<v8::WasmModuleObject> final;
50
+ auto ReadHostObject(v8::Isolate* isolate) -> v8::MaybeLocal<v8::Object> final;
51
+
52
+ private:
53
+ v8::ValueDeserializer* deserializer = nullptr;
54
+ };
55
+
56
+ } // namespace detail
57
+
58
+ /**
59
+ * Abstract serializer which manages boilerplate and lifecycle management of the serialized blob
60
+ */
61
+ class BaseSerializer {
62
+ protected:
63
+ template <class Fn>
64
+ explicit BaseSerializer(Fn fn) {
65
+ // Initialize serializer and delegate
66
+ auto* isolate = v8::Isolate::GetCurrent();
67
+ auto context = isolate->GetCurrentContext();
68
+ detail::SerializerDelegate delegate{transferables, wasm_modules};
69
+ v8::ValueSerializer serializer{isolate, &delegate};
70
+ delegate.SetSerializer(&serializer);
71
+
72
+ // Run serialization
73
+ serializer.WriteHeader();
74
+ fn(serializer, context);
75
+
76
+ // Save to buffer
77
+ auto serialized_data = serializer.Release();
78
+ buffer = {serialized_data.first, std::free};
79
+ size = serialized_data.second;
80
+ }
81
+
82
+ template <class Fn>
83
+ auto Deserialize(Fn fn) {
84
+ // Initialize deserializer and delegate
85
+ auto* isolate = v8::Isolate::GetCurrent();
86
+ auto context = isolate->GetCurrentContext();
87
+ detail::DeserializerDelegate delegate{transferables, wasm_modules};
88
+ v8::ValueDeserializer deserializer{isolate, buffer.get(), size, &delegate};
89
+ delegate.SetDeserializer(&deserializer);
90
+
91
+ // Watch for allocation errors
92
+ auto* allocator = IsolateEnvironment::GetCurrent().GetLimitedAllocator();
93
+ int failures = allocator == nullptr ? 0 : allocator->GetFailureCount();
94
+ Unmaybe(deserializer.ReadHeader(context));
95
+
96
+ // Run implementation
97
+ if (!fn(deserializer, context)) {
98
+ // ValueDeserializer throws an unhelpful message when it fails to allocate an ArrayBuffer, so
99
+ // detect that case here and throw an appropriate message.
100
+ if (allocator != nullptr && allocator->GetFailureCount() != failures) {
101
+ throw RuntimeRangeError("Array buffer allocation failed");
102
+ } else {
103
+ throw RuntimeError();
104
+ }
105
+ }
106
+ }
107
+
108
+ private:
109
+ std::unique_ptr<uint8_t, decltype(std::free)*> buffer = {nullptr, std::free};
110
+ std::deque<std::unique_ptr<Transferable>> transferables;
111
+ std::deque<v8::CompiledWasmModule> wasm_modules;
112
+ size_t size;
113
+ };
114
+
115
+ /**
116
+ * Single serialized value compatible with `Transferable`
117
+ */
118
+ class ExternalCopySerialized : public BaseSerializer, public ExternalCopy {
119
+ public:
120
+ ExternalCopySerialized(v8::Local<v8::Value> value, ArrayRange transfer_list);
121
+ auto CopyInto(bool transfer_in = false) -> v8::Local<v8::Value> final;
122
+
123
+ private:
124
+ std::vector<std::unique_ptr<ExternalCopyArrayBuffer>> array_buffers;
125
+ };
126
+
127
+ class SerializedVector : public BaseSerializer {
128
+ public:
129
+ explicit SerializedVector(const v8::FunctionCallbackInfo<v8::Value>& info);
130
+ auto CopyIntoAsVector() -> std::vector<v8::Local<v8::Value>>;
131
+
132
+ private:
133
+ std::vector<std::unique_ptr<ExternalCopyArrayBuffer>> array_buffers;
134
+ };
135
+
136
+ } // namespace ivm
@@ -0,0 +1,73 @@
1
+ #include "serializer.h"
2
+ #include "isolate/functor_runners.h"
3
+ #include "module/transferable.h"
4
+
5
+ /**
6
+ * This file is compiled *without* runtime type information, which matches the nodejs binary and
7
+ * allows the serializer delegates to resolve correctly.
8
+ */
9
+
10
+ using namespace v8;
11
+
12
+ namespace ivm::detail {
13
+
14
+ void SerializerDelegate::ThrowDataCloneError(Local<String> message) {
15
+ Isolate::GetCurrent()->ThrowException(Exception::TypeError(message));
16
+ }
17
+
18
+ auto SerializerDelegate::GetSharedArrayBufferId(
19
+ Isolate* /*isolate*/, Local<SharedArrayBuffer> shared_array_buffer) -> Maybe<uint32_t> {
20
+ auto result = Nothing<uint32_t>();
21
+ detail::RunBarrier([&]() {
22
+ transferables.emplace_back(std::make_unique<ExternalCopySharedArrayBuffer>(shared_array_buffer));
23
+ result = Just<uint32_t>(transferables.size() - 1);
24
+ });
25
+ return result;
26
+ }
27
+
28
+ auto SerializerDelegate::GetWasmModuleTransferId(
29
+ Isolate* /*isolate*/, Local<WasmModuleObject> module) -> Maybe<uint32_t> {
30
+ auto result = Just<uint32_t>(wasm_modules.size());
31
+ wasm_modules.emplace_back(module->GetCompiledModule());
32
+ return result;
33
+ }
34
+
35
+ auto SerializerDelegate::WriteHostObject(Isolate* /*isolate*/, Local<Object> object) -> Maybe<bool> {
36
+ auto result = Nothing<bool>();
37
+ detail::RunBarrier([&]() {
38
+ serializer->WriteUint32(transferables.size());
39
+ transferables.emplace_back(TransferOut(object));
40
+ result = Just(true);
41
+ });
42
+ return result;
43
+ }
44
+
45
+ auto DeserializerDelegate::ReadHostObject(Isolate* /*isolate*/) -> MaybeLocal<Object> {
46
+ MaybeLocal<Object> result;
47
+ detail::RunBarrier([&]() {
48
+ uint32_t ii;
49
+ assert(deserializer->ReadUint32(&ii));
50
+ result = transferables[ii]->TransferIn().As<Object>();
51
+ });
52
+ return result;
53
+ }
54
+
55
+ auto DeserializerDelegate::GetSharedArrayBufferFromId(
56
+ Isolate* /*isolate*/, uint32_t clone_id) -> MaybeLocal<SharedArrayBuffer> {
57
+ MaybeLocal<SharedArrayBuffer> result;
58
+ detail::RunBarrier([&]() {
59
+ result = transferables[clone_id]->TransferIn().As<SharedArrayBuffer>();
60
+ });
61
+ return result;
62
+ }
63
+
64
+ auto DeserializerDelegate::GetWasmModuleFromId(
65
+ Isolate* isolate, uint32_t transfer_id) -> MaybeLocal<WasmModuleObject> {
66
+ MaybeLocal<WasmModuleObject> result;
67
+ detail::RunBarrier([&]() {
68
+ result = WasmModuleObject::FromCompiledModule(isolate, wasm_modules[transfer_id]);
69
+ });
70
+ return result;
71
+ }
72
+
73
+ } // namespace ivm::detail
@@ -0,0 +1,124 @@
1
+ #include "isolate/environment.h"
2
+ #include "./string.h"
3
+ #include <cstring>
4
+
5
+ using namespace v8;
6
+
7
+ namespace ivm {
8
+ namespace {
9
+
10
+ /**
11
+ * Helper classes passed to v8 so we can reuse the same externally allocated memory for strings
12
+ * between different isolates
13
+ */
14
+ class ExternalString final : public v8::String::ExternalStringResource {
15
+ public:
16
+ explicit ExternalString(std::shared_ptr<std::vector<char>> value) : value{std::move(value)} {
17
+ IsolateEnvironment::GetCurrent().AdjustExtraAllocatedMemory(this->value->size());
18
+ }
19
+
20
+ ExternalString(const ExternalString&) = delete;
21
+
22
+ ~ExternalString() final {
23
+ auto* environment = Executor::GetCurrentEnvironment();
24
+ if (environment != nullptr) {
25
+ environment->AdjustExtraAllocatedMemory(-static_cast<int>(this->value->size()));
26
+ }
27
+ }
28
+
29
+ auto operator= (const ExternalString&) = delete;
30
+
31
+ auto data() const -> const uint16_t* final {
32
+ return reinterpret_cast<uint16_t*>(value->data());
33
+ }
34
+
35
+ auto length() const -> size_t final {
36
+ return value->size() >> 1;
37
+ }
38
+
39
+ private:
40
+ std::shared_ptr<std::vector<char>> value;
41
+ };
42
+
43
+ class ExternalStringOneByte final : public v8::String::ExternalOneByteStringResource {
44
+ public:
45
+ explicit ExternalStringOneByte(std::shared_ptr<std::vector<char>> value) : value{std::move(value)} {
46
+ IsolateEnvironment::GetCurrent().AdjustExtraAllocatedMemory(this->value->size());
47
+ }
48
+
49
+ ExternalStringOneByte(const ExternalStringOneByte&) = delete;
50
+
51
+ ~ExternalStringOneByte() final {
52
+ auto* environment = Executor::GetCurrentEnvironment();
53
+ if (environment != nullptr) {
54
+ environment->AdjustExtraAllocatedMemory(-static_cast<int>(this->value->size()));
55
+ }
56
+ }
57
+
58
+ auto operator= (const ExternalStringOneByte&) = delete;
59
+
60
+ auto data() const -> const char* final {
61
+ return value->data();
62
+ }
63
+
64
+ auto length() const -> size_t final {
65
+ return value->size();
66
+ }
67
+
68
+ private:
69
+ std::shared_ptr<std::vector<char>> value;
70
+ };
71
+
72
+ } // anonymous namespace
73
+
74
+ /**
75
+ * ExternalCopyString implementation
76
+ */
77
+ ExternalCopyString::ExternalCopyString(Local<String> string) :
78
+ ExternalCopy{static_cast<int>((string->Length() << (string->IsOneByte() ? 0 : 1)) + sizeof(ExternalCopyString))} {
79
+ if (string->IsOneByte()) {
80
+ one_byte = true;
81
+ value = std::make_shared<std::vector<char>>(string->Length());
82
+ string->WriteOneByte(
83
+ Isolate::GetCurrent(),
84
+ reinterpret_cast<uint8_t*>(value->data()), 0, -1, String::WriteOptions::NO_NULL_TERMINATION
85
+ );
86
+ } else {
87
+ one_byte = false;
88
+ value = std::make_shared<std::vector<char>>(string->Length() << 1);
89
+ string->Write(
90
+ Isolate::GetCurrent(),
91
+ reinterpret_cast<uint16_t*>(value->data()), 0, -1, String::WriteOptions::NO_NULL_TERMINATION
92
+ );
93
+ }
94
+ }
95
+
96
+ ExternalCopyString::ExternalCopyString(const char* string) :
97
+ value{std::make_shared<std::vector<char>>(string, string + strlen(string))}, one_byte{true} {}
98
+
99
+ ExternalCopyString::ExternalCopyString(const std::string& string) :
100
+ value{std::make_shared<std::vector<char>>(string.begin(), string.end())}, one_byte{true} {}
101
+
102
+ auto ExternalCopyString::CopyInto(bool /*transfer_in*/) -> Local<Value> {
103
+ if (value->size() < 1024) {
104
+ // Strings under 1kb will be internal v8 strings. I didn't experiment with this at all, but it
105
+ // seems self-evident that there's some byte length under which it doesn't make sense to create
106
+ // an external string so I picked 1kb.
107
+ if (one_byte) {
108
+ return Unmaybe(String::NewFromOneByte(Isolate::GetCurrent(),
109
+ reinterpret_cast<uint8_t*>(value->data()), NewStringType::kNormal, value->size()));
110
+ } else {
111
+ return Unmaybe(String::NewFromTwoByte(Isolate::GetCurrent(),
112
+ reinterpret_cast<uint16_t*>(value->data()), NewStringType::kNormal, value->size() >> 1));
113
+ }
114
+ } else {
115
+ // External strings can save memory and/or copies
116
+ if (one_byte) {
117
+ return Unmaybe(String::NewExternalOneByte(Isolate::GetCurrent(), new ExternalStringOneByte(value)));
118
+ } else {
119
+ return Unmaybe(String::NewExternalTwoByte(Isolate::GetCurrent(), new ExternalString(value)));
120
+ }
121
+ }
122
+ }
123
+
124
+ } // namespace ivm
@@ -0,0 +1,28 @@
1
+ #pragma once
2
+ #include "external_copy.h"
3
+ #include <memory>
4
+ #include <vector>
5
+
6
+ namespace ivm {
7
+
8
+ class ExternalCopyString final : public ExternalCopy {
9
+ public:
10
+ ExternalCopyString() = default;
11
+ explicit ExternalCopyString(v8::Local<v8::String> string);
12
+ explicit ExternalCopyString(const char* string);
13
+ explicit ExternalCopyString(const std::string& string);
14
+ ExternalCopyString(const ExternalCopyString&) = delete;
15
+ ExternalCopyString(ExternalCopyString&& that) = default;
16
+ ~ExternalCopyString() final = default;
17
+ auto operator= (const ExternalCopyString&) -> ExternalCopyString& = delete;
18
+ auto operator= (ExternalCopyString&& that) noexcept -> ExternalCopyString& = default;
19
+
20
+ explicit operator bool() const { return static_cast<bool>(value); }
21
+ auto CopyInto(bool transfer_in = false) -> v8::Local<v8::Value> final;
22
+
23
+ private:
24
+ std::shared_ptr<std::vector<char>> value;
25
+ bool one_byte = false;
26
+ };
27
+
28
+ } // namespace ivm
@@ -0,0 +1,32 @@
1
+ #pragma once
2
+ #include <v8.h>
3
+ #include <memory>
4
+ #include "v8_version.h"
5
+
6
+ namespace ivm {
7
+
8
+ class LimitedAllocator : public v8::ArrayBuffer::Allocator {
9
+ private:
10
+ class IsolateEnvironment& env;
11
+ size_t limit;
12
+ size_t v8_heap;
13
+ size_t next_check;
14
+ int failures = 0;
15
+
16
+
17
+ public:
18
+ auto Check(size_t length) -> bool;
19
+ explicit LimitedAllocator(class IsolateEnvironment& env, size_t limit);
20
+ auto Allocate(size_t length) -> void* final;
21
+ auto AllocateUninitialized(size_t length) -> void* final;
22
+ void Free(void* data, size_t length) final;
23
+ auto Reallocate(void* data, size_t old_length, size_t new_length) -> void* final;
24
+
25
+ // This is used by ExternalCopy when an ArrayBuffer is transferred. The memory is not freed but
26
+ // we should no longer count it against the isolate
27
+ void AdjustAllocatedSize(ptrdiff_t length);
28
+ auto GetFailureCount() const -> int;
29
+ void Track(v8::Local<v8::Object> handle, size_t size);
30
+ };
31
+
32
+ } // namespace ivm