mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[INFER] Don't hoist accesses that could underflow the array, bug 649775.
This commit is contained in:
parent
42fa6e5949
commit
0ae73e12fa
17
js/src/jit-test/tests/jaeger/bug649775.js
Normal file
17
js/src/jit-test/tests/jaeger/bug649775.js
Normal file
@ -0,0 +1,17 @@
|
||||
var x = [, ];
|
||||
var n = [, ];
|
||||
var np = 18229;
|
||||
sa = Array;
|
||||
function copy_(x, y) {
|
||||
var i;
|
||||
var k = x < y ? x.length : y.length;
|
||||
for (i = 0; i < k; i--) {
|
||||
x[i];
|
||||
if (i == -100)
|
||||
return;
|
||||
}
|
||||
}
|
||||
function mont_(x, y, n, np) {
|
||||
copy_(x, sa);
|
||||
}
|
||||
mont_(x, x, n, np);
|
@ -494,6 +494,24 @@ struct LifetimeVariable
|
||||
return uint32(-1);
|
||||
}
|
||||
|
||||
/* Return true if the variable cannot decrease during the body of a loop. */
|
||||
bool nonDecreasing(JSScript *script, LifetimeLoop *loop) {
|
||||
Lifetime *segment = lifetime ? lifetime : saved;
|
||||
while (segment && segment->start <= loop->backedge) {
|
||||
if (segment->start >= loop->head && segment->write) {
|
||||
switch (JSOp(script->code[segment->start])) {
|
||||
case JSOP_INCLOCAL:
|
||||
case JSOP_LOCALINC:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
segment = segment->next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the variable is only written once in the body of a loop, offset of
|
||||
* that write. -1 otherwise.
|
||||
@ -562,6 +580,11 @@ class LifetimeScript
|
||||
return lifetimes[slot].firstWrite(loop);
|
||||
}
|
||||
|
||||
bool nonDecreasing(uint32 slot, LifetimeLoop *loop) {
|
||||
JS_ASSERT(slot < nLifetimes);
|
||||
return lifetimes[slot].nonDecreasing(script, loop);
|
||||
}
|
||||
|
||||
uint32 onlyWrite(uint32 slot, LifetimeLoop *loop) {
|
||||
JS_ASSERT(slot < nLifetimes);
|
||||
return lifetimes[slot].onlyWrite(loop);
|
||||
|
@ -393,6 +393,15 @@ LoopState::hoistArrayLengthCheck(const FrameEntry *obj, const FrameEntry *index)
|
||||
uint32 rhs = lifetime->testRHS;
|
||||
int32 constant = lifetime->testConstant;
|
||||
|
||||
/*
|
||||
* If the LHS can decrease in the loop, it could become negative and
|
||||
* underflow the array.
|
||||
*/
|
||||
if (!liveness->nonDecreasing(lifetime->testLHS, lifetime)) {
|
||||
JaegerSpew(JSpew_Analysis, "Index may decrease in future iterations\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 write = liveness->firstWrite(lifetime->testLHS, lifetime);
|
||||
JS_ASSERT(write != LifetimeLoop::UNASSIGNED);
|
||||
if (write < uint32(PC - script->code)) {
|
||||
|
Loading…
Reference in New Issue
Block a user