[wasm] Don't call constructors directly from wasm2js wrappers

For the wasm2js wrappers we have an optimization to call a JavaScript
function directly if the signature of the JavaScript function matches
the signature of the WebAssembly import. However, we are not supposed
to do this optimization if the imported function is a constructor,
because constructors can only be called with `new`. With this CL we
do not apply this optimization when the imported function is a
constructor.

R=titzer@chromium.org

Bug: chromium:824859
Change-Id: I1722367bd865d0b129eadf7d4849182410447179
Reviewed-on: https://chromium-review.googlesource.com/985974
Reviewed-by: Ben Titzer <titzer@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52296}
This commit is contained in:
Andreas Haas 2018-03-29 11:48:11 +02:00 committed by Commit Bot
parent 459570d774
commit fc976f8e23
2 changed files with 23 additions and 6 deletions

View File

@ -3168,7 +3168,8 @@ bool WasmGraphBuilder::BuildWasmToJSWrapper(
if (target->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(target);
if (function->shared()->internal_formal_parameter_count() == wasm_count) {
if (function->shared()->internal_formal_parameter_count() == wasm_count &&
!IsClassConstructor(function->shared()->kind())) {
int pos = 0;
args[pos++] =
LoadImportData(index, kFunction, table); // target callable.

View File

@ -68,9 +68,8 @@ print("Bind function");
var bind_sub = FOREIGN_SUB.bind();
testCallFFI(bind_sub, check_FOREIGN_SUB);
var main_for_constructor_test;
print("Constructor");
(function testCallConstructor() {
print(arguments.callee.name);
class C {}
var builder = new WasmModuleBuilder();
@ -84,13 +83,30 @@ print("Constructor");
]) // --
.exportFunc();
main_for_constructor_test = builder.instantiate({"": {func: C}}).exports.main;
let main_for_constructor_test = builder.instantiate({"": {func: C}}).exports.main;
assertThrows("main_for_constructor_test(12, 43)", TypeError);
assertThrows(_ => main_for_constructor_test(12, 43), TypeError);
}) ();
print("Native function");
(function testCallConstructorWithSuperClass() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_v_v);
let func_index = builder.addImport('', 'func', sig_index);
builder.addExport('exp', func_index);
class B {}
class C extends B {
constructor() {
super();
}
};
let exports = builder.instantiate({'': {func: C}}).exports;
assertThrows(_ => exports.exp(), TypeError);
})();
(function test_ffi_call_to_native() {
print(arguments.callee.name);
var builder = new WasmModuleBuilder();