mirror of
https://github.com/corda/corda.git
synced 2025-01-22 20:38:05 +00:00
sketch implementations of lookupswitch and tableswitch
This commit is contained in:
parent
7eb49f272c
commit
2eeff1d50e
126
src/compile2.cpp
126
src/compile2.cpp
@ -1,9 +1,8 @@
|
|||||||
Operand*
|
Operand*
|
||||||
add(Compiler* c, Buffer* objectPool, object o)
|
add(Compiler* c, Buffer* objectPool, object o)
|
||||||
{
|
{
|
||||||
unsigned offset;
|
Operand* result = c->append(c->constant(0));
|
||||||
Operand* result = c->poolAddress(0, &offset);
|
objectPool->appendAddress(c->poolOffset(result));
|
||||||
objectPool->appendAddress(offset);
|
|
||||||
objectPool->appendAddress(o);
|
objectPool->appendAddress(o);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -667,9 +666,8 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->jne(target);
|
c->jne(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame frame(frame);
|
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
||||||
compile(t, c, &stack, method, codeMask, objectPool, newIp);
|
if (UNLIKELY(t->exception)) return;
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case if_icmpeq:
|
case if_icmpeq:
|
||||||
@ -707,9 +705,8 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame frame(frame);
|
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
||||||
compile(t, c, &stack, method, codeMask, objectPool, newIp);
|
if (UNLIKELY(t->exception)) return;
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ifeq:
|
case ifeq:
|
||||||
@ -745,9 +742,8 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame frame(frame);
|
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
||||||
compile(t, c, &stack, method, codeMask, objectPool, newIp);
|
if (UNLIKELY(t->exception)) return;
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ifnull:
|
case ifnull:
|
||||||
@ -764,9 +760,8 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
c->jne(target);
|
c->jne(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame frame(frame);
|
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
||||||
compile(t, c, &stack, method, codeMask, objectPool, newIp);
|
if (UNLIKELY(t->exception)) return;
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iinc: {
|
case iinc: {
|
||||||
@ -801,13 +796,6 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
frame->loadInt(3);
|
frame->loadInt(3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case impdep1: {
|
|
||||||
// this means we're invoking a virtual method on an instance of a
|
|
||||||
// bootstrap class, so we need to load the real class to get the
|
|
||||||
// real method and call it.
|
|
||||||
#warning todo
|
|
||||||
} goto loop;
|
|
||||||
|
|
||||||
case imul: {
|
case imul: {
|
||||||
Operand* a = frame->popInt();
|
Operand* a = frame->popInt();
|
||||||
c->mul(a, frame->topInt());
|
c->mul(a, frame->topInt());
|
||||||
@ -1014,9 +1002,9 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case lcmp: {
|
case lcmp: {
|
||||||
Operand* next = c->label();;
|
Operand* next = c->label();
|
||||||
Operand* less = c->label();;
|
Operand* less = c->label();
|
||||||
Operand* greater = c->label();;
|
Operand* greater = c->label();
|
||||||
|
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
Operand* b = frame->popLong();
|
Operand* b = frame->popLong();
|
||||||
@ -1127,8 +1115,44 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case lookupswitch: {
|
case lookupswitch: {
|
||||||
#warning todo
|
int32_t base = ip - 1;
|
||||||
} break;
|
|
||||||
|
ip = (ip + 3) & ~3; // pad to four byte boundary
|
||||||
|
|
||||||
|
Operand* key = frame->popInt();
|
||||||
|
|
||||||
|
int32_t defaultIp = base + codeReadInt32(t, code, ip);
|
||||||
|
assert(t, defaultIp < codeLength(t, code));
|
||||||
|
|
||||||
|
compile(t, c, frame, method, codeMask, objectPool, defaultIp);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
|
Operand* default_ = c->append(c->logicalIp(defaultIp));
|
||||||
|
|
||||||
|
int32_t pairCount = codeReadInt32(t, code, ip);
|
||||||
|
|
||||||
|
Operand* start;
|
||||||
|
for (int32_t i = 0; i < pairCount; ++i) {
|
||||||
|
unsigned index = ip + (i * 8);
|
||||||
|
int32_t key = codeReadInt32(t, code, index);
|
||||||
|
int32_t newIp = base + codeReadInt32(t, code, index);
|
||||||
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
|
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
|
Operand* result = c->append(c->constant(key));
|
||||||
|
c->append(c->logicalIp(newIp));
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
start = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c->jmp(c->directCall
|
||||||
|
(lookUpAddress, 4,
|
||||||
|
key, start, c->constant(pairCount), default_));
|
||||||
|
} return;
|
||||||
|
|
||||||
case lor: {
|
case lor: {
|
||||||
Operand* a = frame->popLong();
|
Operand* a = frame->popLong();
|
||||||
@ -1404,8 +1428,52 @@ compile(MyThread* t, Compiler* c, Frame* initialFrame, object method,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case tableswitch: {
|
case tableswitch: {
|
||||||
#warning todo
|
int32_t base = ip - 1;
|
||||||
} break;
|
|
||||||
|
ip = (ip + 3) & ~3; // pad to four byte boundary
|
||||||
|
|
||||||
|
Operand* key = frame->popInt();
|
||||||
|
|
||||||
|
int32_t defaultIp = base + codeReadInt32(t, code, ip);
|
||||||
|
assert(t, defaultIp < codeLength(t, code));
|
||||||
|
|
||||||
|
compile(t, c, frame, method, codeMask, objectPool, defaultIp);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
|
Operand* default_ = c->append(c->logicalIp(defaultIp));
|
||||||
|
|
||||||
|
int32_t bottom = codeReadInt32(t, code, ip);
|
||||||
|
int32_t top = codeReadInt32(t, code, ip);
|
||||||
|
|
||||||
|
Operand* start;
|
||||||
|
for (int32_t i = 0; i < bottom - top + 1; ++i) {
|
||||||
|
unsigned index = ip + (i * 4);
|
||||||
|
int32_t newIp = base + codeReadInt32(t, code, index);
|
||||||
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
|
compile(t, c, frame, method, codeMask, objectPool, newIp);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
|
Operand* result = c->append(c->logicalIp(newIp));
|
||||||
|
if (i == 0) {
|
||||||
|
start = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand* defaultCase = c->label();
|
||||||
|
|
||||||
|
c->cmp(c->constant(bottom), key);
|
||||||
|
c->jl(defaultCase);
|
||||||
|
|
||||||
|
c->cmp(c->constant(top), key);
|
||||||
|
c->jg(defaultCase);
|
||||||
|
|
||||||
|
c->shl(c->constant(2), key);
|
||||||
|
c->jmp(c->offset(start, key));
|
||||||
|
|
||||||
|
c->mark(defaultCase);
|
||||||
|
c->jmp(default_);
|
||||||
|
} return;
|
||||||
|
|
||||||
case wide: {
|
case wide: {
|
||||||
switch (codeBody(t, code, ip++)) {
|
switch (codeBody(t, code, ip++)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user