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 |