summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShu-yu Guo <syg@chromium.org>2023-05-08 23:46:39 -0700
committerGitHub <noreply@github.com>2023-05-09 06:46:39 +0000
commitb2f6eedb65cb9252879a7843ce43f3e3c5ff8da4 (patch)
treea4fb5d894b07ff53045d9ca5f4126355c837d348
parentbf8dd3f293acc913016ff20196a07a8d90860d63 (diff)
downloadnode-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.cc31
-rw-r--r--src/node_messaging.h4
-rw-r--r--test/parallel/test-experimental-shared-value-conveyor.js25
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);
+ }));
+}