OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |