Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: src/value-serializer.cc

Issue 2748473004: [wasm] Transferrable modules (Closed)
Patch Set: error cases Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/value-serializer.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/value-serializer.h" 5 #include "src/value-serializer.h"
6 6
7 #include <type_traits> 7 #include <type_traits>
8 8
9 #include "src/base/logging.h" 9 #include "src/base/logging.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 // ObjectReference to one) serialized just before it. This is a quirk arising 119 // ObjectReference to one) serialized just before it. This is a quirk arising
120 // from the previous stack-based implementation. 120 // from the previous stack-based implementation.
121 kArrayBufferView = 'V', 121 kArrayBufferView = 'V',
122 // Shared array buffer. transferID:uint32_t 122 // Shared array buffer. transferID:uint32_t
123 kSharedArrayBuffer = 'u', 123 kSharedArrayBuffer = 'u',
124 // Compiled WebAssembly module. encodingType:(one-byte tag). 124 // Compiled WebAssembly module. encodingType:(one-byte tag).
125 // If encodingType == 'y' (raw bytes): 125 // If encodingType == 'y' (raw bytes):
126 // wasmWireByteLength:uint32_t, then raw data 126 // wasmWireByteLength:uint32_t, then raw data
127 // compiledDataLength:uint32_t, then raw data 127 // compiledDataLength:uint32_t, then raw data
128 kWasmModule = 'W', 128 kWasmModule = 'W',
129 // A wasm module object transfer. next value is its index.
130 kWasmModuleTransfer = 'w',
129 // The delegate is responsible for processing all following data. 131 // The delegate is responsible for processing all following data.
130 // This "escapes" to whatever wire format the delegate chooses. 132 // This "escapes" to whatever wire format the delegate chooses.
131 kHostObject = '\\', 133 kHostObject = '\\',
132 }; 134 };
133 135
134 namespace { 136 namespace {
135 137
136 enum class ArrayBufferViewTag : uint8_t { 138 enum class ArrayBufferViewTag : uint8_t {
137 kInt8Array = 'b', 139 kInt8Array = 'b',
138 kUint8Array = 'B', 140 kUint8Array = 'B',
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 DCHECK(view->IsJSDataView()); 798 DCHECK(view->IsJSDataView());
797 tag = ArrayBufferViewTag::kDataView; 799 tag = ArrayBufferViewTag::kDataView;
798 } 800 }
799 WriteVarint(static_cast<uint8_t>(tag)); 801 WriteVarint(static_cast<uint8_t>(tag));
800 WriteVarint(NumberToUint32(view->byte_offset())); 802 WriteVarint(NumberToUint32(view->byte_offset()));
801 WriteVarint(NumberToUint32(view->byte_length())); 803 WriteVarint(NumberToUint32(view->byte_length()));
802 return ThrowIfOutOfMemory(); 804 return ThrowIfOutOfMemory();
803 } 805 }
804 806
805 Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) { 807 Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) {
808 if (delegate_ != nullptr) {
809 Maybe<uint32_t> transfer_id = delegate_->GetWasmModuleTransferId(
810 reinterpret_cast<v8::Isolate*>(isolate_),
811 v8::Local<v8::WasmCompiledModule>::Cast(Utils::ToLocal(object)));
812 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate_, Nothing<bool>());
813 uint32_t id = 0;
814 if (transfer_id.To(&id)) {
815 WriteTag(SerializationTag::kWasmModuleTransfer);
816 WriteVarint<uint32_t>(id);
817 return Just(true);
818 }
819 }
820
806 Handle<WasmCompiledModule> compiled_part( 821 Handle<WasmCompiledModule> compiled_part(
807 WasmCompiledModule::cast(object->GetEmbedderField(0)), isolate_); 822 WasmCompiledModule::cast(object->GetEmbedderField(0)), isolate_);
808 WasmEncodingTag encoding_tag = WasmEncodingTag::kRawBytes; 823 WasmEncodingTag encoding_tag = WasmEncodingTag::kRawBytes;
809 WriteTag(SerializationTag::kWasmModule); 824 WriteTag(SerializationTag::kWasmModule);
810 WriteRawBytes(&encoding_tag, sizeof(encoding_tag)); 825 WriteRawBytes(&encoding_tag, sizeof(encoding_tag));
811 826
812 Handle<String> wire_bytes(compiled_part->module_bytes(), isolate_); 827 Handle<String> wire_bytes(compiled_part->module_bytes(), isolate_);
813 int wire_bytes_length = wire_bytes->length(); 828 int wire_bytes_length = wire_bytes->length();
814 WriteVarint<uint32_t>(wire_bytes_length); 829 WriteVarint<uint32_t>(wire_bytes_length);
815 uint8_t* destination; 830 uint8_t* destination;
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 case SerializationTag::kArrayBufferTransfer: { 1158 case SerializationTag::kArrayBufferTransfer: {
1144 const bool is_shared = false; 1159 const bool is_shared = false;
1145 return ReadTransferredJSArrayBuffer(is_shared); 1160 return ReadTransferredJSArrayBuffer(is_shared);
1146 } 1161 }
1147 case SerializationTag::kSharedArrayBuffer: { 1162 case SerializationTag::kSharedArrayBuffer: {
1148 const bool is_shared = true; 1163 const bool is_shared = true;
1149 return ReadTransferredJSArrayBuffer(is_shared); 1164 return ReadTransferredJSArrayBuffer(is_shared);
1150 } 1165 }
1151 case SerializationTag::kWasmModule: 1166 case SerializationTag::kWasmModule:
1152 return ReadWasmModule(); 1167 return ReadWasmModule();
1168 case SerializationTag::kWasmModuleTransfer:
1169 return ReadWasmModuleTransfer();
1153 case SerializationTag::kHostObject: 1170 case SerializationTag::kHostObject:
1154 return ReadHostObject(); 1171 return ReadHostObject();
1155 default: 1172 default:
1156 // Before there was an explicit tag for host objects, all unknown tags 1173 // Before there was an explicit tag for host objects, all unknown tags
1157 // were delegated to the host. 1174 // were delegated to the host.
1158 if (version_ < 13) { 1175 if (version_ < 13) {
1159 position_--; 1176 position_--;
1160 return ReadHostObject(); 1177 return ReadHostObject();
1161 } 1178 }
1162 return MaybeHandle<Object>(); 1179 return MaybeHandle<Object>();
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 byte_length % element_size != 0) { 1605 byte_length % element_size != 0) {
1589 return MaybeHandle<JSArrayBufferView>(); 1606 return MaybeHandle<JSArrayBufferView>();
1590 } 1607 }
1591 Handle<JSTypedArray> typed_array = isolate_->factory()->NewJSTypedArray( 1608 Handle<JSTypedArray> typed_array = isolate_->factory()->NewJSTypedArray(
1592 external_array_type, buffer, byte_offset, byte_length / element_size, 1609 external_array_type, buffer, byte_offset, byte_length / element_size,
1593 pretenure_); 1610 pretenure_);
1594 AddObjectWithID(id, typed_array); 1611 AddObjectWithID(id, typed_array);
1595 return typed_array; 1612 return typed_array;
1596 } 1613 }
1597 1614
1615 MaybeHandle<JSObject> ValueDeserializer::ReadWasmModuleTransfer() {
1616 if (FLAG_wasm_disable_structured_cloning || expect_inline_wasm()) {
1617 return MaybeHandle<JSObject>();
1618 }
1619
1620 uint32_t transfer_id = 0;
1621 Local<Value> module_value;
1622 if (ReadVarint<uint32_t>().To(&transfer_id) && delegate_ != nullptr &&
1623 delegate_
1624 ->GetWasmModuleFromId(reinterpret_cast<v8::Isolate*>(isolate_),
1625 transfer_id)
1626 .ToLocal(&module_value)) {
1627 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject);
jbroman 2017/03/17 19:08:48 This should be in the false path. If an exception
Mircea Trofin 2017/03/17 22:16:48 Acknowledged.
1628 uint32_t id = next_id_++;
1629 Handle<JSObject> module =
1630 Handle<JSObject>::cast(Utils::OpenHandle(*module_value));
1631 AddObjectWithID(id, module);
1632 return module;
1633 } else {
1634 return MaybeHandle<JSObject>();
jbroman 2017/03/17 19:08:48 nit: this might be slightly clearer with early ret
Mircea Trofin 2017/03/17 22:16:48 Done.
1635 }
1636 }
1637
1598 MaybeHandle<JSObject> ValueDeserializer::ReadWasmModule() { 1638 MaybeHandle<JSObject> ValueDeserializer::ReadWasmModule() {
1599 if (FLAG_wasm_disable_structured_cloning) return MaybeHandle<JSObject>(); 1639 if (FLAG_wasm_disable_structured_cloning || !expect_inline_wasm()) {
1640 return MaybeHandle<JSObject>();
1641 }
1600 1642
1601 Vector<const uint8_t> encoding_tag; 1643 Vector<const uint8_t> encoding_tag;
1602 if (!ReadRawBytes(sizeof(WasmEncodingTag)).To(&encoding_tag) || 1644 if (!ReadRawBytes(sizeof(WasmEncodingTag)).To(&encoding_tag) ||
1603 encoding_tag[0] != static_cast<uint8_t>(WasmEncodingTag::kRawBytes)) { 1645 encoding_tag[0] != static_cast<uint8_t>(WasmEncodingTag::kRawBytes)) {
1604 return MaybeHandle<JSObject>(); 1646 return MaybeHandle<JSObject>();
1605 } 1647 }
1606 1648
1607 // Extract the data from the buffer: wasm wire bytes, followed by V8 compiled 1649 // Extract the data from the buffer: wasm wire bytes, followed by V8 compiled
1608 // script data. 1650 // script data.
1609 static_assert(sizeof(int) <= sizeof(uint32_t), 1651 static_assert(sizeof(int) <= sizeof(uint32_t),
1610 "max int must fit in uint32_t"); 1652 "max int must fit in uint32_t");
1611 const uint32_t max_valid_size = std::numeric_limits<int>::max(); 1653 const uint32_t max_valid_size = std::numeric_limits<int>::max();
1612 uint32_t wire_bytes_length = 0; 1654 uint32_t wire_bytes_length = 0;
1613 Vector<const uint8_t> wire_bytes; 1655 Vector<const uint8_t> wire_bytes;
1614 uint32_t compiled_bytes_length = 0; 1656 uint32_t compiled_bytes_length = 0;
1615 Vector<const uint8_t> compiled_bytes; 1657 Vector<const uint8_t> compiled_bytes;
1616 if (!ReadVarint<uint32_t>().To(&wire_bytes_length) || 1658 if (!ReadVarint<uint32_t>().To(&wire_bytes_length) ||
1617 wire_bytes_length > max_valid_size || 1659 wire_bytes_length > max_valid_size ||
1618 !ReadRawBytes(wire_bytes_length).To(&wire_bytes) || 1660 !ReadRawBytes(wire_bytes_length).To(&wire_bytes) ||
1619 !ReadVarint<uint32_t>().To(&compiled_bytes_length) || 1661 !ReadVarint<uint32_t>().To(&compiled_bytes_length) ||
1620 compiled_bytes_length > max_valid_size || 1662 compiled_bytes_length > max_valid_size ||
1621 !ReadRawBytes(compiled_bytes_length).To(&compiled_bytes)) { 1663 !ReadRawBytes(compiled_bytes_length).To(&compiled_bytes)) {
1622 return MaybeHandle<JSObject>(); 1664 return MaybeHandle<JSObject>();
1623 } 1665 }
1624 1666
1625 // Try to deserialize the compiled module first. 1667 // Try to deserialize the compiled module first.
1626 ScriptData script_data(compiled_bytes.start(), compiled_bytes.length()); 1668 ScriptData script_data(compiled_bytes.start(), compiled_bytes.length());
1627 Handle<FixedArray> compiled_part; 1669 Handle<FixedArray> compiled_part;
1670 MaybeHandle<JSObject> result;
1628 if (WasmCompiledModuleSerializer::DeserializeWasmModule( 1671 if (WasmCompiledModuleSerializer::DeserializeWasmModule(
1629 isolate_, &script_data, wire_bytes) 1672 isolate_, &script_data, wire_bytes)
1630 .ToHandle(&compiled_part)) { 1673 .ToHandle(&compiled_part)) {
1631 return WasmModuleObject::New( 1674 result = WasmModuleObject::New(
1632 isolate_, Handle<WasmCompiledModule>::cast(compiled_part)); 1675 isolate_, Handle<WasmCompiledModule>::cast(compiled_part));
1633 } 1676 } else {
1634
1635 // If that fails, recompile.
1636 MaybeHandle<JSObject> result;
1637 {
1638 wasm::ErrorThrower thrower(isolate_, "ValueDeserializer::ReadWasmModule"); 1677 wasm::ErrorThrower thrower(isolate_, "ValueDeserializer::ReadWasmModule");
1639 result = wasm::SyncCompile(isolate_, &thrower, 1678 result = wasm::SyncCompile(isolate_, &thrower,
1640 wasm::ModuleWireBytes(wire_bytes)); 1679 wasm::ModuleWireBytes(wire_bytes));
1641 } 1680 }
1642 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject); 1681 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject);
1682 uint32_t id = next_id_++;
1683 if (!result.is_null()) {
1684 AddObjectWithID(id, result.ToHandleChecked());
1685 }
1643 return result; 1686 return result;
1644 } 1687 }
1645 1688
1646 MaybeHandle<JSObject> ValueDeserializer::ReadHostObject() { 1689 MaybeHandle<JSObject> ValueDeserializer::ReadHostObject() {
1647 if (!delegate_) return MaybeHandle<JSObject>(); 1690 if (!delegate_) return MaybeHandle<JSObject>();
1648 STACK_CHECK(isolate_, MaybeHandle<JSObject>()); 1691 STACK_CHECK(isolate_, MaybeHandle<JSObject>());
1649 uint32_t id = next_id_++; 1692 uint32_t id = next_id_++;
1650 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_); 1693 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
1651 v8::Local<v8::Object> object; 1694 v8::Local<v8::Object> object;
1652 if (!delegate_->ReadHostObject(v8_isolate).ToLocal(&object)) { 1695 if (!delegate_->ReadHostObject(v8_isolate).ToLocal(&object)) {
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 if (stack.size() != 1) { 2012 if (stack.size() != 1) {
1970 isolate_->Throw(*isolate_->factory()->NewError( 2013 isolate_->Throw(*isolate_->factory()->NewError(
1971 MessageTemplate::kDataCloneDeserializationError)); 2014 MessageTemplate::kDataCloneDeserializationError));
1972 return MaybeHandle<Object>(); 2015 return MaybeHandle<Object>();
1973 } 2016 }
1974 return scope.CloseAndEscape(stack[0]); 2017 return scope.CloseAndEscape(stack[0]);
1975 } 2018 }
1976 2019
1977 } // namespace internal 2020 } // namespace internal
1978 } // namespace v8 2021 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.h ('k') | test/cctest/wasm/test-run-wasm-module.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698