| 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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 function_name_handle->length(), | 464 function_name_handle->length(), |
| 465 function_name_handle->ToCString().get(), error); | 465 function_name_handle->ToCString().get(), error); |
| 466 } else { | 466 } else { |
| 467 thrower.Error("Import #%d module=\"%.*s\" error: %s", index, | 467 thrower.Error("Import #%d module=\"%.*s\" error: %s", index, |
| 468 module_name->length(), module_name->ToCString().get(), error); | 468 module_name->length(), module_name->ToCString().get(), error); |
| 469 } | 469 } |
| 470 thrower.Error("Import "); | 470 thrower.Error("Import "); |
| 471 return MaybeHandle<JSFunction>(); | 471 return MaybeHandle<JSFunction>(); |
| 472 } | 472 } |
| 473 | 473 |
| 474 static MaybeHandle<JSFunction> LookupFunction( | 474 static MaybeHandle<JSReceiver> LookupFunction( |
| 475 ErrorThrower& thrower, Factory* factory, Handle<JSReceiver> ffi, | 475 ErrorThrower& thrower, Factory* factory, Handle<JSReceiver> ffi, |
| 476 uint32_t index, Handle<String> module_name, | 476 uint32_t index, Handle<String> module_name, |
| 477 MaybeHandle<String> function_name) { | 477 MaybeHandle<String> function_name) { |
| 478 if (ffi.is_null()) { | 478 if (ffi.is_null()) { |
| 479 return ReportFFIError(thrower, "FFI is not an object", index, module_name, | 479 return ReportFFIError(thrower, "FFI is not an object", index, module_name, |
| 480 function_name); | 480 function_name); |
| 481 } | 481 } |
| 482 | 482 |
| 483 // Look up the module first. | 483 // Look up the module first. |
| 484 MaybeHandle<Object> result = Object::GetProperty(ffi, module_name); | 484 MaybeHandle<Object> result = Object::GetProperty(ffi, module_name); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 502 if (result.is_null()) { | 502 if (result.is_null()) { |
| 503 return ReportFFIError(thrower, "function not found", index, module_name, | 503 return ReportFFIError(thrower, "function not found", index, module_name, |
| 504 function_name); | 504 function_name); |
| 505 } | 505 } |
| 506 function = result.ToHandleChecked(); | 506 function = result.ToHandleChecked(); |
| 507 } else { | 507 } else { |
| 508 // No function specified. Use the "default export". | 508 // No function specified. Use the "default export". |
| 509 function = module; | 509 function = module; |
| 510 } | 510 } |
| 511 | 511 |
| 512 if (!function->IsJSFunction()) { | 512 if (!function->IsCallable()) { |
| 513 return ReportFFIError(thrower, "not a function", index, module_name, | 513 return ReportFFIError(thrower, "not a callable", index, module_name, |
| 514 function_name); | 514 function_name); |
| 515 } | 515 } |
| 516 | 516 |
| 517 return Handle<JSFunction>::cast(function); | 517 return Handle<JSReceiver>::cast(function); |
| 518 } | 518 } |
| 519 | 519 |
| 520 namespace { | 520 namespace { |
| 521 // Fetches the compilation unit of a wasm function and executes its parallel | 521 // Fetches the compilation unit of a wasm function and executes its parallel |
| 522 // phase. | 522 // phase. |
| 523 bool FetchAndExecuteCompilationUnit( | 523 bool FetchAndExecuteCompilationUnit( |
| 524 Isolate* isolate, | 524 Isolate* isolate, |
| 525 std::vector<compiler::WasmCompilationUnit*>* compilation_units, | 525 std::vector<compiler::WasmCompilationUnit*>* compilation_units, |
| 526 std::queue<compiler::WasmCompilationUnit*>* executed_units, | 526 std::queue<compiler::WasmCompilationUnit*>* executed_units, |
| 527 base::Mutex* result_mutex, base::AtomicNumber<size_t>* next_unit) { | 527 base::Mutex* result_mutex, base::AtomicNumber<size_t>* next_unit) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 // TODO(mtrofin): this is an uint32_t, actually. We should rationalize | 654 // TODO(mtrofin): this is an uint32_t, actually. We should rationalize |
| 655 // it when we rationalize signed/unsigned stuff. | 655 // it when we rationalize signed/unsigned stuff. |
| 656 int ret_count = Smi::cast(data->get(kOutputCount))->value(); | 656 int ret_count = Smi::cast(data->get(kOutputCount))->value(); |
| 657 CHECK(ret_count >= 0); | 657 CHECK(ret_count >= 0); |
| 658 Handle<ByteArray> sig_data = | 658 Handle<ByteArray> sig_data = |
| 659 data->GetValueChecked<ByteArray>(isolate, kSignature); | 659 data->GetValueChecked<ByteArray>(isolate, kSignature); |
| 660 int sig_data_size = sig_data->length(); | 660 int sig_data_size = sig_data->length(); |
| 661 int param_count = sig_data_size - ret_count; | 661 int param_count = sig_data_size - ret_count; |
| 662 CHECK(param_count >= 0); | 662 CHECK(param_count >= 0); |
| 663 | 663 |
| 664 MaybeHandle<JSFunction> function = LookupFunction( | 664 MaybeHandle<JSReceiver> function = LookupFunction( |
| 665 *thrower, isolate->factory(), ffi, index, module_name, function_name); | 665 *thrower, isolate->factory(), ffi, index, module_name, function_name); |
| 666 if (function.is_null()) return false; | 666 if (function.is_null()) return false; |
| 667 Handle<Code> code; | 667 Handle<Code> code; |
| 668 Handle<JSFunction> func = function.ToHandleChecked(); | 668 Handle<JSReceiver> target = function.ToHandleChecked(); |
| 669 Handle<Code> export_wrapper_code = handle(func->code()); | |
| 670 bool isMatch = false; | 669 bool isMatch = false; |
| 671 if (export_wrapper_code->kind() == Code::JS_TO_WASM_FUNCTION) { | 670 Handle<Code> export_wrapper_code; |
| 672 int exported_param_count = | 671 if (target->IsJSFunction()) { |
| 673 Smi::cast(func->GetInternalField(kInternalArity))->value(); | 672 Handle<JSFunction> func = Handle<JSFunction>::cast(target); |
| 674 Handle<ByteArray> exportedSig = Handle<ByteArray>( | 673 export_wrapper_code = handle(func->code()); |
| 675 ByteArray::cast(func->GetInternalField(kInternalSignature))); | 674 if (export_wrapper_code->kind() == Code::JS_TO_WASM_FUNCTION) { |
| 676 if (exported_param_count == param_count && | 675 int exported_param_count = |
| 677 exportedSig->length() == sig_data->length() && | 676 Smi::cast(func->GetInternalField(kInternalArity))->value(); |
| 678 memcmp(exportedSig->data(), sig_data->data(), | 677 Handle<ByteArray> exportedSig = Handle<ByteArray>( |
| 679 exportedSig->length()) == 0) { | 678 ByteArray::cast(func->GetInternalField(kInternalSignature))); |
| 680 isMatch = true; | 679 if (exported_param_count == param_count && |
| 680 exportedSig->length() == sig_data->length() && |
| 681 memcmp(exportedSig->data(), sig_data->data(), |
| 682 exportedSig->length()) == 0) { |
| 683 isMatch = true; |
| 684 } |
| 681 } | 685 } |
| 682 } | 686 } |
| 683 if (isMatch) { | 687 if (isMatch) { |
| 684 int wasm_count = 0; | 688 int wasm_count = 0; |
| 685 int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 689 int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
| 686 for (RelocIterator it(*export_wrapper_code, mask); !it.done(); | 690 for (RelocIterator it(*export_wrapper_code, mask); !it.done(); |
| 687 it.next()) { | 691 it.next()) { |
| 688 RelocInfo* rinfo = it.rinfo(); | 692 RelocInfo* rinfo = it.rinfo(); |
| 689 Address target_address = rinfo->target_address(); | 693 Address target_address = rinfo->target_address(); |
| 690 Code* target = Code::GetCodeFromTargetAddress(target_address); | 694 Code* target = Code::GetCodeFromTargetAddress(target_address); |
| 691 if (target->kind() == Code::WASM_FUNCTION) { | 695 if (target->kind() == Code::WASM_FUNCTION) { |
| 692 ++wasm_count; | 696 ++wasm_count; |
| 693 code = handle(target); | 697 code = handle(target); |
| 694 } | 698 } |
| 695 } | 699 } |
| 696 DCHECK(wasm_count == 1); | 700 DCHECK(wasm_count == 1); |
| 697 } else { | 701 } else { |
| 698 // Copy the signature to avoid a raw pointer into a heap object when | 702 // Copy the signature to avoid a raw pointer into a heap object when |
| 699 // GC can happen. | 703 // GC can happen. |
| 700 Zone zone(isolate->allocator()); | 704 Zone zone(isolate->allocator()); |
| 701 MachineRepresentation* reps = | 705 MachineRepresentation* reps = |
| 702 zone.NewArray<MachineRepresentation>(sig_data_size); | 706 zone.NewArray<MachineRepresentation>(sig_data_size); |
| 703 memcpy(reps, sig_data->data(), | 707 memcpy(reps, sig_data->data(), |
| 704 sizeof(MachineRepresentation) * sig_data_size); | 708 sizeof(MachineRepresentation) * sig_data_size); |
| 705 FunctionSig sig(ret_count, param_count, reps); | 709 FunctionSig sig(ret_count, param_count, reps); |
| 706 | 710 |
| 707 code = compiler::CompileWasmToJSWrapper(isolate, func, &sig, index, | 711 code = compiler::CompileWasmToJSWrapper(isolate, target, &sig, index, |
| 708 module_name, function_name); | 712 module_name, function_name); |
| 709 } | 713 } |
| 710 imports.push_back(code); | 714 imports.push_back(code); |
| 711 } | 715 } |
| 712 } | 716 } |
| 713 return true; | 717 return true; |
| 714 } | 718 } |
| 715 | 719 |
| 716 void InitializeParallelCompilation( | 720 void InitializeParallelCompilation( |
| 717 Isolate* isolate, const std::vector<WasmFunction>& functions, | 721 Isolate* isolate, const std::vector<WasmFunction>& functions, |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1653 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); | 1657 return static_cast<int32_t>(HeapNumber::cast(*result)->value()); |
| 1654 } | 1658 } |
| 1655 thrower.Error("WASM.compileRun() failed: Return value should be number"); | 1659 thrower.Error("WASM.compileRun() failed: Return value should be number"); |
| 1656 return -1; | 1660 return -1; |
| 1657 } | 1661 } |
| 1658 | 1662 |
| 1659 } // namespace testing | 1663 } // namespace testing |
| 1660 } // namespace wasm | 1664 } // namespace wasm |
| 1661 } // namespace internal | 1665 } // namespace internal |
| 1662 } // namespace v8 | 1666 } // namespace v8 |
| OLD | NEW |