| 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 "src/macro-assembler.h" | 5 #include "src/macro-assembler.h" |
| 6 #include "src/objects.h" | 6 #include "src/objects.h" |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 #include "src/simulator.h" | 9 #include "src/simulator.h" |
| 10 | 10 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 94 |
| 95 os << " code bytes: " | 95 os << " code bytes: " |
| 96 << (function.code_end_offset - function.code_start_offset); | 96 << (function.code_end_offset - function.code_start_offset); |
| 97 return os; | 97 return os; |
| 98 } | 98 } |
| 99 | 99 |
| 100 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) { | 100 std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) { |
| 101 os << "#" << pair.function_->func_index << ":"; | 101 os << "#" << pair.function_->func_index << ":"; |
| 102 if (pair.function_->name_offset > 0) { | 102 if (pair.function_->name_offset > 0) { |
| 103 if (pair.module_) { | 103 if (pair.module_) { |
| 104 WasmName name = pair.module_->GetName(pair.function_->name_offset, | 104 Vector<const char> name = pair.module_->GetName( |
| 105 pair.function_->name_length); | 105 pair.function_->name_offset, pair.function_->name_length); |
| 106 os.write(name.name, name.length); | 106 os.write(name.start(), name.length()); |
| 107 } else { | 107 } else { |
| 108 os << "+" << pair.function_->func_index; | 108 os << "+" << pair.function_->func_index; |
| 109 } | 109 } |
| 110 } else { | 110 } else { |
| 111 os << "?"; | 111 os << "?"; |
| 112 } | 112 } |
| 113 return os; | 113 return os; |
| 114 } | 114 } |
| 115 | 115 |
| 116 // A helper class for compiling multiple wasm functions that offers | 116 // A helper class for compiling multiple wasm functions that offers |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 : shared_isolate(nullptr), | 326 : shared_isolate(nullptr), |
| 327 module_start(nullptr), | 327 module_start(nullptr), |
| 328 module_end(nullptr), | 328 module_end(nullptr), |
| 329 min_mem_pages(0), | 329 min_mem_pages(0), |
| 330 max_mem_pages(0), | 330 max_mem_pages(0), |
| 331 mem_export(false), | 331 mem_export(false), |
| 332 mem_external(false), | 332 mem_external(false), |
| 333 start_function_index(-1), | 333 start_function_index(-1), |
| 334 origin(kWasmOrigin) {} | 334 origin(kWasmOrigin) {} |
| 335 | 335 |
| 336 static MaybeHandle<JSFunction> ReportFFIError(ErrorThrower& thrower, | 336 static MaybeHandle<JSFunction> ReportFFIError( |
| 337 const char* error, uint32_t index, | 337 ErrorThrower& thrower, const char* error, uint32_t index, |
| 338 wasm::WasmName module_name, | 338 Vector<const char> module_name, Vector<const char> function_name) { |
| 339 wasm::WasmName function_name) { | 339 if (function_name.start()) { |
| 340 if (function_name.name) { | |
| 341 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", | 340 thrower.Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", |
| 342 index, module_name.length, module_name.name, | 341 index, module_name.length(), module_name.start(), |
| 343 function_name.length, function_name.name, error); | 342 function_name.length(), function_name.start(), error); |
| 344 } else { | 343 } else { |
| 345 thrower.Error("Import #%d module=\"%.*s\" error: %s", index, | 344 thrower.Error("Import #%d module=\"%.*s\" error: %s", index, |
| 346 module_name.length, module_name.name, error); | 345 module_name.length(), module_name.start(), error); |
| 347 } | 346 } |
| 348 thrower.Error("Import "); | 347 thrower.Error("Import "); |
| 349 return MaybeHandle<JSFunction>(); | 348 return MaybeHandle<JSFunction>(); |
| 350 } | 349 } |
| 351 | 350 |
| 352 static MaybeHandle<JSFunction> LookupFunction( | 351 static MaybeHandle<JSFunction> LookupFunction( |
| 353 ErrorThrower& thrower, Factory* factory, Handle<JSObject> ffi, | 352 ErrorThrower& thrower, Factory* factory, Handle<JSObject> ffi, |
| 354 uint32_t index, wasm::WasmName module_name, wasm::WasmName function_name) { | 353 uint32_t index, Vector<const char> module_name, |
| 354 Vector<const char> function_name) { |
| 355 if (ffi.is_null()) { | 355 if (ffi.is_null()) { |
| 356 return ReportFFIError(thrower, "FFI is not an object", index, module_name, | 356 return ReportFFIError(thrower, "FFI is not an object", index, module_name, |
| 357 function_name); | 357 function_name); |
| 358 } | 358 } |
| 359 | 359 |
| 360 // Look up the module first. | 360 // Look up the module first. |
| 361 Handle<String> name = factory->InternalizeUtf8String( | 361 Handle<String> name = factory->InternalizeUtf8String(module_name); |
| 362 Vector<const char>(module_name.name, module_name.length)); | |
| 363 MaybeHandle<Object> result = Object::GetProperty(ffi, name); | 362 MaybeHandle<Object> result = Object::GetProperty(ffi, name); |
| 364 if (result.is_null()) { | 363 if (result.is_null()) { |
| 365 return ReportFFIError(thrower, "module not found", index, module_name, | 364 return ReportFFIError(thrower, "module not found", index, module_name, |
| 366 function_name); | 365 function_name); |
| 367 } | 366 } |
| 368 | 367 |
| 369 Handle<Object> module = result.ToHandleChecked(); | 368 Handle<Object> module = result.ToHandleChecked(); |
| 370 | 369 |
| 371 if (!module->IsJSReceiver()) { | 370 if (!module->IsJSReceiver()) { |
| 372 return ReportFFIError(thrower, "module is not an object or function", index, | 371 return ReportFFIError(thrower, "module is not an object or function", index, |
| 373 module_name, function_name); | 372 module_name, function_name); |
| 374 } | 373 } |
| 375 | 374 |
| 376 Handle<Object> function; | 375 Handle<Object> function; |
| 377 if (function_name.name) { | 376 if (function_name.start()) { |
| 378 // Look up the function in the module. | 377 // Look up the function in the module. |
| 379 Handle<String> name = factory->InternalizeUtf8String( | 378 Handle<String> name = factory->InternalizeUtf8String(function_name); |
| 380 Vector<const char>(function_name.name, function_name.length)); | |
| 381 MaybeHandle<Object> result = Object::GetProperty(module, name); | 379 MaybeHandle<Object> result = Object::GetProperty(module, name); |
| 382 if (result.is_null()) { | 380 if (result.is_null()) { |
| 383 return ReportFFIError(thrower, "function not found", index, module_name, | 381 return ReportFFIError(thrower, "function not found", index, module_name, |
| 384 function_name); | 382 function_name); |
| 385 } | 383 } |
| 386 function = result.ToHandleChecked(); | 384 function = result.ToHandleChecked(); |
| 387 } else { | 385 } else { |
| 388 // No function specified. Use the "default export". | 386 // No function specified. Use the "default export". |
| 389 function = module; | 387 function = module; |
| 390 } | 388 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 WasmLinker linker(isolate, functions.size()); | 462 WasmLinker linker(isolate, functions.size()); |
| 465 ModuleEnv module_env; | 463 ModuleEnv module_env; |
| 466 module_env.module = this; | 464 module_env.module = this; |
| 467 module_env.instance = &instance; | 465 module_env.instance = &instance; |
| 468 module_env.linker = &linker; | 466 module_env.linker = &linker; |
| 469 module_env.origin = origin; | 467 module_env.origin = origin; |
| 470 | 468 |
| 471 if (import_table.size() > 0) { | 469 if (import_table.size() > 0) { |
| 472 instance.import_code.reserve(import_table.size()); | 470 instance.import_code.reserve(import_table.size()); |
| 473 for (const WasmImport& import : import_table) { | 471 for (const WasmImport& import : import_table) { |
| 474 WasmName module_name = | 472 Vector<const char> module_name = |
| 475 GetNameOrNull(import.module_name_offset, import.module_name_length); | 473 GetNameOrNull(import.module_name_offset, import.module_name_length); |
| 476 WasmName function_name = GetNameOrNull(import.function_name_offset, | 474 Vector<const char> function_name = GetNameOrNull( |
| 477 import.function_name_length); | 475 import.function_name_offset, import.function_name_length); |
| 478 MaybeHandle<JSFunction> function = LookupFunction( | 476 MaybeHandle<JSFunction> function = LookupFunction( |
| 479 thrower, factory, ffi, index, module_name, function_name); | 477 thrower, factory, ffi, index, module_name, function_name); |
| 480 if (function.is_null()) return MaybeHandle<JSObject>(); | 478 if (function.is_null()) return MaybeHandle<JSObject>(); |
| 481 Handle<Code> code = compiler::CompileWasmToJSWrapper( | 479 Handle<Code> code = compiler::CompileWasmToJSWrapper( |
| 482 isolate, &module_env, function.ToHandleChecked(), import.sig, | 480 isolate, &module_env, function.ToHandleChecked(), import.sig, |
| 483 module_name, function_name); | 481 module_name, function_name); |
| 484 instance.import_code.push_back(code); | 482 instance.import_code.push_back(code); |
| 485 index++; | 483 index++; |
| 486 } | 484 } |
| 487 } | 485 } |
| 488 | 486 |
| 489 //------------------------------------------------------------------------- | 487 //------------------------------------------------------------------------- |
| 490 // Compile all functions in the module. | 488 // Compile all functions in the module. |
| 491 //------------------------------------------------------------------------- | 489 //------------------------------------------------------------------------- |
| 492 { | 490 { |
| 493 isolate->counters()->wasm_functions_per_module()->AddSample( | 491 isolate->counters()->wasm_functions_per_module()->AddSample( |
| 494 static_cast<int>(functions.size())); | 492 static_cast<int>(functions.size())); |
| 495 | 493 |
| 496 // First pass: compile each function and initialize the code table. | 494 // First pass: compile each function and initialize the code table. |
| 497 index = FLAG_skip_compiling_wasm_funcs; | 495 index = FLAG_skip_compiling_wasm_funcs; |
| 498 while (index < functions.size()) { | 496 while (index < functions.size()) { |
| 499 const WasmFunction& func = functions[index]; | 497 const WasmFunction& func = functions[index]; |
| 500 if (thrower.error()) break; | 498 if (thrower.error()) break; |
| 501 DCHECK_EQ(index, func.func_index); | 499 DCHECK_EQ(index, func.func_index); |
| 502 | 500 |
| 503 WasmName str = GetName(func.name_offset, func.name_length); | 501 Vector<const char> str = GetName(func.name_offset, func.name_length); |
| 504 WasmName str_null = {nullptr, 0}; | 502 Vector<const char> str_null = {nullptr, 0}; |
| 505 Handle<String> name = factory->InternalizeUtf8String( | 503 Handle<String> name = factory->InternalizeUtf8String(str); |
| 506 Vector<const char>(str.name, str.length)); | |
| 507 Handle<Code> code = Handle<Code>::null(); | 504 Handle<Code> code = Handle<Code>::null(); |
| 508 Handle<JSFunction> function = Handle<JSFunction>::null(); | 505 Handle<JSFunction> function = Handle<JSFunction>::null(); |
| 509 if (func.external) { | 506 if (func.external) { |
| 510 // Lookup external function in FFI object. | 507 // Lookup external function in FFI object. |
| 511 MaybeHandle<JSFunction> function = | 508 MaybeHandle<JSFunction> function = |
| 512 LookupFunction(thrower, factory, ffi, index, str, str_null); | 509 LookupFunction(thrower, factory, ffi, index, str, str_null); |
| 513 if (function.is_null()) return MaybeHandle<JSObject>(); | 510 if (function.is_null()) return MaybeHandle<JSObject>(); |
| 514 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, | 511 code = compiler::CompileWasmToJSWrapper(isolate, &module_env, |
| 515 function.ToHandleChecked(), | 512 function.ToHandleChecked(), |
| 516 func.sig, str, str_null); | 513 func.sig, str, str_null); |
| 517 } else { | 514 } else { |
| 518 // Compile the function. | 515 // Compile the function. |
| 519 code = | 516 code = |
| 520 compiler::CompileWasmFunction(thrower, isolate, &module_env, func); | 517 compiler::CompileWasmFunction(thrower, isolate, &module_env, func); |
| 521 if (code.is_null()) { | 518 if (code.is_null()) { |
| 522 thrower.Error("Compilation of #%d:%.*s failed.", index, str.length, | 519 thrower.Error("Compilation of #%d:%.*s failed.", index, str.length(), |
| 523 str.name); | 520 str.start()); |
| 524 return MaybeHandle<JSObject>(); | 521 return MaybeHandle<JSObject>(); |
| 525 } | 522 } |
| 526 if (func.exported) { | 523 if (func.exported) { |
| 527 function = compiler::CompileJSToWasmWrapper( | 524 function = compiler::CompileJSToWasmWrapper( |
| 528 isolate, &module_env, name, code, instance.js_object, index); | 525 isolate, &module_env, name, code, instance.js_object, index); |
| 529 } | 526 } |
| 530 } | 527 } |
| 531 if (!code.is_null()) { | 528 if (!code.is_null()) { |
| 532 // Install the code into the linker table. | 529 // Install the code into the linker table. |
| 533 linker.Finish(index, code); | 530 linker.Finish(index, code); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 556 isolate->native_context()->object_function(), isolate); | 553 isolate->native_context()->object_function(), isolate); |
| 557 Handle<JSObject> exports_object = | 554 Handle<JSObject> exports_object = |
| 558 factory->NewJSObject(object_function, TENURED); | 555 factory->NewJSObject(object_function, TENURED); |
| 559 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); | 556 Handle<String> exports_name = factory->InternalizeUtf8String("exports"); |
| 560 JSObject::AddProperty(instance.js_object, exports_name, exports_object, | 557 JSObject::AddProperty(instance.js_object, exports_name, exports_object, |
| 561 READ_ONLY); | 558 READ_ONLY); |
| 562 | 559 |
| 563 // Compile wrappers and add them to the exports object. | 560 // Compile wrappers and add them to the exports object. |
| 564 for (const WasmExport& exp : export_table) { | 561 for (const WasmExport& exp : export_table) { |
| 565 if (thrower.error()) break; | 562 if (thrower.error()) break; |
| 566 WasmName str = GetName(exp.name_offset, exp.name_length); | 563 Vector<const char> str = GetName(exp.name_offset, exp.name_length); |
| 567 Handle<String> name = factory->InternalizeUtf8String( | 564 Handle<String> name = factory->InternalizeUtf8String(str); |
| 568 Vector<const char>(str.name, str.length)); | |
| 569 Handle<Code> code = linker.GetFunctionCode(exp.func_index); | 565 Handle<Code> code = linker.GetFunctionCode(exp.func_index); |
| 570 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( | 566 Handle<JSFunction> function = compiler::CompileJSToWasmWrapper( |
| 571 isolate, &module_env, name, code, instance.js_object, | 567 isolate, &module_env, name, code, instance.js_object, |
| 572 exp.func_index); | 568 exp.func_index); |
| 573 JSObject::AddProperty(exports_object, name, function, READ_ONLY); | 569 JSObject::AddProperty(exports_object, name, function, READ_ONLY); |
| 574 } | 570 } |
| 575 | 571 |
| 576 if (mem_export) { | 572 if (mem_export) { |
| 577 // Export the memory as a named property. | 573 // Export the memory as a named property. |
| 578 Handle<String> name = factory->InternalizeUtf8String("memory"); | 574 Handle<String> name = factory->InternalizeUtf8String("memory"); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 } | 724 } |
| 729 if (result->IsHeapNumber()) { | 725 if (result->IsHeapNumber()) { |
| 730 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 726 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
| 731 } | 727 } |
| 732 thrower.Error("WASM.compileRun() failed: Return value should be number"); | 728 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
| 733 return -1; | 729 return -1; |
| 734 } | 730 } |
| 735 } // namespace wasm | 731 } // namespace wasm |
| 736 } // namespace internal | 732 } // namespace internal |
| 737 } // namespace v8 | 733 } // namespace v8 |
| OLD | NEW |