| // 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-13) | 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-10; |
| } |
| 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 fround2 = 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; } |
| |
| // type -> f32 |
| function fround_i32(x) { x = x | 0; return fround(x|0); } |
| function fround_u32(x) { x = x | 0; return fround(x>>>0); } |
| function fround_f32(x) { x = fround(x); return fround(x); } |
| function fround_f64(x) { x = +x; return fround(x); } |
| |
| // type -> f32 -> type |
| function fround2_i32(x) { x = x | 0; return ~~fround2(x|0) | 0; } |
| function fround2_u32(x) { x = x | 0; return ~~fround2(x>>>0) | 0; } |
| function fround2_f32(x) { x = fround2(x); return fround2(x); } |
| function fround2_f64(x) { x = +x; return +fround2(x); } |
| |
| function min_i32(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; } |
| 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, |
| fround_f64: fround_f64, |
| fround2_i32: fround2_i32, |
| fround2_u32: fround2_u32, |
| fround2_f32: fround2_f32, |
| fround2_f64: fround2_f64, |
| min_i32: min_i32, |
| min_f32: min_f32, |
| min_f64: min_f64, |
| max_i32: max_i32, |
| 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.25, 0.125, 0.9, -0.9, 1.414, |
| 0x7F, -0x80, -0x8000, -0x80000000, |
| 0x7FFF, 0x7FFFFFFF, Infinity, -Infinity, NaN, |
| ], |
| f64: [ |
| 0, -0, 1, -1, 0.25, 0.125, 0.9, -0.9, 1.414, |
| 0x7F, -0x80, -0x8000, -0x80000000, |
| 0x7FFF, 0x7FFFFFFF, Infinity, -Infinity, NaN, |
| ], |
| }; |
| var converts = { |
| i32: function(x) { return x | 0; }, |
| 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'], |
| fround: ['i32', 'u32', 'f32', 'f64'], |
| min: ['i32', 'f32', 'f64'], |
| max: ['i32', 'f32', 'f64'], |
| }; |
| var per_func_equals = { |
| // JS uses fdlib for these, so they may not match. |
| // ECMAscript does not required them to have a particular precision. |
| exp_f64: function(x, y) { return looseEqual(x, y, 1e55); }, |
| sqrt_f32: function(x, y) { return looseEqual(x, y, 1e-5); }, |
| cos_f64: looseEqual, |
| sin_f64: looseEqual, |
| tan_f64: looseEqual, |
| // TODO(bradnelson): |
| // Figure out why some builds (avx2, rel_ng) return a uint. |
| imul_u32: function(x, y) { return (x | 0) === (y | 0); }, |
| }; |
| 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 name = func + '_' + type; |
| if (func === 'fround') { |
| // fround returns f32 regardless of input. |
| var expected = Math[func](val0); |
| var actual = m[name](val0); |
| } else if (two_args[func]) { |
| var expected = converts[type](Math[func](val0, val1)); |
| var actual = m[name](val0, val1); |
| } else { |
| var expected = converts[type](Math[func](val0, val1)); |
| var actual = m[name](val0, val1); |
| } |
| var compare = per_func_equals[name]; |
| if (compare === undefined) { |
| compare = plainEqual; |
| } |
| assertTrue(typeof(compare) === 'function'); |
| if (!compare(expected, actual)) { |
| print(expected + ' !== ' + actual + ' for ' + name + |
| ' with input ' + val0 + ' ' + val1); |
| assertTrue(false); |
| } |
| } |
| } |
| } |
| } |
| })(); |