diff options
author | Shu-yu Guo <syg@chromium.org> | 2023-05-08 23:46:39 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-09 06:46:39 +0000 |
commit | b2f6eedb65cb9252879a7843ce43f3e3c5ff8da4 (patch) | |
tree | a4fb5d894b07ff53045d9ca5f4126355c837d348 | |
parent | bf8dd3f293acc913016ff20196a07a8d90860d63 (diff) | |
download | node-new-b2f6eedb65cb9252879a7843ce43f3e3c5ff8da4.tar.gz |
src: support V8 experimental shared values in messaging
PR-URL: https://github.com/nodejs/node/pull/47706
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
-rw-r--r-- | src/node_messaging.cc | 31 | ||||
-rw-r--r-- | src/node_messaging.h | 4 | ||||
-rw-r--r-- | test/parallel/test-experimental-shared-value-conveyor.js | 25 |
3 files changed, 56 insertions, 4 deletions
diff --git a/src/node_messaging.cc b/src/node_messaging.cc index d7d5848bfb..19b393bb30 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -31,6 +31,7 @@ using v8::MaybeLocal; using v8::Nothing; using v8::Object; using v8::SharedArrayBuffer; +using v8::SharedValueConveyor; using v8::String; using v8::Symbol; using v8::Value; @@ -92,10 +93,12 @@ class DeserializerDelegate : public ValueDeserializer::Delegate { Environment* env, const std::vector<BaseObjectPtr<BaseObject>>& host_objects, const std::vector<Local<SharedArrayBuffer>>& shared_array_buffers, - const std::vector<CompiledWasmModule>& wasm_modules) + const std::vector<CompiledWasmModule>& wasm_modules, + const std::optional<SharedValueConveyor>& shared_value_conveyor) : host_objects_(host_objects), shared_array_buffers_(shared_array_buffers), - wasm_modules_(wasm_modules) {} + wasm_modules_(wasm_modules), + shared_value_conveyor_(shared_value_conveyor) {} MaybeLocal<Object> ReadHostObject(Isolate* isolate) override { // Identifying the index in the message's BaseObject array is sufficient. @@ -128,12 +131,18 @@ class DeserializerDelegate : public ValueDeserializer::Delegate { isolate, wasm_modules_[transfer_id]); } + const SharedValueConveyor* GetSharedValueConveyor(Isolate* isolate) override { + CHECK(shared_value_conveyor_.has_value()); + return &shared_value_conveyor_.value(); + } + ValueDeserializer* deserializer = nullptr; private: const std::vector<BaseObjectPtr<BaseObject>>& host_objects_; const std::vector<Local<SharedArrayBuffer>>& shared_array_buffers_; const std::vector<CompiledWasmModule>& wasm_modules_; + const std::optional<SharedValueConveyor>& shared_value_conveyor_; }; } // anonymous namespace @@ -198,8 +207,12 @@ MaybeLocal<Value> Message::Deserialize(Environment* env, shared_array_buffers.push_back(sab); } - DeserializerDelegate delegate( - this, env, host_objects, shared_array_buffers, wasm_modules_); + DeserializerDelegate delegate(this, + env, + host_objects, + shared_array_buffers, + wasm_modules_, + shared_value_conveyor_); ValueDeserializer deserializer( env->isolate(), reinterpret_cast<const uint8_t*>(main_message_buf_.data), @@ -243,6 +256,10 @@ uint32_t Message::AddWASMModule(CompiledWasmModule&& mod) { return wasm_modules_.size() - 1; } +void Message::AdoptSharedValueConveyor(SharedValueConveyor&& conveyor) { + shared_value_conveyor_.emplace(std::move(conveyor)); +} + namespace { MaybeLocal<Function> GetEmitMessageFunction(Local<Context> context) { @@ -347,6 +364,12 @@ class SerializerDelegate : public ValueSerializer::Delegate { return Just(msg_->AddWASMModule(module->GetCompiledModule())); } + bool AdoptSharedValueConveyor(Isolate* isolate, + SharedValueConveyor&& conveyor) override { + msg_->AdoptSharedValueConveyor(std::move(conveyor)); + return true; + } + Maybe<bool> Finish(Local<Context> context) { for (uint32_t i = 0; i < host_objects_.size(); i++) { BaseObjectPtr<BaseObject> host_object = std::move(host_objects_[i]); diff --git a/src/node_messaging.h b/src/node_messaging.h index 6b65d4523e..1c2a564d8d 100644 --- a/src/node_messaging.h +++ b/src/node_messaging.h @@ -88,6 +88,9 @@ class Message : public MemoryRetainer { // Internal method of Message that is called when a new WebAssembly.Module // object is encountered in the incoming value's structure. uint32_t AddWASMModule(v8::CompiledWasmModule&& mod); + // Internal method of Message that is called when a shared value is + // encountered for the first time in the incoming value's structure. + void AdoptSharedValueConveyor(v8::SharedValueConveyor&& conveyor); // The host objects that will be transferred, as recorded by Serialize() // (e.g. MessagePorts). @@ -114,6 +117,7 @@ class Message : public MemoryRetainer { std::vector<std::shared_ptr<v8::BackingStore>> shared_array_buffers_; std::vector<std::unique_ptr<TransferData>> transferables_; std::vector<v8::CompiledWasmModule> wasm_modules_; + std::optional<v8::SharedValueConveyor> shared_value_conveyor_; friend class MessagePort; }; diff --git a/test/parallel/test-experimental-shared-value-conveyor.js b/test/parallel/test-experimental-shared-value-conveyor.js new file mode 100644 index 0000000000..e61c5efebd --- /dev/null +++ b/test/parallel/test-experimental-shared-value-conveyor.js @@ -0,0 +1,25 @@ +'use strict'; + +// Flags: --harmony-struct + +const common = require('../common'); +const assert = require('assert'); +const { Worker, parentPort } = require('worker_threads'); + +// Do not use isMainThread so that this test itself can be run inside a Worker. +if (!process.env.HAS_STARTED_WORKER) { + process.env.HAS_STARTED_WORKER = 1; + const m = new globalThis.SharedArray(16); + + const worker = new Worker(__filename); + worker.once('message', common.mustCall((message) => { + assert.strictEqual(message, m); + })); + + worker.postMessage(m); +} else { + parentPort.once('message', common.mustCall((message) => { + // Simple echo. + parentPort.postMessage(message); + })); +} |