mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
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>
This commit is contained in:
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
25
test/parallel/test-experimental-shared-value-conveyor.js
Normal file
25
test/parallel/test-experimental-shared-value-conveyor.js
Normal file
@@ -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);
|
||||
}));
|
||||
}
|
||||
Reference in New Issue
Block a user