//@ skip // This test checks that the pow function returns coherent results: // (a) Across different compilation tiers // (b) With integer exponents represented as int32 or as double function pow42() { return { value: Math.pow(2.1, 42), ftl: isFinalTier() }; } function build42AsDouble() { function opaqueAdd(x, y) { return x + y; } return opaqueAdd(42 - 0.123, 0.123); } var double42 = build42AsDouble(); if (double42 !== 42) throw new Error("42 (as double) should be === to 42 (as int)"); function powDouble42() { return { value: Math.pow(2.1, double42), ftl: isFinalTier() }; } function clobber() { } noInline(clobber); function pow42NoConstantFolding() { var obj = { x: 2.1, y: 42 }; clobber(obj); return { value: Math.pow(obj.x, obj.y), ftl: isFinalTier() }; } function powDouble42NoConstantFolding() { var obj = { x: 2.1, y: double42 }; clobber(obj); return { value: Math.pow(obj.x, obj.y), ftl: isFinalTier() }; } var results = { 'jit': {}, 'dfg': {}, 'ftl': {} }; var funs = [ [ 'pow42', pow42 ], [ 'powDouble42', powDouble42 ], [ 'pow42NoConstantFolding', pow42NoConstantFolding ], [ 'powDouble42NoConstantFolding', powDouble42NoConstantFolding ] ]; var tiers = ['jit', 'dfg', 'ftl']; for (var i = 0; i < 100000; ++i) { for (var j in funs) { var name = funs[j][0]; var fun = funs[j][1]; var result = fun(); if (result.ftl) results['ftl'][name] = result.value; else if (numberOfDFGCompiles(fun) > 0) results['dfg'][name] = result.value; else results['jit'][name] = result.value; } } var errors = []; var valuesFor = {}; for (var i in tiers) { var tier = tiers[i]; var result = results[tier]; // We don't have this tier if (Object.keys(result).length === 0) continue; for (var j in funs) { var name = funs[j][0]; if (!(name in result)) errors.push(name + " was not compiled to " + tier); else if (!(name in valuesFor)) valuesFor[name] = { value: result[name], tiers: [tier] }; else if (result[name] !== valuesFor[name].value) errors.push(name + " has different results in " + tier + " (" + result[name] + ") and " + valuesFor[name].tiers + " (" + valuesFor[name].value + ")"); else valuesFor[name].tiers.push(tier); } } var reference = funs[0][0]; var result = valuesFor[reference].value; for (var j in funs) { var name = funs[j][0]; if (valuesFor[name].value !== result) errors.push(name + " (" + valuesFor[name].value + ") and " + reference + " (" + result + ") have different results"); } if (errors.length > 0) throw new Error(errors.join('\n'));