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 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 i < module->functions.size(); ++i) { | 558 i < module->functions.size(); ++i) { |
559 const WasmFunction& func = module->functions[i]; | 559 const WasmFunction& func = module->functions[i]; |
560 if (func.imported) continue; // Imports are compiled at instantiation time. | 560 if (func.imported) continue; // Imports are compiled at instantiation time. |
561 | 561 |
562 WasmName str = module->GetName(func.name_offset, func.name_length); | 562 WasmName str = module->GetName(func.name_offset, func.name_length); |
563 Handle<Code> code = Handle<Code>::null(); | 563 Handle<Code> code = Handle<Code>::null(); |
564 // Compile the function. | 564 // Compile the function. |
565 code = compiler::WasmCompilationUnit::CompileWasmFunction( | 565 code = compiler::WasmCompilationUnit::CompileWasmFunction( |
566 thrower, isolate, module_env, &func); | 566 thrower, isolate, module_env, &func); |
567 if (code.is_null()) { | 567 if (code.is_null()) { |
568 thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(), | 568 thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(), |
569 str.start()); | 569 str.start()); |
570 break; | 570 break; |
571 } | 571 } |
572 // Install the code into the linker table. | 572 // Install the code into the linker table. |
573 functions[i] = code; | 573 functions[i] = code; |
574 } | 574 } |
575 } | 575 } |
576 | 576 |
577 void PatchDirectCalls(Handle<FixedArray> old_functions, | 577 void PatchDirectCalls(Handle<FixedArray> old_functions, |
578 Handle<FixedArray> new_functions, int start) { | 578 Handle<FixedArray> new_functions, int start) { |
579 DCHECK_EQ(new_functions->length(), old_functions->length()); | 579 DCHECK_EQ(new_functions->length(), old_functions->length()); |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 // Set up the globals for the new instance. | 1261 // Set up the globals for the new instance. |
1262 //-------------------------------------------------------------------------- | 1262 //-------------------------------------------------------------------------- |
1263 MaybeHandle<JSArrayBuffer> old_globals; | 1263 MaybeHandle<JSArrayBuffer> old_globals; |
1264 MaybeHandle<JSArrayBuffer> globals; | 1264 MaybeHandle<JSArrayBuffer> globals; |
1265 uint32_t globals_size = compiled_module_->globals_size(); | 1265 uint32_t globals_size = compiled_module_->globals_size(); |
1266 if (globals_size > 0) { | 1266 if (globals_size > 0) { |
1267 Handle<JSArrayBuffer> global_buffer = | 1267 Handle<JSArrayBuffer> global_buffer = |
1268 NewArrayBuffer(isolate_, globals_size); | 1268 NewArrayBuffer(isolate_, globals_size); |
1269 globals = global_buffer; | 1269 globals = global_buffer; |
1270 if (globals.is_null()) { | 1270 if (globals.is_null()) { |
1271 thrower_->Error("Out of memory: wasm globals"); | 1271 thrower_->RangeError("Out of memory: wasm globals"); |
1272 return nothing; | 1272 return nothing; |
1273 } | 1273 } |
1274 Address old_address = owner.is_null() | 1274 Address old_address = owner.is_null() |
1275 ? nullptr | 1275 ? nullptr |
1276 : GetGlobalStartAddressFromCodeTemplate( | 1276 : GetGlobalStartAddressFromCodeTemplate( |
1277 *factory->undefined_value(), | 1277 *factory->undefined_value(), |
1278 JSObject::cast(*owner.ToHandleChecked())); | 1278 JSObject::cast(*owner.ToHandleChecked())); |
1279 RelocateGlobals(instance, old_address, | 1279 RelocateGlobals(instance, old_address, |
1280 static_cast<Address>(global_buffer->backing_store())); | 1280 static_cast<Address>(global_buffer->backing_store())); |
1281 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); | 1281 instance->SetInternalField(kWasmGlobalsArrayBuffer, *global_buffer); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1418 } | 1418 } |
1419 module_object_->SetInternalField(0, *compiled_module_); | 1419 module_object_->SetInternalField(0, *compiled_module_); |
1420 instance->SetInternalField(kWasmCompiledModule, *compiled_module_); | 1420 instance->SetInternalField(kWasmCompiledModule, *compiled_module_); |
1421 compiled_module_->set_weak_owning_instance(link_to_owning_instance); | 1421 compiled_module_->set_weak_owning_instance(link_to_owning_instance); |
1422 GlobalHandles::MakeWeak(global_handle.location(), | 1422 GlobalHandles::MakeWeak(global_handle.location(), |
1423 global_handle.location(), &InstanceFinalizer, | 1423 global_handle.location(), &InstanceFinalizer, |
1424 v8::WeakCallbackType::kFinalizer); | 1424 v8::WeakCallbackType::kFinalizer); |
1425 } | 1425 } |
1426 } | 1426 } |
1427 | 1427 |
| 1428 DCHECK(wasm::IsWasmObject(*instance)); |
| 1429 |
1428 //-------------------------------------------------------------------------- | 1430 //-------------------------------------------------------------------------- |
1429 // Run the start function if one was specified. | 1431 // Run the start function if one was specified. |
1430 //-------------------------------------------------------------------------- | 1432 //-------------------------------------------------------------------------- |
1431 if (compiled_module_->has_startup_function()) { | 1433 if (compiled_module_->has_startup_function()) { |
1432 Handle<FixedArray> startup_data = compiled_module_->startup_function(); | 1434 Handle<FixedArray> startup_data = compiled_module_->startup_function(); |
1433 HandleScope scope(isolate_); | 1435 HandleScope scope(isolate_); |
1434 int32_t start_index = | 1436 int32_t start_index = |
1435 startup_data->GetValueChecked<Smi>(isolate_, kExportIndex)->value(); | 1437 startup_data->GetValueChecked<Smi>(isolate_, kExportIndex)->value(); |
1436 Handle<Code> startup_code = | 1438 Handle<Code> startup_code = |
1437 code_table->GetValueChecked<Code>(isolate_, start_index); | 1439 code_table->GetValueChecked<Code>(isolate_, start_index); |
1438 int arity = Smi::cast(startup_data->get(kExportArity))->value(); | 1440 int arity = Smi::cast(startup_data->get(kExportArity))->value(); |
1439 MaybeHandle<ByteArray> startup_signature = | 1441 MaybeHandle<ByteArray> startup_signature = |
1440 startup_data->GetValue<ByteArray>(isolate_, kExportedSignature); | 1442 startup_data->GetValue<ByteArray>(isolate_, kExportedSignature); |
1441 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( | 1443 Handle<JSFunction> startup_fct = WrapExportCodeAsJSFunction( |
1442 isolate_, startup_code, factory->InternalizeUtf8String("start"), | 1444 isolate_, startup_code, factory->InternalizeUtf8String("start"), |
1443 arity, startup_signature, instance); | 1445 arity, startup_signature, instance); |
1444 RecordStats(isolate_, *startup_code); | 1446 RecordStats(isolate_, *startup_code); |
1445 // Call the JS function. | 1447 // Call the JS function. |
1446 Handle<Object> undefined = factory->undefined_value(); | 1448 Handle<Object> undefined = factory->undefined_value(); |
1447 MaybeHandle<Object> retval = | 1449 MaybeHandle<Object> retval = |
1448 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); | 1450 Execution::Call(isolate_, startup_fct, undefined, 0, nullptr); |
1449 | 1451 |
1450 if (retval.is_null()) { | 1452 if (retval.is_null()) { |
1451 thrower_->Error("WASM.instantiateModule(): start function failed"); | 1453 DCHECK(isolate_->has_pending_exception()); |
| 1454 isolate_->OptionalRescheduleException(false); |
1452 // It's unfortunate that the new instance is already linked in the | 1455 // It's unfortunate that the new instance is already linked in the |
1453 // chain. However, we need to set up everything before executing the | 1456 // chain. However, we need to set up everything before executing the |
1454 // start function, such that stack trace information can be generated | 1457 // start function, such that stack trace information can be generated |
1455 // correctly already in the start function. | 1458 // correctly already in the start function. |
1456 return nothing; | 1459 return nothing; |
1457 } | 1460 } |
1458 } | 1461 } |
1459 | 1462 |
1460 DCHECK(wasm::IsWasmObject(*instance)); | 1463 DCHECK(!isolate_->has_pending_exception()); |
1461 | |
1462 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); | 1464 TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
1463 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); | 1465 TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); |
1464 return instance; | 1466 return instance; |
1465 } | 1467 } |
1466 | 1468 |
1467 private: | 1469 private: |
1468 Isolate* isolate_; | 1470 Isolate* isolate_; |
1469 ErrorThrower* thrower_; | 1471 ErrorThrower* thrower_; |
1470 Handle<JSObject> module_object_; | 1472 Handle<JSObject> module_object_; |
1471 Handle<JSReceiver> ffi_; | 1473 Handle<JSReceiver> ffi_; |
1472 Handle<JSArrayBuffer> memory_; | 1474 Handle<JSArrayBuffer> memory_; |
1473 Handle<WasmCompiledModule> compiled_module_; | 1475 Handle<WasmCompiledModule> compiled_module_; |
1474 | 1476 |
1475 // Helper routine to print out errors with imports (FFI). | 1477 // Helper routine to print out errors with imports (FFI). |
1476 MaybeHandle<JSFunction> ReportFFIError(const char* error, uint32_t index, | 1478 MaybeHandle<JSFunction> ReportFFIError(const char* error, uint32_t index, |
1477 Handle<String> module_name, | 1479 Handle<String> module_name, |
1478 MaybeHandle<String> function_name) { | 1480 MaybeHandle<String> function_name) { |
1479 Handle<String> function_name_handle; | 1481 Handle<String> function_name_handle; |
1480 if (function_name.ToHandle(&function_name_handle)) { | 1482 if (function_name.ToHandle(&function_name_handle)) { |
1481 thrower_->Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", | 1483 thrower_->TypeError( |
1482 index, module_name->length(), | 1484 "Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index, |
1483 module_name->ToCString().get(), | 1485 module_name->length(), module_name->ToCString().get(), |
1484 function_name_handle->length(), | 1486 function_name_handle->length(), |
1485 function_name_handle->ToCString().get(), error); | 1487 function_name_handle->ToCString().get(), error); |
1486 } else { | 1488 } else { |
1487 thrower_->Error("Import #%d module=\"%.*s\" error: %s", index, | 1489 thrower_->TypeError("Import #%d module=\"%.*s\" error: %s", index, |
1488 module_name->length(), module_name->ToCString().get(), | 1490 module_name->length(), module_name->ToCString().get(), |
1489 error); | 1491 error); |
1490 } | 1492 } |
1491 thrower_->Error("Import "); | 1493 thrower_->TypeError("Import "); |
1492 return MaybeHandle<JSFunction>(); | 1494 return MaybeHandle<JSFunction>(); |
1493 } | 1495 } |
1494 | 1496 |
1495 // Look up an import value in the {ffi_} object. | 1497 // Look up an import value in the {ffi_} object. |
1496 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, | 1498 MaybeHandle<Object> LookupImport(uint32_t index, Handle<String> module_name, |
1497 MaybeHandle<String> import_name) { | 1499 MaybeHandle<String> import_name) { |
1498 if (ffi_.is_null()) { | 1500 if (ffi_.is_null()) { |
1499 return ReportFFIError("FFI is not an object", index, module_name, | 1501 return ReportFFIError("FFI is not an object", index, module_name, |
1500 import_name); | 1502 import_name); |
1501 } | 1503 } |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1766 if (type == kLocalI64 || type == kLocalF64) size = sizeof(double); | 1768 if (type == kLocalI64 || type == kLocalF64) size = sizeof(double); |
1767 memcpy(raw_buffer_ptr(globals, offset), | 1769 memcpy(raw_buffer_ptr(globals, offset), |
1768 raw_buffer_ptr(globals, old_offset), size); | 1770 raw_buffer_ptr(globals, old_offset), size); |
1769 } | 1771 } |
1770 } | 1772 } |
1771 } | 1773 } |
1772 | 1774 |
1773 // Allocate memory for a module instance as a new JSArrayBuffer. | 1775 // Allocate memory for a module instance as a new JSArrayBuffer. |
1774 Handle<JSArrayBuffer> AllocateMemory(uint32_t min_mem_pages) { | 1776 Handle<JSArrayBuffer> AllocateMemory(uint32_t min_mem_pages) { |
1775 if (min_mem_pages > WasmModule::kMaxMemPages) { | 1777 if (min_mem_pages > WasmModule::kMaxMemPages) { |
1776 thrower_->Error("Out of memory: wasm memory too large"); | 1778 thrower_->RangeError("Out of memory: wasm memory too large"); |
1777 return Handle<JSArrayBuffer>::null(); | 1779 return Handle<JSArrayBuffer>::null(); |
1778 } | 1780 } |
1779 Handle<JSArrayBuffer> mem_buffer = | 1781 Handle<JSArrayBuffer> mem_buffer = |
1780 NewArrayBuffer(isolate_, min_mem_pages * WasmModule::kPageSize); | 1782 NewArrayBuffer(isolate_, min_mem_pages * WasmModule::kPageSize); |
1781 | 1783 |
1782 if (mem_buffer.is_null()) { | 1784 if (mem_buffer.is_null()) { |
1783 thrower_->Error("Out of memory: wasm memory"); | 1785 thrower_->RangeError("Out of memory: wasm memory"); |
1784 } | 1786 } |
1785 return mem_buffer; | 1787 return mem_buffer; |
1786 } | 1788 } |
1787 | 1789 |
1788 // Process the exports, creating wrappers for functions, tables, memories, | 1790 // Process the exports, creating wrappers for functions, tables, memories, |
1789 // and globals. | 1791 // and globals. |
1790 void ProcessExports(MaybeHandle<JSArrayBuffer> globals, | 1792 void ProcessExports(MaybeHandle<JSArrayBuffer> globals, |
1791 Handle<FixedArray> code_table, | 1793 Handle<FixedArray> code_table, |
1792 Handle<JSObject> instance) { | 1794 Handle<JSObject> instance) { |
1793 if (!compiled_module_->has_exports()) return; | 1795 if (!compiled_module_->has_exports()) return; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 break; | 1876 break; |
1875 } | 1877 } |
1876 default: | 1878 default: |
1877 UNREACHABLE(); | 1879 UNREACHABLE(); |
1878 break; | 1880 break; |
1879 } | 1881 } |
1880 | 1882 |
1881 v8::Maybe<bool> status = JSReceiver::DefineOwnProperty( | 1883 v8::Maybe<bool> status = JSReceiver::DefineOwnProperty( |
1882 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); | 1884 isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); |
1883 if (!status.IsJust()) { | 1885 if (!status.IsJust()) { |
1884 thrower_->Error("export of %.*s failed.", name->length(), | 1886 thrower_->TypeError("export of %.*s failed.", name->length(), |
1885 name->ToCString().get()); | 1887 name->ToCString().get()); |
1886 return; | 1888 return; |
1887 } | 1889 } |
1888 } | 1890 } |
1889 } | 1891 } |
1890 }; | 1892 }; |
1891 | 1893 |
1892 // Instantiates a WASM module, creating a WebAssembly.Instance from a | 1894 // Instantiates a WASM module, creating a WebAssembly.Instance from a |
1893 // WebAssembly.Module. | 1895 // WebAssembly.Module. |
1894 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, | 1896 MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate, |
1895 ErrorThrower* thrower, | 1897 ErrorThrower* thrower, |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2159 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, | 2161 Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, |
2160 ModuleOrigin origin, Handle<Script> asm_js_script, | 2162 ModuleOrigin origin, Handle<Script> asm_js_script, |
2161 const byte* asm_js_offset_tables_start, | 2163 const byte* asm_js_offset_tables_start, |
2162 const byte* asm_js_offset_tables_end) { | 2164 const byte* asm_js_offset_tables_end) { |
2163 MaybeHandle<JSObject> nothing; | 2165 MaybeHandle<JSObject> nothing; |
2164 Zone zone(isolate->allocator()); | 2166 Zone zone(isolate->allocator()); |
2165 ModuleResult result = | 2167 ModuleResult result = |
2166 DecodeWasmModule(isolate, &zone, start, end, false, origin); | 2168 DecodeWasmModule(isolate, &zone, start, end, false, origin); |
2167 std::unique_ptr<const WasmModule> decoded_module(result.val); | 2169 std::unique_ptr<const WasmModule> decoded_module(result.val); |
2168 if (result.failed()) { | 2170 if (result.failed()) { |
2169 thrower->Failed("Wasm decoding failed", result); | 2171 thrower->CompileFailed("Wasm decoding failed", result); |
2170 return nothing; | 2172 return nothing; |
2171 } | 2173 } |
2172 MaybeHandle<WasmCompiledModule> maybe_compiled_module = | 2174 MaybeHandle<WasmCompiledModule> maybe_compiled_module = |
2173 decoded_module->CompileFunctions(isolate, thrower); | 2175 decoded_module->CompileFunctions(isolate, thrower); |
2174 if (maybe_compiled_module.is_null()) return nothing; | 2176 if (maybe_compiled_module.is_null()) return nothing; |
2175 Handle<WasmCompiledModule> compiled_module = | 2177 Handle<WasmCompiledModule> compiled_module = |
2176 maybe_compiled_module.ToHandleChecked(); | 2178 maybe_compiled_module.ToHandleChecked(); |
2177 | 2179 |
2178 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); | 2180 DCHECK_EQ(origin == kAsmJsOrigin, !asm_js_script.is_null()); |
2179 DCHECK(!compiled_module->has_asm_js_script()); | 2181 DCHECK(!compiled_module->has_asm_js_script()); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2326 } | 2328 } |
2327 | 2329 |
2328 void testing::ValidateOrphanedInstance(Isolate* isolate, | 2330 void testing::ValidateOrphanedInstance(Isolate* isolate, |
2329 Handle<JSObject> instance) { | 2331 Handle<JSObject> instance) { |
2330 DisallowHeapAllocation no_gc; | 2332 DisallowHeapAllocation no_gc; |
2331 CHECK(IsWasmObject(*instance)); | 2333 CHECK(IsWasmObject(*instance)); |
2332 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); | 2334 WasmCompiledModule* compiled_module = GetCompiledModule(*instance); |
2333 CHECK(compiled_module->has_weak_module_object()); | 2335 CHECK(compiled_module->has_weak_module_object()); |
2334 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); | 2336 CHECK(compiled_module->ptr_to_weak_module_object()->cleared()); |
2335 } | 2337 } |
OLD | NEW |