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