| // 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)); |
| })(); |