don't abort when compiling an array lookup with a constant negative index

Instead, just compile it as a direct call to the thunk which throws an
ArrayIndexOutOfBoundsException.
This commit is contained in:
Joel Dice 2010-09-25 15:48:15 -06:00
parent ebc54c234f
commit e75b57a127
2 changed files with 34 additions and 17 deletions

View File

@ -4865,12 +4865,13 @@ class BoundsCheckEvent: public Event {
Assembler* a = c->assembler;
ConstantSite* constant = findConstantSite(c, index);
CodePromise* nextPromise = codePromise
(c, static_cast<Promise*>(0));
CodePromise* outOfBoundsPromise = 0;
if (constant) {
expect(c, constant->value->value() >= 0);
if (constant->value->value() < 0) {
Assembler::Constant handlerConstant(resolved(c, handler));
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
}
} else {
outOfBoundsPromise = codePromise(c, static_cast<Promise*>(0));
@ -4880,24 +4881,29 @@ class BoundsCheckEvent: public Event {
BytesPerWord, &oob, &oob);
}
assert(c, object->source->type(c) == RegisterOperand);
MemorySite length(static_cast<RegisterSite*>(object->source)->number,
lengthOffset, NoRegister, 1);
length.acquired = true;
if (constant == 0 or constant->value->value() >= 0) {
assert(c, object->source->type(c) == RegisterOperand);
MemorySite length(static_cast<RegisterSite*>(object->source)->number,
lengthOffset, NoRegister, 1);
length.acquired = true;
ConstantSite next(nextPromise);
apply(c, JumpIfGreater, 4, index->source, index->source, 4, &length,
&length, BytesPerWord, &next, &next);
CodePromise* nextPromise = codePromise
(c, static_cast<Promise*>(0));
if (constant == 0) {
outOfBoundsPromise->offset = a->offset();
ConstantSite next(nextPromise);
apply(c, JumpIfGreater, 4, index->source, index->source, 4, &length,
&length, BytesPerWord, &next, &next);
if (constant == 0) {
outOfBoundsPromise->offset = a->offset();
}
Assembler::Constant handlerConstant(resolved(c, handler));
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
nextPromise->offset = a->offset();
}
Assembler::Constant handlerConstant(resolved(c, handler));
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
nextPromise->offset = a->offset();
popRead(c, this, object);
popRead(c, this, index);
}

View File

@ -15,6 +15,17 @@ public class Arrays {
expect(exception != null);
}
{ int[] array = new int[0];
Exception exception = null;
try {
int x = array[-1];
} catch (ArrayIndexOutOfBoundsException e) {
exception = e;
}
expect(exception != null);
}
{ int[] array = new int[3];
int i = 0;
array[i++] = 1;