Commit 665a5d17 authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Imported WebAssembly function are never wrapped.

According to the spec, import wrappers are only generated for JavaScript
functions, not for WebAssembly function. If an imported WebAssembly
function does not have the expected type, then a type error is thrown.

R=titzer@chromium.org, rossberg@chromium.org
TEST=mjsunit/wasm/test-import-export-wrapper

Review-Url: https://codereview.chromium.org/2486943005
Cr-Commit-Position: refs/heads/master@{#40901}
parent c71e5e12
...@@ -916,10 +916,14 @@ static Handle<Code> CompileImportWrapper(Isolate* isolate, int index, ...@@ -916,10 +916,14 @@ static Handle<Code> CompileImportWrapper(Isolate* isolate, int index,
MaybeHandle<String> import_name) { MaybeHandle<String> import_name) {
Handle<Code> code; Handle<Code> code;
WasmFunction* other_func = GetWasmFunctionForImportWrapper(isolate, target); WasmFunction* other_func = GetWasmFunctionForImportWrapper(isolate, target);
if (other_func && sig->Equals(other_func->sig)) { if (other_func) {
if (sig->Equals(other_func->sig)) {
// Signature matched. Unwrap the JS->WASM wrapper and return the raw // Signature matched. Unwrap the JS->WASM wrapper and return the raw
// WASM function code. // WASM function code.
return UnwrapImportWrapper(target); return UnwrapImportWrapper(target);
} else {
return Handle<Code>::null();
}
} else { } else {
// Signature mismatch. Compile a new wrapper for the new signature. // Signature mismatch. Compile a new wrapper for the new signature.
return compiler::CompileWasmToJSWrapper(isolate, target, sig, index, return compiler::CompileWasmToJSWrapper(isolate, target, sig, index,
...@@ -1449,6 +1453,11 @@ class WasmInstanceBuilder { ...@@ -1449,6 +1453,11 @@ class WasmInstanceBuilder {
Handle<Code> import_wrapper = CompileImportWrapper( Handle<Code> import_wrapper = CompileImportWrapper(
isolate_, index, module_->functions[import.index].sig, isolate_, index, module_->functions[import.index].sig,
Handle<JSReceiver>::cast(function), module_name, function_name); Handle<JSReceiver>::cast(function), module_name, function_name);
if (import_wrapper.is_null()) {
ReportFFIError("imported function does not match the expected type",
index, module_name, function_name);
return -1;
}
code_table->set(num_imported_functions, *import_wrapper); code_table->set(num_imported_functions, *import_wrapper);
RecordStats(isolate_, *import_wrapper); RecordStats(isolate_, *import_wrapper);
num_imported_functions++; num_imported_functions++;
......
...@@ -128,9 +128,9 @@ var expect_no_elison = 1; ...@@ -128,9 +128,9 @@ var expect_no_elison = 1;
// function calls stack: first_export -> first_func -> first_import -> // function calls stack: first_export -> first_func -> first_import ->
// second_export -> second_import // second_export -> second_import
// In this case, second_export has less params than first_import, // In this case, second_export has fewer params than first_import,
// So that wrappers will not be removed // so instantiation should fail.
(function TestWasmWrapperNoElisionLessParams() { assertThrows(function TestWasmWrapperNoElisionLessParams() {
var imported = function (a) { var imported = function (a) {
return a; return a;
}; };
...@@ -181,13 +181,13 @@ var expect_no_elison = 1; ...@@ -181,13 +181,13 @@ var expect_no_elison = 1;
assertEquals(the_export(0, 2), 0); assertEquals(the_export(0, 2), 0);
assertEquals(the_export(9.9, 4.3), 9); assertEquals(the_export(9.9, 4.3), 9);
assertEquals(%CheckWasmWrapperElision(the_export, expect_no_elison), true); assertEquals(%CheckWasmWrapperElision(the_export, expect_no_elison), true);
})(); });
// function calls stack: first_export -> first_func -> first_import -> // function calls stack: first_export -> first_func -> first_import ->
// second_export -> second_import // second_export -> second_import
// In this case, second_export has more params than first_import, // In this case, second_export has more params than first_import,
// So that wrappers will not be removed // so instantiation should fail.
(function TestWasmWrapperNoElisionMoreParams() { assertThrows(function TestWasmWrapperNoElisionMoreParams() {
var imported = function (a, b, c) { var imported = function (a, b, c) {
return a+b+c; return a+b+c;
}; };
...@@ -240,13 +240,13 @@ var expect_no_elison = 1; ...@@ -240,13 +240,13 @@ var expect_no_elison = 1;
assertEquals(the_export(0, 0), 0); assertEquals(the_export(0, 0), 0);
assertEquals(the_export(1.1, 2.7), 3); assertEquals(the_export(1.1, 2.7), 3);
assertEquals(%CheckWasmWrapperElision(the_export, expect_no_elison), true); assertEquals(%CheckWasmWrapperElision(the_export, expect_no_elison), true);
})(); });
// function calls stack: first_export -> first_func -> first_import -> // function calls stack: first_export -> first_func -> first_import ->
// second_export -> second_import // second_export -> second_import
// In this case, second_export has different params type with first_import, // In this case, second_export has different params type with first_import,
// So that wrappers will not be removed // so instantiation should fail.
(function TestWasmWrapperNoElisionTypeMismatch() { assertThrows(function TestWasmWrapperNoElisionTypeMismatch() {
var imported = function (a, b) { var imported = function (a, b) {
return a+b; return a+b;
}; };
...@@ -298,4 +298,4 @@ var expect_no_elison = 1; ...@@ -298,4 +298,4 @@ var expect_no_elison = 1;
assertEquals(the_export(0.0, 0.0), 0); assertEquals(the_export(0.0, 0.0), 0);
assertEquals(the_export(2, -2), 0); assertEquals(the_export(2, -2), 0);
assertEquals(%CheckWasmWrapperElision(the_export, expect_no_elison), true); assertEquals(%CheckWasmWrapperElision(the_export, expect_no_elison), true);
})(); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment