Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(651)

Side by Side Diff: src/wasm/wasm-module.cc

Issue 2421453002: [wasm] Implement {Compile,Runtime}Error; fix traps from start function (Closed)
Patch Set: Fix merge artefact Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/wasm-js.cc ('k') | src/wasm/wasm-result.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/wasm/wasm-js.cc ('k') | src/wasm/wasm-result.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698