Chromium Code Reviews| 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" |
| 11 #include "src/objects.h" | 11 #include "src/objects.h" |
| 12 #include "src/property-descriptor.h" | 12 #include "src/property-descriptor.h" |
| 13 #include "src/simulator.h" | 13 #include "src/simulator.h" |
| 14 #include "src/snapshot/snapshot.h" | 14 #include "src/snapshot/snapshot.h" |
| 15 #include "src/v8.h" | 15 #include "src/v8.h" |
| 16 | 16 |
| 17 #include "src/wasm/ast-decoder.h" | 17 #include "src/wasm/ast-decoder.h" |
| 18 #include "src/wasm/module-decoder.h" | 18 #include "src/wasm/module-decoder.h" |
| 19 #include "src/wasm/wasm-debug.h" | 19 #include "src/wasm/wasm-debug.h" |
| 20 #include "src/wasm/wasm-js.h" | 20 #include "src/wasm/wasm-js.h" |
| 21 #include "src/wasm/wasm-module.h" | 21 #include "src/wasm/wasm-module.h" |
| 22 #include "src/wasm/wasm-objects.h" | |
| 22 #include "src/wasm/wasm-result.h" | 23 #include "src/wasm/wasm-result.h" |
| 23 | 24 |
| 24 #include "src/compiler/wasm-compiler.h" | 25 #include "src/compiler/wasm-compiler.h" |
| 25 | 26 |
| 26 using namespace v8::internal; | 27 using namespace v8::internal; |
| 27 using namespace v8::internal::wasm; | 28 using namespace v8::internal::wasm; |
| 28 namespace base = v8::base; | 29 namespace base = v8::base; |
| 29 | 30 |
| 30 #define TRACE(...) \ | 31 #define TRACE(...) \ |
| 31 do { \ | 32 do { \ |
| (...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1094 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); | 1095 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); |
| 1095 } | 1096 } |
| 1096 | 1097 |
| 1097 //-------------------------------------------------------------------------- | 1098 //-------------------------------------------------------------------------- |
| 1098 // Prepare for initialization of function tables. | 1099 // Prepare for initialization of function tables. |
| 1099 //-------------------------------------------------------------------------- | 1100 //-------------------------------------------------------------------------- |
| 1100 int function_table_count = | 1101 int function_table_count = |
| 1101 static_cast<int>(module_->function_tables.size()); | 1102 static_cast<int>(module_->function_tables.size()); |
| 1102 table_instances_.reserve(module_->function_tables.size()); | 1103 table_instances_.reserve(module_->function_tables.size()); |
| 1103 for (int index = 0; index < function_table_count; ++index) { | 1104 for (int index = 0; index < function_table_count; ++index) { |
| 1104 table_instances_.push_back({Handle<JSObject>::null(), | 1105 table_instances_.push_back({Handle<WasmTableObject>::null(), |
| 1105 Handle<FixedArray>::null(), | 1106 Handle<FixedArray>::null(), |
| 1106 Handle<FixedArray>::null()}); | 1107 Handle<FixedArray>::null()}); |
| 1107 } | 1108 } |
| 1108 | 1109 |
| 1109 //-------------------------------------------------------------------------- | 1110 //-------------------------------------------------------------------------- |
| 1110 // Process the imports for the module. | 1111 // Process the imports for the module. |
| 1111 //-------------------------------------------------------------------------- | 1112 //-------------------------------------------------------------------------- |
| 1112 int num_imported_functions = ProcessImports(code_table, instance); | 1113 int num_imported_functions = ProcessImports(code_table, instance); |
| 1113 if (num_imported_functions < 0) return nothing; | 1114 if (num_imported_functions < 0) return nothing; |
| 1114 | 1115 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1265 | 1266 |
| 1266 DCHECK(!isolate_->has_pending_exception()); | 1267 DCHECK(!isolate_->has_pending_exception()); |
| 1267 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); | 1268 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
| 1268 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 1269 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); |
| 1269 return instance; | 1270 return instance; |
| 1270 } | 1271 } |
| 1271 | 1272 |
| 1272 private: | 1273 private: |
| 1273 // Represents the initialized state of a table. | 1274 // Represents the initialized state of a table. |
| 1274 struct TableInstance { | 1275 struct TableInstance { |
| 1275 Handle<JSObject> table_object; // WebAssembly.Table instance | 1276 Handle<WasmTableObject> table_object; // WebAssembly.Table instance |
| 1276 Handle<FixedArray> js_wrappers; // JSFunctions exported | 1277 Handle<FixedArray> js_wrappers; // JSFunctions exported |
| 1277 Handle<FixedArray> dispatch_table; // internal (code, sig) pairs | 1278 Handle<FixedArray> dispatch_table; // internal (code, sig) pairs |
| 1278 }; | 1279 }; |
| 1279 | 1280 |
| 1280 Isolate* isolate_; | 1281 Isolate* isolate_; |
| 1281 WasmModule* module_; | 1282 WasmModule* module_; |
| 1282 ErrorThrower* thrower_; | 1283 ErrorThrower* thrower_; |
| 1283 Handle<JSObject> module_object_; | 1284 Handle<JSObject> module_object_; |
| 1284 Handle<JSReceiver> ffi_; | 1285 Handle<JSReceiver> ffi_; |
| 1285 Handle<JSArrayBuffer> memory_; | 1286 Handle<JSArrayBuffer> memory_; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1453 case kExternalTable: { | 1454 case kExternalTable: { |
| 1454 Handle<Object> value = result.ToHandleChecked(); | 1455 Handle<Object> value = result.ToHandleChecked(); |
| 1455 if (!WasmJs::IsWasmTableObject(isolate_, value)) { | 1456 if (!WasmJs::IsWasmTableObject(isolate_, value)) { |
| 1456 ReportFFIError("table import requires a WebAssembly.Table", index, | 1457 ReportFFIError("table import requires a WebAssembly.Table", index, |
| 1457 module_name, function_name); | 1458 module_name, function_name); |
| 1458 return -1; | 1459 return -1; |
| 1459 } | 1460 } |
| 1460 WasmIndirectFunctionTable& table = | 1461 WasmIndirectFunctionTable& table = |
| 1461 module_->function_tables[num_imported_tables]; | 1462 module_->function_tables[num_imported_tables]; |
| 1462 TableInstance& table_instance = table_instances_[num_imported_tables]; | 1463 TableInstance& table_instance = table_instances_[num_imported_tables]; |
| 1463 table_instance.table_object = Handle<JSObject>::cast(value); | 1464 table_instance.table_object = Handle<WasmTableObject>::cast(value); |
| 1464 table_instance.js_wrappers = WasmJs::GetWasmTableFunctions( | 1465 table_instance.js_wrappers = WasmJs::GetWasmTableFunctions( |
| 1465 isolate_, table_instance.table_object); | 1466 isolate_, table_instance.table_object); |
| 1466 | 1467 |
| 1467 // TODO(titzer): import table size must match exactly for now. | 1468 // TODO(titzer): import table size must match exactly for now. |
| 1468 int table_size = table_instance.js_wrappers->length(); | 1469 int table_size = table_instance.js_wrappers->length(); |
| 1469 if (table_size != table.min_size) { | 1470 if (table_size != table.min_size) { |
| 1470 thrower_->TypeError( | 1471 thrower_->TypeError( |
| 1471 "table import %d is wrong size (%d), expected %u", index, | 1472 "table import %d is wrong size (%d), expected %u", index, |
| 1472 table_size, table.min_size); | 1473 table_size, table.min_size); |
| 1473 return -1; | 1474 return -1; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1501 num_imported_tables++; | 1502 num_imported_tables++; |
| 1502 break; | 1503 break; |
| 1503 } | 1504 } |
| 1504 case kExternalMemory: { | 1505 case kExternalMemory: { |
| 1505 Handle<Object> object = result.ToHandleChecked(); | 1506 Handle<Object> object = result.ToHandleChecked(); |
| 1506 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { | 1507 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { |
| 1507 ReportFFIError("memory import must be a WebAssembly.Memory object", | 1508 ReportFFIError("memory import must be a WebAssembly.Memory object", |
| 1508 index, module_name, function_name); | 1509 index, module_name, function_name); |
| 1509 return -1; | 1510 return -1; |
| 1510 } | 1511 } |
| 1512 auto memory = Handle<WasmMemoryObject>::cast(object); | |
|
ahaas
2016/11/10 09:51:13
Can you not just use the type here instead of auto
titzer
2016/11/10 10:33:24
I think that's redundant, since a Handle<X>::cast(
| |
| 1511 instance->SetInternalField(kWasmMemObject, *object); | 1513 instance->SetInternalField(kWasmMemObject, *object); |
| 1512 memory_ = WasmJs::GetWasmMemoryArrayBuffer(isolate_, object); | 1514 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_); |
| 1513 break; | 1515 break; |
| 1514 } | 1516 } |
| 1515 case kExternalGlobal: { | 1517 case kExternalGlobal: { |
| 1516 // Global imports are converted to numbers and written into the | 1518 // Global imports are converted to numbers and written into the |
| 1517 // {globals_} array buffer. | 1519 // {globals_} array buffer. |
| 1518 Handle<Object> object = result.ToHandleChecked(); | 1520 Handle<Object> object = result.ToHandleChecked(); |
| 1519 MaybeHandle<Object> number = Object::ToNumber(object); | 1521 MaybeHandle<Object> number = Object::ToNumber(object); |
| 1520 if (number.is_null()) { | 1522 if (number.is_null()) { |
| 1521 ReportFFIError("global import could not be converted to number", | 1523 ReportFFIError("global import could not be converted to number", |
| 1522 index, module_name, function_name); | 1524 index, module_name, function_name); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1658 desc.set_value(js_function); | 1660 desc.set_value(js_function); |
| 1659 export_index++; | 1661 export_index++; |
| 1660 break; | 1662 break; |
| 1661 } | 1663 } |
| 1662 case kExternalTable: { | 1664 case kExternalTable: { |
| 1663 // Export a table as a WebAssembly.Table object. | 1665 // Export a table as a WebAssembly.Table object. |
| 1664 TableInstance& table_instance = table_instances_[exp.index]; | 1666 TableInstance& table_instance = table_instances_[exp.index]; |
| 1665 WasmIndirectFunctionTable& table = | 1667 WasmIndirectFunctionTable& table = |
| 1666 module_->function_tables[exp.index]; | 1668 module_->function_tables[exp.index]; |
| 1667 if (table_instance.table_object.is_null()) { | 1669 if (table_instance.table_object.is_null()) { |
| 1668 table_instance.table_object = WasmJs::CreateWasmTableObject( | 1670 table_instance.table_object = WasmTableObject::New( |
| 1669 isolate_, table.min_size, table.has_max, table.max_size, | 1671 isolate_, table.min_size, table.has_max, table.max_size, |
| 1670 &table_instance.js_wrappers); | 1672 &table_instance.js_wrappers); |
| 1671 } | 1673 } |
| 1672 desc.set_value(table_instance.table_object); | 1674 desc.set_value(table_instance.table_object); |
| 1673 break; | 1675 break; |
| 1674 } | 1676 } |
| 1675 case kExternalMemory: { | 1677 case kExternalMemory: { |
| 1676 // Export the memory as a WebAssembly.Memory object. | 1678 // Export the memory as a WebAssembly.Memory object. |
| 1677 Handle<Object> memory_object( | 1679 Handle<Object> memory_object( |
| 1678 instance->GetInternalField(kWasmMemObject), isolate_); | 1680 instance->GetInternalField(kWasmMemObject), isolate_); |
| 1679 if (memory_object->IsUndefined(isolate_)) { | 1681 if (memory_object->IsUndefined(isolate_)) { |
| 1680 // If there was no imported WebAssembly.Memory object, create one. | 1682 // If there was no imported WebAssembly.Memory object, create one. |
| 1681 Handle<JSArrayBuffer> buffer( | 1683 Handle<JSArrayBuffer> buffer( |
| 1682 JSArrayBuffer::cast( | 1684 JSArrayBuffer::cast( |
| 1683 instance->GetInternalField(kWasmMemArrayBuffer)), | 1685 instance->GetInternalField(kWasmMemArrayBuffer)), |
| 1684 isolate_); | 1686 isolate_); |
| 1685 memory_object = WasmJs::CreateWasmMemoryObject( | 1687 memory_object = WasmMemoryObject::New( |
| 1686 isolate_, buffer, (module_->max_mem_pages != 0), | 1688 isolate_, buffer, |
| 1687 module_->max_mem_pages); | 1689 (module_->max_mem_pages != 0) ? module_->max_mem_pages : -1); |
|
ahaas
2016/11/10 09:51:13
Could you do this check also in {WasmMemoryObject:
titzer
2016/11/10 10:33:24
WasmMemoryObject::New() is just a constructor, so
| |
| 1688 instance->SetInternalField(kWasmMemObject, *memory_object); | 1690 instance->SetInternalField(kWasmMemObject, *memory_object); |
| 1689 } | 1691 } |
| 1690 | 1692 |
| 1691 desc.set_value(memory_object); | 1693 desc.set_value(memory_object); |
| 1692 break; | 1694 break; |
| 1693 } | 1695 } |
| 1694 case kExternalGlobal: { | 1696 case kExternalGlobal: { |
| 1695 // Export the value of the global variable as a number. | 1697 // Export the value of the global variable as a number. |
| 1696 WasmGlobal& global = module_->globals[exp.index]; | 1698 WasmGlobal& global = module_->globals[exp.index]; |
| 1697 double num = 0; | 1699 double num = 0; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1749 table_instance.dispatch_table->set(i, Smi::FromInt(kInvalidSigIndex)); | 1751 table_instance.dispatch_table->set(i, Smi::FromInt(kInvalidSigIndex)); |
| 1750 } | 1752 } |
| 1751 } | 1753 } |
| 1752 | 1754 |
| 1753 new_function_tables->set(static_cast<int>(index), | 1755 new_function_tables->set(static_cast<int>(index), |
| 1754 *table_instance.dispatch_table); | 1756 *table_instance.dispatch_table); |
| 1755 | 1757 |
| 1756 Handle<FixedArray> all_dispatch_tables; | 1758 Handle<FixedArray> all_dispatch_tables; |
| 1757 if (!table_instance.table_object.is_null()) { | 1759 if (!table_instance.table_object.is_null()) { |
| 1758 // Get the existing dispatch table(s) with the WebAssembly.Table object. | 1760 // Get the existing dispatch table(s) with the WebAssembly.Table object. |
| 1759 all_dispatch_tables = WasmJs::AddWasmTableDispatchTable( | 1761 all_dispatch_tables = WasmTableObject::AddDispatchTable( |
| 1760 isolate_, table_instance.table_object, Handle<JSObject>::null(), | 1762 isolate_, table_instance.table_object, |
| 1761 index, Handle<FixedArray>::null()); | 1763 Handle<WasmInstanceObject>::null(), index, |
| 1764 Handle<FixedArray>::null()); | |
| 1762 } | 1765 } |
| 1763 | 1766 |
| 1764 // TODO(titzer): this does redundant work if there are multiple tables, | 1767 // TODO(titzer): this does redundant work if there are multiple tables, |
| 1765 // since initializations are not sorted by table index. | 1768 // since initializations are not sorted by table index. |
| 1766 for (auto table_init : module_->table_inits) { | 1769 for (auto table_init : module_->table_inits) { |
| 1767 uint32_t base = EvalUint32InitExpr(table_init.offset); | 1770 uint32_t base = EvalUint32InitExpr(table_init.offset); |
| 1768 if (base > static_cast<uint32_t>(table_size) || | 1771 if (base > static_cast<uint32_t>(table_size) || |
| 1769 (base + table_init.entries.size() > | 1772 (base + table_init.entries.size() > |
| 1770 static_cast<uint32_t>(table_size))) { | 1773 static_cast<uint32_t>(table_size))) { |
| 1771 thrower_->CompileError("table initializer is out of bounds"); | 1774 thrower_->CompileError("table initializer is out of bounds"); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1815 table_index, function, wasm_code); | 1818 table_index, function, wasm_code); |
| 1816 } | 1819 } |
| 1817 } | 1820 } |
| 1818 } | 1821 } |
| 1819 | 1822 |
| 1820 // TODO(titzer): we add the new dispatch table at the end to avoid | 1823 // TODO(titzer): we add the new dispatch table at the end to avoid |
| 1821 // redundant work and also because the new instance is not yet fully | 1824 // redundant work and also because the new instance is not yet fully |
| 1822 // initialized. | 1825 // initialized. |
| 1823 if (!table_instance.table_object.is_null()) { | 1826 if (!table_instance.table_object.is_null()) { |
| 1824 // Add the new dispatch table to the WebAssembly.Table object. | 1827 // Add the new dispatch table to the WebAssembly.Table object. |
| 1825 all_dispatch_tables = WasmJs::AddWasmTableDispatchTable( | 1828 // TODO: remove the cast of WasmInstanceObject |
| 1826 isolate_, table_instance.table_object, instance, index, | 1829 Handle<WasmInstanceObject> handle( |
| 1830 reinterpret_cast<WasmInstanceObject*>(*instance), isolate_); | |
| 1831 all_dispatch_tables = WasmTableObject::AddDispatchTable( | |
| 1832 isolate_, table_instance.table_object, handle, index, | |
| 1827 table_instance.dispatch_table); | 1833 table_instance.dispatch_table); |
| 1828 } | 1834 } |
| 1829 } | 1835 } |
| 1830 // Patch all code that has references to the old indirect tables. | 1836 // Patch all code that has references to the old indirect tables. |
| 1831 for (int i = 0; i < code_table->length(); ++i) { | 1837 for (int i = 0; i < code_table->length(); ++i) { |
| 1832 if (!code_table->get(i)->IsCode()) continue; | 1838 if (!code_table->get(i)->IsCode()) continue; |
| 1833 Handle<Code> code(Code::cast(code_table->get(i)), isolate_); | 1839 Handle<Code> code(Code::cast(code_table->get(i)), isolate_); |
| 1834 for (int j = 0; j < function_table_count; ++j) { | 1840 for (int j = 0; j < function_table_count; ++j) { |
| 1835 ReplaceReferenceInCode( | 1841 ReplaceReferenceInCode( |
| 1836 code, Handle<Object>(old_function_tables->get(j), isolate_), | 1842 code, Handle<Object>(old_function_tables->get(j), isolate_), |
| 1837 Handle<Object>(new_function_tables->get(j), isolate_)); | 1843 Handle<Object>(new_function_tables->get(j), isolate_)); |
| 1838 } | 1844 } |
| 1839 } | 1845 } |
| 1840 compiled_module_->set_function_tables(new_function_tables); | 1846 compiled_module_->set_function_tables(new_function_tables); |
| 1841 } | 1847 } |
| 1842 }; | 1848 }; |
| 1843 | 1849 |
| 1844 // Instantiates a WASM module, creating a WebAssembly.Instance from a | 1850 // Instantiates a WASM module, creating a WebAssembly.Instance from a |
| 1845 // WebAssembly.Module. | 1851 // WebAssembly.Module. |
| 1846 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, | 1852 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
| 1847 ErrorThrower* thrower, | 1853 ErrorThrower* thrower, |
| 1848 Handle<JSObject> wasm_module, | 1854 Handle<JSObject> wasm_module, |
| 1849 Handle<JSReceiver> ffi, | 1855 Handle<JSReceiver> ffi, |
| 1850 Handle<JSArrayBuffer> memory) { | 1856 Handle<JSArrayBuffer> memory) { |
| 1851 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); | 1857 WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory); |
| 1852 return builder.Build(); | 1858 return builder.Build(); |
| 1853 } | 1859 } |
| 1854 | 1860 |
| 1855 Handle<WasmCompiledModule> WasmCompiledModule::New( | |
| 1856 Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper) { | |
| 1857 Handle<FixedArray> ret = | |
| 1858 isolate->factory()->NewFixedArray(PropertyIndices::Count, TENURED); | |
| 1859 // WasmCompiledModule::cast would fail since module bytes are not set yet. | |
| 1860 Handle<WasmCompiledModule> compiled_module( | |
| 1861 reinterpret_cast<WasmCompiledModule*>(*ret), isolate); | |
| 1862 compiled_module->InitId(); | |
| 1863 compiled_module->set_module_wrapper(module_wrapper); | |
| 1864 return compiled_module; | |
| 1865 } | |
| 1866 | |
| 1867 void WasmCompiledModule::InitId() { | |
| 1868 #if DEBUG | |
| 1869 static uint32_t instance_id_counter = 0; | |
| 1870 set(kID_instance_id, Smi::FromInt(instance_id_counter++)); | |
| 1871 TRACE("New compiled module id: %d\n", instance_id()); | |
| 1872 #endif | |
| 1873 } | |
| 1874 | |
| 1875 bool WasmCompiledModule::IsWasmCompiledModule(Object* obj) { | |
| 1876 if (!obj->IsFixedArray()) return false; | |
| 1877 FixedArray* arr = FixedArray::cast(obj); | |
| 1878 if (arr->length() != PropertyIndices::Count) return false; | |
| 1879 Isolate* isolate = arr->GetIsolate(); | |
| 1880 #define WCM_CHECK_SMALL_NUMBER(TYPE, NAME) \ | |
| 1881 if (!arr->get(kID_##NAME)->IsSmi()) return false; | |
| 1882 #define WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) \ | |
| 1883 if (!arr->get(kID_##NAME)->IsUndefined(isolate) && \ | |
| 1884 !arr->get(kID_##NAME)->Is##TYPE()) \ | |
| 1885 return false; | |
| 1886 #define WCM_CHECK_OBJECT(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(TYPE, NAME) | |
| 1887 #define WCM_CHECK_WEAK_LINK(TYPE, NAME) WCM_CHECK_OBJECT_OR_WEAK(WeakCell, NAME) | |
| 1888 #define WCM_CHECK(KIND, TYPE, NAME) WCM_CHECK_##KIND(TYPE, NAME) | |
| 1889 WCM_PROPERTY_TABLE(WCM_CHECK) | |
| 1890 #undef WCM_CHECK | |
| 1891 | |
| 1892 // All checks passed. | |
| 1893 return true; | |
| 1894 } | |
| 1895 | |
| 1896 void WasmCompiledModule::PrintInstancesChain() { | |
| 1897 #if DEBUG | |
| 1898 if (!FLAG_trace_wasm_instances) return; | |
| 1899 for (WasmCompiledModule* current = this; current != nullptr;) { | |
| 1900 PrintF("->%d", current->instance_id()); | |
| 1901 if (current->ptr_to_weak_next_instance() == nullptr) break; | |
| 1902 CHECK(!current->ptr_to_weak_next_instance()->cleared()); | |
| 1903 current = | |
| 1904 WasmCompiledModule::cast(current->ptr_to_weak_next_instance()->value()); | |
| 1905 } | |
| 1906 PrintF("\n"); | |
| 1907 #endif | |
| 1908 } | |
| 1909 | |
| 1910 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, | 1861 Handle<Object> wasm::GetWasmFunctionNameOrNull(Isolate* isolate, |
| 1911 Handle<Object> instance, | 1862 Handle<Object> instance, |
| 1912 uint32_t func_index) { | 1863 uint32_t func_index) { |
| 1913 if (!instance->IsUndefined(isolate)) { | 1864 if (!instance->IsUndefined(isolate)) { |
| 1914 DCHECK(IsWasmInstance(*instance)); | 1865 DCHECK(IsWasmInstance(*instance)); |
| 1915 WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance)); | 1866 WasmModule* module = GetCppModule(Handle<JSObject>::cast(instance)); |
| 1916 WasmFunction& function = module->functions[func_index]; | 1867 WasmFunction& function = module->functions[func_index]; |
| 1917 Handle<WasmCompiledModule> compiled_module(GetCompiledModule(*instance), | 1868 Handle<WasmCompiledModule> compiled_module(GetCompiledModule(*instance), |
| 1918 isolate); | 1869 isolate); |
| 1919 MaybeHandle<String> string = ExtractStringFromModuleBytes( | 1870 MaybeHandle<String> string = ExtractStringFromModuleBytes( |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2016 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); | 1967 Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym()); |
| 2017 Object::SetProperty(wasm_module, module_sym, wasm_module, STRICT).Check(); | 1968 Object::SetProperty(wasm_module, module_sym, wasm_module, STRICT).Check(); |
| 2018 } | 1969 } |
| 2019 Handle<WeakCell> link_to_module = | 1970 Handle<WeakCell> link_to_module = |
| 2020 isolate->factory()->NewWeakCell(wasm_module); | 1971 isolate->factory()->NewWeakCell(wasm_module); |
| 2021 compiled_module->set_weak_wasm_module(link_to_module); | 1972 compiled_module->set_weak_wasm_module(link_to_module); |
| 2022 return wasm_module; | 1973 return wasm_module; |
| 2023 } | 1974 } |
| 2024 | 1975 |
| 2025 // TODO(clemensh): origin can be inferred from asm_js_script; remove it. | 1976 // TODO(clemensh): origin can be inferred from asm_js_script; remove it. |
| 2026 MaybeHandle<JSObject> wasm::CreateModuleObjectFromBytes( | 1977 MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes( |
| 2027 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, | 1978 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, |
| 2028 ModuleOrigin origin, Handle<Script> asm_js_script, | 1979 ModuleOrigin origin, Handle<Script> asm_js_script, |
| 2029 const byte* asm_js_offset_tables_start, | 1980 const byte* asm_js_offset_tables_start, |
| 2030 const byte* asm_js_offset_tables_end) { | 1981 const byte* asm_js_offset_tables_end) { |
| 2031 MaybeHandle<JSObject> nothing; | 1982 MaybeHandle<WasmModuleObject> nothing; |
| 2032 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); | 1983 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); |
| 2033 if (result.failed()) { | 1984 if (result.failed()) { |
| 2034 if (result.val) delete result.val; | 1985 if (result.val) delete result.val; |
| 2035 thrower->CompileFailed("Wasm decoding failed", result); | 1986 thrower->CompileFailed("Wasm decoding failed", result); |
| 2036 return nothing; | 1987 return nothing; |
| 2037 } | 1988 } |
| 2038 // The {module_wrapper} will take ownership of the {WasmModule} object, | 1989 // The {module_wrapper} will take ownership of the {WasmModule} object, |
| 2039 // and it will be destroyed when the GC reclaims the wrapper object. | 1990 // and it will be destroyed when the GC reclaims the wrapper object. |
| 2040 Handle<WasmModuleWrapper> module_wrapper = | 1991 Handle<WasmModuleWrapper> module_wrapper = |
| 2041 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); | 1992 WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val)); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2057 size_t offset_tables_len = | 2008 size_t offset_tables_len = |
| 2058 asm_js_offset_tables_end - asm_js_offset_tables_start; | 2009 asm_js_offset_tables_end - asm_js_offset_tables_start; |
| 2059 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); | 2010 DCHECK_GE(static_cast<size_t>(kMaxInt), offset_tables_len); |
| 2060 Handle<ByteArray> offset_tables = | 2011 Handle<ByteArray> offset_tables = |
| 2061 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); | 2012 isolate->factory()->NewByteArray(static_cast<int>(offset_tables_len)); |
| 2062 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, | 2013 memcpy(offset_tables->GetDataStartAddress(), asm_js_offset_tables_start, |
| 2063 offset_tables_len); | 2014 offset_tables_len); |
| 2064 compiled_module->set_asm_js_offset_tables(offset_tables); | 2015 compiled_module->set_asm_js_offset_tables(offset_tables); |
| 2065 } | 2016 } |
| 2066 | 2017 |
| 2067 return CreateWasmModuleObject(isolate, compiled_module, origin); | 2018 return WasmModuleObject::New(isolate, compiled_module); |
| 2068 } | 2019 } |
| 2069 | 2020 |
| 2070 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, | 2021 bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start, |
| 2071 const byte* end, ErrorThrower* thrower, | 2022 const byte* end, ErrorThrower* thrower, |
| 2072 ModuleOrigin origin) { | 2023 ModuleOrigin origin) { |
| 2073 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); | 2024 ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin); |
| 2074 if (result.val) { | 2025 if (result.val) { |
| 2075 delete result.val; | 2026 delete result.val; |
| 2076 } else { | 2027 } else { |
| 2077 DCHECK(!result.ok()); | 2028 DCHECK(!result.ok()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2104 return 0; | 2055 return 0; |
| 2105 } else { | 2056 } else { |
| 2106 return buffer->byte_length()->Number() / WasmModule::kPageSize; | 2057 return buffer->byte_length()->Number() / WasmModule::kPageSize; |
| 2107 } | 2058 } |
| 2108 } | 2059 } |
| 2109 | 2060 |
| 2110 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { | 2061 uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { |
| 2111 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | 2062 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), |
| 2112 isolate); | 2063 isolate); |
| 2113 if (!memory_object->IsUndefined(isolate)) { | 2064 if (!memory_object->IsUndefined(isolate)) { |
| 2114 uint32_t mem_obj_max = | 2065 int maximum = |
| 2115 WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object); | 2066 Handle<WasmMemoryObject>::cast(memory_object)->maximum_pages(); |
| 2116 if (mem_obj_max != 0) return mem_obj_max; | 2067 if (maximum > 0) return static_cast<uint32_t>(maximum); |
| 2117 } | 2068 } |
| 2118 uint32_t compiled_max_pages = GetCompiledModule(*instance)->max_mem_pages(); | 2069 uint32_t compiled_max_pages = GetCompiledModule(*instance)->max_mem_pages(); |
| 2119 isolate->counters()->wasm_max_mem_pages_count()->AddSample( | 2070 isolate->counters()->wasm_max_mem_pages_count()->AddSample( |
| 2120 compiled_max_pages); | 2071 compiled_max_pages); |
| 2121 if (compiled_max_pages != 0) return compiled_max_pages; | 2072 if (compiled_max_pages != 0) return compiled_max_pages; |
| 2122 return WasmModule::kV8MaxPages; | 2073 return WasmModule::kV8MaxPages; |
| 2123 } | 2074 } |
| 2124 | 2075 |
| 2125 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, | 2076 int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, |
| 2126 uint32_t pages) { | 2077 uint32_t pages) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2161 if (old_size != 0) { | 2112 if (old_size != 0) { |
| 2162 memcpy(new_mem_start, old_mem_start, old_size); | 2113 memcpy(new_mem_start, old_mem_start, old_size); |
| 2163 } | 2114 } |
| 2164 SetInstanceMemory(instance, *buffer); | 2115 SetInstanceMemory(instance, *buffer); |
| 2165 Handle<FixedArray> code_table = GetCompiledModule(*instance)->code_table(); | 2116 Handle<FixedArray> code_table = GetCompiledModule(*instance)->code_table(); |
| 2166 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start, | 2117 RelocateMemoryReferencesInCode(code_table, old_mem_start, new_mem_start, |
| 2167 old_size, new_size); | 2118 old_size, new_size); |
| 2168 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), | 2119 Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), |
| 2169 isolate); | 2120 isolate); |
| 2170 if (!memory_object->IsUndefined(isolate)) { | 2121 if (!memory_object->IsUndefined(isolate)) { |
| 2171 WasmJs::SetWasmMemoryArrayBuffer(isolate, memory_object, buffer); | 2122 Handle<WasmMemoryObject>::cast(memory_object)->set_buffer(*buffer); |
| 2172 } | 2123 } |
| 2173 | 2124 |
| 2174 DCHECK(old_size % WasmModule::kPageSize == 0); | 2125 DCHECK(old_size % WasmModule::kPageSize == 0); |
| 2175 return (old_size / WasmModule::kPageSize); | 2126 return (old_size / WasmModule::kPageSize); |
| 2176 } | 2127 } |
| 2177 | 2128 |
| 2178 void testing::ValidateInstancesChain(Isolate* isolate, | 2129 void testing::ValidateInstancesChain(Isolate* isolate, |
| 2179 Handle<JSObject> wasm_module, | 2130 Handle<JSObject> wasm_module, |
| 2180 int instance_count) { | 2131 int instance_count) { |
| 2181 CHECK_GE(instance_count, 0); | 2132 CHECK_GE(instance_count, 0); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2246 CHECK_NOT_NULL(result.val); | 2197 CHECK_NOT_NULL(result.val); |
| 2247 module = const_cast<WasmModule*>(result.val); | 2198 module = const_cast<WasmModule*>(result.val); |
| 2248 } | 2199 } |
| 2249 | 2200 |
| 2250 Handle<WasmModuleWrapper> module_wrapper = | 2201 Handle<WasmModuleWrapper> module_wrapper = |
| 2251 WasmModuleWrapper::New(isolate, module); | 2202 WasmModuleWrapper::New(isolate, module); |
| 2252 | 2203 |
| 2253 compiled_module->set_module_wrapper(module_wrapper); | 2204 compiled_module->set_module_wrapper(module_wrapper); |
| 2254 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); | 2205 DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module)); |
| 2255 } | 2206 } |
| OLD | NEW |