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

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

Issue 2208703002: [wasm] Allow import function to be any kind of callables. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix the problem in wasm-module.cc, and refactor the code in wasm-compiler.cc Created 4 years, 4 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
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/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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698