corda/src/vm.cpp

1149 lines
26 KiB
C++
Raw Normal View History

2007-05-21 15:47:44 +00:00
namespace {
object
run(Thread* t)
{
unsigned ip = 0;
2007-05-30 00:08:10 +00:00
unsigned parameterCount = 0;
2007-05-21 15:47:44 +00:00
#define PUSH(x) t->stack[(t->sp)++] = x
#define POP(x) x = t->stack[--(t->sp)]
loop:
2007-05-22 00:05:29 +00:00
switch (codeBody(t->code)[ip++]) {
2007-05-21 15:47:44 +00:00
case aaload: {
object index; POP(index);
object array; POP(array);
if (array) {
int32_t i = intValue(index);
if (i >= 0 and i < objectArrayLength(array)) {
PUSH(objectArrayBody(array)[i]);
} else {
object message = makeString(t, "%d not in [0,%d]", i,
objectArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-21 15:47:44 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-21 15:47:44 +00:00
goto throw_;
}
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aastore: {
object value; POP(value);
object index; POP(index);
object array; POP(array);
int32_t i = intValue(index);
if (array) {
if (i >= 0 and i < objectArrayLength(array)) {
set(t, objectArrayBody(array)[i], value);
} else {
object message = makeString(t, "%d not in [0,%d]", i,
objectArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-21 15:47:44 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-21 15:47:44 +00:00
goto throw_;
}
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aconst_null: {
PUSH(0);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload: {
2007-05-22 00:05:29 +00:00
PUSH(frameBody(t->frame)[codeBody(t->code)[ip++]]);
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_0: {
PUSH(frameBody(t->frame)[0]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_1: {
PUSH(frameBody(t->frame)[1]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_2: {
PUSH(frameBody(t->frame)[2]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_3: {
PUSH(frameBody(t->frame)[3]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case anewarray: {
object count; POP(count);
int32_t c = intValue(count);
if (c >= 0) {
2007-05-22 00:05:29 +00:00
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
2007-05-21 15:47:44 +00:00
uint16_t index = (index1 << 8) | index2;
2007-05-22 00:05:29 +00:00
object class_ = resolveClass(t, codePool(t->code), index);
2007-05-21 15:47:44 +00:00
if (t->exception) goto throw_;
object array = makeObjectArray(t, class_, c);
memset(objectArrayBody(array), 0, c * 4);
PUSH(array);
} else {
object message = makeString(t, "%d", c);
2007-05-25 14:48:07 +00:00
t->exception = makeNegativeArrayStoreException(t, message);
2007-05-21 15:47:44 +00:00
goto throw_;
}
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
2007-05-30 00:08:10 +00:00
case areturn:
case ireturn:
case lreturn: {
t->frame = frameNext(t->frame);
if (t->frame) {
2007-05-21 15:47:44 +00:00
t->code = frameCode(t->frame);
ip = frameIp(t->frame);
goto loop;
} else {
2007-05-30 00:08:10 +00:00
object value; POP(value);
t->code = 0;
2007-05-21 15:47:44 +00:00
return value;
}
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case arraylength: {
object array; POP(array);
if (array) {
PUSH(makeInt(t, arrayLength(array)));
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-21 15:47:44 +00:00
goto throw_;
}
} UNREACHABLE;
2007-05-30 00:08:10 +00:00
case astore:
case istore:
case lstore: {
2007-05-21 15:47:44 +00:00
object value; POP(value);
2007-05-22 00:05:29 +00:00
set(t, frameBody(t->frame)[codeBody(t->code)[ip++]], value);
} goto loop;
2007-05-21 15:47:44 +00:00
2007-05-30 00:08:10 +00:00
case astore_0:
case istore_0:
case lstore_0: {
2007-05-21 15:47:44 +00:00
object value; POP(value);
set(t, frameBody(t->frame)[0], value);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
2007-05-30 00:08:10 +00:00
case astore_1:
case istore_1:
case lstore_1: {
2007-05-21 15:47:44 +00:00
object value; POP(value);
set(t, frameBody(t->frame)[1], value);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
2007-05-30 00:08:10 +00:00
case astore_2:
case istore_2:
case lstore_2: {
2007-05-21 15:47:44 +00:00
object value; POP(value);
set(t, frameBody(t->frame)[2], value);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
2007-05-30 00:08:10 +00:00
case astore_3:
case istore_3:
case lstore_3: {
2007-05-21 15:47:44 +00:00
object value; POP(value);
set(t, frameBody(t->frame)[3], value);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case athrow: {
POP(t->exception);
2007-05-22 00:05:29 +00:00
if (t->exception == 0) {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
}
2007-05-21 15:47:44 +00:00
goto throw_;
} UNREACHABLE;
2007-05-22 00:05:29 +00:00
case baload: {
object index; POP(index);
object array; POP(array);
if (array) {
int32_t i = intValue(index);
if (i >= 0 and i < byteArrayLength(array)) {
PUSH(makeByte(t, byteArrayBody(array)[i]));
} else {
object message = makeString(t, "%d not in [0,%d]", i,
byteArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case bastore: {
object value; POP(value);
object index; POP(index);
object array; POP(array);
int32_t i = intValue(index);
if (array) {
if (i >= 0 and i < byteArrayLength(array)) {
byteArrayBody(array)[i] = intValue(value);
} else {
object message = makeString(t, "%d not in [0,%d]", i,
byteArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case bipush: {
PUSH(makeInt(t, codeBody(t->code)[ip++]));
} goto loop;
case caload: {
object index; POP(index);
object array; POP(array);
if (array) {
int32_t i = intValue(index);
if (i >= 0 and i < charArrayLength(array)) {
PUSH(makeInt(t, charArrayBody(array)[i]));
} else {
object message = makeString(t, "%d not in [0,%d]", i,
charArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case castore: {
object value; POP(value);
object index; POP(index);
object array; POP(array);
int32_t i = intValue(index);
if (array) {
if (i >= 0 and i < charArrayLength(array)) {
charArrayBody(array)[i] = intValue(value);
} else {
object message = makeString(t, "%d not in [0,%d]", i,
charArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case checkcast: {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
if (t->stack[t->sp - 1]) {
uint16_t index = (index1 << 8) | index2;
object class_ = resolveClass(t, codePool(t->code), index);
if (t->exception) goto throw_;
if (not instanceOf(t, class_, t->stack[t->sp - 1])) {
2007-05-25 14:48:07 +00:00
t->exception = makeClassCastException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
}
} goto loop;
case dup: {
object value = t->stack[t->sp - 1];
PUSH(value);
} goto loop;
case dup_x1: {
object first; POP(first);
object second; POP(second);
PUSH(first);
PUSH(second);
PUSH(first);
} goto loop;
case dup_x2: {
object first; POP(first);
object second; POP(second);
object third; POP(third);
PUSH(first);
PUSH(third);
PUSH(second);
PUSH(first);
} goto loop;
case dup2: {
object first = t->stack[t->sp - 1];
if (isLongOrDouble(first)) {
PUSH(first);
} else {
object second = t->stack[t->sp - 2];
PUSH(second);
PUSH(first);
}
} goto loop;
case dup2_x1: {
object first; POP(first);
object second; POP(second);
if (isLongOrDouble(first)) {
PUSH(first);
PUSH(second);
PUSH(first);
} else {
object third; POP(third);
PUSH(second);
PUSH(first);
PUSH(third);
PUSH(second);
PUSH(first);
}
} goto loop;
case dup2_x2: {
object first; POP(first);
object second; POP(second);
if (isLongOrDouble(first)) {
if (isLongOrDouble(second)) {
PUSH(first);
PUSH(second);
PUSH(first);
} else {
object third; POP(third);
PUSH(first);
PUSH(third);
PUSH(second);
PUSH(first);
}
} else {
object third; POP(third);
if (isLongOrDouble(third)) {
PUSH(second);
PUSH(first);
PUSH(third);
PUSH(second);
PUSH(first);
} else {
object fourth; POP(fourth);
PUSH(second);
PUSH(first);
PUSH(fourth);
PUSH(third);
PUSH(second);
PUSH(first);
}
}
} goto loop;
case getfield: {
object instance; POP(instance);
if (instance) {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
uint16_t index = (index1 << 8) | index2;
object field = resolveField(t, codePool(t->code), index);
if (t->exception) goto throw_;
PUSH(getField(instance, field));
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case getstatic: {
if (instance) {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
uint16_t index = (index1 << 8) | index2;
2007-05-25 14:48:07 +00:00
2007-05-22 00:05:29 +00:00
object field = resolveField(t, codePool(t->code), index);
if (t->exception) goto throw_;
2007-05-25 14:48:07 +00:00
if (not classInitialized(fieldClass(field))) {
t->code = classInitializer(fieldClass(field));
2007-05-30 00:08:10 +00:00
ip -= 3;
parameterCount = 0;
goto invoke;
2007-05-25 14:48:07 +00:00
}
2007-05-22 00:05:29 +00:00
PUSH(getStatic(field));
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case goto_: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
ip = (ip - 1) + ((offset1 << 8) | offset2);
} goto loop;
case goto_w: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
uint8_t offset3 = codeBody(t->code)[ip++];
uint8_t offset4 = codeBody(t->code)[ip++];
ip = (ip - 1)
+ ((offset1 << 24) | (offset2 << 16) | (offset3 << 8) | offset4);
} goto loop;
case i2b: {
object v; POP(v);
PUSH(makeInt(t, static_cast<int8_t>(intValue(v))));
} goto loop;
case i2c: {
object v; POP(v);
PUSH(makeInt(t, static_cast<uint16_t>(intValue(v))));
} goto loop;
case i2l: {
object v; POP(v);
PUSH(makeLong(t, intValue(v)));
} goto loop;
case i2s: {
object v; POP(v);
PUSH(makeInt(t, static_cast<int16_t>(intValue(v))));
} goto loop;
case iadd: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) + intValue(b)));
} goto loop;
case iaload: {
object index; POP(index);
object array; POP(array);
if (array) {
int32_t i = intValue(index);
if (i >= 0 and i < intArrayLength(array)) {
PUSH(makeInt(t, intArrayBody(array)[i]));
} else {
object message = makeString(t, "%d not in [0,%d]", i,
intArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case iand: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) & intValue(b)));
} goto loop;
case iastore: {
object value; POP(value);
object index; POP(index);
object array; POP(array);
int32_t i = intValue(index);
if (array) {
if (i >= 0 and i < intArrayLength(array)) {
intArrayBody(array)[i] = intValue(value);
} else {
object message = makeString(t, "%d not in [0,%d]", i,
intArrayLength(array));
2007-05-25 14:48:07 +00:00
t->exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
2007-05-25 14:48:07 +00:00
t->exception = makeNullPointerException(t, 0);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case iconst_0: {
PUSH(makeInt(0));
} goto loop;
case iconst_1: {
PUSH(makeInt(1));
} goto loop;
case iconst_2: {
PUSH(makeInt(2));
} goto loop;
case iconst_3: {
PUSH(makeInt(3));
} goto loop;
case iconst_4: {
PUSH(makeInt(4));
} goto loop;
case iconst_5: {
PUSH(makeInt(5));
} goto loop;
case idiv: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) / intValue(b)));
} goto loop;
case if_acmpeq: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (a == b) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case if_acmpne: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (a != b) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case if_icmpeq: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (intValue(a) == intValue(b)) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case if_icmpne: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (intValue(a) != intValue(b)) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case if_icmpgt: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (intValue(a) > intValue(b)) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case if_icmpge: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (intValue(a) >= intValue(b)) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case if_icmplt: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (intValue(a) < intValue(b)) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case if_icmple: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object b; POP(b);
object a; POP(a);
if (intValue(a) < intValue(b)) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case ifeq: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (intValue(v) == 0) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case ifne: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (intValue(v)) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case ifgt: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (intValue(v) > 0) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case ifge: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (intValue(v) >= 0) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case iflt: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (intValue(v) < 0) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case ifle: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (intValue(v) <= 0) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case ifnonnull: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (v) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case ifnull: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
object v; POP(v);
if (v == 0) {
ip = (ip - 1) + ((offset1 << 8) | offset2);
}
} goto loop;
case iinc: {
uint8_t index = codeBody(t->code)[ip++];
int8_t c = codeBody(t->code)[ip++];
int32_t v = intValue(frameBody(t->frame)[index]);
frameBody(t->frame)[index] = makeInt(t, v + c);
} goto loop;
2007-05-30 00:08:10 +00:00
case iload:
case lload: {
PUSH(frameBody(t->frame)[codeBody(t->code)[ip++]]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-30 00:08:10 +00:00
case iload_0:
case lload_0: {
PUSH(frameBody(t->frame)[0]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-30 00:08:10 +00:00
case iload_1:
case lload_1: {
PUSH(frameBody(t->frame)[1]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-30 00:08:10 +00:00
case iload_2:
case lload_2: {
PUSH(frameBody(t->frame)[2]);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-30 00:08:10 +00:00
case iload_3:
case lload_3: {
PUSH(frameBody(t->frame)[3]);
2007-05-22 00:05:29 +00:00
} goto loop;
case imul: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) * intValue(b)));
} goto loop;
case ineg: {
object v; POP(v);
PUSH(makeInt(t, - intValue(v)));
} goto loop;
case instanceof: {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
if (t->stack[t->sp - 1]) {
uint16_t index = (index1 << 8) | index2;
object class_ = resolveClass(t, codePool(t->code), index);
if (t->exception) goto throw_;
if (instanceOf(t, class_, t->stack[t->sp - 1])) {
PUSH(makeInt(t, 1));
} else {
PUSH(makeInt(t, 0));
}
} else {
PUSH(makeInt(t, 0));
}
} goto loop;
2007-05-25 14:48:07 +00:00
case invokeinterface: {
2007-05-30 00:08:10 +00:00
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
uint16_t index = (index1 << 8) | index2;
ip += 2;
object method = resolveMethod(t, codePool(t->code), index);
if (t->exception) goto throw_;
parameterCount = methodParameterCount(method);
if (t->stack[t->sp - parameterCount]) {
t->code = methodCode
(findInterfaceMethod(t, method, t->stack[t->sp - parameterCount]));
if (t->exception) goto throw_;
goto invoke;
} else {
t->exception = makeNullPointerException(t, 0);
goto throw_;
}
} goto loop;
case invokespecial: {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
uint16_t index = (index1 << 8) | index2;
object method = resolveMethod(t, codePool(t->code), index);
if (t->exception) goto throw_;
parameterCount = methodParameterCount(method);
if (t->stack[t->sp - parameterCount]) {
if (isSpecialMethod(method, t->stack[t->sp - parameterCount])) {
t->code = methodCode
(findSpecialMethod(t, method, t->stack[t->sp - parameterCount]));
if (t->exception) goto throw_;
} else {
t->code = methodCode(method);
}
goto invoke;
} else {
t->exception = makeNullPointerException(t, 0);
goto throw_;
}
} goto loop;
case invokestatic: {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
uint16_t index = (index1 << 8) | index2;
object method = resolveMethod(t, codePool(t->code), index);
if (t->exception) goto throw_;
if (not classInitialized(methodClass(method))) {
t->code = classInitializer(methodClass(method));
ip -= 2;
parameterCount = 0;
goto invoke;
}
parameterCount = methodParameterCount(method);
t->code = methodCode(method);
} goto invoke;
case invokevirtual: {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
uint16_t index = (index1 << 8) | index2;
object method = resolveMethod(t, codePool(t->code), index);
if (t->exception) goto throw_;
parameterCount = methodParameterCount(method);
if (t->stack[t->sp - parameterCount]) {
t->code = methodCode
(findVirtualMethod(t, method, t->stack[t->sp - parameterCount]));
if (t->exception) goto throw_;
goto invoke;
} else {
t->exception = makeNullPointerException(t, 0);
goto throw_;
}
} goto loop;
case ior: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) | intValue(b)));
} goto loop;
case irem: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) % intValue(b)));
} goto loop;
case ishl: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) << intValue(b)));
} goto loop;
case ishr: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) >> intValue(b)));
} goto loop;
case isub: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) - intValue(b)));
} goto loop;
case iushr: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, static_cast<uint32_t>(intValue(a)) >> intValue(b)));
} goto loop;
case ixor: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, intValue(a) ^ intValue(b)));
} goto loop;
case jsr: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
PUSH(makeInt(ip));
ip = (ip - 1) + ((offset1 << 8) | offset2);
} goto loop;
case jsr_w: {
uint8_t offset1 = codeBody(t->code)[ip++];
uint8_t offset2 = codeBody(t->code)[ip++];
uint8_t offset3 = codeBody(t->code)[ip++];
uint8_t offset4 = codeBody(t->code)[ip++];
PUSH(makeInt(ip));
ip = (ip - 1)
+ ((offset1 << 24) | (offset2 << 16) | (offset3 << 8) | offset4);
} goto loop;
case l2i: {
object v; POP(v);
PUSH(makeInt(t, static_cast<int32_t>(longValue(v))));
} goto loop;
case ladd: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) + longValue(b)));
2007-05-25 14:48:07 +00:00
} goto loop;
2007-05-30 00:08:10 +00:00
case laload: {
object index; POP(index);
object array; POP(array);
if (array) {
int32_t i = intValue(index);
if (i >= 0 and i < longArrayLength(array)) {
PUSH(makeLong(t, longArrayBody(array)[i]));
} else {
object message = makeString(t, "%d not in [0,%d]", i,
longArrayLength(array));
t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
t->exception = makeNullPointerException(t, 0);
goto throw_;
}
} goto loop;
case land: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) & longValue(b)));
} goto loop;
case lastore: {
object value; POP(value);
object index; POP(index);
object array; POP(array);
int32_t i = intValue(index);
if (array) {
if (i >= 0 and i < longArrayLength(array)) {
longArrayBody(array)[i] = longValue(value);
} else {
object message = makeString(t, "%d not in [0,%d]", i,
longArrayLength(array));
t->exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
t->exception = makeNullPointerException(t, 0);
goto throw_;
}
} goto loop;
case lcmp: {
object b; POP(b);
object a; POP(a);
PUSH(makeInt(t, longValue(a) > longValue(b) ? 1
: longValue(a) == longValue(b) ? 0 : -1));
} goto loop;
case lconst_0: {
PUSH(makeLong(0));
} goto loop;
case lconst_1: {
PUSH(makeLong(1));
} goto loop;
case ldc: {
PUSH(codePool(t->code)[codeBody(t->code)[ip++]]);
} goto loop;
case ldc_w:
case ldc2_w: {
uint8_t index1 = codeBody(t->code)[ip++];
uint8_t index2 = codeBody(t->code)[ip++];
PUSH(codePool(t->code)[codeBody(t->code)[(offset1 << 8) | offset2]]);
} goto loop;
case ldiv: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) / longValue(b)));
} goto loop;
case lmul: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) * longValue(b)));
} goto loop;
case lneg: {
object v; POP(v);
PUSH(makeLong(t, - longValue(v)));
} goto loop;
case lor: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) | longValue(b)));
} goto loop;
case lrem: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) % longValue(b)));
} goto loop;
case lshl: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) << longValue(b)));
} goto loop;
case lshr: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) >> longValue(b)));
} goto loop;
case lsub: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) - longValue(b)));
} goto loop;
case lushr: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, static_cast<uint64_t>(longValue(a)) << longValue(b)));
} goto loop;
case lxor: {
object b; POP(b);
object a; POP(a);
PUSH(makeLong(t, longValue(a) ^ longValue(b)));
} goto loop;
case multianewarray: {
// tbc
} goto loop;
default: UNREACHABLE;
}
invoke:
if (codeMaxStack(t->code) + t->sp - parameterCount > Thread::StackSize) {
t->exception = makeStackOverflowException(t, 0);
goto throw_;
2007-05-21 15:47:44 +00:00
}
2007-05-30 00:08:10 +00:00
frameIp(t->frame) = ip;
t->frame = makeFrame(t, t->code, t->frame);
memcpy(frameLocals(t->frame),
t->stack + t->sp - parameterCount,
parameterCount);
t->sp -= parameterCount;
ip = 0;
goto loop;
2007-05-21 15:47:44 +00:00
throw_:
2007-05-25 14:48:07 +00:00
for (; t->frame; t->frame = frameNext(t->frame)) {
t->code = frameCode(t->frame);
object eht = codeExceptionHandlerTable(t->code);
if (eht) {
for (unsigned i = 0; i < exceptionHandleTableLength(eht); ++i) {
ExceptionHandler* eh = exceptionHandlerTableBody(eht)[i];
uint16_t catchType = exceptionHandlerCatchType(eh);
if (catchType == 0 or
instanceOf(rawArrayBody(codePool(t->code))[catchType],
t->exception))
{
t->sp = frameStackBase(t->frame);
ip = exceptionHandlerIp(eh);
PUSH(t->exception);
t->exception = 0;
goto loop;
2007-05-21 15:47:44 +00:00
}
}
}
}
t->code = defaultExceptionHandler(t);
2007-05-25 14:48:07 +00:00
t->frame = makeFrame(t, t->code);
2007-05-22 00:05:29 +00:00
t->sp = 0;
2007-05-21 15:47:44 +00:00
ip = 0;
PUSH(t->exception);
t->exception = 0;
goto loop;
}
} // namespace