[INFER] OOL path for truncating doubles slightly outside the int32 range, bug 643037.

This commit is contained in:
Brian Hackett 2011-03-18 16:42:00 -07:00
parent d88b1fda69
commit 3ac25e55a7
3 changed files with 40 additions and 2 deletions

View File

@ -0,0 +1,10 @@
// check correctness of truncation of doubles slightly outside the int32 range.
function truncate(x) {
return x | 0;
}
assertEq(truncate(0xffffffff), -1);
assertEq(truncate(0xffffffff + 5000.5), 4999);
assertEq(truncate(-0xffffffff - 5000.5), -4999);

View File

@ -2531,6 +2531,10 @@ TypeObject::print(JSContext *cx)
if (unknownProperties)
printf(" unknown");
else if (isPackedArray)
printf(" packed");
else if (isDenseArray)
printf(" dense");
if (propertyCount == 0) {
printf(" {}\n");

View File

@ -128,11 +128,35 @@ mjit::Compiler::ensureInteger(FrameEntry *fe, Uses uses)
}
} else if (fe->isType(JSVAL_TYPE_DOUBLE)) {
FPRegisterID fpreg = frame.tempFPRegForData(fe);
FPRegisterID fptemp = frame.allocFPReg();
RegisterID data = frame.allocReg();
Jump truncateGuard = masm.branchTruncateDoubleToInt32(fpreg, data);
stubcc.linkExit(truncateGuard, uses);
Label syncPath = stubcc.syncExitAndJump(uses);
stubcc.linkExitDirect(truncateGuard, stubcc.masm.label());
/*
* Try an OOL path to convert doubles representing integers within 2^32
* of a signed integer, by adding/subtracting 2^32 and then trying to
* convert to int32. This has to be an exact conversion, as otherwise
* the truncation works incorrectly on the modified value.
*/
stubcc.masm.zeroDouble(fptemp);
Jump positive = stubcc.masm.branchDouble(Assembler::DoubleGreaterThan, fpreg, fptemp);
stubcc.masm.slowLoadConstantDouble(double(4294967296.0), fptemp);
Jump skip = stubcc.masm.jump();
positive.linkTo(stubcc.masm.label(), &stubcc.masm);
stubcc.masm.slowLoadConstantDouble(double(-4294967296.0), fptemp);
skip.linkTo(stubcc.masm.label(), &stubcc.masm);
JumpList isDouble;
stubcc.masm.addDouble(fpreg, fptemp);
stubcc.masm.branchConvertDoubleToInt32(fptemp, data, isDouble, Registers::FPConversionTemp);
stubcc.crossJump(stubcc.masm.jump(), masm.label());
isDouble.linkTo(syncPath, &stubcc.masm);
frame.freeReg(fptemp);
frame.learnType(fe, JSVAL_TYPE_INT32, data);
} else if (!fe->isType(JSVAL_TYPE_INT32)) {
RegisterID typeReg = frame.tempRegForType(fe);