| 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/adapters.h" | 7 #include "src/base/adapters.h" |
| 8 #include "src/base/atomic-utils.h" | 8 #include "src/base/atomic-utils.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/compiler/wasm-compiler.h" | 10 #include "src/compiler/wasm-compiler.h" |
| (...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 WasmModule* module_; | 1383 WasmModule* module_; |
| 1384 ErrorThrower* thrower_; | 1384 ErrorThrower* thrower_; |
| 1385 Handle<JSObject> module_object_; | 1385 Handle<JSObject> module_object_; |
| 1386 Handle<JSReceiver> ffi_; | 1386 Handle<JSReceiver> ffi_; |
| 1387 Handle<JSArrayBuffer> memory_; | 1387 Handle<JSArrayBuffer> memory_; |
| 1388 Handle<JSArrayBuffer> globals_; | 1388 Handle<JSArrayBuffer> globals_; |
| 1389 Handle<WasmCompiledModule> compiled_module_; | 1389 Handle<WasmCompiledModule> compiled_module_; |
| 1390 std::vector<TableInstance> table_instances_; | 1390 std::vector<TableInstance> table_instances_; |
| 1391 std::vector<Handle<JSFunction>> js_wrappers_; | 1391 std::vector<Handle<JSFunction>> js_wrappers_; |
| 1392 | 1392 |
| 1393 // Helper routine to print out errors with imports (FFI). | 1393 // Helper routines to print out errors with imports. |
| 1394 MaybeHandle<JSFunction> ReportFFIError(const char* error, uint32_t index, | 1394 void ReportLinkError(const char* error, uint32_t index, |
| 1395 Handle<String> module_name, | 1395 Handle<String> module_name, |
| 1396 MaybeHandle<String> function_name) { | 1396 Handle<String> import_name) { |
| 1397 Handle<String> function_name_handle; | 1397 thrower_->LinkError( |
| 1398 if (function_name.ToHandle(&function_name_handle)) { | 1398 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, |
| 1399 thrower_->TypeError( | 1399 module_name->length(), module_name->ToCString().get(), |
| 1400 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, | 1400 import_name->length(), import_name->ToCString().get(), error); |
| 1401 module_name->length(), module_name->ToCString().get(), | 1401 } |
| 1402 function_name_handle->length(), | 1402 |
| 1403 function_name_handle->ToCString().get(), error); | 1403 MaybeHandle<Object> ReportTypeError(const char* error, uint32_t index, |
| 1404 } else { | 1404 Handle<String> module_name) { |
| 1405 thrower_->TypeError("Import #%d module=\"%.*s\" error: %s", index, | 1405 thrower_->TypeError("Import #%d module=\"%.*s\" error: %s", index, |
| 1406 module_name->length(), module_name->ToCString().get(), | 1406 module_name->length(), module_name->ToCString().get(), |
| 1407 error); | 1407 error); |
| 1408 } | 1408 return MaybeHandle<Object>(); |
| 1409 thrower_->TypeError("Import "); | |
| 1410 return MaybeHandle<JSFunction>(); | |
| 1411 } | 1409 } |
| 1412 | 1410 |
| 1413 // Look up an import value in the {ffi_} object. | 1411 // Look up an import value in the {ffi_} object. |
| 1414 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, | 1412 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, |
| 1415 MaybeHandle<String> import_name) { | 1413 Handle<String> import_name) { |
| 1416 if (ffi_.is_null()) { | 1414 if (ffi_.is_null()) { |
| 1417 return ReportFFIError("FFI is not an object", index, module_name, | 1415 return ReportTypeError("FFI is not an object", index, module_name); |
| 1418 import_name); | |
| 1419 } | 1416 } |
| 1420 | 1417 |
| 1421 // Look up the module first. | 1418 // Look up the module first. |
| 1422 MaybeHandle<Object> result = | 1419 MaybeHandle<Object> result = |
| 1423 Object::GetPropertyOrElement(ffi_, module_name); | 1420 Object::GetPropertyOrElement(ffi_, module_name); |
| 1424 if (result.is_null()) { | 1421 if (result.is_null()) { |
| 1425 return ReportFFIError("module not found", index, module_name, | 1422 return ReportTypeError("module not found", index, module_name); |
| 1426 import_name); | |
| 1427 } | 1423 } |
| 1428 | 1424 |
| 1429 Handle<Object> module = result.ToHandleChecked(); | 1425 Handle<Object> module = result.ToHandleChecked(); |
| 1430 | 1426 |
| 1431 if (!import_name.is_null()) { | 1427 // TODO(bradnelson): Making this conditional on non-empty names violates the |
| 1428 // Wasm spec, but seems to be a hack intended for the asm-to-wasm pipeline. |
| 1429 // We need to get rid of it. |
| 1430 if (import_name->length() != 0) { |
| 1432 // Look up the value in the module. | 1431 // Look up the value in the module. |
| 1433 if (!module->IsJSReceiver()) { | 1432 if (!module->IsJSReceiver()) { |
| 1434 return ReportFFIError("module is not an object or function", index, | 1433 return ReportTypeError("module is not an object or function", index, |
| 1435 module_name, import_name); | 1434 module_name); |
| 1436 } | 1435 } |
| 1437 | 1436 |
| 1438 result = | 1437 result = Object::GetPropertyOrElement(module, import_name); |
| 1439 Object::GetPropertyOrElement(module, import_name.ToHandleChecked()); | |
| 1440 if (result.is_null()) { | 1438 if (result.is_null()) { |
| 1441 return ReportFFIError("import not found", index, module_name, | 1439 ReportLinkError("import not found", index, module_name, import_name); |
| 1442 import_name); | 1440 return MaybeHandle<JSFunction>(); |
| 1443 } | 1441 } |
| 1444 } else { | |
| 1445 // No function specified. Use the "default export". | |
| 1446 result = module; | |
| 1447 } | 1442 } |
| 1448 | 1443 |
| 1449 return result; | 1444 return result; |
| 1450 } | 1445 } |
| 1451 | 1446 |
| 1452 uint32_t EvalUint32InitExpr(const WasmInitExpr& expr) { | 1447 uint32_t EvalUint32InitExpr(const WasmInitExpr& expr) { |
| 1453 switch (expr.kind) { | 1448 switch (expr.kind) { |
| 1454 case WasmInitExpr::kI32Const: | 1449 case WasmInitExpr::kI32Const: |
| 1455 return expr.val.i32_const; | 1450 return expr.val.i32_const; |
| 1456 case WasmInitExpr::kGlobalIndex: { | 1451 case WasmInitExpr::kGlobalIndex: { |
| 1457 uint32_t offset = module_->globals[expr.val.global_index].offset; | 1452 uint32_t offset = module_->globals[expr.val.global_index].offset; |
| 1458 return *reinterpret_cast<uint32_t*>(raw_buffer_ptr(globals_, offset)); | 1453 return *reinterpret_cast<uint32_t*>(raw_buffer_ptr(globals_, offset)); |
| 1459 } | 1454 } |
| 1460 default: | 1455 default: |
| 1461 UNREACHABLE(); | 1456 UNREACHABLE(); |
| 1462 return 0; | 1457 return 0; |
| 1463 } | 1458 } |
| 1464 } | 1459 } |
| 1465 | 1460 |
| 1466 // Load data segments into the memory. | 1461 // Load data segments into the memory. |
| 1467 void LoadDataSegments(Address mem_addr, size_t mem_size) { | 1462 void LoadDataSegments(Address mem_addr, size_t mem_size) { |
| 1468 Handle<SeqOneByteString> module_bytes = compiled_module_->module_bytes(); | 1463 Handle<SeqOneByteString> module_bytes = compiled_module_->module_bytes(); |
| 1469 for (const WasmDataSegment& segment : module_->data_segments) { | 1464 for (const WasmDataSegment& segment : module_->data_segments) { |
| 1470 uint32_t source_size = segment.source_size; | 1465 uint32_t source_size = segment.source_size; |
| 1471 // Segments of size == 0 are just nops. | 1466 // Segments of size == 0 are just nops. |
| 1472 if (source_size == 0) continue; | 1467 if (source_size == 0) continue; |
| 1473 uint32_t dest_offset = EvalUint32InitExpr(segment.dest_addr); | 1468 uint32_t dest_offset = EvalUint32InitExpr(segment.dest_addr); |
| 1474 if (dest_offset >= mem_size || source_size >= mem_size || | 1469 if (dest_offset >= mem_size || source_size >= mem_size || |
| 1475 dest_offset > (mem_size - source_size)) { | 1470 dest_offset > (mem_size - source_size)) { |
| 1476 thrower_->TypeError("data segment (start = %" PRIu32 ", size = %" PRIu32 | 1471 thrower_->LinkError("data segment (start = %" PRIu32 ", size = %" PRIu32 |
| 1477 ") does not fit into memory (size = %" PRIuS ")", | 1472 ") does not fit into memory (size = %" PRIuS ")", |
| 1478 dest_offset, source_size, mem_size); | 1473 dest_offset, source_size, mem_size); |
| 1479 return; | 1474 return; |
| 1480 } | 1475 } |
| 1481 byte* dest = mem_addr + dest_offset; | 1476 byte* dest = mem_addr + dest_offset; |
| 1482 const byte* src = reinterpret_cast<const byte*>( | 1477 const byte* src = reinterpret_cast<const byte*>( |
| 1483 module_bytes->GetCharsAddress() + segment.source_offset); | 1478 module_bytes->GetCharsAddress() + segment.source_offset); |
| 1484 memcpy(dest, src, source_size); | 1479 memcpy(dest, src, source_size); |
| 1485 } | 1480 } |
| 1486 } | 1481 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 // Process the imports, including functions, tables, globals, and memory, in | 1513 // Process the imports, including functions, tables, globals, and memory, in |
| 1519 // order, loading them from the {ffi_} object. Returns the number of imported | 1514 // order, loading them from the {ffi_} object. Returns the number of imported |
| 1520 // functions. | 1515 // functions. |
| 1521 int ProcessImports(Handle<FixedArray> code_table, | 1516 int ProcessImports(Handle<FixedArray> code_table, |
| 1522 Handle<WasmInstanceObject> instance) { | 1517 Handle<WasmInstanceObject> instance) { |
| 1523 int num_imported_functions = 0; | 1518 int num_imported_functions = 0; |
| 1524 int num_imported_tables = 0; | 1519 int num_imported_tables = 0; |
| 1525 for (int index = 0; index < static_cast<int>(module_->import_table.size()); | 1520 for (int index = 0; index < static_cast<int>(module_->import_table.size()); |
| 1526 ++index) { | 1521 ++index) { |
| 1527 WasmImport& import = module_->import_table[index]; | 1522 WasmImport& import = module_->import_table[index]; |
| 1528 Handle<String> module_name = | 1523 |
| 1524 Handle<String> module_name; |
| 1525 MaybeHandle<String> maybe_module_name = |
| 1529 ExtractStringFromModuleBytes(isolate_, compiled_module_, | 1526 ExtractStringFromModuleBytes(isolate_, compiled_module_, |
| 1530 import.module_name_offset, | 1527 import.module_name_offset, |
| 1531 import.module_name_length) | 1528 import.module_name_length); |
| 1532 .ToHandleChecked(); | 1529 if (!maybe_module_name.ToHandle(&module_name)) return -1; |
| 1533 Handle<String> function_name = Handle<String>::null(); | 1530 |
| 1534 if (import.field_name_length > 0) { | 1531 Handle<String> import_name; |
| 1535 function_name = ExtractStringFromModuleBytes(isolate_, compiled_module_, | 1532 MaybeHandle<String> maybe_import_name = |
| 1536 import.field_name_offset, | 1533 ExtractStringFromModuleBytes(isolate_, compiled_module_, |
| 1537 import.field_name_length) | 1534 import.field_name_offset, |
| 1538 .ToHandleChecked(); | 1535 import.field_name_length); |
| 1539 } | 1536 if (!maybe_import_name.ToHandle(&import_name)) return -1; |
| 1540 | 1537 |
| 1541 MaybeHandle<Object> result = | 1538 MaybeHandle<Object> result = |
| 1542 LookupImport(index, module_name, function_name); | 1539 LookupImport(index, module_name, import_name); |
| 1543 if (thrower_->error()) return -1; | 1540 if (thrower_->error()) return -1; |
| 1541 Handle<Object> value = result.ToHandleChecked(); |
| 1544 | 1542 |
| 1545 switch (import.kind) { | 1543 switch (import.kind) { |
| 1546 case kExternalFunction: { | 1544 case kExternalFunction: { |
| 1547 // Function imports must be callable. | 1545 // Function imports must be callable. |
| 1548 Handle<Object> function = result.ToHandleChecked(); | 1546 if (!value->IsCallable()) { |
| 1549 if (!function->IsCallable()) { | 1547 ReportLinkError("function import requires a callable", index, |
| 1550 ReportFFIError("function import requires a callable", index, | 1548 module_name, import_name); |
| 1551 module_name, function_name); | |
| 1552 return -1; | 1549 return -1; |
| 1553 } | 1550 } |
| 1554 | 1551 |
| 1555 Handle<Code> import_wrapper = CompileImportWrapper( | 1552 Handle<Code> import_wrapper = CompileImportWrapper( |
| 1556 isolate_, index, module_->functions[import.index].sig, | 1553 isolate_, index, module_->functions[import.index].sig, |
| 1557 Handle<JSReceiver>::cast(function), module_name, function_name, | 1554 Handle<JSReceiver>::cast(value), module_name, import_name, |
| 1558 module_->origin); | 1555 module_->origin); |
| 1559 if (import_wrapper.is_null()) { | 1556 if (import_wrapper.is_null()) { |
| 1560 ReportFFIError("imported function does not match the expected type", | 1557 ReportLinkError( |
| 1561 index, module_name, function_name); | 1558 "imported function does not match the expected type", |
| 1559 index, module_name, import_name); |
| 1562 return -1; | 1560 return -1; |
| 1563 } | 1561 } |
| 1564 code_table->set(num_imported_functions, *import_wrapper); | 1562 code_table->set(num_imported_functions, *import_wrapper); |
| 1565 RecordStats(isolate_, *import_wrapper); | 1563 RecordStats(isolate_, *import_wrapper); |
| 1566 num_imported_functions++; | 1564 num_imported_functions++; |
| 1567 break; | 1565 break; |
| 1568 } | 1566 } |
| 1569 case kExternalTable: { | 1567 case kExternalTable: { |
| 1570 Handle<Object> value = result.ToHandleChecked(); | |
| 1571 if (!WasmJs::IsWasmTableObject(isolate_, value)) { | 1568 if (!WasmJs::IsWasmTableObject(isolate_, value)) { |
| 1572 ReportFFIError("table import requires a WebAssembly.Table", index, | 1569 ReportLinkError("table import requires a WebAssembly.Table", index, |
| 1573 module_name, function_name); | 1570 module_name, import_name); |
| 1574 return -1; | 1571 return -1; |
| 1575 } | 1572 } |
| 1576 WasmIndirectFunctionTable& table = | 1573 WasmIndirectFunctionTable& table = |
| 1577 module_->function_tables[num_imported_tables]; | 1574 module_->function_tables[num_imported_tables]; |
| 1578 TableInstance& table_instance = table_instances_[num_imported_tables]; | 1575 TableInstance& table_instance = table_instances_[num_imported_tables]; |
| 1579 table_instance.table_object = Handle<WasmTableObject>::cast(value); | 1576 table_instance.table_object = Handle<WasmTableObject>::cast(value); |
| 1580 table_instance.js_wrappers = Handle<FixedArray>( | 1577 table_instance.js_wrappers = Handle<FixedArray>( |
| 1581 table_instance.table_object->get_functions(), isolate_); | 1578 table_instance.table_object->get_functions(), isolate_); |
| 1582 | 1579 |
| 1583 // TODO(titzer): import table size must match exactly for now. | 1580 // TODO(titzer): import table size must match exactly for now. |
| 1584 int table_size = table_instance.js_wrappers->length(); | 1581 int table_size = table_instance.js_wrappers->length(); |
| 1585 if (table_size != static_cast<int>(table.min_size)) { | 1582 if (table_size != static_cast<int>(table.min_size)) { |
| 1586 thrower_->TypeError( | 1583 thrower_->LinkError( |
| 1587 "table import %d is wrong size (%d), expected %u", index, | 1584 "table import %d is wrong size (%d), expected %u", index, |
| 1588 table_size, table.min_size); | 1585 table_size, table.min_size); |
| 1589 return -1; | 1586 return -1; |
| 1590 } | 1587 } |
| 1591 | 1588 |
| 1592 // Allocate a new dispatch table. | 1589 // Allocate a new dispatch table. |
| 1593 table_instance.dispatch_table = | 1590 table_instance.dispatch_table = |
| 1594 isolate_->factory()->NewFixedArray(table_size * 2); | 1591 isolate_->factory()->NewFixedArray(table_size * 2); |
| 1595 for (int i = 0; i < table_size * 2; ++i) { | 1592 for (int i = 0; i < table_size * 2; ++i) { |
| 1596 table_instance.dispatch_table->set(i, | 1593 table_instance.dispatch_table->set(i, |
| 1597 Smi::FromInt(kInvalidSigIndex)); | 1594 Smi::FromInt(kInvalidSigIndex)); |
| 1598 } | 1595 } |
| 1599 // Initialize the dispatch table with the (foreign) JS functions | 1596 // Initialize the dispatch table with the (foreign) JS functions |
| 1600 // that are already in the table. | 1597 // that are already in the table. |
| 1601 for (int i = 0; i < table_size; ++i) { | 1598 for (int i = 0; i < table_size; ++i) { |
| 1602 Handle<Object> val(table_instance.js_wrappers->get(i), isolate_); | 1599 Handle<Object> val(table_instance.js_wrappers->get(i), isolate_); |
| 1603 if (!val->IsJSFunction()) continue; | 1600 if (!val->IsJSFunction()) continue; |
| 1604 WasmFunction* function = | 1601 WasmFunction* function = |
| 1605 GetWasmFunctionForImportWrapper(isolate_, val); | 1602 GetWasmFunctionForImportWrapper(isolate_, val); |
| 1606 if (function == nullptr) { | 1603 if (function == nullptr) { |
| 1607 thrower_->TypeError("table import %d[%d] is not a WASM function", | 1604 thrower_->LinkError("table import %d[%d] is not a WASM function", |
| 1608 index, i); | 1605 index, i); |
| 1609 return -1; | 1606 return -1; |
| 1610 } | 1607 } |
| 1611 int sig_index = table.map.FindOrInsert(function->sig); | 1608 int sig_index = table.map.FindOrInsert(function->sig); |
| 1612 table_instance.dispatch_table->set(i, Smi::FromInt(sig_index)); | 1609 table_instance.dispatch_table->set(i, Smi::FromInt(sig_index)); |
| 1613 table_instance.dispatch_table->set(i + table_size, | 1610 table_instance.dispatch_table->set(i + table_size, |
| 1614 *UnwrapImportWrapper(val)); | 1611 *UnwrapImportWrapper(val)); |
| 1615 } | 1612 } |
| 1616 | 1613 |
| 1617 num_imported_tables++; | 1614 num_imported_tables++; |
| 1618 break; | 1615 break; |
| 1619 } | 1616 } |
| 1620 case kExternalMemory: { | 1617 case kExternalMemory: { |
| 1621 Handle<Object> object = result.ToHandleChecked(); | 1618 if (!WasmJs::IsWasmMemoryObject(isolate_, value)) { |
| 1622 if (!WasmJs::IsWasmMemoryObject(isolate_, object)) { | 1619 ReportLinkError("memory import must be a WebAssembly.Memory object", |
| 1623 ReportFFIError("memory import must be a WebAssembly.Memory object", | 1620 index, module_name, import_name); |
| 1624 index, module_name, function_name); | |
| 1625 return -1; | 1621 return -1; |
| 1626 } | 1622 } |
| 1627 auto memory = Handle<WasmMemoryObject>::cast(object); | 1623 auto memory = Handle<WasmMemoryObject>::cast(value); |
| 1628 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory)); | 1624 DCHECK(WasmJs::IsWasmMemoryObject(isolate_, memory)); |
| 1629 instance->set_memory_object(*memory); | 1625 instance->set_memory_object(*memory); |
| 1630 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_); | 1626 memory_ = Handle<JSArrayBuffer>(memory->get_buffer(), isolate_); |
| 1631 break; | 1627 break; |
| 1632 } | 1628 } |
| 1633 case kExternalGlobal: { | 1629 case kExternalGlobal: { |
| 1634 // Global imports are converted to numbers and written into the | 1630 // Global imports are converted to numbers and written into the |
| 1635 // {globals_} array buffer. | 1631 // {globals_} array buffer. |
| 1636 Handle<Object> object = result.ToHandleChecked(); | 1632 if (!value->IsNumber()) { |
| 1637 MaybeHandle<Object> number = Object::ToNumber(object); | 1633 ReportLinkError("global import must be a number", |
| 1638 if (number.is_null()) { | 1634 index, module_name, import_name); |
| 1639 ReportFFIError("global import could not be converted to number", | |
| 1640 index, module_name, function_name); | |
| 1641 return -1; | 1635 return -1; |
| 1642 } | 1636 } |
| 1643 Handle<Object> val = number.ToHandleChecked(); | 1637 WriteGlobalValue(module_->globals[import.index], value); |
| 1644 WriteGlobalValue(module_->globals[import.index], val); | |
| 1645 break; | 1638 break; |
| 1646 } | 1639 } |
| 1647 default: | 1640 default: |
| 1648 UNREACHABLE(); | 1641 UNREACHABLE(); |
| 1649 break; | 1642 break; |
| 1650 } | 1643 } |
| 1651 } | 1644 } |
| 1652 return num_imported_functions; | 1645 return num_imported_functions; |
| 1653 } | 1646 } |
| 1654 | 1647 |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 if (module_->origin == kAsmJsOrigin) { | 1849 if (module_->origin == kAsmJsOrigin) { |
| 1857 v8::Maybe<bool> status = | 1850 v8::Maybe<bool> status = |
| 1858 JSReceiver::HasOwnProperty(exports_object, name); | 1851 JSReceiver::HasOwnProperty(exports_object, name); |
| 1859 if (status.FromMaybe(false)) { | 1852 if (status.FromMaybe(false)) { |
| 1860 continue; | 1853 continue; |
| 1861 } | 1854 } |
| 1862 } | 1855 } |
| 1863 v8::Maybe<bool> status = JSReceiver::DefineOwnProperty( | 1856 v8::Maybe<bool> status = JSReceiver::DefineOwnProperty( |
| 1864 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); | 1857 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); |
| 1865 if (!status.IsJust()) { | 1858 if (!status.IsJust()) { |
| 1866 thrower_->TypeError("export of %.*s failed.", name->length(), | 1859 thrower_->LinkError("export of %.*s failed.", name->length(), |
| 1867 name->ToCString().get()); | 1860 name->ToCString().get()); |
| 1868 return; | 1861 return; |
| 1869 } | 1862 } |
| 1870 } | 1863 } |
| 1871 } | 1864 } |
| 1872 | 1865 |
| 1873 void InitializeTables(Handle<FixedArray> code_table, | 1866 void InitializeTables(Handle<FixedArray> code_table, |
| 1874 Handle<WasmInstanceObject> instance) { | 1867 Handle<WasmInstanceObject> instance) { |
| 1875 Handle<FixedArray> old_function_tables = | 1868 Handle<FixedArray> old_function_tables = |
| 1876 compiled_module_->function_tables(); | 1869 compiled_module_->function_tables(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1906 Handle<FixedArray>::null()); | 1899 Handle<FixedArray>::null()); |
| 1907 } | 1900 } |
| 1908 | 1901 |
| 1909 // TODO(titzer): this does redundant work if there are multiple tables, | 1902 // TODO(titzer): this does redundant work if there are multiple tables, |
| 1910 // since initializations are not sorted by table index. | 1903 // since initializations are not sorted by table index. |
| 1911 for (auto table_init : module_->table_inits) { | 1904 for (auto table_init : module_->table_inits) { |
| 1912 uint32_t base = EvalUint32InitExpr(table_init.offset); | 1905 uint32_t base = EvalUint32InitExpr(table_init.offset); |
| 1913 if (base > static_cast<uint32_t>(table_size) || | 1906 if (base > static_cast<uint32_t>(table_size) || |
| 1914 (base + table_init.entries.size() > | 1907 (base + table_init.entries.size() > |
| 1915 static_cast<uint32_t>(table_size))) { | 1908 static_cast<uint32_t>(table_size))) { |
| 1916 thrower_->CompileError("table initializer is out of bounds"); | 1909 thrower_->LinkError("table initializer is out of bounds"); |
| 1917 continue; | 1910 continue; |
| 1918 } | 1911 } |
| 1919 for (int i = 0; i < static_cast<int>(table_init.entries.size()); ++i) { | 1912 for (int i = 0; i < static_cast<int>(table_init.entries.size()); ++i) { |
| 1920 uint32_t func_index = table_init.entries[i]; | 1913 uint32_t func_index = table_init.entries[i]; |
| 1921 WasmFunction* function = &module_->functions[func_index]; | 1914 WasmFunction* function = &module_->functions[func_index]; |
| 1922 int table_index = static_cast<int>(i + base); | 1915 int table_index = static_cast<int>(i + base); |
| 1923 int32_t sig_index = table.map.Find(function->sig); | 1916 int32_t sig_index = table.map.Find(function->sig); |
| 1924 DCHECK_GE(sig_index, 0); | 1917 DCHECK_GE(sig_index, 0); |
| 1925 table_instance.dispatch_table->set(table_index, | 1918 table_instance.dispatch_table->set(table_index, |
| 1926 Smi::FromInt(sig_index)); | 1919 Smi::FromInt(sig_index)); |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 MaybeHandle<String> WasmCompiledModule::GetFunctionName( | 2387 MaybeHandle<String> WasmCompiledModule::GetFunctionName( |
| 2395 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { | 2388 Handle<WasmCompiledModule> compiled_module, uint32_t func_index) { |
| 2396 DCHECK_LT(func_index, compiled_module->module()->functions.size()); | 2389 DCHECK_LT(func_index, compiled_module->module()->functions.size()); |
| 2397 WasmFunction& function = compiled_module->module()->functions[func_index]; | 2390 WasmFunction& function = compiled_module->module()->functions[func_index]; |
| 2398 Isolate* isolate = compiled_module->GetIsolate(); | 2391 Isolate* isolate = compiled_module->GetIsolate(); |
| 2399 MaybeHandle<String> string = ExtractStringFromModuleBytes( | 2392 MaybeHandle<String> string = ExtractStringFromModuleBytes( |
| 2400 isolate, compiled_module, function.name_offset, function.name_length); | 2393 isolate, compiled_module, function.name_offset, function.name_length); |
| 2401 if (!string.is_null()) return string.ToHandleChecked(); | 2394 if (!string.is_null()) return string.ToHandleChecked(); |
| 2402 return {}; | 2395 return {}; |
| 2403 } | 2396 } |
| OLD | NEW |