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