corda/src/interpret.cpp

3185 lines
73 KiB
C++
Raw Normal View History

#include "common.h"
#include "system.h"
#include "constants.h"
2007-07-06 23:50:26 +00:00
#include "machine.h"
#include "processor.h"
2007-07-02 01:42:35 +00:00
using namespace vm;
2007-05-21 15:47:44 +00:00
namespace {
class Thread: public vm::Thread {
public:
static const unsigned StackSizeInBytes = 64 * 1024;
static const unsigned StackSizeInWords = StackSizeInBytes / BytesPerWord;
Thread(Machine* m, object javaThread, vm::Thread* parent):
vm::Thread(m, javaThread, parent),
ip(0),
sp(0),
frame(-1),
code(0)
{ }
unsigned ip;
unsigned sp;
int frame;
object code;
uintptr_t stack[StackSizeInWords];
};
inline void
pushObject(Thread* t, object o)
{
if (DebugStack) {
fprintf(stderr, "push object %p at %d\n", o, t->sp);
}
assert(t, t->sp + 1 < Thread::StackSizeInWords / 2);
t->stack[(t->sp * 2) ] = ObjectTag;
t->stack[(t->sp * 2) + 1] = reinterpret_cast<uintptr_t>(o);
++ t->sp;
}
inline void
pushInt(Thread* t, uint32_t v)
{
if (DebugStack) {
fprintf(stderr, "push int %d at %d\n", v, t->sp);
}
assert(t, t->sp + 1 < Thread::StackSizeInWords / 2);
t->stack[(t->sp * 2) ] = IntTag;
t->stack[(t->sp * 2) + 1] = v;
++ t->sp;
}
inline void
pushFloat(Thread* t, float v)
{
uint32_t a; memcpy(&a, &v, sizeof(uint32_t));
pushInt(t, a);
}
inline void
pushLong(Thread* t, uint64_t v)
{
if (DebugStack) {
fprintf(stderr, "push long %"LLD" at %d\n", v, t->sp);
}
pushInt(t, v >> 32);
pushInt(t, v & 0xFFFFFFFF);
}
inline void
pushDouble(Thread* t, double v)
{
uint64_t a; memcpy(&a, &v, sizeof(uint64_t));
pushLong(t, a);
}
inline object
popObject(Thread* t)
{
if (DebugStack) {
fprintf(stderr, "pop object %p at %d\n",
reinterpret_cast<object>(t->stack[((t->sp - 1) * 2) + 1]),
t->sp - 1);
}
assert(t, t->stack[(t->sp - 1) * 2] == ObjectTag);
return reinterpret_cast<object>(t->stack[((-- t->sp) * 2) + 1]);
}
inline uint32_t
popInt(Thread* t)
{
if (DebugStack) {
fprintf(stderr, "pop int %"ULD" at %d\n",
t->stack[((t->sp - 1) * 2) + 1],
t->sp - 1);
}
assert(t, t->stack[(t->sp - 1) * 2] == IntTag);
return t->stack[((-- t->sp) * 2) + 1];
}
inline float
popFloat(Thread* t)
{
uint32_t a = popInt(t);
float f; memcpy(&f, &a, sizeof(float));
return f;
}
inline uint64_t
popLong(Thread* t)
{
if (DebugStack) {
fprintf(stderr, "pop long %"LLD" at %d\n",
(static_cast<uint64_t>(t->stack[((t->sp - 2) * 2) + 1]) << 32)
| static_cast<uint64_t>(t->stack[((t->sp - 1) * 2) + 1]),
t->sp - 2);
}
uint64_t a = popInt(t);
uint64_t b = popInt(t);
return (b << 32) | a;
}
inline float
popDouble(Thread* t)
{
uint64_t a = popLong(t);
double d; memcpy(&d, &a, sizeof(double));
return d;
}
inline object
peekObject(Thread* t, unsigned index)
{
if (DebugStack) {
fprintf(stderr, "peek object %p at %d\n",
reinterpret_cast<object>(t->stack[(index * 2) + 1]),
index);
}
assert(t, index < Thread::StackSizeInWords / 2);
assert(t, t->stack[index * 2] == ObjectTag);
return *reinterpret_cast<object*>(t->stack + (index * 2) + 1);
}
inline uint32_t
peekInt(Thread* t, unsigned index)
{
if (DebugStack) {
fprintf(stderr, "peek int %"ULD" at %d\n",
t->stack[(index * 2) + 1],
index);
}
assert(t, index < Thread::StackSizeInWords / 2);
assert(t, t->stack[index * 2] == IntTag);
return t->stack[(index * 2) + 1];
}
inline uint64_t
peekLong(Thread* t, unsigned index)
{
if (DebugStack) {
fprintf(stderr, "peek long %"LLD" at %d\n",
(static_cast<uint64_t>(t->stack[(index * 2) + 1]) << 32)
| static_cast<uint64_t>(t->stack[((index + 1) * 2) + 1]),
index);
}
return (static_cast<uint64_t>(peekInt(t, index)) << 32)
| static_cast<uint64_t>(peekInt(t, index + 1));
}
inline void
pokeObject(Thread* t, unsigned index, object value)
{
if (DebugStack) {
fprintf(stderr, "poke object %p at %d\n", value, index);
}
t->stack[index * 2] = ObjectTag;
t->stack[(index * 2) + 1] = reinterpret_cast<uintptr_t>(value);
}
inline void
pokeInt(Thread* t, unsigned index, uint32_t value)
{
if (DebugStack) {
fprintf(stderr, "poke int %d at %d\n", value, index);
}
t->stack[index * 2] = IntTag;
t->stack[(index * 2) + 1] = value;
}
inline void
pokeLong(Thread* t, unsigned index, uint64_t value)
{
if (DebugStack) {
fprintf(stderr, "poke long %"LLD" at %d\n", value, index);
}
pokeInt(t, index, value >> 32);
pokeInt(t, index + 1, value & 0xFFFFFFFF);
}
inline object*
pushReference(Thread* t, object o)
{
if (o) {
expect(t, t->sp + 1 < Thread::StackSizeInWords / 2);
pushObject(t, o);
return reinterpret_cast<object*>(t->stack + ((t->sp - 1) * 2) + 1);
} else {
return 0;
}
}
inline int
frameNext(Thread* t, int frame)
{
return peekInt(t, frame + FrameNextOffset);
}
inline object
frameMethod(Thread* t, int frame)
{
return peekObject(t, frame + FrameMethodOffset);
}
inline unsigned
frameIp(Thread* t, int frame)
{
return peekInt(t, frame + FrameIpOffset);
}
inline unsigned
frameBase(Thread* t, int frame)
{
return peekInt(t, frame + FrameBaseOffset);
}
inline object
localObject(Thread* t, unsigned index)
{
return peekObject(t, frameBase(t, t->frame) + index);
}
inline uint32_t
localInt(Thread* t, unsigned index)
{
return peekInt(t, frameBase(t, t->frame) + index);
}
inline uint64_t
localLong(Thread* t, unsigned index)
{
return peekLong(t, frameBase(t, t->frame) + index);
}
inline void
setLocalObject(Thread* t, unsigned index, object value)
{
pokeObject(t, frameBase(t, t->frame) + index, value);
}
inline void
setLocalInt(Thread* t, unsigned index, uint32_t value)
{
pokeInt(t, frameBase(t, t->frame) + index, value);
}
inline void
setLocalLong(Thread* t, unsigned index, uint64_t value)
{
pokeLong(t, frameBase(t, t->frame) + index, value);
}
void
pushFrame(Thread* t, object method)
{
if (t->frame >= 0) {
pokeInt(t, t->frame + FrameIpOffset, t->ip);
2007-07-04 17:58:27 +00:00
}
t->ip = 0;
2007-07-04 17:58:27 +00:00
unsigned parameterFootprint = methodParameterFootprint(t, method);
unsigned base = t->sp - parameterFootprint;
unsigned locals = parameterFootprint;
if ((methodFlags(t, method) & ACC_NATIVE) == 0) {
t->code = methodCode(t, method);
locals = codeMaxLocals(t, t->code);
memset(t->stack + ((base + parameterFootprint) * 2), 0,
(locals - parameterFootprint) * BytesPerWord * 2);
}
unsigned frame = base + locals;
pokeInt(t, frame + FrameNextOffset, t->frame);
t->frame = frame;
t->sp = frame + FrameFootprint;
pokeInt(t, frame + FrameBaseOffset, base);
pokeObject(t, frame + FrameMethodOffset, method);
2007-07-07 23:47:35 +00:00
pokeInt(t, t->frame + FrameIpOffset, 0);
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
if (methodFlags(t, method) & ACC_STATIC) {
acquire(t, methodClass(t, method));
} else {
acquire(t, peekObject(t, base));
}
}
}
void
popFrame(Thread* t)
{
2007-07-07 23:47:35 +00:00
object method = frameMethod(t, t->frame);
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
if (methodFlags(t, method) & ACC_STATIC) {
release(t, methodClass(t, method));
} else {
release(t, peekObject(t, frameBase(t, t->frame)));
}
}
if (UNLIKELY(methodVmFlags(t, method) & ClassInitFlag)) {
if (t->exception) {
t->exception = makeExceptionInInitializerError(t, t->exception);
}
classVmFlags(t, methodClass(t, method)) &= ~(NeedInitFlag | InitFlag);
release(t, t->m->classLock);
}
2007-07-07 23:47:35 +00:00
t->sp = frameBase(t, t->frame);
t->frame = frameNext(t, t->frame);
if (t->frame >= 0) {
t->code = methodCode(t, frameMethod(t, t->frame));
t->ip = frameIp(t, t->frame);
} else {
t->code = 0;
t->ip = 0;
}
}
object
findInterfaceMethod(Thread* t, object method, object class_)
{
2007-06-17 22:03:27 +00:00
object interface = methodClass(t, method);
object itable = classInterfaceTable(t, class_);
2007-06-17 22:03:27 +00:00
for (unsigned i = 0; i < arrayLength(t, itable); i += 2) {
if (arrayBody(t, itable, i) == interface) {
return arrayBody(t, arrayBody(t, itable, i + 1),
methodOffset(t, method));
}
}
abort(t);
}
inline object
findMethod(Thread* t, object method, object class_)
{
return arrayBody(t, classVirtualTable(t, class_),
methodOffset(t, method));
}
bool
isSuperclass(Thread* t, object class_, object base)
{
for (object oc = classSuper(t, base); oc; oc = classSuper(t, oc)) {
2007-06-17 22:03:27 +00:00
if (oc == class_) {
return true;
}
}
return false;
}
inline bool
isSpecialMethod(Thread* t, object method, object class_)
{
return (classFlags(t, class_) & ACC_SUPER)
and strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0)) != 0
and isSuperclass(t, methodClass(t, method), class_);
}
2007-06-14 23:55:06 +00:00
inline object
resolveClass(Thread* t, object pool, unsigned index)
{
object o = arrayBody(t, pool, index);
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType))
{
2007-06-14 23:55:06 +00:00
PROTECT(t, pool);
o = resolveClass(t, o);
if (UNLIKELY(t->exception)) return 0;
set(t, arrayBody(t, pool, index), o);
2007-06-14 23:55:06 +00:00
}
return o;
}
inline object
resolveClass(Thread* t, object container,
object& (*class_)(vm::Thread*, object))
2007-06-14 23:55:06 +00:00
{
object o = class_(t, container);
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType))
{
2007-06-14 23:55:06 +00:00
PROTECT(t, container);
o = resolveClass(t, o);
if (UNLIKELY(t->exception)) return 0;
set(t, class_(t, container), o);
}
return o;
}
inline object
resolve(Thread* t, object pool, unsigned index,
object (*find)(vm::Thread*, object, object, object),
object (*makeError)(vm::Thread*, object))
{
object o = arrayBody(t, pool, index);
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType))
{
PROTECT(t, pool);
object reference = o;
PROTECT(t, reference);
2007-06-14 23:55:06 +00:00
object class_ = resolveClass(t, o, referenceClass);
if (UNLIKELY(t->exception)) return 0;
o = findInHierarchy
(t, class_, referenceName(t, reference), referenceSpec(t, reference),
find, makeError);
if (UNLIKELY(t->exception)) return 0;
set(t, arrayBody(t, pool, index), o);
}
return o;
}
inline object
resolveField(Thread* t, object pool, unsigned index)
{
return resolve(t, pool, index, findFieldInClass, makeNoSuchFieldError);
}
inline object
resolveMethod(Thread* t, object pool, unsigned index)
{
return resolve(t, pool, index, findMethodInClass, makeNoSuchMethodError);
}
2007-06-24 21:49:04 +00:00
object
makeNativeMethodData(Thread* t, object method, void* function)
2007-06-24 21:49:04 +00:00
{
PROTECT(t, method);
unsigned count = methodParameterCount(t, method) + 1;
if (methodFlags(t, method) & ACC_STATIC) {
++ count;
}
2007-06-24 21:49:04 +00:00
object data = makeNativeMethodData(t,
function,
0, // argument table size
0, // return code,
count,
2007-06-24 21:49:04 +00:00
false);
unsigned argumentTableSize = BytesPerWord * 2;
2007-06-24 21:49:04 +00:00
unsigned index = 0;
2007-06-29 02:58:48 +00:00
nativeMethodDataParameterTypes(t, data, index++) = POINTER_TYPE;
nativeMethodDataParameterTypes(t, data, index++) = POINTER_TYPE;
2007-06-24 21:49:04 +00:00
const char* s = reinterpret_cast<const char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
++ s; // skip '('
while (*s and *s != ')') {
unsigned code = fieldCode(t, *s);
2007-06-29 02:58:48 +00:00
nativeMethodDataParameterTypes(t, data, index++) = fieldType(t, code);
2007-06-24 21:49:04 +00:00
switch (*s) {
case 'L':
2007-06-29 02:58:48 +00:00
argumentTableSize += BytesPerWord;
2007-06-24 21:49:04 +00:00
while (*s and *s != ';') ++ s;
++ s;
break;
case '[':
2007-06-29 02:58:48 +00:00
argumentTableSize += BytesPerWord;
2007-06-24 21:49:04 +00:00
while (*s == '[') ++ s;
2007-07-24 03:16:59 +00:00
switch (*s) {
case 'L':
while (*s and *s != ';') ++ s;
++ s;
break;
default:
++ s;
break;
}
2007-06-24 21:49:04 +00:00
break;
default:
2007-06-29 02:58:48 +00:00
argumentTableSize += pad(primitiveSize(t, code));
2007-06-24 21:49:04 +00:00
++ s;
break;
}
}
nativeMethodDataArgumentTableSize(t, data) = argumentTableSize;
nativeMethodDataReturnCode(t, data) = fieldCode(t, s[1]);
return data;
}
2007-06-24 01:39:49 +00:00
inline object
resolveNativeMethodData(Thread* t, object method)
{
if (objectClass(t, methodCode(t, method))
== arrayBody(t, t->m->types, Machine::ByteArrayType))
2007-06-24 01:39:49 +00:00
{
2007-06-24 21:49:04 +00:00
object data = 0;
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
2007-06-24 01:39:49 +00:00
void* p = lib->resolve(reinterpret_cast<const char*>
(&byteArrayBody(t, methodCode(t, method), 0)));
if (p) {
PROTECT(t, method);
data = makeNativeMethodData(t, method, p);
2007-06-24 21:49:04 +00:00
break;
}
}
2007-06-24 01:39:49 +00:00
2007-06-25 02:20:35 +00:00
if (LIKELY(data)) {
2007-06-24 21:49:04 +00:00
set(t, methodCode(t, method), data);
2007-06-25 02:20:35 +00:00
} else {
object message = makeString
(t, "%s", &byteArrayBody(t, methodCode(t, method), 0));
t->exception = makeUnsatisfiedLinkError(t, message);
2007-06-24 21:49:04 +00:00
}
2007-06-25 02:20:35 +00:00
2007-06-24 21:49:04 +00:00
return data;
} else {
return methodCode(t, method);
}
}
2007-07-04 17:58:27 +00:00
inline void
2007-07-07 18:09:16 +00:00
checkStack(Thread* t, object method)
{
2007-07-26 00:52:10 +00:00
if (UNLIKELY(t->sp
+ methodParameterFootprint(t, method)
2007-07-07 18:09:16 +00:00
+ codeMaxLocals(t, methodCode(t, method))
+ FrameFootprint
+ codeMaxStack(t, methodCode(t, method))
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
}
}
unsigned
2007-06-24 21:49:04 +00:00
invokeNative(Thread* t, object method)
{
2007-07-19 23:45:44 +00:00
PROTECT(t, method);
2007-06-24 21:49:04 +00:00
object data = resolveNativeMethodData(t, method);
2007-06-25 02:20:35 +00:00
if (UNLIKELY(t->exception)) {
2007-07-07 18:09:16 +00:00
return VoidField;
2007-06-24 21:49:04 +00:00
}
2007-07-17 00:23:23 +00:00
PROTECT(t, data);
pushFrame(t, method);
2007-06-29 02:58:48 +00:00
unsigned count = methodParameterCount(t, method);
if (methodFlags(t, method) & ACC_STATIC) {
++ count;
}
2007-06-24 01:39:49 +00:00
2007-06-29 02:58:48 +00:00
unsigned size = nativeMethodDataArgumentTableSize(t, data);
uintptr_t args[size / BytesPerWord];
2007-06-24 21:49:04 +00:00
unsigned offset = 0;
2007-06-24 01:39:49 +00:00
2007-06-29 02:58:48 +00:00
args[offset++] = reinterpret_cast<uintptr_t>(t);
2007-06-24 21:49:04 +00:00
2007-07-26 00:52:10 +00:00
unsigned i = 0;
if (methodFlags(t, method) & ACC_STATIC) {
2007-07-26 00:52:10 +00:00
++ i;
args[offset++] = reinterpret_cast<uintptr_t>
(pushReference(t, methodClass(t, method)));
}
unsigned sp = frameBase(t, t->frame);
2007-07-26 00:52:10 +00:00
for (; i < count; ++i) {
unsigned type = nativeMethodDataParameterTypes(t, data, i + 1);
2007-06-24 21:49:04 +00:00
2007-06-29 02:58:48 +00:00
switch (type) {
case INT8_TYPE:
case INT16_TYPE:
case INT32_TYPE:
case FLOAT_TYPE:
2007-07-04 17:58:27 +00:00
args[offset++] = peekInt(t, sp++);
2007-06-29 02:58:48 +00:00
break;
case INT64_TYPE:
case DOUBLE_TYPE: {
2007-07-04 17:58:27 +00:00
uint64_t v = peekLong(t, sp);
2007-06-29 02:58:48 +00:00
memcpy(args + offset, &v, 8);
offset += (8 / BytesPerWord);
2007-07-04 17:58:27 +00:00
sp += 2;
2007-06-29 02:58:48 +00:00
} break;
case POINTER_TYPE: {
object* v = reinterpret_cast<object*>(t->stack + ((sp++) * 2) + 1);
if (*v == 0) {
v = 0;
}
args[offset++] = reinterpret_cast<uintptr_t>(v);
} break;
2007-06-29 02:58:48 +00:00
default: abort(t);
2007-06-24 01:39:49 +00:00
}
2007-06-24 21:49:04 +00:00
}
unsigned returnCode = nativeMethodDataReturnCode(t, data);
2007-06-29 02:58:48 +00:00
unsigned returnType = fieldType(t, returnCode);
2007-06-24 21:49:04 +00:00
void* function = nativeMethodDataFunction(t, data);
2007-07-07 23:47:35 +00:00
if (DebugRun) {
fprintf(stderr, "invoke native method %s.%s\n",
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
&byteArrayBody(t, methodName(t, method), 0));
}
uint64_t result;
{ ENTER(t, Thread::IdleState);
result = t->m->system->call
(function,
args,
&nativeMethodDataParameterTypes(t, data, 0),
count + 1,
size,
returnType);
}
2007-06-24 21:49:04 +00:00
2007-07-07 23:47:35 +00:00
if (DebugRun) {
fprintf(stderr, "return from native method %s.%s\n",
&byteArrayBody
(t, className(t, methodClass(t, frameMethod(t, t->frame))), 0),
&byteArrayBody
(t, methodName(t, frameMethod(t, t->frame)), 0));
}
popFrame(t);
2007-07-04 17:58:27 +00:00
if (UNLIKELY(t->exception)) {
2007-07-07 18:09:16 +00:00
return VoidField;
2007-07-04 17:58:27 +00:00
}
switch (returnCode) {
case ByteField:
case BooleanField:
case CharField:
case ShortField:
case FloatField:
case IntField:
2007-07-07 23:47:35 +00:00
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", result);
2007-07-07 23:47:35 +00:00
}
2007-07-04 17:58:27 +00:00
pushInt(t, result);
break;
case LongField:
case DoubleField:
2007-07-07 23:47:35 +00:00
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", result);
2007-07-07 23:47:35 +00:00
}
2007-07-04 17:58:27 +00:00
pushLong(t, result);
break;
case ObjectField:
2007-07-07 23:47:35 +00:00
if (DebugRun) {
fprintf(stderr, "result: %p at %p\n", result == 0 ? 0 :
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)),
reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
}
2007-07-04 17:58:27 +00:00
pushObject(t, result == 0 ? 0 :
*reinterpret_cast<object*>(static_cast<uintptr_t>(result)));
break;
case VoidField:
break;
default:
abort(t);
};
2007-07-07 18:09:16 +00:00
return returnCode;
}
bool
classInit2(Thread* t, object class_, unsigned ipOffset)
{
PROTECT(t, class_);
acquire(t, t->m->classLock);
if (classVmFlags(t, class_) & NeedInitFlag
and (classVmFlags(t, class_) & InitFlag) == 0)
{
classVmFlags(t, class_) |= InitFlag;
t->code = classInitializer(t, class_);
t->ip -= ipOffset;
return true;
} else {
release(t, t->m->classLock);
return false;
}
}
inline bool
classInit(Thread* t, object class_, unsigned ipOffset)
{
if (UNLIKELY(classVmFlags(t, class_) & NeedInitFlag)) {
return classInit2(t, class_, ipOffset);
} else {
return false;
}
}
inline int16_t
codeReadInt16(Thread* t, unsigned& i)
{
uint8_t v1 = codeBody(t, t->code, i++);
uint8_t v2 = codeBody(t, t->code, i++);
return ((v1 << 8) | v2);
}
inline int32_t
codeReadInt32(Thread* t, unsigned& i)
{
uint8_t v1 = codeBody(t, t->code, i++);
uint8_t v2 = codeBody(t, t->code, i++);
uint8_t v3 = codeBody(t, t->code, i++);
uint8_t v4 = codeBody(t, t->code, i++);
return ((v1 << 24) | (v2 << 16) | (v3 << 8) | v4);
}
inline void
store(Thread* t, unsigned index)
{
memcpy(t->stack + ((frameBase(t, t->frame) + index) * 2),
t->stack + ((-- t->sp) * 2),
BytesPerWord * 2);
}
void
populateMultiArray(Thread* t, object array, int32_t* counts,
unsigned index, unsigned dimensions)
{
if (index + 1 == dimensions or counts[index] == 0) {
return;
}
PROTECT(t, array);
object spec = className(t, objectClass(t, array));
PROTECT(t, spec);
object elementSpec = makeByteArray
(t, byteArrayLength(t, spec) - 1, false);
memcpy(&byteArrayBody(t, elementSpec, 0),
&byteArrayBody(t, spec, 1),
byteArrayLength(t, spec) - 1);
object class_ = resolveClass(t, elementSpec);
PROTECT(t, class_);
for (int32_t i = 0; i < counts[index]; ++i) {
object a = makeArray(t, counts[index + 1], true);
setObjectClass(t, a, class_);
set(t, objectArrayBody(t, array, i), a);
populateMultiArray(t, a, counts, index + 1, dimensions);
}
}
2007-05-21 15:47:44 +00:00
object
interpret(Thread* t)
2007-05-21 15:47:44 +00:00
{
2007-07-24 01:44:20 +00:00
const int base = t->frame;
unsigned instruction = nop;
unsigned& ip = t->ip;
unsigned& sp = t->sp;
int& frame = t->frame;
object& code = t->code;
object& exception = t->exception;
uintptr_t* stack = t->stack;
2007-05-21 15:47:44 +00:00
if (UNLIKELY(exception)) {
goto throw_;
}
if (UNLIKELY(classInit(t, methodClass(t, frameMethod(t, frame)), 0))) {
goto invoke;
}
2007-05-21 15:47:44 +00:00
loop:
instruction = codeBody(t, code, ip++);
2007-07-04 17:58:27 +00:00
if (DebugRun) {
fprintf(stderr, "ip: %d; instruction: 0x%x in %s.%s ",
ip - 1,
instruction,
&byteArrayBody
(t, className(t, methodClass(t, frameMethod(t, frame))), 0),
&byteArrayBody
(t, methodName(t, frameMethod(t, frame)), 0));
int line = lineNumber(t, frameMethod(t, frame), ip);
switch (line) {
case NativeLine:
fprintf(stderr, "(native)\n");
break;
case UnknownLine:
fprintf(stderr, "(unknown line)\n");
break;
default:
fprintf(stderr, "(line %d)\n", line);
}
}
switch (instruction) {
2007-05-21 15:47:44 +00:00
case aaload: {
int32_t index = popInt(t);
object array = popObject(t);
2007-05-21 15:47:44 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < objectArrayLength(t, array)))
{
pushObject(t, objectArrayBody(t, array, index));
2007-05-21 15:47:44 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
objectArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-21 15:47:44 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
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 = popObject(t);
int32_t index = popInt(t);
object array = popObject(t);
2007-05-21 15:47:44 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < objectArrayLength(t, array)))
{
set(t, objectArrayBody(t, array, index), value);
2007-05-21 15:47:44 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
objectArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-21 15:47:44 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
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: {
pushObject(t, 0);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload: {
pushObject(t, localObject(t, codeBody(t, code, ip++)));
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_0: {
pushObject(t, localObject(t, 0));
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_1: {
pushObject(t, localObject(t, 1));
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_2: {
pushObject(t, localObject(t, 2));
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case aload_3: {
pushObject(t, localObject(t, 3));
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case anewarray: {
int32_t count = popInt(t);
2007-05-21 15:47:44 +00:00
if (LIKELY(count >= 0)) {
uint16_t index = codeReadInt16(t, ip);
2007-05-21 15:47:44 +00:00
2007-06-21 01:38:02 +00:00
object class_ = resolveClass(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
pushObject(t, makeObjectArray(t, class_, count, true));
2007-05-21 15:47:44 +00:00
} else {
object message = makeString(t, "%d", count);
2007-07-07 23:47:35 +00:00
exception = makeNegativeArraySizeException(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-07-07 23:47:35 +00:00
case areturn: {
object result = popObject(t);
2007-07-24 01:44:20 +00:00
if (frame > base) {
popFrame(t);
2007-07-07 23:47:35 +00:00
pushObject(t, result);
2007-05-21 15:47:44 +00:00
goto loop;
} else {
2007-07-07 23:47:35 +00:00
return result;
2007-05-21 15:47:44 +00:00
}
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case arraylength: {
object array = popObject(t);
if (LIKELY(array)) {
pushInt(t, cast<uintptr_t>(array, BytesPerWord));
2007-05-21 15:47:44 +00:00
} else {
exception = makeNullPointerException(t);
2007-05-21 15:47:44 +00:00
goto throw_;
}
2007-07-07 23:47:35 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case astore: {
store(t, codeBody(t, code, ip++));
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case astore_0: {
store(t, 0);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case astore_1: {
store(t, 1);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case astore_2: {
store(t, 2);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case astore_3: {
store(t, 3);
2007-05-22 00:05:29 +00:00
} goto loop;
2007-05-21 15:47:44 +00:00
case athrow: {
exception = popObject(t);
if (UNLIKELY(exception == 0)) {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
}
} goto throw_;
2007-05-22 00:05:29 +00:00
case baload: {
int32_t index = popInt(t);
object array = popObject(t);
2007-05-22 00:05:29 +00:00
if (LIKELY(array)) {
if (objectClass(t, array)
== arrayBody(t, t->m->types, Machine::BooleanArrayType))
{
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index)
< booleanArrayLength(t, array)))
{
pushInt(t, booleanArrayBody(t, array, index));
} else {
object message = makeString(t, "%d not in [0,%d)", index,
booleanArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
2007-05-22 00:05:29 +00:00
} else {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index)
< byteArrayLength(t, array)))
{
pushInt(t, byteArrayBody(t, array, index));
} else {
object message = makeString(t, "%d not in [0,%d)", index,
byteArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
2007-05-22 00:05:29 +00:00
}
} else {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case bastore: {
int8_t value = popInt(t);
int32_t index = popInt(t);
object array = popObject(t);
2007-05-22 00:05:29 +00:00
if (LIKELY(array)) {
if (objectClass(t, array)
== arrayBody(t, t->m->types, Machine::BooleanArrayType))
{
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index)
< booleanArrayLength(t, array)))
{
booleanArrayBody(t, array, index) = value;
} else {
object message = makeString(t, "%d not in [0,%d)", index,
booleanArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
2007-05-22 00:05:29 +00:00
} else {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < byteArrayLength(t, array)))
{
byteArrayBody(t, array, index) = value;
} else {
object message = makeString(t, "%d not in [0,%d)", index,
byteArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
2007-05-22 00:05:29 +00:00
}
} else {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case bipush: {
pushInt(t, static_cast<int8_t>(codeBody(t, code, ip++)));
2007-05-22 00:05:29 +00:00
} goto loop;
case caload: {
int32_t index = popInt(t);
object array = popObject(t);
2007-05-22 00:05:29 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < charArrayLength(t, array)))
{
pushInt(t, charArrayBody(t, array, index));
2007-05-22 00:05:29 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
charArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case castore: {
uint16_t value = popInt(t);
int32_t index = popInt(t);
object array = popObject(t);
2007-05-22 00:05:29 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < charArrayLength(t, array)))
{
charArrayBody(t, array, index) = value;
2007-05-22 00:05:29 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
charArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case checkcast: {
uint16_t index = codeReadInt16(t, ip);
2007-05-22 00:05:29 +00:00
if (peekObject(t, sp - 1)) {
2007-06-21 01:38:02 +00:00
object class_ = resolveClass(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-05-22 00:05:29 +00:00
if (not instanceOf(t, class_, peekObject(t, sp - 1))) {
object message = makeString
(t, "%s as %s",
&byteArrayBody
(t, className(t, objectClass(t, peekObject(t, sp - 1))), 0),
&byteArrayBody(t, className(t, class_), 0));
exception = makeClassCastException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
}
} goto loop;
2007-08-13 14:06:31 +00:00
case d2f: {
pushFloat(t, static_cast<float>(popDouble(t)));
} goto loop;
case d2i: {
pushInt(t, static_cast<int32_t>(popDouble(t)));
} goto loop;
case d2l: {
pushLong(t, static_cast<int64_t>(popDouble(t)));
} goto loop;
case dadd: {
double b = popDouble(t);
double a = popDouble(t);
pushDouble(t, a + b);
} goto loop;
case daload: {
int32_t index = popInt(t);
object array = popObject(t);
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < doubleArrayLength(t, array)))
{
double d;
memcpy(&d, &doubleArrayBody(t, array, index), sizeof(double));
pushDouble(t, d);
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
2007-08-13 14:06:31 +00:00
doubleArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case dastore: {
double value = popDouble(t);
int32_t index = popInt(t);
object array = popObject(t);
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < doubleArrayLength(t, array)))
{
memcpy(&doubleArrayBody(t, array, index), &value, sizeof(uint64_t));
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
2007-08-13 14:06:31 +00:00
doubleArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case dcmpg: {
double b = popDouble(t);
double a = popDouble(t);
pushInt(t, (a > b ? 1 : 0));
} goto loop;
case dcmpl: {
double b = popDouble(t);
double a = popDouble(t);
pushInt(t, (a < b ? 1 : 0));
} goto loop;
case dconst_0: {
pushDouble(t, 0);
} goto loop;
case dconst_1: {
pushDouble(t, 1);
} goto loop;
case ddiv: {
double b = popDouble(t);
double a = popDouble(t);
pushDouble(t, a / b);
} goto loop;
case dmul: {
double b = popDouble(t);
double a = popDouble(t);
pushDouble(t, a * b);
} goto loop;
case dneg: {
double a = popDouble(t);
pushDouble(t, - a);
} goto loop;
case vm::drem: {
double b = popDouble(t);
double a = popDouble(t);
pushDouble(t, fmod(a, b));
} goto loop;
case dsub: {
double b = popDouble(t);
double a = popDouble(t);
pushDouble(t, a - b);
} goto loop;
2007-05-22 00:05:29 +00:00
case dup: {
2007-07-04 17:58:27 +00:00
if (DebugStack) {
fprintf(stderr, "dup\n");
}
memcpy(stack + ((sp ) * 2), stack + ((sp - 1) * 2), BytesPerWord * 2);
++ sp;
2007-05-22 00:05:29 +00:00
} goto loop;
case dup_x1: {
2007-07-04 17:58:27 +00:00
if (DebugStack) {
fprintf(stderr, "dup_x1\n");
}
memcpy(stack + ((sp ) * 2), stack + ((sp - 1) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 1) * 2), stack + ((sp - 2) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 2) * 2), stack + ((sp ) * 2), BytesPerWord * 2);
++ sp;
2007-05-22 00:05:29 +00:00
} goto loop;
case dup_x2: {
2007-07-04 17:58:27 +00:00
if (DebugStack) {
fprintf(stderr, "dup_x2\n");
}
memcpy(stack + ((sp ) * 2), stack + ((sp - 1) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 1) * 2), stack + ((sp - 2) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 2) * 2), stack + ((sp - 3) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 3) * 2), stack + ((sp ) * 2), BytesPerWord * 2);
++ sp;
2007-05-22 00:05:29 +00:00
} goto loop;
case dup2: {
2007-07-04 17:58:27 +00:00
if (DebugStack) {
fprintf(stderr, "dup2\n");
}
memcpy(stack + ((sp ) * 2), stack + ((sp - 2) * 2), BytesPerWord * 4);
sp += 2;
2007-05-22 00:05:29 +00:00
} goto loop;
case dup2_x1: {
2007-07-04 17:58:27 +00:00
if (DebugStack) {
fprintf(stderr, "dup2_x1\n");
}
memcpy(stack + ((sp + 1) * 2), stack + ((sp - 1) * 2), BytesPerWord * 2);
memcpy(stack + ((sp ) * 2), stack + ((sp - 2) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 1) * 2), stack + ((sp - 3) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 3) * 2), stack + ((sp ) * 2), BytesPerWord * 4);
sp += 2;
2007-05-22 00:05:29 +00:00
} goto loop;
case dup2_x2: {
2007-07-04 17:58:27 +00:00
if (DebugStack) {
fprintf(stderr, "dup2_x2\n");
}
memcpy(stack + ((sp + 1) * 2), stack + ((sp - 1) * 2), BytesPerWord * 2);
memcpy(stack + ((sp ) * 2), stack + ((sp - 2) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 1) * 2), stack + ((sp - 3) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 2) * 2), stack + ((sp - 4) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 4) * 2), stack + ((sp ) * 2), BytesPerWord * 4);
sp += 2;
2007-05-22 00:05:29 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case f2d: {
pushDouble(t, popFloat(t));
} goto loop;
case f2i: {
pushInt(t, static_cast<int32_t>(popFloat(t)));
} goto loop;
case f2l: {
pushLong(t, static_cast<int64_t>(popFloat(t)));
} goto loop;
case fadd: {
float b = popFloat(t);
float a = popFloat(t);
pushFloat(t, a + b);
} goto loop;
case faload: {
int32_t index = popInt(t);
object array = popObject(t);
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < floatArrayLength(t, array)))
{
float f; memcpy(&f, &floatArrayBody(t, array, index), sizeof(float));
pushFloat(t, f);
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
2007-08-13 14:06:31 +00:00
floatArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case fastore: {
float value = popFloat(t);
int32_t index = popInt(t);
object array = popObject(t);
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < floatArrayLength(t, array)))
{
memcpy(&floatArrayBody(t, array, index), &value, sizeof(uint32_t));
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
2007-08-13 14:06:31 +00:00
floatArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case fcmpg: {
float b = popFloat(t);
float a = popFloat(t);
pushInt(t, (a > b ? 1 : 0));
} goto loop;
case fcmpl: {
float b = popFloat(t);
float a = popFloat(t);
pushInt(t, (a < b ? 1 : 0));
} goto loop;
case fconst_0: {
pushFloat(t, 0);
} goto loop;
case fconst_1: {
pushFloat(t, 1);
} goto loop;
case fconst_2: {
pushFloat(t, 2);
} goto loop;
case fdiv: {
float b = popFloat(t);
float a = popFloat(t);
pushFloat(t, a / b);
} goto loop;
case fmul: {
float b = popFloat(t);
float a = popFloat(t);
pushFloat(t, a * b);
} goto loop;
case fneg: {
float a = popFloat(t);
pushFloat(t, - a);
} goto loop;
case frem: {
float b = popFloat(t);
float a = popFloat(t);
pushFloat(t, fmodf(a, b));
} goto loop;
case fsub: {
float b = popFloat(t);
float a = popFloat(t);
pushFloat(t, a - b);
} goto loop;
2007-05-22 00:05:29 +00:00
case getfield: {
2007-07-17 01:55:49 +00:00
if (LIKELY(peekObject(t, sp - 1))) {
uint16_t index = codeReadInt16(t, ip);
2007-05-22 00:05:29 +00:00
2007-06-21 01:38:02 +00:00
object field = resolveField(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-05-22 00:05:29 +00:00
2007-07-17 01:55:49 +00:00
object instance = popObject(t);
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
pushInt(t, cast<int8_t>(instance, fieldOffset(t, field)));
2007-07-07 18:09:16 +00:00
break;
case CharField:
case ShortField:
pushInt(t, cast<int16_t>(instance, fieldOffset(t, field)));
2007-07-07 18:09:16 +00:00
break;
case FloatField:
case IntField:
pushInt(t, cast<int32_t>(instance, fieldOffset(t, field)));
2007-07-07 18:09:16 +00:00
break;
case DoubleField:
case LongField:
pushLong(t, cast<int64_t>(instance, fieldOffset(t, field)));
2007-07-07 18:09:16 +00:00
break;
case ObjectField:
pushObject(t, cast<object>(instance, fieldOffset(t, field)));
2007-07-07 18:09:16 +00:00
break;
2007-07-07 18:09:16 +00:00
default:
abort(t);
}
2007-05-22 00:05:29 +00:00
} else {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case getstatic: {
uint16_t index = codeReadInt16(t, ip);
2007-05-25 14:48:07 +00:00
2007-06-21 01:38:02 +00:00
object field = resolveField(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-09-15 00:32:32 +00:00
PROTECT(t, field);
2007-05-25 14:48:07 +00:00
if (UNLIKELY(classInit(t, fieldClass(t, field), 3))) goto invoke;
object v = arrayBody(t, classStaticTable(t, fieldClass(t, field)),
fieldOffset(t, field));
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
case CharField:
case ShortField:
case FloatField:
case IntField:
pushInt(t, v ? intValue(t, v) : 0);
break;
case DoubleField:
case LongField:
pushLong(t, v ? longValue(t, v) : 0);
break;
case ObjectField:
pushObject(t, v);
break;
default: abort(t);
}
2007-05-22 00:05:29 +00:00
} goto loop;
case goto_: {
int16_t offset = codeReadInt16(t, ip);
ip = (ip - 3) + offset;
2007-05-22 00:05:29 +00:00
} goto loop;
case goto_w: {
int32_t offset = codeReadInt32(t, ip);
ip = (ip - 5) + offset;
2007-05-22 00:05:29 +00:00
} goto loop;
case i2b: {
pushInt(t, static_cast<int8_t>(popInt(t)));
2007-05-22 00:05:29 +00:00
} goto loop;
case i2c: {
pushInt(t, static_cast<uint16_t>(popInt(t)));
2007-05-22 00:05:29 +00:00
} goto loop;
2007-09-14 01:42:12 +00:00
case i2d: {
double f = static_cast<double>(popInt(t));
int64_t i; memcpy(&i, &f, 8);
pushLong(t, i);
} goto loop;
case i2f: {
float f = static_cast<float>(popInt(t));
int32_t i; memcpy(&i, &f, 4);
pushInt(t, i);
} goto loop;
2007-05-22 00:05:29 +00:00
case i2l: {
2007-09-17 22:16:17 +00:00
pushLong(t, static_cast<int32_t>(popInt(t)));
2007-05-22 00:05:29 +00:00
} goto loop;
case i2s: {
pushInt(t, static_cast<int16_t>(popInt(t)));
2007-05-22 00:05:29 +00:00
} goto loop;
case iadd: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
pushInt(t, a + b);
2007-05-22 00:05:29 +00:00
} goto loop;
case iaload: {
int32_t index = popInt(t);
object array = popObject(t);
2007-05-22 00:05:29 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < intArrayLength(t, array)))
{
pushInt(t, intArrayBody(t, array, index));
2007-05-22 00:05:29 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
intArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
case iand: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
pushInt(t, a & b);
2007-05-22 00:05:29 +00:00
} goto loop;
case iastore: {
int32_t value = popInt(t);
int32_t index = popInt(t);
object array = popObject(t);
2007-05-22 00:05:29 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < intArrayLength(t, array)))
{
intArrayBody(t, array, index) = value;
2007-05-22 00:05:29 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
intArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
2007-05-22 00:05:29 +00:00
goto throw_;
}
} goto loop;
2007-08-14 00:37:00 +00:00
case iconst_m1: {
pushInt(t, static_cast<unsigned>(-1));
} goto loop;
2007-05-22 00:05:29 +00:00
case iconst_0: {
pushInt(t, 0);
2007-05-22 00:05:29 +00:00
} goto loop;
case iconst_1: {
pushInt(t, 1);
2007-05-22 00:05:29 +00:00
} goto loop;
case iconst_2: {
pushInt(t, 2);
2007-05-22 00:05:29 +00:00
} goto loop;
case iconst_3: {
pushInt(t, 3);
2007-05-22 00:05:29 +00:00
} goto loop;
case iconst_4: {
pushInt(t, 4);
2007-05-22 00:05:29 +00:00
} goto loop;
case iconst_5: {
pushInt(t, 5);
2007-05-22 00:05:29 +00:00
} goto loop;
case idiv: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
pushInt(t, a / b);
2007-05-22 00:05:29 +00:00
} goto loop;
case if_acmpeq: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
object b = popObject(t);
object a = popObject(t);
2007-05-22 00:05:29 +00:00
if (a == b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case if_acmpne: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
object b = popObject(t);
object a = popObject(t);
2007-05-22 00:05:29 +00:00
if (a != b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case if_icmpeq: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
if (a == b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case if_icmpne: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
if (a != b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case if_icmpgt: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
if (a > b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case if_icmpge: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
if (a >= b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case if_icmplt: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
if (a < b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case if_icmple: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
2007-07-07 23:47:35 +00:00
if (a <= b) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case ifeq: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (popInt(t) == 0) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case ifne: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (popInt(t)) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case ifgt: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (static_cast<int32_t>(popInt(t)) > 0) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case ifge: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (static_cast<int32_t>(popInt(t)) >= 0) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case iflt: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (static_cast<int32_t>(popInt(t)) < 0) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case ifle: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (static_cast<int32_t>(popInt(t)) <= 0) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case ifnonnull: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (popObject(t)) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case ifnull: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (popObject(t) == 0) {
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-22 00:05:29 +00:00
}
} goto loop;
case iinc: {
uint8_t index = codeBody(t, code, ip++);
int8_t c = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
setLocalInt(t, index, localInt(t, index) + c);
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case iload:
case fload: {
pushInt(t, localInt(t, codeBody(t, code, ip++)));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case iload_0:
case fload_0: {
pushInt(t, localInt(t, 0));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case iload_1:
case fload_1: {
pushInt(t, localInt(t, 1));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case iload_2:
case fload_2: {
pushInt(t, localInt(t, 2));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case iload_3:
case fload_3: {
pushInt(t, localInt(t, 3));
2007-05-22 00:05:29 +00:00
} goto loop;
case imul: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-22 00:05:29 +00:00
pushInt(t, a * b);
2007-05-22 00:05:29 +00:00
} goto loop;
case ineg: {
pushInt(t, - popInt(t));
2007-05-22 00:05:29 +00:00
} goto loop;
case instanceof: {
uint8_t index1 = codeBody(t, code, ip++);
uint8_t index2 = codeBody(t, code, ip++);
2007-05-22 00:05:29 +00:00
if (peekObject(t, sp - 1)) {
2007-05-22 00:05:29 +00:00
uint16_t index = (index1 << 8) | index2;
2007-06-21 01:38:02 +00:00
object class_ = resolveClass(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-05-22 00:05:29 +00:00
2007-08-15 01:14:55 +00:00
if (instanceOf(t, class_, popObject(t))) {
pushInt(t, 1);
2007-05-22 00:05:29 +00:00
} else {
pushInt(t, 0);
2007-05-22 00:05:29 +00:00
}
} else {
2007-08-15 01:14:55 +00:00
popObject(t);
pushInt(t, 0);
2007-05-22 00:05:29 +00:00
}
} goto loop;
2007-05-25 14:48:07 +00:00
case invokeinterface: {
uint16_t index = codeReadInt16(t, ip);
2007-05-30 00:08:10 +00:00
ip += 2;
2007-06-21 01:38:02 +00:00
object method = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-05-30 00:08:10 +00:00
unsigned parameterFootprint = methodParameterFootprint(t, method);
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
code = findInterfaceMethod
(t, method, objectClass(t, peekObject(t, sp - parameterFootprint)));
2007-05-30 00:08:10 +00:00
goto invoke;
} else {
exception = makeNullPointerException(t);
2007-05-30 00:08:10 +00:00
goto throw_;
}
} goto loop;
case invokespecial: {
uint16_t index = codeReadInt16(t, ip);
2007-05-30 00:08:10 +00:00
2007-06-21 01:38:02 +00:00
object method = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-05-30 00:08:10 +00:00
unsigned parameterFootprint = methodParameterFootprint(t, method);
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
object class_ = methodClass(t, frameMethod(t, frame));
if (isSpecialMethod(t, method, class_)) {
class_ = classSuper(t, class_);
2007-07-11 01:38:06 +00:00
if (classVirtualTable(t, class_) == 0) {
2007-08-14 00:37:00 +00:00
PROTECT(t, method);
PROTECT(t, class_);
resolveClass(t, className(t, class_));
if (UNLIKELY(exception)) goto throw_;
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
}
code = findMethod(t, method, class_);
2007-05-30 00:08:10 +00:00
} else {
code = method;
2007-05-30 00:08:10 +00:00
}
goto invoke;
} else {
exception = makeNullPointerException(t);
2007-05-30 00:08:10 +00:00
goto throw_;
}
} goto loop;
case invokestatic: {
uint16_t index = codeReadInt16(t, ip);
2007-05-30 00:08:10 +00:00
2007-06-21 01:38:02 +00:00
object method = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-09-15 00:32:32 +00:00
PROTECT(t, method);
2007-05-30 00:08:10 +00:00
if (UNLIKELY(classInit(t, methodClass(t, method), 3))) goto invoke;
2007-05-30 00:08:10 +00:00
code = method;
2007-05-30 00:08:10 +00:00
} goto invoke;
case invokevirtual: {
uint16_t index = codeReadInt16(t, ip);
2007-05-30 00:08:10 +00:00
2007-06-21 01:38:02 +00:00
object method = resolveMethod(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-05-30 00:08:10 +00:00
unsigned parameterFootprint = methodParameterFootprint(t, method);
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
2007-07-11 01:38:06 +00:00
if (classVirtualTable(t, class_) == 0) {
2007-08-14 00:37:00 +00:00
PROTECT(t, method);
PROTECT(t, class_);
resolveClass(t, className(t, class_));
if (UNLIKELY(exception)) goto throw_;
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
}
code = findMethod(t, method, class_);
2007-05-30 00:08:10 +00:00
goto invoke;
} else {
exception = makeNullPointerException(t);
2007-05-30 00:08:10 +00:00
goto throw_;
}
} goto loop;
case ior: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a | b);
2007-05-30 00:08:10 +00:00
} goto loop;
case irem: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a % b);
2007-05-30 00:08:10 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case ireturn:
case freturn: {
2007-07-07 23:47:35 +00:00
int32_t result = popInt(t);
2007-07-24 01:44:20 +00:00
if (frame > base) {
popFrame(t);
2007-07-07 23:47:35 +00:00
pushInt(t, result);
goto loop;
} else {
return makeInt(t, result);
}
} goto loop;
2007-05-30 00:08:10 +00:00
case ishl: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a << b);
2007-05-30 00:08:10 +00:00
} goto loop;
case ishr: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a >> b);
} goto loop;
2007-08-13 14:06:31 +00:00
case istore:
case fstore: {
setLocalInt(t, codeBody(t, code, ip++), popInt(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case istore_0:
case fstore_0: {
setLocalInt(t, 0, popInt(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case istore_1:
case fstore_1: {
setLocalInt(t, 1, popInt(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case istore_2:
case fstore_2: {
setLocalInt(t, 2, popInt(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case istore_3:
case fstore_3: {
setLocalInt(t, 3, popInt(t));
2007-05-30 00:08:10 +00:00
} goto loop;
case isub: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a - b);
2007-05-30 00:08:10 +00:00
} goto loop;
case iushr: {
int32_t b = popInt(t);
uint32_t a = popInt(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a >> b);
2007-05-30 00:08:10 +00:00
} goto loop;
case ixor: {
int32_t b = popInt(t);
int32_t a = popInt(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a ^ b);
2007-05-30 00:08:10 +00:00
} goto loop;
case jsr: {
uint8_t offset1 = codeBody(t, code, ip++);
uint8_t offset2 = codeBody(t, code, ip++);
2007-05-30 00:08:10 +00:00
pushInt(t, ip);
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
2007-05-30 00:08:10 +00:00
} 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++);
2007-05-30 00:08:10 +00:00
pushInt(t, ip);
ip = (ip - 3) + static_cast<int32_t>
((offset1 << 24) | (offset2 << 16) | (offset3 << 8) | offset4);
2007-05-30 00:08:10 +00:00
} goto loop;
case l2i: {
2007-07-07 23:47:35 +00:00
pushInt(t, static_cast<int32_t>(popLong(t)));
2007-05-30 00:08:10 +00:00
} goto loop;
case ladd: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a + b);
2007-05-25 14:48:07 +00:00
} goto loop;
2007-05-30 00:08:10 +00:00
case laload: {
int32_t index = popInt(t);
object array = popObject(t);
2007-05-30 00:08:10 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < longArrayLength(t, array)))
{
pushLong(t, longArrayBody(t, array, index));
2007-05-30 00:08:10 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
longArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-30 00:08:10 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
2007-05-30 00:08:10 +00:00
goto throw_;
}
} goto loop;
case land: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a & b);
2007-05-30 00:08:10 +00:00
} goto loop;
case lastore: {
int64_t value = popLong(t);
int32_t index = popInt(t);
object array = popObject(t);
2007-05-30 00:08:10 +00:00
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < longArrayLength(t, array)))
{
longArrayBody(t, array, index) = value;
2007-05-30 00:08:10 +00:00
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
longArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
2007-05-30 00:08:10 +00:00
goto throw_;
}
} else {
exception = makeNullPointerException(t);
2007-05-30 00:08:10 +00:00
goto throw_;
}
} goto loop;
case lcmp: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushInt(t, a > b ? 1 : a == b ? 0 : -1);
2007-05-30 00:08:10 +00:00
} goto loop;
case lconst_0: {
pushLong(t, 0);
2007-05-30 00:08:10 +00:00
} goto loop;
case lconst_1: {
pushLong(t, 1);
2007-05-30 00:08:10 +00:00
} goto loop;
case ldc:
case ldc_w: {
uint16_t index;
if (instruction == ldc) {
index = codeBody(t, code, ip++);
} else {
uint8_t index1 = codeBody(t, code, ip++);
uint8_t index2 = codeBody(t, code, ip++);
index = (index1 << 8) | index2;
}
object v = arrayBody(t, codePool(t, code), index - 1);
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::IntType)) {
pushInt(t, intValue(t, v));
} else if (objectClass(t, v)
== arrayBody(t, t->m->types, Machine::FloatType))
{
pushInt(t, floatValue(t, v));
2007-07-24 03:16:59 +00:00
} else if (objectClass(t, v)
== arrayBody(t, t->m->types, Machine::StringType))
2007-07-24 03:16:59 +00:00
{
pushObject(t, v);
} else {
object class_ = resolveClass(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
pushObject(t, class_);
}
2007-05-30 00:08:10 +00:00
} goto loop;
case ldc2_w: {
uint8_t index1 = codeBody(t, code, ip++);
uint8_t index2 = codeBody(t, code, ip++);
2007-05-30 00:08:10 +00:00
object v = arrayBody(t, codePool(t, code), ((index1 << 8) | index2) - 1);
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType)) {
pushLong(t, longValue(t, v));
} else if (objectClass(t, v)
== arrayBody(t, t->m->types, Machine::DoubleType))
{
pushLong(t, doubleValue(t, v));
} else {
abort(t);
}
2007-05-30 00:08:10 +00:00
} goto loop;
case ldiv_: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a / b);
2007-05-30 00:08:10 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case lload:
case dload: {
pushLong(t, localLong(t, codeBody(t, code, ip++)));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case lload_0:
case dload_0: {
pushLong(t, localLong(t, 0));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case lload_1:
case dload_1: {
pushLong(t, localLong(t, 1));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case lload_2:
case dload_2: {
pushLong(t, localLong(t, 2));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case lload_3:
case dload_3: {
pushLong(t, localLong(t, 3));
2007-07-04 17:58:27 +00:00
} goto loop;
2007-05-30 00:08:10 +00:00
case lmul: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a * b);
2007-05-30 00:08:10 +00:00
} goto loop;
case lneg: {
2007-08-19 20:24:26 +00:00
pushLong(t, - popLong(t));
2007-05-30 00:08:10 +00:00
} goto loop;
case lookupswitch: {
int32_t base = ip - 1;
ip += 3;
ip -= (ip % 4);
int32_t default_ = codeReadInt32(t, ip);
int32_t pairCount = codeReadInt32(t, ip);
int32_t key = popInt(t);
int32_t bottom = 0;
int32_t top = pairCount;
for (int32_t span = top - bottom; span; span = top - bottom) {
int32_t middle = bottom + (span / 2);
unsigned index = ip + (middle * 8);
int32_t k = codeReadInt32(t, index);
if (key < k) {
top = middle;
} else if (key > k) {
bottom = middle + 1;
} else {
ip = base + codeReadInt32(t, index);
goto loop;
}
}
ip = base + default_;
} goto loop;
2007-05-30 00:08:10 +00:00
case lor: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a | b);
2007-05-30 00:08:10 +00:00
} goto loop;
case lrem: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a % b);
2007-05-30 00:08:10 +00:00
} goto loop;
2007-08-13 14:06:31 +00:00
case lreturn:
case dreturn: {
2007-07-07 23:47:35 +00:00
int64_t result = popLong(t);
2007-07-24 01:44:20 +00:00
if (frame > base) {
popFrame(t);
2007-07-07 23:47:35 +00:00
pushLong(t, result);
goto loop;
} else {
return makeLong(t, result);
}
} goto loop;
2007-05-30 00:08:10 +00:00
case lshl: {
2007-09-14 03:59:39 +00:00
int32_t b = popInt(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a << b);
2007-05-30 00:08:10 +00:00
} goto loop;
case lshr: {
2007-09-14 03:59:39 +00:00
int32_t b = popInt(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a >> b);
} goto loop;
2007-08-13 14:06:31 +00:00
case lstore:
case dstore: {
setLocalLong(t, codeBody(t, code, ip++), popLong(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case lstore_0:
case dstore_0:{
setLocalLong(t, 0, popLong(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case lstore_1:
case dstore_1: {
setLocalLong(t, 1, popLong(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case lstore_2:
case dstore_2: {
setLocalLong(t, 2, popLong(t));
} goto loop;
2007-08-13 14:06:31 +00:00
case lstore_3:
case dstore_3: {
setLocalLong(t, 3, popLong(t));
2007-05-30 00:08:10 +00:00
} goto loop;
case lsub: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a - b);
2007-05-30 00:08:10 +00:00
} goto loop;
case lushr: {
int64_t b = popLong(t);
uint64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a >> b);
2007-05-30 00:08:10 +00:00
} goto loop;
case lxor: {
int64_t b = popLong(t);
int64_t a = popLong(t);
2007-05-30 00:08:10 +00:00
pushLong(t, a ^ b);
2007-05-30 00:08:10 +00:00
} goto loop;
2007-07-02 01:42:35 +00:00
case monitorenter: {
object o = popObject(t);
2007-07-02 01:42:35 +00:00
if (LIKELY(o)) {
2007-07-07 23:47:35 +00:00
acquire(t, o);
2007-07-02 01:42:35 +00:00
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case monitorexit: {
object o = popObject(t);
2007-07-02 01:42:35 +00:00
if (LIKELY(o)) {
2007-07-07 23:47:35 +00:00
release(t, o);
2007-07-02 01:42:35 +00:00
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case multianewarray: {
uint16_t index = codeReadInt16(t, ip);
uint8_t dimensions = codeBody(t, code, ip++);
object class_ = resolveClass(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
PROTECT(t, class_);
int32_t counts[dimensions];
for (int i = dimensions - 1; i >= 0; --i) {
counts[i] = popInt(t);
if (UNLIKELY(counts[i] < 0)) {
object message = makeString(t, "%d", counts[i]);
exception = makeNegativeArraySizeException(t, message);
goto throw_;
}
}
object array = makeArray(t, counts[0], true);
setObjectClass(t, array, class_);
PROTECT(t, array);
populateMultiArray(t, array, counts, 0, dimensions);
pushObject(t, array);
} goto loop;
case new_: {
uint16_t index = codeReadInt16(t, ip);
2007-06-21 01:38:02 +00:00
object class_ = resolveClass(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-09-15 00:32:32 +00:00
PROTECT(t, class_);
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
pushObject(t, make(t, class_));
} goto loop;
case newarray: {
int32_t count = popInt(t);
if (LIKELY(count >= 0)) {
uint8_t type = codeBody(t, code, ip++);
object array;
switch (type) {
case T_BOOLEAN:
array = makeBooleanArray(t, count, true);
break;
case T_CHAR:
array = makeCharArray(t, count, true);
break;
case T_FLOAT:
array = makeFloatArray(t, count, true);
break;
case T_DOUBLE:
array = makeDoubleArray(t, count, true);
break;
case T_BYTE:
array = makeByteArray(t, count, true);
break;
case T_SHORT:
array = makeShortArray(t, count, true);
break;
case T_INT:
array = makeIntArray(t, count, true);
break;
case T_LONG:
array = makeLongArray(t, count, true);
break;
default: abort(t);
}
2007-06-21 19:43:33 +00:00
pushObject(t, array);
} else {
object message = makeString(t, "%d", count);
2007-07-07 23:47:35 +00:00
exception = makeNegativeArraySizeException(t, message);
goto throw_;
}
} goto loop;
case nop: goto loop;
2007-06-25 02:02:24 +00:00
case pop_: {
-- sp;
} goto loop;
case pop2: {
sp -= 2;
} goto loop;
case putfield: {
uint16_t index = codeReadInt16(t, ip);
object field = resolveField(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
case CharField:
case ShortField:
case FloatField:
case IntField: {
int32_t value = popInt(t);
object o = popObject(t);
if (LIKELY(o)) {
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
cast<int8_t>(o, fieldOffset(t, field)) = value;
break;
case CharField:
case ShortField:
cast<int16_t>(o, fieldOffset(t, field)) = value;
break;
case FloatField:
case IntField:
cast<int32_t>(o, fieldOffset(t, field)) = value;
break;
}
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} break;
case DoubleField:
case LongField: {
int64_t value = popLong(t);
object o = popObject(t);
if (LIKELY(o)) {
cast<int64_t>(o, fieldOffset(t, field)) = value;
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} break;
case ObjectField: {
object value = popObject(t);
object o = popObject(t);
if (LIKELY(o)) {
set(t, cast<object>(o, fieldOffset(t, field)), value);
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} break;
default: abort(t);
}
} goto loop;
case putstatic: {
uint16_t index = codeReadInt16(t, ip);
2007-06-21 01:38:02 +00:00
object field = resolveField(t, codePool(t, code), index - 1);
if (UNLIKELY(exception)) goto throw_;
2007-09-15 00:32:32 +00:00
PROTECT(t, field);
if (UNLIKELY(classInit(t, fieldClass(t, field), 3))) goto invoke;
object v;
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
case CharField:
case ShortField:
case FloatField:
case IntField: {
v = makeInt(t, popInt(t));
} break;
case DoubleField:
case LongField: {
v = makeLong(t, popLong(t));
} break;
case ObjectField:
v = popObject(t);
break;
default: abort(t);
}
set(t, arrayBody(t, classStaticTable(t, fieldClass(t, field)),
fieldOffset(t, field)), v);
} goto loop;
case ret: {
ip = localInt(t, codeBody(t, code, ip));
} goto loop;
case return_: {
2007-07-24 01:44:20 +00:00
if (frame > base) {
popFrame(t);
goto loop;
} else {
return 0;
}
} goto loop;
case saload: {
int32_t index = popInt(t);
object array = popObject(t);
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < shortArrayLength(t, array)))
{
pushInt(t, shortArrayBody(t, array, index));
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
shortArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case sastore: {
int16_t value = popInt(t);
int32_t index = popInt(t);
object array = popObject(t);
if (LIKELY(array)) {
if (LIKELY(index >= 0 and
static_cast<uintptr_t>(index) < shortArrayLength(t, array)))
{
shortArrayBody(t, array, index) = value;
} else {
2007-08-21 00:24:54 +00:00
object message = makeString(t, "%d not in [0,%d)", index,
shortArrayLength(t, array));
exception = makeArrayIndexOutOfBoundsException(t, message);
goto throw_;
}
} else {
exception = makeNullPointerException(t);
goto throw_;
}
} goto loop;
case sipush: {
uint8_t byte1 = codeBody(t, code, ip++);
uint8_t byte2 = codeBody(t, code, ip++);
pushInt(t, static_cast<int16_t>((byte1 << 8) | byte2));
} goto loop;
case swap: {
uintptr_t tmp[2];
memcpy(tmp , stack + ((sp - 1) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 1) * 2), stack + ((sp - 2) * 2), BytesPerWord * 2);
memcpy(stack + ((sp - 2) * 2), tmp , BytesPerWord * 2);
} goto loop;
case tableswitch: {
int32_t base = ip - 1;
ip += 3;
ip -= (ip % 4);
int32_t default_ = codeReadInt32(t, ip);
int32_t bottom = codeReadInt32(t, ip);
int32_t top = codeReadInt32(t, ip);
int32_t key = popInt(t);
if (key >= bottom and key <= top) {
unsigned index = ip + ((key - bottom) * 4);
ip = base + codeReadInt32(t, index);
} else {
ip = base + default_;
}
} goto loop;
case wide: goto wide;
default: abort(t);
}
wide:
switch (codeBody(t, code, ip++)) {
case aload: {
pushObject(t, localObject(t, codeReadInt16(t, ip)));
} goto loop;
case astore: {
setLocalObject(t, codeReadInt16(t, ip), popObject(t));
} goto loop;
case iinc: {
uint16_t index = codeReadInt16(t, ip);
uint16_t count = codeReadInt16(t, ip);
setLocalInt(t, index, localInt(t, index) + count);
} goto loop;
case iload: {
pushInt(t, localInt(t, codeReadInt16(t, ip)));
} goto loop;
case istore: {
setLocalInt(t, codeReadInt16(t, ip), popInt(t));
} goto loop;
case lload: {
pushLong(t, localLong(t, codeReadInt16(t, ip)));
} goto loop;
case lstore: {
setLocalLong(t, codeReadInt16(t, ip), popLong(t));
} goto loop;
case ret: {
ip = localInt(t, codeReadInt16(t, ip));
2007-05-30 00:08:10 +00:00
} goto loop;
default: abort(t);
2007-05-30 00:08:10 +00:00
}
invoke: {
if (methodFlags(t, code) & ACC_NATIVE) {
2007-07-04 17:58:27 +00:00
invokeNative(t, code);
2007-07-07 18:09:16 +00:00
if (UNLIKELY(exception)) goto throw_;
2007-06-24 01:39:49 +00:00
} else {
2007-07-07 18:09:16 +00:00
checkStack(t, code);
if (UNLIKELY(exception)) goto throw_;
2007-06-25 02:20:35 +00:00
pushFrame(t, code);
}
} goto loop;
2007-05-21 15:47:44 +00:00
throw_:
if (DebugRun) {
fprintf(stderr, "throw\n");
}
pokeInt(t, t->frame + FrameIpOffset, t->ip);
for (; frame >= base; popFrame(t)) {
code = methodCode(t, frameMethod(t, frame));
object eht = codeExceptionHandlerTable(t, code);
2007-05-25 14:48:07 +00:00
if (eht) {
2007-06-06 02:24:09 +00:00
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
if (frameIp(t, frame) - 1 >= exceptionHandlerStart(eh)
and frameIp(t, frame) - 1 < exceptionHandlerEnd(eh))
2007-05-25 14:48:07 +00:00
{
2007-07-05 02:44:01 +00:00
object catchType = 0;
if (exceptionHandlerCatchType(eh)) {
object e = exception;
exception = 0;
PROTECT(t, e);
2007-07-19 23:45:44 +00:00
PROTECT(t, eht);
catchType = resolveClass
(t, codePool(t, code), exceptionHandlerCatchType(eh) - 1);
if (catchType) {
eh = exceptionHandlerTableBody(t, eht, i);
exception = e;
} else {
// can't find what we're supposed to catch - move on.
continue;
}
}
if (catchType == 0 or instanceOf(t, catchType, exception)) {
sp = frame + FrameFootprint;
2007-07-05 02:44:01 +00:00
ip = exceptionHandlerIp(eh);
pushObject(t, exception);
exception = 0;
goto loop;
}
2007-05-21 15:47:44 +00:00
}
}
}
}
return 0;
2007-05-21 15:47:44 +00:00
}
2007-07-24 01:44:20 +00:00
void
2007-09-07 23:20:21 +00:00
pushArguments(Thread* t, object this_, const char* spec, bool indirectObjects,
va_list a)
{
if (this_) {
pushObject(t, this_);
}
2007-07-24 01:44:20 +00:00
const char* s = spec;
++ s; // skip '('
while (*s and *s != ')') {
switch (*s) {
case 'L':
while (*s and *s != ';') ++ s;
++ s;
2007-09-13 03:15:16 +00:00
if (indirectObjects) {
object* v = va_arg(a, object*);
pushObject(t, v ? *v : 0);
} else {
pushObject(t, va_arg(a, object));
}
break;
case '[':
while (*s == '[') ++ s;
switch (*s) {
case 'L':
while (*s and *s != ';') ++ s;
++ s;
break;
default:
++ s;
break;
}
2007-09-13 03:15:16 +00:00
if (indirectObjects) {
object* v = va_arg(a, object*);
pushObject(t, v ? *v : 0);
} else {
pushObject(t, va_arg(a, object));
}
break;
case 'J':
case 'D':
++ s;
pushLong(t, va_arg(a, uint64_t));
break;
default:
++ s;
pushInt(t, va_arg(a, uint32_t));
break;
}
}
2007-07-24 01:44:20 +00:00
}
void
pushArguments(Thread* t, object this_, const char* spec, object a)
{
if (this_) {
pushObject(t, this_);
}
unsigned index = 0;
const char* s = spec;
++ s; // skip '('
while (*s and *s != ')') {
switch (*s) {
case 'L':
while (*s and *s != ';') ++ s;
++ s;
pushObject(t, objectArrayBody(t, a, index++));
break;
case '[':
while (*s == '[') ++ s;
switch (*s) {
case 'L':
while (*s and *s != ';') ++ s;
++ s;
break;
default:
++ s;
break;
}
pushObject(t, objectArrayBody(t, a, index++));
break;
case 'J':
case 'D':
++ s;
pushLong(t, cast<int64_t>(objectArrayBody(t, a, index++), BytesPerWord));
break;
default:
++ s;
pushInt(t, cast<int32_t>(objectArrayBody(t, a, index++), BytesPerWord));
break;
}
}
}
inline unsigned
returnCode(Thread* t, object method)
{
const char* s = reinterpret_cast<const char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
while (*s and *s != ')') ++ s;
return fieldCode(t, s[1]);
}
2007-07-24 01:44:20 +00:00
object
invoke(Thread* t, object method)
{
PROTECT(t, method);
object class_;
PROTECT(t, class_);
if (methodFlags(t, method) & ACC_STATIC) {
class_ = methodClass(t, method);
} else {
unsigned parameterFootprint = methodParameterFootprint(t, method);
class_ = objectClass(t, peekObject(t, t->sp - parameterFootprint));
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
method = findInterfaceMethod(t, method, class_);
} else {
if (classVirtualTable(t, class_) == 0) {
resolveClass(t, className(t, class_));
if (UNLIKELY(t->exception)) return 0;
}
method = findMethod(t, method, class_);
}
}
initClass(t, class_);
2007-07-24 01:44:20 +00:00
object result = 0;
if (methodFlags(t, method) & ACC_NATIVE) {
unsigned returnCode = invokeNative(t, method);
if (LIKELY(t->exception == 0)) {
switch (returnCode) {
case ByteField:
case BooleanField:
case CharField:
case ShortField:
case FloatField:
case IntField:
result = makeInt(t, popInt(t));
break;
2007-07-24 01:44:20 +00:00
case LongField:
case DoubleField:
result = makeLong(t, popLong(t));
break;
2007-07-24 01:44:20 +00:00
case ObjectField:
result = popObject(t);
break;
2007-07-24 01:44:20 +00:00
case VoidField:
result = 0;
break;
2007-07-24 01:44:20 +00:00
default:
abort(t);
};
}
} else {
checkStack(t, method);
if (LIKELY(t->exception == 0)) {
pushFrame(t, method);
result = interpret(t);
2007-07-24 03:16:59 +00:00
if (LIKELY(t->exception == 0)) {
popFrame(t);
}
2007-07-24 01:44:20 +00:00
}
}
2007-08-28 23:38:47 +00:00
if (UNLIKELY(t->exception)) {
return 0;
}
switch (returnCode(t, method)) {
case ByteField:
return makeByte(t, static_cast<int8_t>(intValue(t, result)));
case BooleanField:
return makeBoolean(t, static_cast<uint8_t>(intValue(t, result)));
case CharField:
return makeChar(t, static_cast<uint16_t>(intValue(t, result)));
case ShortField:
return makeShort(t, static_cast<int16_t>(intValue(t, result)));
case FloatField:
return makeFloat(t, static_cast<uint32_t>(intValue(t, result)));
case DoubleField:
return makeDouble(t, static_cast<uint64_t>(longValue(t, result)));
case ObjectField:
case IntField:
case LongField:
case VoidField:
return result;
default:
abort(t);
}
2007-07-24 01:44:20 +00:00
}
2007-09-24 13:46:48 +00:00
class MyProcessor: public Processor {
public:
MyProcessor(System* s):
s(s)
{ }
2007-09-24 13:46:48 +00:00
virtual vm::Thread*
makeThread(Machine* m, object javaThread, vm::Thread* parent)
{
return new (s->allocate(sizeof(Thread))) Thread(m, javaThread, parent);
}
2007-09-24 13:46:48 +00:00
virtual void
visitObjects(vm::Thread* vmt, Heap::Visitor* v)
{
Thread* t = static_cast<Thread*>(vmt);
2007-09-24 13:46:48 +00:00
v->visit(&(t->code));
for (unsigned i = 0; i < t->sp; ++i) {
if (t->stack[i * 2] == ObjectTag) {
v->visit(t->stack + (i * 2) + 1);
}
}
}
2007-09-24 13:46:48 +00:00
virtual uintptr_t
frameStart(vm::Thread* vmt)
{
Thread* t = static_cast<Thread*>(vmt);
2007-09-24 13:46:48 +00:00
if (t->frame >= 0) {
pokeInt(t, t->frame + FrameIpOffset, t->ip);
}
2007-09-24 13:46:48 +00:00
return t->frame;
}
2007-09-24 13:46:48 +00:00
virtual uintptr_t
frameNext(vm::Thread* vmt, uintptr_t frame)
{
Thread* t = static_cast<Thread*>(vmt);
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
assert(t, static_cast<intptr_t>(frame) >= 0);
return ::frameNext(t, frame);
}
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
virtual bool
frameValid(vm::Thread*, uintptr_t frame)
2007-07-24 01:44:20 +00:00
{
2007-09-24 13:46:48 +00:00
return static_cast<intptr_t>(frame) >= 0;
2007-07-24 01:44:20 +00:00
}
2007-09-24 13:46:48 +00:00
virtual object
frameMethod(vm::Thread* vmt, uintptr_t frame)
{
Thread* t = static_cast<Thread*>(vmt);
2007-09-07 23:20:21 +00:00
2007-09-24 13:46:48 +00:00
assert(t, static_cast<intptr_t>(frame) >= 0);
return ::frameMethod(t, frame);
}
2007-09-07 23:20:21 +00:00
2007-09-24 13:46:48 +00:00
virtual unsigned
frameIp(vm::Thread* vmt, uintptr_t frame)
{
Thread* t = static_cast<Thread*>(vmt);
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
assert(t, static_cast<intptr_t>(frame) >= 0);
return ::frameIp(t, frame);
}
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
virtual object*
makeLocalReference(vm::Thread* vmt, object o)
{
Thread* t = static_cast<Thread*>(vmt);
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
return pushReference(t, o);
}
virtual void
disposeLocalReference(vm::Thread*, object* r)
2007-07-24 01:44:20 +00:00
{
2007-09-24 13:46:48 +00:00
if (r) {
*r = 0;
}
2007-07-24 01:44:20 +00:00
}
2007-09-24 13:46:48 +00:00
virtual object
invokeArray(vm::Thread* vmt, object method, object this_, object arguments)
{
Thread* t = static_cast<Thread*>(vmt);
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
2007-09-24 13:46:48 +00:00
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, arguments);
2007-07-24 01:44:20 +00:00
2007-09-24 13:46:48 +00:00
return ::invoke(t, method);
2007-07-24 01:44:20 +00:00
}
2007-09-24 13:46:48 +00:00
virtual object
invokeList(vm::Thread* vmt, object method, object this_,
bool indirectObjects,
va_list arguments)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
2007-07-07 18:09:16 +00:00
2007-09-24 13:46:48 +00:00
if (UNLIKELY(t->sp + methodParameterFootprint(t, method) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
const char* spec = reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, method), 0));
pushArguments(t, this_, spec, indirectObjects, arguments);
return ::invoke(t, method);
}
2007-09-24 13:46:48 +00:00
virtual object
invokeList(vm::Thread* vmt, const char* className, const char* methodName,
const char* methodSpec, object this_, va_list arguments)
{
Thread* t = static_cast<Thread*>(vmt);
assert(t, t->state == Thread::ActiveState
or t->state == Thread::ExclusiveState);
if (UNLIKELY(t->sp + parameterFootprint(methodSpec) + 1
> Thread::StackSizeInWords / 2))
{
t->exception = makeStackOverflowError(t);
return 0;
}
pushArguments(t, this_, methodSpec, false, arguments);
object method = resolveMethod(t, className, methodName, methodSpec);
if (LIKELY(t->exception == 0)) {
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
return ::invoke(t, method);
} else {
return 0;
}
}
virtual void dispose() {
s->free(this);
}
System* s;
};
} // namespace
namespace vm {
Processor*
makeProcessor(System* system)
{
return new (system->allocate(sizeof(MyProcessor))) MyProcessor(system);
}
} // namespace vm