Chromium Code Reviews| Index: test/mjsunit/wasm/asm-wasm-stdlib.js |
| diff --git a/test/mjsunit/wasm/asm-wasm-stdlib.js b/test/mjsunit/wasm/asm-wasm-stdlib.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b47d60c87c746a2ebe2876152d8441419560a4d8 |
| --- /dev/null |
| +++ b/test/mjsunit/wasm/asm-wasm-stdlib.js |
| @@ -0,0 +1,356 @@ |
| +// Copyright 2016 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 |
| + |
| +(function TestStdlibConstants() { |
| + function Module(stdlib) { |
| + "use asm"; |
| + |
| + var StdlibInfinity = stdlib.Infinity; |
| + var StdlibNaN = stdlib.NaN; |
| + var StdlibMathE = stdlib.Math.E; |
| + var StdlibMathLN10 = stdlib.Math.LN10; |
| + var StdlibMathLN2 = stdlib.Math.LN2; |
| + var StdlibMathLOG2E = stdlib.Math.LOG2E; |
| + var StdlibMathLOG10E = stdlib.Math.LOG10E; |
| + var StdlibMathPI = stdlib.Math.PI; |
| + var StdlibMathSQRT1_2 = stdlib.Math.SQRT1_2; |
| + var StdlibMathSQRT2 = stdlib.Math.SQRT2; |
| + |
| + function caller() { |
| + if (StdlibInfinity != 1.0 / 0.0) return 0; |
| + if (StdlibMathE != 2.718281828459045) return 0; |
| + if (StdlibMathLN10 != 2.302585092994046) return 0; |
| + if (StdlibMathLN2 != 0.6931471805599453) return 0; |
| + if (StdlibMathLOG2E != 1.4426950408889634) return 0; |
| + if (StdlibMathLOG10E != 0.4342944819032518) return 0; |
| + if (StdlibMathPI != 3.141592653589793) return 0; |
| + if (StdlibMathSQRT1_2 != 0.7071067811865476) return 0; |
| + if (StdlibMathSQRT2 != 1.4142135623730951) return 0; |
| + return 1; |
| + } |
| + |
| + function nanCheck() { |
| + return +StdlibNaN; |
| + } |
| + |
| + return {caller:caller, nanCheck:nanCheck}; |
| + } |
| + |
| + var m =Wasm.instantiateModuleFromAsm(Module.toString()); |
| + assertEquals(1, m.caller()); |
| + assertTrue(isNaN(m.nanCheck())); |
| +})(); |
| + |
| + |
| +(function TestStdlibFunctionsInside() { |
| + function Module(stdlib) { |
| + "use asm"; |
| + |
| + var StdlibMathCeil = stdlib.Math.ceil; |
| + var StdlibMathFloor = stdlib.Math.floor; |
| + var StdlibMathSqrt = stdlib.Math.sqrt; |
| + var StdlibMathAbs = stdlib.Math.abs; |
| + var StdlibMathMin = stdlib.Math.min; |
| + var StdlibMathMax = stdlib.Math.max; |
| + |
| + var StdlibMathAcos = stdlib.Math.acos; |
| + var StdlibMathAsin = stdlib.Math.asin; |
| + var StdlibMathAtan = stdlib.Math.atan; |
| + var StdlibMathCos = stdlib.Math.cos; |
| + var StdlibMathSin = stdlib.Math.sin; |
| + var StdlibMathTan = stdlib.Math.tan; |
| + var StdlibMathExp = stdlib.Math.exp; |
| + var StdlibMathLog = stdlib.Math.log; |
| + |
| + var StdlibMathAtan2 = stdlib.Math.atan2; |
| + var StdlibMathPow = stdlib.Math.pow; |
| + var StdlibMathImul = stdlib.Math.imul; |
| + |
| + var fround = stdlib.Math.fround; |
| + |
| + function deltaEqual(x, y) { |
| + x = +x; |
| + y = +y; |
| + var t = 0.0; |
| + t = x - y; |
| + if (t < 0.0) { |
| + t = t * -1.0; |
| + } |
| + return (t < 1.0e-10) | 0; |
| + } |
| + |
| + function caller() { |
| + if (!deltaEqual(StdlibMathSqrt(123.0), 11.090536506409418)) return 0; |
| + if (StdlibMathSqrt(fround(256.0)) != fround(16.0)) return 0; |
| + if (StdlibMathCeil(123.7) != 124.0) return 0; |
| + if (StdlibMathCeil(fround(123.7)) != fround(124.0)) return 0; |
| + if (StdlibMathFloor(123.7) != 123.0) return 0; |
| + if (StdlibMathFloor(fround(123.7)) != fround(123.0)) return 0; |
| + if (StdlibMathAbs(-123.0) != 123.0) return 0; |
| + if (StdlibMathAbs(fround(-123.0)) != fround(123.0)) return 0; |
| + if (StdlibMathMin(123.4, 1236.4) != 123.4) return 0; |
| + if (StdlibMathMin(fround(123.4), |
| + fround(1236.4)) != fround(123.4)) return 0; |
| + if (StdlibMathMax(123.4, 1236.4) != 1236.4) return 0; |
| + if (StdlibMathMax(fround(123.4), fround(1236.4)) |
| + != fround(1236.4)) return 0; |
| + |
| + if (!deltaEqual(StdlibMathAcos(0.1), 1.4706289056333368)) return 0; |
| + if (!deltaEqual(StdlibMathAsin(0.2), 0.2013579207903308)) return 0; |
| + if (!deltaEqual(StdlibMathAtan(0.2), 0.19739555984988078)) return 0; |
| + if (!deltaEqual(StdlibMathCos(0.2), 0.9800665778412416)) return 0; |
| + if (!deltaEqual(StdlibMathSin(0.2), 0.19866933079506122)) return 0; |
| + if (!deltaEqual(StdlibMathTan(0.2), 0.20271003550867250)) return 0; |
| + if (!deltaEqual(StdlibMathExp(0.2), 1.2214027581601699)) return 0; |
| + if (!deltaEqual(StdlibMathLog(0.2), -1.6094379124341003)) return 0; |
| + |
| + if (StdlibMathImul(6, 7) != 42) return 0; |
| + if (!deltaEqual(StdlibMathAtan2(6.0, 7.0), 0.7086262721276703)) return 0; |
| + if (StdlibMathPow(6.0, 7.0) != 279936.0) return 0; |
| + |
| + return 1; |
| + } |
| + |
| + return {caller:caller}; |
| + } |
| + |
| + var m = Wasm.instantiateModuleFromAsm(Module.toString()); |
| + assertEquals(1, m.caller()); |
| +})(); |
| + |
| + |
| +(function TestStdlibFunctionOutside() { |
| + function looseEqual(x, y, delta) { |
| + if (delta === undefined) { |
| + delta = 1.0e-13; |
| + } |
| + if (isNaN(x) && isNaN(y)) { |
| + return true; |
| + } |
| + if (!isFinite(x) && !isFinite(y)) { |
| + return true; |
| + } |
| + x = +x; |
| + y = +y; |
| + var t = 0.0; |
| + t = x - y; |
| + if (t < 0.0) { |
| + t = t * -1.0; |
| + } |
| + return (t < delta) | 0; |
| + } |
| + |
| + function plainEqual(x, y) { |
| + if (isNaN(x) && isNaN(y)) { |
| + return true; |
| + } |
| + return x === y; |
| + } |
| + |
| + function Module(stdlib) { |
| + "use asm"; |
| + var ceil = stdlib.Math.ceil; |
| + var floor = stdlib.Math.floor; |
| + var sqrt = stdlib.Math.sqrt; |
| + var abs = stdlib.Math.abs; |
| + var fround = stdlib.Math.fround; |
| + |
| + var acos = stdlib.Math.acos; |
| + var asin = stdlib.Math.asin; |
| + var atan = stdlib.Math.atan; |
| + var cos = stdlib.Math.cos; |
| + var sin = stdlib.Math.sin; |
| + var tan = stdlib.Math.tan; |
| + var exp = stdlib.Math.exp; |
| + var log = stdlib.Math.log; |
| + |
| + var atan2 = stdlib.Math.atan2; |
| + var pow = stdlib.Math.pow; |
| + var imul = stdlib.Math.imul; |
| + var min = stdlib.Math.min; |
| + var max = stdlib.Math.max; |
| + |
| + function ceil_f64(x) { x = +x; return +ceil(x); } |
| + function ceil_f32(x) { x = fround(x); return fround(ceil(x)); } |
| + |
| + function floor_f64(x) { x = +x; return +floor(x); } |
| + function floor_f32(x) { x = fround(x); return fround(floor(x)); } |
| + |
| + function sqrt_f64(x) { x = +x; return +sqrt(x); } |
| + function sqrt_f32(x) { x = fround(x); return fround(sqrt(x)); } |
| + |
| + function abs_f64(x) { x = +x; return +abs(x); } |
| + function abs_f32(x) { x = fround(x); return fround(abs(x)); } |
| + function abs_i32(x) { x = x | 0; return abs(x|0) | 0; } |
| + |
| + function acos_f64(x) { x = +x; return +acos(x); } |
| + function asin_f64(x) { x = +x; return +asin(x); } |
| + function atan_f64(x) { x = +x; return +atan(x); } |
| + function cos_f64(x) { x = +x; return +cos(x); } |
| + function sin_f64(x) { x = +x; return +sin(x); } |
| + function tan_f64(x) { x = +x; return +tan(x); } |
| + function exp_f64(x) { x = +x; return +exp(x); } |
| + function log_f64(x) { x = +x; return +log(x); } |
| + |
| + function atan2_f64(x, y) { x = +x; y = +y; return +atan2(x, y); } |
| + function pow_f64(x, y) { x = +x; y = +y; return +atan2(x, y); } |
| + |
| + function imul_i32(x, y) { x = x | 0; y = y | 0; return imul(x, y) | 0; } |
| + function imul_u32(x, y) { |
| + x = x | 0; y = y | 0; return imul(x>>>0, y>>>0) | 0; } |
| + |
| + function fround_i32(x) { x = x | 0; return fround(x|0) | 0; } |
| + function fround_u32(x) { x = x | 0; return fround(x>>>0) | 0; } |
| + function fround_f32(x) { x = fround(x); return fround(x); } |
| + // TODO(bradnelson): Fix and enable. |
| + //function fround_f64(x) { x = +x; return fround(x); } |
| + |
| + function min_i32(x, y) { x = x | 0; y = y | 0; return min(x|0, y|0) | 0; } |
| + // TODO(bradnelson): Fix and enable. |
| + //function min_u32(x, y) { |
| + // x = x | 0; y = y | 0; return min(x>>>0, y>>>0) | 0; } |
| + function min_f32(x, y) { |
| + x = fround(x); y = fround(y); return fround(min(x, y)); } |
| + function min_f64(x, y) { x = +x; y = +y; return +min(x, y); } |
| + |
| + function max_i32(x, y) { x = x | 0; y = y | 0; return max(x|0, y|0) | 0; } |
| + // TODO(bradnelson): Fix and enable. |
| + //function max_u32(x, y) { |
| + // x = x | 0; y = y | 0; return max(x>>>0, y>>>0) | 0; } |
| + function max_f32(x, y) { |
| + x = fround(x); y = fround(y); return fround(max(x, y)); } |
| + function max_f64(x, y) { x = +x; y = +y; return +max(x, y); } |
| + |
| + return { |
| + ceil_f64: ceil_f64, |
| + ceil_f32: ceil_f32, |
| + floor_f64: floor_f64, |
| + floor_f32: floor_f32, |
| + sqrt_f64: sqrt_f64, |
| + sqrt_f32: sqrt_f32, |
| + abs_f64: abs_f64, |
| + abs_f32: abs_f32, |
| + abs_i32: abs_i32, |
| + acos_f64: acos_f64, |
| + asin_f64: asin_f64, |
| + atan_f64: atan_f64, |
| + cos_f64: cos_f64, |
| + sin_f64: sin_f64, |
| + tan_f64: tan_f64, |
| + exp_f64: exp_f64, |
| + log_f64: log_f64, |
| + imul_i32: imul_i32, |
| + imul_u32: imul_u32, |
| + fround_i32: fround_i32, |
| + fround_u32: fround_u32, |
| + fround_f32: fround_f32, |
| + // TODO(bradnelson): Fix and enable. |
| + // fround_f64: fround_f64, |
| + min_i32: min_i32, |
| + // TODO(bradnelson): Fix and enable. |
| + // min_u32: min_u32, |
| + min_f32: min_f32, |
| + min_f64: min_f64, |
| + max_i32: max_i32, |
| + // TODO(bradnelson): Fix and enable. |
| + // max_u32: max_u32, |
| + max_f32: max_f32, |
| + max_f64: max_f64, |
| + }; |
| + } |
| + var m = Wasm.instantiateModuleFromAsm(Module.toString()); |
| + var values = { |
| + 'i32': [ |
| + 0, 1, -1, 123, 456, -123, -456, |
| + 0x40000000, 0x7FFFFFFF, -0x80000000, |
| + ], |
| + 'u32': [ |
| + 0, 1, 123, 456, |
| + 0x40000000, 0x7FFFFFFF, 0xFFFFFFFF, 0x80000000, |
| + ], |
| + 'f32': [ |
| + 0, -0, 1, -1, 0.9, -0.9, 1.414, 0x7F, -0x80, -0x8000, -0x80000000, |
|
titzer
2016/03/16 09:44:05
Not sure if it matters here but 0.9 is not exactly
bradnelson
2016/03/19 03:48:48
Got these "edge case" values from the simd tests.
|
| + 0x7FFF, 0x7FFFFFFF, Infinity, -Infinity, NaN, |
| + ], |
| + 'f64': [ |
| + 0, -0, 1, -1, 0.9, -0.9, 1.414, 0x7F, -0x80, -0x8000, -0x80000000, |
| + 0x7FFF, 0x7FFFFFFF, Infinity, -Infinity, NaN, |
| + ], |
| + }; |
| + var converts = { |
| + 'i32': function(x) { return x | 0; }, |
|
titzer
2016/03/16 09:44:05
You can drop the single quotes from these property
bradnelson
2016/03/19 03:48:48
Done.
|
| + 'u32': function(x) { return x >>> 0; }, |
| + 'f32': function(x) { return Math.fround(x); }, |
| + 'f64': function(x) { return x; }, |
| + }; |
| + var two_args = {'atan2': true, 'pow': true, 'imul': true, |
| + 'min': true, 'max': true}; |
| + var funcs = { |
| + 'ceil': ['f32', 'f64'], |
| + 'floor': ['f32', 'f64'], |
| + 'sqrt': ['f32', 'f64'], |
| + 'abs': ['i32', 'f32', 'f64'], |
| + 'acos': ['f64'], |
| + 'asin': ['f64'], |
| + 'atan': ['f64'], |
| + 'cos': ['f64'], |
| + 'sin': ['f64'], |
| + 'tan': ['f64'], |
| + 'exp': ['f64'], |
| + 'log': ['f64'], |
| + 'imul': ['i32', 'u32'], |
| + // TODO(bradnelson): Fix and enable. |
| + // 'fround': ['i32', 'u32', 'f32', 'f64'], |
| + 'fround': ['i32', 'u32', 'f32'], |
| + // TODO(bradnelson): Fix and enable. |
| + // 'min': ['i32', 'u32', 'f32', 'f64'], |
| + 'min': ['i32', 'f32', 'f64'], |
| + // TODO(bradnelson): Fix and enable. |
| + // 'max': ['i32', 'u32', 'f32', 'f64'], |
| + 'max': ['i32', 'f32', 'f64'], |
| + }; |
| + var equals = { |
| + 'f64': looseEqual, |
| + 'f32': plainEqual, |
| + 'i32': plainEqual, |
| + }; |
| + var per_func_equals = { |
| + // exp not required to have a particular precision. |
| + 'exp_f64': function(x, y) { return looseEqual(x, y, 1e55); }, |
| + }; |
| + for (var func in funcs) { |
| + var types = funcs[func]; |
| + for (var i = 0; i < types.length; i++) { |
| + var type = types[i]; |
| + var interesting = values[type]; |
| + for (var j = 0; j < interesting.length; j++) { |
| + for (var k = 0; k < interesting.length; k++) { |
| + var val0 = interesting[j]; |
| + var val1 = interesting[k]; |
| + var input0 = converts[type](val0); |
| + var input1 = converts[type](val1); |
| + var name = func + '_' + type; |
| + if (two_args[func]) { |
| + var expected = converts[type](Math[func](input0, input1)); |
| + var actual = m[name](input0, input1); |
| + } else { |
| + var expected = converts[type](Math[func](input0, input1)); |
| + var actual = m[name](input0, input1); |
| + } |
| + var compare = per_func_equals[name]; |
| + if (compare === undefined) { |
| + compare = equals[type]; |
| + } |
| + if (!compare(expected, actual)) { |
| + print(expected + ' !== ' + actual + ' for ' + name + |
| + ' with input ' + input0 + ' ' + input1); |
| + assertTrue(false); |
| + } |
| + } |
| + } |
| + } |
| + } |
| +})(); |