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

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2392943006: [wasm] Implement importing of WebAssembly.Memory. (Closed)
Patch Set: Address review comments Created 4 years, 2 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/wasm/wasm-js.cc ('k') | test/mjsunit/wasm/import-memory.js » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 <memory> 5 #include <memory>
6 6
7 #include "src/base/atomic-utils.h" 7 #include "src/base/atomic-utils.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 9
10 #include "src/macro-assembler.h" 10 #include "src/macro-assembler.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 kInternalModuleInstance, 46 kInternalModuleInstance,
47 kInternalArity, 47 kInternalArity,
48 kInternalSignature 48 kInternalSignature
49 }; 49 };
50 50
51 // Internal constants for the layout of the module object. 51 // Internal constants for the layout of the module object.
52 enum WasmInstanceObjectFields { 52 enum WasmInstanceObjectFields {
53 kWasmCompiledModule = 0, 53 kWasmCompiledModule = 0,
54 kWasmModuleFunctionTable, 54 kWasmModuleFunctionTable,
55 kWasmModuleCodeTable, 55 kWasmModuleCodeTable,
56 kWasmMemObject,
56 kWasmMemArrayBuffer, 57 kWasmMemArrayBuffer,
57 kWasmGlobalsArrayBuffer, 58 kWasmGlobalsArrayBuffer,
58 kWasmDebugInfo, 59 kWasmDebugInfo,
59 kWasmModuleInternalFieldCount 60 kWasmModuleInternalFieldCount
60 }; 61 };
61 62
62 enum WasmImportData { 63 enum WasmImportData {
63 kImportKind, // Smi. an ExternalKind 64 kImportKind, // Smi. an ExternalKind
64 kImportGlobalType, // Smi. Type for globals. 65 kImportGlobalType, // Smi. Type for globals.
65 kImportIndex, // Smi. index for the import. 66 kImportIndex, // Smi. index for the import.
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 } 1237 }
1237 1238
1238 //-------------------------------------------------------------------------- 1239 //--------------------------------------------------------------------------
1239 // Allocate the instance object. 1240 // Allocate the instance object.
1240 //-------------------------------------------------------------------------- 1241 //--------------------------------------------------------------------------
1241 Handle<Map> map = factory->NewMap( 1242 Handle<Map> map = factory->NewMap(
1242 JS_OBJECT_TYPE, 1243 JS_OBJECT_TYPE,
1243 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1244 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1244 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED); 1245 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED);
1245 instance->SetInternalField(kWasmModuleCodeTable, *code_table); 1246 instance->SetInternalField(kWasmModuleCodeTable, *code_table);
1247 instance->SetInternalField(kWasmMemObject, *factory->undefined_value());
1248
1249 //--------------------------------------------------------------------------
1250 // Set up the globals for the new instance.
1251 //--------------------------------------------------------------------------
1252 MaybeHandle<JSArrayBuffer> old_globals;
1253 MaybeHandle<JSArrayBuffer> globals;
1254 uint32_t globals_size = compiled_module_->globals_size();
1255 if (globals_size > 0) {
1256 Handle<JSArrayBuffer> global_buffer =
1257 NewArrayBuffer(isolate_, globals_size);
1258 globals = global_buffer;
1259 if (globals.is_null()) {
1260 thrower_->Error("Out of memory: wasm globals");
1261 return nothing;
1262 }
1263 Address old_address =
1264 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate(
1265 *factory->undefined_value(),
1266 JSObject::cast(*owner));
1267 RelocateGlobals(instance, old_address,
1268 static_cast<Address>(global_buffer->backing_store()));
1269 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer);
1270 }
1271
1272 //--------------------------------------------------------------------------
1273 // Process the imports for the module.
1274 //--------------------------------------------------------------------------
1275 int num_imported_functions = ProcessImports(globals, code_table, instance);
1276 if (num_imported_functions < 0) return nothing;
1246 1277
1247 //-------------------------------------------------------------------------- 1278 //--------------------------------------------------------------------------
1248 // Set up the memory for the new instance. 1279 // Set up the memory for the new instance.
1249 //-------------------------------------------------------------------------- 1280 //--------------------------------------------------------------------------
1250 MaybeHandle<JSArrayBuffer> old_memory; 1281 MaybeHandle<JSArrayBuffer> old_memory;
1251 // TODO(titzer): handle imported memory properly. 1282 // TODO(titzer): handle imported memory properly.
1252 1283
1253 uint32_t min_mem_pages = compiled_module_->min_memory_pages(); 1284 uint32_t min_mem_pages = compiled_module_->min_memory_pages();
1254 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); 1285 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages);
1255 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. 1286 // TODO(wasm): re-enable counter for max_mem_pages when we use that field.
(...skipping 16 matching lines...) Expand all
1272 Address old_mem_start = 1303 Address old_mem_start =
1273 compiled_module_->has_heap() 1304 compiled_module_->has_heap()
1274 ? static_cast<Address>(compiled_module_->heap()->backing_store()) 1305 ? static_cast<Address>(compiled_module_->heap()->backing_store())
1275 : nullptr; 1306 : nullptr;
1276 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, 1307 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size,
1277 mem_size); 1308 mem_size);
1278 compiled_module_->set_heap(memory_); 1309 compiled_module_->set_heap(memory_);
1279 } 1310 }
1280 1311
1281 //-------------------------------------------------------------------------- 1312 //--------------------------------------------------------------------------
1282 // Set up the globals for the new instance.
1283 //--------------------------------------------------------------------------
1284 MaybeHandle<JSArrayBuffer> old_globals;
1285 MaybeHandle<JSArrayBuffer> globals;
1286 uint32_t globals_size = compiled_module_->globals_size();
1287 if (globals_size > 0) {
1288 Handle<JSArrayBuffer> global_buffer =
1289 NewArrayBuffer(isolate_, globals_size);
1290 globals = global_buffer;
1291 if (globals.is_null()) {
1292 thrower_->Error("Out of memory: wasm globals");
1293 return nothing;
1294 }
1295 Address old_address =
1296 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate(
1297 *factory->undefined_value(),
1298 JSObject::cast(*owner));
1299 RelocateGlobals(instance, old_address,
1300 static_cast<Address>(global_buffer->backing_store()));
1301 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer);
1302 }
1303
1304 //--------------------------------------------------------------------------
1305 // Process the imports for the module.
1306 //--------------------------------------------------------------------------
1307 int num_imported_functions = ProcessImports(globals, code_table);
1308 if (num_imported_functions < 0) return nothing;
1309
1310 //--------------------------------------------------------------------------
1311 // Process the initialization for the module's globals. 1313 // Process the initialization for the module's globals.
1312 //-------------------------------------------------------------------------- 1314 //--------------------------------------------------------------------------
1313 ProcessInits(globals); 1315 ProcessInits(globals);
1314 1316
1315 //-------------------------------------------------------------------------- 1317 //--------------------------------------------------------------------------
1316 // Set up the runtime support for the new instance. 1318 // Set up the runtime support for the new instance.
1317 //-------------------------------------------------------------------------- 1319 //--------------------------------------------------------------------------
1318 Handle<WeakCell> weak_link = factory->NewWeakCell(instance); 1320 Handle<WeakCell> weak_link = factory->NewWeakCell(instance);
1319 1321
1320 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs; 1322 for (int i = num_imported_functions + FLAG_skip_compiling_wasm_funcs;
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1619 break; 1621 break;
1620 default: 1622 default:
1621 UNREACHABLE(); 1623 UNREACHABLE();
1622 } 1624 }
1623 } 1625 }
1624 1626
1625 // Process the imports, including functions, tables, globals, and memory, in 1627 // Process the imports, including functions, tables, globals, and memory, in
1626 // order, loading them from the {ffi_} object. Returns the number of imported 1628 // order, loading them from the {ffi_} object. Returns the number of imported
1627 // functions. 1629 // functions.
1628 int ProcessImports(MaybeHandle<JSArrayBuffer> globals, 1630 int ProcessImports(MaybeHandle<JSArrayBuffer> globals,
1629 Handle<FixedArray> code_table) { 1631 Handle<FixedArray> code_table, Handle<JSObject> instance) {
1630 int num_imported_functions = 0; 1632 int num_imported_functions = 0;
1631 if (!compiled_module_->has_imports()) return num_imported_functions; 1633 if (!compiled_module_->has_imports()) return num_imported_functions;
1632 1634
1633 Handle<FixedArray> imports = compiled_module_->imports(); 1635 Handle<FixedArray> imports = compiled_module_->imports();
1634 for (int index = 0; index < imports->length(); ++index) { 1636 for (int index = 0; index < imports->length(); ++index) {
1635 Handle<FixedArray> data = 1637 Handle<FixedArray> data =
1636 imports->GetValueChecked<FixedArray>(isolate_, index); 1638 imports->GetValueChecked<FixedArray>(isolate_, index);
1637 1639
1638 Handle<String> module_name = 1640 Handle<String> module_name =
1639 data->GetValueChecked<String>(isolate_, kModuleName); 1641 data->GetValueChecked<String>(isolate_, kModuleName);
(...skipping 21 matching lines...) Expand all
1661 function_name); 1663 function_name);
1662 int func_index = Smi::cast(data->get(kImportIndex))->value(); 1664 int func_index = Smi::cast(data->get(kImportIndex))->value();
1663 code_table->set(func_index, *import_wrapper); 1665 code_table->set(func_index, *import_wrapper);
1664 RecordStats(isolate_, *import_wrapper); 1666 RecordStats(isolate_, *import_wrapper);
1665 num_imported_functions++; 1667 num_imported_functions++;
1666 break; 1668 break;
1667 } 1669 }
1668 case kExternalTable: 1670 case kExternalTable:
1669 // TODO(titzer): Table imports must be a WebAssembly.Table. 1671 // TODO(titzer): Table imports must be a WebAssembly.Table.
1670 break; 1672 break;
1671 case kExternalMemory: 1673 case kExternalMemory: {
1672 // TODO(titzer): Memory imports must be a WebAssembly.Memory. 1674 Handle<Object> object = result.ToHandleChecked();
1675 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) {
1676 ReportFFIError("memory import must be a WebAssembly.Memory object",
1677 index, module_name, function_name);
1678 return -1;
1679 }
1680 instance->SetInternalField(kWasmMemObject, *object);
1681 memory_ = WasmJs::GetWasmMemoryArrayBuffer(isolate_, object);
1673 break; 1682 break;
1683 }
1674 case kExternalGlobal: { 1684 case kExternalGlobal: {
1675 // Global imports are converted to numbers and written into the 1685 // Global imports are converted to numbers and written into the
1676 // {globals} array buffer. 1686 // {globals} array buffer.
1677 Handle<Object> object = result.ToHandleChecked(); 1687 Handle<Object> object = result.ToHandleChecked();
1678 MaybeHandle<Object> number = Object::ToNumber(object); 1688 MaybeHandle<Object> number = Object::ToNumber(object);
1679 if (number.is_null()) { 1689 if (number.is_null()) {
1680 ReportFFIError("global import could not be converted to number", 1690 ReportFFIError("global import could not be converted to number",
1681 index, module_name, function_name); 1691 index, module_name, function_name);
1682 return -1; 1692 return -1;
1683 } 1693 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 export_data->GetValue<ByteArray>(isolate_, kExportedSignature); 1790 export_data->GetValue<ByteArray>(isolate_, kExportedSignature);
1781 desc.set_value(WrapExportCodeAsJSFunction( 1791 desc.set_value(WrapExportCodeAsJSFunction(
1782 isolate_, export_code, name, arity, signature, instance)); 1792 isolate_, export_code, name, arity, signature, instance));
1783 break; 1793 break;
1784 } 1794 }
1785 case kExternalTable: 1795 case kExternalTable:
1786 // TODO(titzer): create a WebAssembly.Table instance. 1796 // TODO(titzer): create a WebAssembly.Table instance.
1787 // TODO(titzer): should it have the same identity as an import? 1797 // TODO(titzer): should it have the same identity as an import?
1788 break; 1798 break;
1789 case kExternalMemory: { 1799 case kExternalMemory: {
1790 // TODO(titzer): should memory have the same identity as an 1800 // Export the memory as a WebAssembly.Memory object.
1791 // import? 1801 Handle<Object> memory_object(
1792 Handle<JSArrayBuffer> buffer = 1802 instance->GetInternalField(kWasmMemObject), isolate_);
1793 Handle<JSArrayBuffer>(JSArrayBuffer::cast( 1803 if (memory_object->IsUndefined(isolate_)) {
1794 instance->GetInternalField(kWasmMemArrayBuffer))); 1804 // If there was no imported WebAssembly.Memory object, create one.
1795 desc.set_value( 1805 Handle<JSArrayBuffer> buffer(
1796 WasmJs::CreateWasmMemoryObject(isolate_, buffer, false, 0)); 1806 JSArrayBuffer::cast(
1807 instance->GetInternalField(kWasmMemArrayBuffer)),
1808 isolate_);
1809 memory_object =
1810 WasmJs::CreateWasmMemoryObject(isolate_, buffer, false, 0);
1811 instance->SetInternalField(kWasmMemObject, *memory_object);
1812 }
1813
1814 desc.set_value(memory_object);
1797 break; 1815 break;
1798 } 1816 }
1799 case kExternalGlobal: { 1817 case kExternalGlobal: {
1800 // Export the value of the global variable as a number. 1818 // Export the value of the global variable as a number.
1801 int offset = Smi::cast(export_data->get(kExportIndex))->value(); 1819 int offset = Smi::cast(export_data->get(kExportIndex))->value();
1802 byte* ptr = raw_buffer_ptr(globals, offset); 1820 byte* ptr = raw_buffer_ptr(globals, offset);
1803 double num = 0; 1821 double num = 0;
1804 switch (Smi::cast(export_data->get(kExportGlobalType))->value()) { 1822 switch (Smi::cast(export_data->get(kExportGlobalType))->value()) {
1805 case kLocalI32: 1823 case kLocalI32:
1806 num = *reinterpret_cast<int32_t*>(ptr); 1824 num = *reinterpret_cast<int32_t*>(ptr);
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
2233 WasmCompiledModule* compiled_module = 2251 WasmCompiledModule* compiled_module =
2234 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); 2252 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule));
2235 CHECK(compiled_module->has_weak_module_object()); 2253 CHECK(compiled_module->has_weak_module_object());
2236 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); 2254 CHECK(compiled_module->ptr_to_weak_module_object()->cleared());
2237 } 2255 }
2238 2256
2239 } // namespace testing 2257 } // namespace testing
2240 } // namespace wasm 2258 } // namespace wasm
2241 } // namespace internal 2259 } // namespace internal
2242 } // namespace v8 2260 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/wasm-js.cc ('k') | test/mjsunit/wasm/import-memory.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698