From cee0ba8326d436796fa59746c24592049ada362a Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Mon, 24 Apr 2023 11:15:07 -0700 Subject: [PATCH 1/5] src: support V8 experimental shared values in messaging --- src/node_messaging.cc | 31 +++++++++++++++++++++++++++---- src/node_messaging.h | 4 ++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/node_messaging.cc b/src/node_messaging.cc index b40868a1ceeff4..44519b57fabf0a 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>& host_objects, const std::vector>& shared_array_buffers, - const std::vector& wasm_modules) + const std::vector& wasm_modules, + const std::optional& 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 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>& host_objects_; const std::vector>& shared_array_buffers_; const std::vector& wasm_modules_; + const std::optional& shared_value_conveyor_; }; } // anonymous namespace @@ -198,8 +207,12 @@ MaybeLocal 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(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 GetEmitMessageFunction(Local 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 Finish(Local context) { for (uint32_t i = 0; i < host_objects_.size(); i++) { BaseObjectPtr host_object = std::move(host_objects_[i]); diff --git a/src/node_messaging.h b/src/node_messaging.h index 6b65d4523e6ac3..1c2a564d8d58e1 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> shared_array_buffers_; std::vector> transferables_; std::vector wasm_modules_; + std::optional shared_value_conveyor_; friend class MessagePort; }; From f02aad9fd8feb0f7040bbd294d0cfaa68e0272b0 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Tue, 2 May 2023 13:49:57 -0700 Subject: [PATCH 2/5] Add a test --- ...test-experimental-shared-value-conveyor.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/parallel/test-experimental-shared-value-conveyor.js 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 00000000000000..74d54d0de0acfc --- /dev/null +++ b/test/parallel/test-experimental-shared-value-conveyor.js @@ -0,0 +1,23 @@ +'use strict'; + +// Flags: --harmony-struct + +const common = require('../common'); +const assert = require('assert'); +const { Worker, isMainThread, parentPort } = require('worker_threads'); + +if (isMainThread) { + let m = new globalThis.SharedArray(16); + + let 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); + })); +} From edfb5d85c070d3b092a3cc647b7480c0e848137b Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Tue, 2 May 2023 14:14:40 -0700 Subject: [PATCH 3/5] Fix linter errors --- test/parallel/test-experimental-shared-value-conveyor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-experimental-shared-value-conveyor.js b/test/parallel/test-experimental-shared-value-conveyor.js index 74d54d0de0acfc..7f26e89855faa9 100644 --- a/test/parallel/test-experimental-shared-value-conveyor.js +++ b/test/parallel/test-experimental-shared-value-conveyor.js @@ -7,9 +7,9 @@ const assert = require('assert'); const { Worker, isMainThread, parentPort } = require('worker_threads'); if (isMainThread) { - let m = new globalThis.SharedArray(16); + const m = new globalThis.SharedArray(16); - let worker = new Worker(__filename); + const worker = new Worker(__filename); worker.once('message', common.mustCall((message) => { assert.strictEqual(message, m); })); From eeaf8430481a9e908e12e308d0dde84cbe260d36 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Fri, 5 May 2023 17:09:16 -0400 Subject: [PATCH 4/5] Update test/parallel/test-experimental-shared-value-conveyor.js Co-authored-by: Joyee Cheung --- test/parallel/test-experimental-shared-value-conveyor.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-experimental-shared-value-conveyor.js b/test/parallel/test-experimental-shared-value-conveyor.js index 7f26e89855faa9..620d5f9d939735 100644 --- a/test/parallel/test-experimental-shared-value-conveyor.js +++ b/test/parallel/test-experimental-shared-value-conveyor.js @@ -6,7 +6,9 @@ const common = require('../common'); const assert = require('assert'); const { Worker, isMainThread, parentPort } = require('worker_threads'); -if (isMainThread) { +// 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); From a0946e9158259499f6c9006675dc7d50f1fd27d8 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Fri, 5 May 2023 15:05:18 -0700 Subject: [PATCH 5/5] Quell linter --- test/parallel/test-experimental-shared-value-conveyor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-experimental-shared-value-conveyor.js b/test/parallel/test-experimental-shared-value-conveyor.js index 620d5f9d939735..e61c5efebd0eeb 100644 --- a/test/parallel/test-experimental-shared-value-conveyor.js +++ b/test/parallel/test-experimental-shared-value-conveyor.js @@ -4,7 +4,7 @@ const common = require('../common'); const assert = require('assert'); -const { Worker, isMainThread, parentPort } = require('worker_threads'); +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) {