Bug 1158632 - IonBuilder TableSwitch, fill-the-gap cases should encore the PC of the default block. r=h4writer

This commit is contained in:
Nicolas B. Pierron 2015-10-22 14:23:25 +02:00
parent 6a02deeadc
commit cb40608ac4
2 changed files with 28 additions and 15 deletions

View File

@ -0,0 +1,13 @@
for (var j = 0; j < 1; ++j) {
function f(x) {
x = 4294967295 >>> 4294967295 % x
switch (-1) {
case 1:
// case 0:
case -1:
x = 0;
// default:
}
}
f();
}

View File

@ -3406,34 +3406,34 @@ IonBuilder::tableSwitch(JSOp op, jssrcnote* sn)
casepc = pc + GET_JUMP_OFFSET(pc2); casepc = pc + GET_JUMP_OFFSET(pc2);
MOZ_ASSERT(casepc >= pc && casepc <= exitpc); MOZ_ASSERT(casepc >= pc && casepc <= exitpc);
MBasicBlock* caseblock;
MBasicBlock* caseblock = newBlock(current, casepc);
if (!caseblock)
return ControlStatus_Error;
// If the casepc equals the current pc, it is not a written case,
// but a filled gap. That way we can use a tableswitch instead of
// condswitch, even if not all numbers are consecutive.
// In that case this block goes to the default case
if (casepc == pc) { if (casepc == pc) {
// If the casepc equals the current pc, it is not a written case,
// but a filled gap. That way we can use a tableswitch instead of
// condswitch, even if not all numbers are consecutive.
// In that case this block goes to the default case
caseblock = newBlock(current, defaultpc);
if (!caseblock)
return ControlStatus_Error;
caseblock->end(MGoto::New(alloc(), defaultcase)); caseblock->end(MGoto::New(alloc(), defaultcase));
if (!defaultcase->addPredecessor(alloc(), caseblock)) if (!defaultcase->addPredecessor(alloc(), caseblock))
return ControlStatus_Error; return ControlStatus_Error;
} } else {
// If this is an actual case (not filled gap),
// add this block to the list that still needs to get processed.
caseblock = newBlock(current, casepc);
if (!caseblock)
return ControlStatus_Error;
tableswitch->addCase(tableswitch->addSuccessor(caseblock));
// If this is an actual case (not filled gap),
// add this block to the list that still needs to get processed.
if (casepc != pc) {
tableswitch->addBlock(caseblock); tableswitch->addBlock(caseblock);
// Add constant to indicate which case this is for use by // Add constant to indicate which case this is for use by
// processNextTableSwitchCase. // processNextTableSwitchCase.
MConstant* constant = MConstant::New(alloc(), Int32Value(i + low)); MConstant* constant = MConstant::New(alloc(), Int32Value(i + low));
caseblock->add(constant); caseblock->add(constant);
} }
tableswitch->addCase(tableswitch->addSuccessor(caseblock));
pc2 += JUMP_OFFSET_LEN; pc2 += JUMP_OFFSET_LEN;
} }