| // Copyright 2018 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: --validate-asm --allow-natives-syntax |
| |
| var stdlib = this; |
| |
| function assertValidAsm(func) { |
| assertTrue(%IsAsmWasmCode(func), "must be valid asm code"); |
| } |
| |
| function assertWasm(expected, func, ffi) { |
| print("Testing " + func.name + "..."); |
| assertEquals( |
| expected, func(stdlib, ffi, new ArrayBuffer(1024)).caller()); |
| assertValidAsm(func); |
| } |
| |
| |
| function TestForeignFunctions() { |
| function AsmModule(stdlib, foreign, buffer) { |
| "use asm"; |
| |
| var setVal = foreign.setVal; |
| var getVal = foreign.getVal; |
| |
| function caller(initial_value, new_value) { |
| initial_value = initial_value|0; |
| new_value = new_value|0; |
| if ((getVal()|0) == (initial_value|0)) { |
| setVal(new_value|0); |
| return getVal()|0; |
| } |
| return 0; |
| } |
| |
| return {caller:caller}; |
| } |
| |
| function ffi(initial_val) { |
| var val = initial_val; |
| |
| function getVal() { |
| return val; |
| } |
| |
| function setVal(new_val) { |
| val = new_val; |
| } |
| |
| return {getVal:getVal, setVal:setVal}; |
| } |
| |
| var foreign = new ffi(23); |
| |
| var module = AsmModule({Math: Math}, foreign, null); |
| assertValidAsm(AsmModule); |
| |
| assertEquals(103, module.caller(23, 103)); |
| } |
| |
| print("TestForeignFunctions..."); |
| TestForeignFunctions(); |
| |
| |
| function TestForeignFunctionMultipleUse() { |
| function AsmModule(stdlib, foreign, buffer) { |
| "use asm"; |
| |
| var getVal = foreign.getVal; |
| |
| function caller(int_val, double_val) { |
| int_val = int_val|0; |
| double_val = +double_val; |
| if ((getVal()|0) == (int_val|0)) { |
| if ((+getVal()) == (+double_val)) { |
| return 89; |
| } |
| } |
| return 0; |
| } |
| |
| return {caller:caller}; |
| } |
| |
| function ffi() { |
| function getVal() { |
| return 83.25; |
| } |
| |
| return {getVal:getVal}; |
| } |
| |
| var foreign = new ffi(); |
| |
| var module_decl = eval('(' + AsmModule.toString() + ')'); |
| var module = module_decl(stdlib, foreign, null); |
| assertValidAsm(module_decl); |
| |
| assertEquals(89, module.caller(83, 83.25)); |
| } |
| |
| print("TestForeignFunctionMultipleUse..."); |
| TestForeignFunctionMultipleUse(); |
| |
| function TestForeignVariables() { |
| function AsmModule(stdlib, foreign, buffer) { |
| "use asm"; |
| |
| var i1 = foreign.foo | 0; |
| var f1 = +foreign.bar; |
| var i2 = foreign.baz | 0; |
| var f2 = +foreign.baz; |
| |
| function geti1() { |
| return i1|0; |
| } |
| |
| function getf1() { |
| return +f1; |
| } |
| |
| function geti2() { |
| return i2|0; |
| } |
| |
| function getf2() { |
| return +f2; |
| } |
| |
| return {geti1:geti1, getf1:getf1, geti2:geti2, getf2:getf2}; |
| } |
| |
| function TestCase(env, i1, f1, i2, f2) { |
| print("Testing foreign variables..."); |
| var module_decl = eval('(' + AsmModule.toString() + ')'); |
| var module = module_decl(stdlib, env); |
| assertValidAsm(module_decl); |
| assertEquals(i1, module.geti1()); |
| assertEquals(f1, module.getf1()); |
| assertEquals(i2, module.geti2()); |
| assertEquals(f2, module.getf2()); |
| } |
| |
| // Check normal operation. |
| TestCase({foo: 123, bar: 234.5, baz: 345.7}, 123, 234.5, 345, 345.7); |
| // Check partial operation. |
| TestCase({baz: 345.7}, 0, NaN, 345, 345.7); |
| // Check that undefined values are converted to proper defaults. |
| TestCase({qux: 999}, 0, NaN, 0, NaN); |
| // Check that true values are converted properly. |
| TestCase({foo: true, bar: true, baz: true}, 1, 1.0, 1, 1.0); |
| // Check that false values are converted properly. |
| TestCase({foo: false, bar: false, baz: false}, 0, 0, 0, 0); |
| // Check that null values are converted properly. |
| TestCase({foo: null, bar: null, baz: null}, 0, 0, 0, 0); |
| // Check that string values are converted properly. |
| TestCase({foo: 'hi', bar: 'there', baz: 'dude'}, 0, NaN, 0, NaN); |
| TestCase({foo: '0xff', bar: '234', baz: '456.1'}, 255, 234, 456, 456.1); |
| // Check that function values are converted properly. |
| TestCase({foo: TestCase, bar: TestCase, qux: TestCase}, 0, NaN, 0, NaN); |
| } |
| |
| print("TestForeignVariables..."); |
| TestForeignVariables(); |
| |
| |
| function TestGlobalBlock(stdlib, foreign, buffer) { |
| "use asm"; |
| |
| var x = foreign.x | 0, y = foreign.y | 0; |
| |
| function test() { |
| return (x + y) | 0; |
| } |
| |
| return {caller: test}; |
| } |
| |
| assertWasm(15, TestGlobalBlock, { x: 4, y: 11 }); |