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

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: Rebase. 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
« no previous file with comments | « src/runtime/runtime-test.cc ('k') | test/cctest/wasm/test-run-wasm-js.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
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
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
OLDNEW
« no previous file with comments | « src/runtime/runtime-test.cc ('k') | test/cctest/wasm/test-run-wasm-js.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698