Bug 863045 - OdinMonkey: fix duplicate-evaluation in double-to-int coercion (r=sstangl)

--HG--
extra : rebase_source : b6c832b6a2a5a1f25c137ca7e276316b85ff3650
This commit is contained in:
Luke Wagner 2013-04-17 17:34:29 -07:00
parent e0bf1ede5f
commit 90d93e6668
3 changed files with 43 additions and 12 deletions

View File

@ -3495,24 +3495,39 @@ CheckNeg(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type)
return f.fail("Operand to unary - must be an int", operand);
}
static bool
CheckCoerceToInt(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *type)
{
JS_ASSERT(expr->isKind(PNK_BITNOT));
ParseNode *operand = UnaryKid(expr);
MDefinition *operandDef;
Type operandType;
if (!CheckExpr(f, operand, Use::ToInt32, &operandDef, &operandType))
return false;
if (operandType.isDoublish()) {
*def = f.unary<MTruncateToInt32>(operandDef);
*type = Type::Signed;
return true;
}
if (!operandType.isIntish())
return f.fail("Operand to ~ must be intish or doublish", operand);
*def = operandDef;
*type = Type::Signed;
return true;
}
static bool
CheckBitNot(FunctionCompiler &f, ParseNode *neg, MDefinition **def, Type *type)
{
JS_ASSERT(neg->isKind(PNK_BITNOT));
ParseNode *operand = UnaryKid(neg);
if (operand->isKind(PNK_BITNOT)) {
MDefinition *operandDef;
Type operandType;
if (!CheckExpr(f, UnaryKid(operand), Use::NoCoercion, &operandDef, &operandType))
return false;
if (operandType.isDouble()) {
*def = f.unary<MTruncateToInt32>(operandDef);
*type = Type::Signed;
return true;
}
}
if (operand->isKind(PNK_BITNOT))
return CheckCoerceToInt(f, operand, def, type);
MDefinition *operandDef;
Type operandType;

View File

@ -8,6 +8,7 @@ assertEq(asmLink(asmCompile(USE_ASM + "function f(i,e) { i=i|0;e=+e; return +(+~
assertEq(asmLink(asmCompile(USE_ASM + "function f(d,i) { d=+d;i=i|0; return +(d + +(i|0)) } return f"))(.1, 1), 1.1);
assertEq(asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return +(d-e) } return f"))(1.1, .8), (1.1-.8));
assertEq(asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return +(d*e) } return f"))(1.1, 2.2), (1.1*2.2));
assertEq(asmLink(asmCompile(USE_ASM + "function g() { var i=2; return (~~(i=(i+1)|0))|0 } return g"))(), 3);
var f = asmLink(asmCompile(USE_ASM + "function f(d,e) { d=+d;e=+e; return (d<e)|0 } return f"));
assertEq(f(1.1, 2.2), 1);
@ -109,6 +110,9 @@ function ffi(d) { str = String(d) }
var g = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'var ffi=imp.ffi; function g() { ffi(+f64[0]) } return g'), this, {ffi:ffi}, buf);
var h = asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function g() { return +(+f64[0] < 0.0 ? -+f64[0] : +f64[0]) } return g'), this, null, buf)
function ffi1() { return 2.6 }
assertEq(asmLink(asmCompile('glob', 'imp', USE_ASM + "var ffi1=imp.ffi1; function g() { var i=0,j=0.0; i=~~ffi1(); j=+ffi1(); return +(+(i|0)+j) } return g"), null, {ffi1:ffi1})(), 2+2.6);
// that sounds dangerous!
var a = [0,1,0xffff0000,0x7fff0000,0xfff80000,0x7ff80000,0xfffc0000,0x7ffc0000,0xffffffff,0x0000ffff,0x00008fff7];
for (i of a) {

View File

@ -82,6 +82,18 @@ assertEq(f(0x7f),0x7f);
assertEq(f(0xff),0xff);
assertEq(f(0x100),0);
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return (~~f64[i>>3])|0}; return f');
var f = asmLink(code, this, null, new ArrayBuffer(4096));
assertEq(f(0, 1.3), 1);
assertEq(f(4088, 2.5), 2);
assertEq(f(4096, 3.8), 0);
var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i,j) {i=i|0;j=+j; f64[i>>3] = j; return +f64[i>>3]}; return f');
var f = asmLink(code, this, null, new ArrayBuffer(4096));
assertEq(f(0, 1.3), 1.3);
assertEq(f(4088, 2.5), 2.5);
assertEq(f(4096, 3.8), NaN);
var i32 = new Int32Array(4096/4);
i32[0] = 13;
i32[1] = 0xfffeeee;