Index: src/value-serializer.cc |
diff --git a/src/value-serializer.cc b/src/value-serializer.cc |
index 7b17275b014d5a9f210ad1d63e6fae134bddc840..b9471b84059c2d7d6c9eb903d108d7d98b3320ac 100644 |
--- a/src/value-serializer.cc |
+++ b/src/value-serializer.cc |
@@ -126,6 +126,8 @@ enum class SerializationTag : uint8_t { |
// wasmWireByteLength:uint32_t, then raw data |
// compiledDataLength:uint32_t, then raw data |
kWasmModule = 'W', |
+ // A wasm module object transfer. next value is its index. |
+ kWasmModuleTransfer = 'w', |
// The delegate is responsible for processing all following data. |
// This "escapes" to whatever wire format the delegate chooses. |
kHostObject = '\\', |
@@ -803,6 +805,18 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) { |
} |
Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) { |
+ if (delegate_ != nullptr) { |
+ Maybe<uint32_t> transfer_id = delegate_->GetWasmModuleTransferId( |
+ reinterpret_cast<v8::Isolate*>(isolate_), |
+ v8::Local<v8::WasmCompiledModule>::Cast(Utils::ToLocal(object))); |
+ uint32_t id = 0; |
+ if (transfer_id.To(&id)) { |
+ WriteTag(SerializationTag::kWasmModuleTransfer); |
+ WriteVarint<uint32_t>(id); |
+ return Just(true); |
+ } |
+ } |
+ |
Handle<WasmCompiledModule> compiled_part( |
WasmCompiledModule::cast(object->GetInternalField(0)), isolate_); |
WasmEncodingTag encoding_tag = WasmEncodingTag::kRawBytes; |
@@ -1054,6 +1068,18 @@ void ValueDeserializer::TransferArrayBuffer( |
} |
} |
+void ValueDeserializer::TransferWasmModule(uint32_t transfer_id, |
+ Handle<WasmModuleObject> module) { |
+ // We don't realistically expect too many wasm modules to be posted around. |
+ // See v8:6106 also. |
+ size_t necessary_size = Max(transferred_wasm_modules_.size(), |
+ static_cast<size_t>(transfer_id + 1)); |
+ if (transferred_wasm_modules_.size() < necessary_size) { |
+ transferred_wasm_modules_.resize(necessary_size); |
+ } |
+ transferred_wasm_modules_[transfer_id] = module; |
+} |
+ |
MaybeHandle<Object> ValueDeserializer::ReadObject() { |
MaybeHandle<Object> result = ReadObjectInternal(); |
@@ -1150,6 +1176,8 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() { |
} |
case SerializationTag::kWasmModule: |
return ReadWasmModule(); |
+ case SerializationTag::kWasmModuleTransfer: |
+ return ReadWasmModuleTransfer(); |
case SerializationTag::kHostObject: |
return ReadHostObject(); |
default: |
@@ -1595,8 +1623,27 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView( |
return typed_array; |
} |
+MaybeHandle<JSObject> ValueDeserializer::ReadWasmModuleTransfer() { |
+ if (FLAG_wasm_disable_structured_cloning || allow_inline_wasm()) { |
+ return MaybeHandle<JSObject>(); |
+ } |
+ |
+ uint32_t index = 0; |
+ if (ReadVarint<uint32_t>().To(&index) && |
+ index < transferred_wasm_modules_.size()) { |
+ Handle<JSObject> module = transferred_wasm_modules_[index]; |
+ uint32_t id = next_id_++; |
+ AddObjectWithID(id, module); |
+ return module; |
+ } else { |
+ return MaybeHandle<JSObject>(); |
+ } |
+} |
+ |
MaybeHandle<JSObject> ValueDeserializer::ReadWasmModule() { |
- if (FLAG_wasm_disable_structured_cloning) return MaybeHandle<JSObject>(); |
+ if (FLAG_wasm_disable_structured_cloning || !allow_inline_wasm()) { |
+ return MaybeHandle<JSObject>(); |
+ } |
Vector<const uint8_t> encoding_tag; |
if (!ReadRawBytes(sizeof(WasmEncodingTag)).To(&encoding_tag) || |
@@ -1625,21 +1672,22 @@ MaybeHandle<JSObject> ValueDeserializer::ReadWasmModule() { |
// Try to deserialize the compiled module first. |
ScriptData script_data(compiled_bytes.start(), compiled_bytes.length()); |
Handle<FixedArray> compiled_part; |
+ MaybeHandle<JSObject> result; |
if (WasmCompiledModuleSerializer::DeserializeWasmModule( |
isolate_, &script_data, wire_bytes) |
.ToHandle(&compiled_part)) { |
- return WasmModuleObject::New( |
+ result = WasmModuleObject::New( |
isolate_, Handle<WasmCompiledModule>::cast(compiled_part)); |
- } |
- |
- // If that fails, recompile. |
- MaybeHandle<JSObject> result; |
- { |
+ } else { |
wasm::ErrorThrower thrower(isolate_, "ValueDeserializer::ReadWasmModule"); |
result = wasm::SyncCompile(isolate_, &thrower, |
wasm::ModuleWireBytes(wire_bytes)); |
} |
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject); |
+ uint32_t id = next_id_++; |
+ if (!result.is_null()) { |
+ AddObjectWithID(id, result.ToHandleChecked()); |
+ } |
return result; |
} |