blob: c2db4ab9229db4fa56ba396d77526b838b0512a8 [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.
//-------------------------------------------------------------------------------------------------------
// Lossless conversion to int32 for compensation, needs to bail out even with aggressive int spec disabled. Incr_A is not
// type-specialized on loop second pass, because 'a' is live on the back-edge and becomes a NumberValue on merge, in turn
// because '++a' may overflow a 32-bit integer during the loop. The lossless conversion to int32 therefore must include bailout,
// to account for the overflow. Ideally, we should not do the conversion to int32 on the back-edge, and instead make the var sym
// live in the landing pad (or loop header if it's only live inside the loop).
function test0(n) {
var k = 0x3fffffff;
k <<= 1;
if(n === 1)
--k;
var a = k;
while(n-- !== 0)
++a;
return a;
}
WScript.Echo("test0: " + test0(2));
// Array element type specialization bug (uses lossy int32 index)
function test1() {
var a = [1];
a.foo = 2;
function test1a(i) {
var j = i & 1;
return a[i] + a[j];
}
return test1a("foo");
}
WScript.Echo("test1: " + test1());
// Loop prepass, upon type specialization, should keep the destination value consistent with that sym's liveness. In this case,
// 'i' is not int-specialized in the loop prepass when aggressive int type specialization is disabled, so 'i' should be given
// a number or unknown value.
function test2() {
var i = 0;
do {
++i;
} while(i < 1);
return i;
}
WScript.Echo("test2: " + test2());
// - Lossy conversion of 'a' to int32 due to 'a | 0' should include a bailout on implicit calls since it may have a side effect
// - The FromVar with bailout should not be dead-store-removed due to the possibility of side effects
// - When lossy int type specialization is disabled, the resulting value of '~a' should still be an int range value so that the
// '+' can still be int-specialized
// - Errors during ToPrimitive are handled appropriately by throwing after bailing out
function test3a(a) {
a | 0;
return ~a + 1;
}
WScript.Echo("test3a: " + test3a(-2));
function test3b(a) {
a | 0;
return ~a + 1;
}
WScript.Echo(
"test3b: " +
test3b(
{
valueOf:
function () {
WScript.Echo("test3b: valueOf");
return -2;
}
}));
function test3c(a) {
a | 0;
return a | 0;
}
WScript.Echo("test3c: " + safeCall(test3c, { valueOf: null, toString: null }));
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function safeCall(f) {
var args = [];
for(var a = 1; a < arguments.length; ++a)
args.push(arguments[a]);
try {
return f.apply(this, args);
} catch(ex) {
return ex.name;
}
}
// Conversions from uint32 to int32 should be treated as lossy
WScript.Echo("test4");
function makeArrayLength(x) {
print( Math.floor(x));
}
function test4(a) {
var func2 = function () {
};
func2.length = 1;
func2.prop4 = 1;
var __loopvar2 = 0;
while ((func2.prop4+ 2147483650) |1) {
if (__loopvar2) {
break;
}
__loopvar2 = 2;
makeArrayLength(2147483650);
}
}
test4();
test4();