blob: 22d2860df10bddb6fc216958f12bb755f8175f75 [file] [log] [blame]
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --experimental-wasm-return-call --stack-size=64
load("test/mjsunit/wasm/wasm-module-builder.js");
(function TestFactorialReturnCall() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
const sig_i_iii = builder.addType(kSig_i_iii);
// construct the code for the function
// f_aux(N,X) where N=<1 => X
// f_aux(N,X) => f_aux(N-1,X*N)
let fact_aux = builder.addFunction("fact_aux",kSig_i_ii);
fact_aux.addBody([
kExprGetLocal, 0, kExprI32Const, 1, kExprI32LeS,
kExprIf, kWasmI32,
kExprGetLocal, 1,
kExprElse,
kExprGetLocal, 0,
kExprI32Const, 1,
kExprI32Sub,
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprI32Mul,
kExprReturnCall, fact_aux.index,
kExprEnd
]);
//main(N)=>fact_aux(N,1)
let main = builder.addFunction("main", kSig_i_i)
.addBody([
kExprGetLocal, 0,
kExprI32Const, 1,
kExprReturnCall,0
]).exportFunc();
let module = builder.instantiate();
print(" --three--");
assertEquals(6, module.exports.main(3));
print(" --four--");
assertEquals(24, module.exports.main(4));
})();
(function TestIndirectFactorialReturnCall() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
const sig_i_iii = builder.addType(kSig_i_iii);
// construct the code for the function
// fact(N) => f_ind(N,1,f).
//
// f_ind(N,X,_) where N=<1 => X
// f_ind(N,X,F) => F(N-1,X*N,F).
let f_ind = builder.addFunction("f_ind",kSig_i_iii).
addBody([
kExprGetLocal, 0, kExprI32Const, 1, kExprI32LeS,
kExprIf, kWasmI32,
kExprGetLocal, 1,
kExprElse,
kExprGetLocal, 0,
kExprI32Const, 1,
kExprI32Sub,
kExprGetLocal, 0,
kExprGetLocal, 1,
kExprI32Mul,
kExprGetLocal, 2,
kExprGetLocal, 2,
kExprReturnCallIndirect, sig_i_iii, kTableZero,
kExprEnd
]);
//main(N)=>fact_aux(N,1)
let main = builder.addFunction("main", kSig_i_i)
.addBody([
kExprGetLocal, 0,
kExprI32Const, 1,
kExprI32Const, f_ind.index,
kExprReturnCall, f_ind.index
]).exportFunc();
builder.appendToTable([f_ind.index, main.index]);
let module = builder.instantiate();
print(" --three--");
assertEquals(6, module.exports.main(3));
print(" --four--");
assertEquals(24, module.exports.main(4));
})();
(function TestImportReturnCall() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
const sig_i_iii = builder.addType(kSig_i_iii);
let pick = builder.addImport("q", "pick", sig_i_iii);
let main = builder.addFunction("main", kSig_i_iii)
.addBody([
kExprGetLocal, 1,
kExprGetLocal, 2,
kExprGetLocal, 0,
kExprReturnCall, pick
])
.exportFunc();
let module = builder.instantiate({q: {
pick: function(a, b, c) { return c ? a : b; }}});
print(" --left--");
assertEquals(-2, module.exports.main(1, -2, 3));
print(" --right--");
assertEquals(3, module.exports.main(0, -2, 3));
})();
(function TestImportIndirectReturnCall() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
const sig_i_iii = builder.addType(kSig_i_iii);
let pick = builder.addImport("q", "pick", sig_i_iii);
builder.addTable(kWasmAnyFunc, 4);
// Arbitrary location in the table.
const tableIndex = 3;
builder.addElementSegment(0, tableIndex,false,[pick]);
let main = builder.addFunction("main", kSig_i_iii)
.addBody([
kExprGetLocal, 1,
kExprGetLocal, 2,
kExprGetLocal, 0,
kExprI32Const, tableIndex,
kExprReturnCallIndirect, sig_i_iii, kTableZero
])
.exportFunc();
builder.appendToTable([pick, main.index]);
let module = builder.instantiate({q: {
pick: function(a, b, c) { return c ? a : b; }
}});
print(" --left--");
assertEquals(-2, module.exports.main(1, -2, 3));
print(" --right--");
assertEquals(3, module.exports.main(0, -2, 3));
})();