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

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

Issue 2392943006: [wasm] Implement importing of WebAssembly.Memory. (Closed)
Patch Set: 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
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,
Mircea Trofin 2016/10/06 18:10:44 Could this move on the compiled module object inst
56 kWasmMemArrayBuffer, 57 kWasmMemArrayBuffer,
57 kWasmGlobalsArrayBuffer, 58 kWasmGlobalsArrayBuffer,
58 // TODO(clemensh): Remove function name array, extract names from module 59 // TODO(clemensh): Remove function name array, extract names from module
59 // bytes. 60 // bytes.
60 kWasmFunctionNamesArray, 61 kWasmFunctionNamesArray,
61 kWasmModuleBytesString, 62 kWasmModuleBytesString,
62 kWasmDebugInfo, 63 kWasmDebugInfo,
63 kWasmNumImportedFunctions, 64 kWasmNumImportedFunctions,
64 kWasmModuleInternalFieldCount 65 kWasmModuleInternalFieldCount
65 }; 66 };
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 } 1230 }
1230 1231
1231 //-------------------------------------------------------------------------- 1232 //--------------------------------------------------------------------------
1232 // Allocate the instance object. 1233 // Allocate the instance object.
1233 //-------------------------------------------------------------------------- 1234 //--------------------------------------------------------------------------
1234 Handle<Map> map = factory->NewMap( 1235 Handle<Map> map = factory->NewMap(
1235 JS_OBJECT_TYPE, 1236 JS_OBJECT_TYPE,
1236 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize); 1237 JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
1237 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED); 1238 Handle<JSObject> instance = factory->NewJSObjectFromMap(map, TENURED);
1238 instance->SetInternalField(kWasmModuleCodeTable, *code_table); 1239 instance->SetInternalField(kWasmModuleCodeTable, *code_table);
1240 instance->SetInternalField(kWasmMemObject, *factory->undefined_value());
1241
1242 //--------------------------------------------------------------------------
1243 // Set up the globals for the new instance.
1244 //--------------------------------------------------------------------------
1245 MaybeHandle<JSArrayBuffer> old_globals;
1246 MaybeHandle<JSArrayBuffer> globals;
1247 uint32_t globals_size = compiled_module_->globals_size();
1248 if (globals_size > 0) {
1249 Handle<JSArrayBuffer> global_buffer =
1250 NewArrayBuffer(isolate_, globals_size);
1251 globals = global_buffer;
1252 if (globals.is_null()) {
1253 thrower_->Error("Out of memory: wasm globals");
1254 return nothing;
1255 }
1256 Address old_address =
1257 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate(
1258 *factory->undefined_value(),
1259 JSObject::cast(*owner));
1260 RelocateGlobals(instance, old_address,
1261 static_cast<Address>(global_buffer->backing_store()));
1262 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer);
1263 }
1264
1265 //--------------------------------------------------------------------------
1266 // Process the imports for the module.
1267 //--------------------------------------------------------------------------
1268 int num_imported_functions = ProcessImports(globals, code_table, instance);
1269 if (num_imported_functions < 0) return nothing;
1239 1270
1240 //-------------------------------------------------------------------------- 1271 //--------------------------------------------------------------------------
1241 // Set up the memory for the new instance. 1272 // Set up the memory for the new instance.
1242 //-------------------------------------------------------------------------- 1273 //--------------------------------------------------------------------------
1243 MaybeHandle<JSArrayBuffer> old_memory; 1274 MaybeHandle<JSArrayBuffer> old_memory;
1244 // TODO(titzer): handle imported memory properly. 1275 // TODO(titzer): handle imported memory properly.
1245 1276
1246 uint32_t min_mem_pages = compiled_module_->min_memory_pages(); 1277 uint32_t min_mem_pages = compiled_module_->min_memory_pages();
1247 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages); 1278 isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages);
1248 // TODO(wasm): re-enable counter for max_mem_pages when we use that field. 1279 // TODO(wasm): re-enable counter for max_mem_pages when we use that field.
(...skipping 16 matching lines...) Expand all
1265 Address old_mem_start = 1296 Address old_mem_start =
1266 compiled_module_->has_heap() 1297 compiled_module_->has_heap()
1267 ? static_cast<Address>(compiled_module_->heap()->backing_store()) 1298 ? static_cast<Address>(compiled_module_->heap()->backing_store())
1268 : nullptr; 1299 : nullptr;
1269 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size, 1300 RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size,
1270 mem_size); 1301 mem_size);
1271 compiled_module_->set_heap(memory_); 1302 compiled_module_->set_heap(memory_);
1272 } 1303 }
1273 1304
1274 //-------------------------------------------------------------------------- 1305 //--------------------------------------------------------------------------
1275 // Set up the globals for the new instance.
1276 //--------------------------------------------------------------------------
1277 MaybeHandle<JSArrayBuffer> old_globals;
1278 MaybeHandle<JSArrayBuffer> globals;
1279 uint32_t globals_size = compiled_module_->globals_size();
1280 if (globals_size > 0) {
1281 Handle<JSArrayBuffer> global_buffer =
1282 NewArrayBuffer(isolate_, globals_size);
1283 globals = global_buffer;
1284 if (globals.is_null()) {
1285 thrower_->Error("Out of memory: wasm globals");
1286 return nothing;
1287 }
1288 Address old_address =
1289 owner.is_null() ? nullptr : GetGlobalStartAddressFromCodeTemplate(
1290 *factory->undefined_value(),
1291 JSObject::cast(*owner));
1292 RelocateGlobals(instance, old_address,
1293 static_cast<Address>(global_buffer->backing_store()));
1294 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer);
1295 }
1296
1297 //--------------------------------------------------------------------------
1298 // Process the imports for the module.
1299 //--------------------------------------------------------------------------
1300 int num_imported_functions = ProcessImports(globals, code_table);
1301 if (num_imported_functions < 0) return nothing;
1302
1303 //--------------------------------------------------------------------------
1304 // Process the initialization for the module's globals. 1306 // Process the initialization for the module's globals.
1305 //-------------------------------------------------------------------------- 1307 //--------------------------------------------------------------------------
1306 ProcessInits(globals); 1308 ProcessInits(globals);
1307 1309
1308 //-------------------------------------------------------------------------- 1310 //--------------------------------------------------------------------------
1309 // Set up the debug support for the new instance. 1311 // Set up the debug support for the new instance.
1310 //-------------------------------------------------------------------------- 1312 //--------------------------------------------------------------------------
1311 // TODO(wasm): avoid referencing this stuff from the instance, use it off 1313 // TODO(wasm): avoid referencing this stuff from the instance, use it off
1312 // the compiled module instead. See the following 3 assignments: 1314 // the compiled module instead. See the following 3 assignments:
1313 if (compiled_module_->has_module_bytes()) { 1315 if (compiled_module_->has_module_bytes()) {
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 break; 1633 break;
1632 default: 1634 default:
1633 UNREACHABLE(); 1635 UNREACHABLE();
1634 } 1636 }
1635 } 1637 }
1636 1638
1637 // Process the imports, including functions, tables, globals, and memory, in 1639 // Process the imports, including functions, tables, globals, and memory, in
1638 // order, loading them from the {ffi_} object. Returns the number of imported 1640 // order, loading them from the {ffi_} object. Returns the number of imported
1639 // functions. 1641 // functions.
1640 int ProcessImports(MaybeHandle<JSArrayBuffer> globals, 1642 int ProcessImports(MaybeHandle<JSArrayBuffer> globals,
1641 Handle<FixedArray> code_table) { 1643 Handle<FixedArray> code_table, Handle<JSObject> instance) {
1642 int num_imported_functions = 0; 1644 int num_imported_functions = 0;
1643 if (!compiled_module_->has_imports()) return num_imported_functions; 1645 if (!compiled_module_->has_imports()) return num_imported_functions;
1644 1646
1645 Handle<FixedArray> imports = compiled_module_->imports(); 1647 Handle<FixedArray> imports = compiled_module_->imports();
1646 for (int index = 0; index < imports->length(); ++index) { 1648 for (int index = 0; index < imports->length(); ++index) {
1647 Handle<FixedArray> data = 1649 Handle<FixedArray> data =
1648 imports->GetValueChecked<FixedArray>(isolate_, index); 1650 imports->GetValueChecked<FixedArray>(isolate_, index);
1649 1651
1650 Handle<String> module_name = 1652 Handle<String> module_name =
1651 data->GetValueChecked<String>(isolate_, kModuleName); 1653 data->GetValueChecked<String>(isolate_, kModuleName);
(...skipping 21 matching lines...) Expand all
1673 function_name); 1675 function_name);
1674 int func_index = Smi::cast(data->get(kImportIndex))->value(); 1676 int func_index = Smi::cast(data->get(kImportIndex))->value();
1675 code_table->set(func_index, *import_wrapper); 1677 code_table->set(func_index, *import_wrapper);
1676 RecordStats(isolate_, *import_wrapper); 1678 RecordStats(isolate_, *import_wrapper);
1677 num_imported_functions++; 1679 num_imported_functions++;
1678 break; 1680 break;
1679 } 1681 }
1680 case kExternalTable: 1682 case kExternalTable:
1681 // TODO(titzer): Table imports must be a WebAssembly.Table. 1683 // TODO(titzer): Table imports must be a WebAssembly.Table.
1682 break; 1684 break;
1683 case kExternalMemory: 1685 case kExternalMemory: {
1684 // TODO(titzer): Memory imports must be a WebAssembly.Memory. 1686 Handle<Object> object = result.ToHandleChecked();
1687 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) {
1688 ReportFFIError("memory import must be a WebAssembly.Memory object",
1689 index, module_name, function_name);
1690 return -1;
1691 }
1692 instance->SetInternalField(kWasmMemObject, *object);
1693 memory_ = WasmJs::GetWasmMemoryArrayBuffer(isolate_, object);
1685 break; 1694 break;
1695 }
1686 case kExternalGlobal: { 1696 case kExternalGlobal: {
1687 // Global imports are converted to numbers and written into the 1697 // Global imports are converted to numbers and written into the
1688 // {globals} array buffer. 1698 // {globals} array buffer.
1689 Handle<Object> object = result.ToHandleChecked(); 1699 Handle<Object> object = result.ToHandleChecked();
1690 MaybeHandle<Object> number = Object::ToNumber(object); 1700 MaybeHandle<Object> number = Object::ToNumber(object);
1691 if (number.is_null()) { 1701 if (number.is_null()) {
1692 ReportFFIError("global import could not be converted to number", 1702 ReportFFIError("global import could not be converted to number",
1693 index, module_name, function_name); 1703 index, module_name, function_name);
1694 return -1; 1704 return -1;
1695 } 1705 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1792 export_data->GetValue<ByteArray>(isolate_, kExportedSignature); 1802 export_data->GetValue<ByteArray>(isolate_, kExportedSignature);
1793 desc.set_value(WrapExportCodeAsJSFunction( 1803 desc.set_value(WrapExportCodeAsJSFunction(
1794 isolate_, export_code, name, arity, signature, instance)); 1804 isolate_, export_code, name, arity, signature, instance));
1795 break; 1805 break;
1796 } 1806 }
1797 case kExternalTable: 1807 case kExternalTable:
1798 // TODO(titzer): create a WebAssembly.Table instance. 1808 // TODO(titzer): create a WebAssembly.Table instance.
1799 // TODO(titzer): should it have the same identity as an import? 1809 // TODO(titzer): should it have the same identity as an import?
1800 break; 1810 break;
1801 case kExternalMemory: { 1811 case kExternalMemory: {
1802 // TODO(titzer): should memory have the same identity as an 1812 // Export the memory as a WebAssembly.Memory object.
1803 // import? 1813 Handle<Object> memory_object(
1804 Handle<JSArrayBuffer> buffer = 1814 instance->GetInternalField(kWasmMemObject), isolate_);
1805 Handle<JSArrayBuffer>(JSArrayBuffer::cast( 1815 if (memory_object->IsUndefined(isolate_)) {
1806 instance->GetInternalField(kWasmMemArrayBuffer))); 1816 // If there was no imported WebAssembly.Memory object, create one.
1807 desc.set_value( 1817 Handle<JSArrayBuffer> buffer(
1808 WasmJs::CreateWasmMemoryObject(isolate_, buffer, false, 0)); 1818 JSArrayBuffer::cast(
1819 instance->GetInternalField(kWasmMemArrayBuffer)),
1820 isolate_);
1821 memory_object =
1822 WasmJs::CreateWasmMemoryObject(isolate_, buffer, false, 0);
1823 instance->SetInternalField(kWasmMemObject, *memory_object);
1824 }
1825
1826 desc.set_value(memory_object);
1809 break; 1827 break;
1810 } 1828 }
1811 case kExternalGlobal: { 1829 case kExternalGlobal: {
1812 // Export the value of the global variable as a number. 1830 // Export the value of the global variable as a number.
1813 int offset = Smi::cast(export_data->get(kExportIndex))->value(); 1831 int offset = Smi::cast(export_data->get(kExportIndex))->value();
1814 byte* ptr = raw_buffer_ptr(globals, offset); 1832 byte* ptr = raw_buffer_ptr(globals, offset);
1815 double num = 0; 1833 double num = 0;
1816 switch (Smi::cast(export_data->get(kExportGlobalType))->value()) { 1834 switch (Smi::cast(export_data->get(kExportGlobalType))->value()) {
1817 case kLocalI32: 1835 case kLocalI32:
1818 num = *reinterpret_cast<int32_t*>(ptr); 1836 num = *reinterpret_cast<int32_t*>(ptr);
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
2224 WasmCompiledModule* compiled_module = 2242 WasmCompiledModule* compiled_module =
2225 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule)); 2243 WasmCompiledModule::cast(instance->GetInternalField(kWasmCompiledModule));
2226 CHECK(compiled_module->has_weak_module_object()); 2244 CHECK(compiled_module->has_weak_module_object());
2227 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); 2245 CHECK(compiled_module->ptr_to_weak_module_object()->cleared());
2228 } 2246 }
2229 2247
2230 } // namespace testing 2248 } // namespace testing
2231 } // namespace wasm 2249 } // namespace wasm
2232 } // namespace internal 2250 } // namespace internal
2233 } // namespace v8 2251 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698