Commit 22e4c461 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] [interpreter] Fix interpreter-to-wasm calls

When calling the CWasmEntry in order to call from the interpreter to a
wasm function, the given buffer must hold the arguments, and must also
have enough space to hold the return values. We were missing the second
part, hence we failed when there are no parameters, but a return.

R=ahaas@chromium.org

Bug: chromium:784125
Change-Id: I08d417cae60eea64fda8a72e898dbed9f3e88148
Reviewed-on: https://chromium-review.googlesource.com/771633
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49402}
parent a087abb0
...@@ -2338,6 +2338,16 @@ class ThreadImpl { ...@@ -2338,6 +2338,16 @@ class ThreadImpl {
offset += param_size; offset += param_size;
} }
// Ensure that there is enough space in the arg_buffer to hold the return
// value(s).
uint32_t return_size = 0;
for (ValueType t : sig->returns()) {
return_size += 1 << ElementSizeLog2Of(t);
}
if (arg_buffer.size() < return_size) {
arg_buffer.resize(return_size);
}
// Wrap the arg_buffer data pointer in a handle. As this is an aligned // Wrap the arg_buffer data pointer in a handle. As this is an aligned
// pointer, to the GC it will look like a Smi. // pointer, to the GC it will look like a Smi.
Handle<Object> arg_buffer_obj(reinterpret_cast<Object*>(arg_buffer.data()), Handle<Object> arg_buffer_obj(reinterpret_cast<Object*>(arg_buffer.data()),
......
...@@ -22,6 +22,7 @@ function checkStack(stack, expected_lines) { ...@@ -22,6 +22,7 @@ function checkStack(stack, expected_lines) {
} }
(function testCallImported() { (function testCallImported() {
print(arguments.callee.name);
var stack; var stack;
let func = () => stack = new Error('test imported stack').stack; let func = () => stack = new Error('test imported stack').stack;
...@@ -47,6 +48,7 @@ function checkStack(stack, expected_lines) { ...@@ -47,6 +48,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testCallImportedWithParameters() { (function testCallImportedWithParameters() {
print(arguments.callee.name);
var stack; var stack;
var passed_args = []; var passed_args = [];
let func1 = (i, j) => (passed_args.push(i, j), 2 * i + j); let func1 = (i, j) => (passed_args.push(i, j), 2 * i + j);
...@@ -80,6 +82,7 @@ function checkStack(stack, expected_lines) { ...@@ -80,6 +82,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testTrap() { (function testTrap() {
print(arguments.callee.name);
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
var foo_idx = builder.addFunction('foo', kSig_v_v) var foo_idx = builder.addFunction('foo', kSig_v_v)
.addBody([kExprNop, kExprNop, kExprUnreachable]) .addBody([kExprNop, kExprNop, kExprUnreachable])
...@@ -110,6 +113,7 @@ function checkStack(stack, expected_lines) { ...@@ -110,6 +113,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testThrowFromImport() { (function testThrowFromImport() {
print(arguments.callee.name);
function func() { function func() {
throw new Error('thrown from imported function'); throw new Error('thrown from imported function');
} }
...@@ -141,6 +145,7 @@ function checkStack(stack, expected_lines) { ...@@ -141,6 +145,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testGlobals() { (function testGlobals() {
print(arguments.callee.name);
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
builder.addGlobal(kWasmI32, true); // 0 builder.addGlobal(kWasmI32, true); // 0
builder.addGlobal(kWasmI64, true); // 1 builder.addGlobal(kWasmI64, true); // 1
...@@ -190,6 +195,7 @@ function checkStack(stack, expected_lines) { ...@@ -190,6 +195,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testReentrantInterpreter() { (function testReentrantInterpreter() {
print(arguments.callee.name);
var stacks; var stacks;
var instance; var instance;
function func(i) { function func(i) {
...@@ -227,6 +233,7 @@ function checkStack(stack, expected_lines) { ...@@ -227,6 +233,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testIndirectImports() { (function testIndirectImports() {
print(arguments.callee.name);
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
var sig_i_ii = builder.addType(kSig_i_ii); var sig_i_ii = builder.addType(kSig_i_ii);
...@@ -260,6 +267,7 @@ function checkStack(stack, expected_lines) { ...@@ -260,6 +267,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testIllegalImports() { (function testIllegalImports() {
print(arguments.callee.name);
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
var sig_l_v = builder.addType(kSig_l_v); var sig_l_v = builder.addType(kSig_l_v);
...@@ -311,6 +319,7 @@ function checkStack(stack, expected_lines) { ...@@ -311,6 +319,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testInfiniteRecursion() { (function testInfiniteRecursion() {
print(arguments.callee.name);
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
var direct = builder.addFunction('main', kSig_v_v) var direct = builder.addFunction('main', kSig_v_v)
...@@ -331,6 +340,7 @@ function checkStack(stack, expected_lines) { ...@@ -331,6 +340,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testUnwindSingleActivation() { (function testUnwindSingleActivation() {
print(arguments.callee.name);
// Create two activations and unwind just the top one. // Create two activations and unwind just the top one.
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
...@@ -367,6 +377,7 @@ function checkStack(stack, expected_lines) { ...@@ -367,6 +377,7 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testInterpreterGC() { (function testInterpreterGC() {
print(arguments.callee.name);
function run(f) { function run(f) {
// wrap the creation in a closure so that the only thing returned is // wrap the creation in a closure so that the only thing returned is
// the module (i.e. the underlying array buffer of wasm wire bytes dies). // the module (i.e. the underlying array buffer of wasm wire bytes dies).
...@@ -400,10 +411,11 @@ function checkStack(stack, expected_lines) { ...@@ -400,10 +411,11 @@ function checkStack(stack, expected_lines) {
})(); })();
(function testImportThrowsOnToNumber() { (function testImportThrowsOnToNumber() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder(); const builder = new WasmModuleBuilder();
builder.addImport('mod', 'func', kSig_i_v); const imp_idx = builder.addImport('mod', 'func', kSig_i_v);
builder.addFunction('main', kSig_i_v) builder.addFunction('main', kSig_i_v)
.addBody([kExprCallFunction, 0]) .addBody([kExprCallFunction, imp_idx])
.exportFunc(); .exportFunc();
var num_callback_calls = 0; var num_callback_calls = 0;
const callback = () => { const callback = () => {
...@@ -421,3 +433,19 @@ function checkStack(stack, expected_lines) { ...@@ -421,3 +433,19 @@ function checkStack(stack, expected_lines) {
assertEquals(i + 1, num_callback_calls); assertEquals(i + 1, num_callback_calls);
} }
})(); })();
(function testCallWithMoreReturnsThenParams() {
print(arguments.callee.name);
const builder1 = new WasmModuleBuilder();
builder1.addFunction('exp', kSig_l_v)
.addBody([kExprI64Const, 23])
.exportFunc();
const exp = builder1.instantiate().exports.exp;
const builder2 = new WasmModuleBuilder();
const imp_idx = builder2.addImport('imp', 'func', kSig_l_v);
builder2.addFunction('main', kSig_i_v)
.addBody([kExprCallFunction, imp_idx, kExprI32ConvertI64])
.exportFunc();
const instance = builder2.instantiate({imp: {func: exp}});
assertEquals(23, instance.exports.main());
})();
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