handle zero-length lookup tables in lookupswitch

This commit is contained in:
Joel Dice 2009-08-12 19:32:12 -06:00
parent db58097165
commit 61cb8b3deb

View File

@ -2228,6 +2228,8 @@ throw_(MyThread* t, object o)
t->exception = makeNullPointerException(t); t->exception = makeNullPointerException(t);
} }
// printTrace(t, t->exception);
unwind(t); unwind(t);
} }
@ -3811,37 +3813,42 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
int32_t pairCount = codeReadInt32(t, code, ip); int32_t pairCount = codeReadInt32(t, code, ip);
Compiler::Operand* start = 0; if (pairCount) {
uint32_t ipTable[pairCount]; Compiler::Operand* start = 0;
for (int32_t i = 0; i < pairCount; ++i) { uint32_t ipTable[pairCount];
unsigned index = ip + (i * 8); for (int32_t i = 0; i < pairCount; ++i) {
int32_t key = codeReadInt32(t, code, index); unsigned index = ip + (i * 8);
uint32_t newIp = base + codeReadInt32(t, code, index); int32_t key = codeReadInt32(t, code, index);
assert(t, newIp < codeLength(t, code)); uint32_t newIp = base + codeReadInt32(t, code, index);
assert(t, newIp < codeLength(t, code));
ipTable[i] = newIp; ipTable[i] = newIp;
Promise* p = c->poolAppend(key); Promise* p = c->poolAppend(key);
if (i == 0) { if (i == 0) {
start = frame->addressOperand(p); start = frame->addressOperand(p);
}
c->poolAppendPromise(frame->addressPromise(c->machineIp(newIp)));
} }
c->poolAppendPromise(frame->addressPromise(c->machineIp(newIp))); assert(t, start);
}
assert(t, start);
c->jmp c->jmp
(c->call (c->call
(c->constant(getThunk(t, lookUpAddressThunk)), (c->constant(getThunk(t, lookUpAddressThunk)),
0, 0, BytesPerWord, 0, 0, BytesPerWord,
4, key, start, c->constant(pairCount), default_)); 4, key, start, c->constant(pairCount), default_));
Compiler::State* state = c->saveState(); Compiler::State* state = c->saveState();
for (int32_t i = 0; i < pairCount; ++i) { for (int32_t i = 0; i < pairCount; ++i) {
compile(t, frame, ipTable[i]); compile(t, frame, ipTable[i]);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state); c->restoreState(state);
}
} else {
// a switch statement with no cases, apparently
c->jmp(default_);
} }
ip = defaultIp; ip = defaultIp;