blob: c2023252ad04170943d2e2e6dea0b4848a72a73b [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
// Notes on running this script:
// - rldirs.xml is set up in the following way so that this script is called 2 times:
// - First, it's called for interpreted variant.
// - Then, when it's called for dynapogo variant, jshost is called with: -args dynapogo.
// - This script is not called for the default variant.
// - Idea:
// - Collect dynamic profile cache when called for interpreted variant.
// - Use dynamic profile cache when called with -args dynapogo.
// - Some tests cause bailout by passing different parameter to test function
// as when dynamic profile cache was created.
// - How to manually run/repro:
// - jshost -nonative -dynamicprofilecache:inlineBuiltIns.dpl inlineBuiltIns.js
// - jshost -forcenative -dynamicprofileinput:inlineBuiltIns.dpl inlineBuiltIns.js -args dynapogo
// - also trying using -testtrace:bailout to make sure you get the bailouts.
// TODO: change passing -args native to jshost and instead
// add support to WScript to expose getFlagByString() for Js::ConfigFlagsTable flags and check for -native.
if (typeof (WScript) != "undefined") {
WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js", "self");
}
var Runtime = {
// returns true when this jshost is called with arguments: -args native
get isDynapogo() {
return WScript.Arguments.length > 0 && WScript.Arguments[0] == "dynapogo";
}
};
var tests = {
test01: {
name: "Bailout on function = null",
body: function () {
function TestSin(x) {
var r1 = Math.sin(x);
return r1;
};
if (Runtime.isDynapogo) {
var sinOrig = Math.sin; // back up Math.sin
assert.throws(function() {
Math.sin = null;
var r = TestSin({});
assert.isTrue(isNaN(r));
}, TypeError);
Math.sin = sinOrig; // restore Math.sin
}
else TestSin();
}
},
test02: {
name: "Bailout on function = object, not a function",
body: function () {
function TestSin(x) {
var r1 = Math.sin(x);
return r1;
};
if (Runtime.isDynapogo) {
var sinOrig = Math.sin; // back up Math.sin
assert.throws(function() {
Math.sin = {};
var r = TestSin({});
assert.isTrue(isNaN(r));
}, TypeError);
Math.sin = sinOrig; // restore Math.sin
}
else TestSin();
}
},
test03: {
name: "Bailout on function = wrong function",
body: function () {
function TestSin(x) {
var r1 = Math.sin(x);
return r1;
};
var sinOrig = Math.sin; // back up Math.sin
Math.sin = Math.cos;
var r = TestSin({});
assert.isTrue(isNaN(r));
Math.sin = sinOrig; // restore Math.sin
}
},
test04: {
name: "Bailout on argument = string",
body: function () {
function TestSin(x) {
var r1 = Math.sin(x);
return r1;
};
var r = TestSin("string");
assert.isTrue(isNaN(r));
}
},
test05: {
name: "Bailout on argument = object",
body: function () {
function TestSin(x) {
var r1 = Math.sin(x);
return r1;
};
var r = TestSin({});
assert.isTrue(isNaN(r));
}
},
test06: {
name: "Bailout on 2nd argument = string",
body: function () {
function TestPow(x, y) {
var r1 = Math.pow(x, y);
return r1;
};
var r = TestPow(2, "string");
assert.isTrue(isNaN(r));
}
},
test07: {
name: "Float/int type specialized argOuts which we restore at bailout",
body: function () {
// As long as there is no assert/crash, we are fine.
(function() {
var i = -8.1E+18;
var r = Math.pow(1, Math.exp(Math.atan2(1, ((~i) - 737882964))));
})();
(function() {
var e = 1;
return Math.pow(e >> 1, 3.2)
})();
(function() {
var e = 1;
Math.atan2(1, Math.pow((e >>= 1), Math.tan((-1031883772 * Math.abs(-951135089)))));
})();
(function() {
var ary = new Array();
ary[0] = 0;
Math.pow(1808815940.1, -ary[0]);
})();
(function() {
return Math.pow(Math.sin(1), Math.pow(1, 1));
})();
(function() {
var o = { x: 0 };
var func0 = function()
{
Math.pow(1.1, o.x * -1);
}
Math.atan2(func0(), 1);
})();
}
},
test08: {
name: "Bailout on argument after function copy-prop into InlineBuiltInStart",
body: function () {
for(var i in [0, 1])
assert.isTrue(isNaN(Math.pow(Math.pow(/x/, 0.1), 0.1)));
}
},
test09: {
name: "Bailout (pre-op) on 2nd arg which is updated in the place of the call - make sure 1st arg is not updated",
body: function() {
var accumulator = "";
var vOf = function vOf() { accumulator += "x"; return 3; }
function testFunc() {
var i = 1;
do {
// We need to make sure that we pass original value of i (== 1) as 1st arg.
var x = Math.pow(i, Runtime.isDynapogo ? i = { valueOf: vOf } : 1);
} while (vOf == undefined);
}
testFunc();
if (Runtime.isDynapogo) {
assert.areEqual("x", accumulator, "valueOf was called wrong number of times");
}
}
},
}; // tests.
testRunner.runTests(tests);