initial commit

This commit is contained in:
Joel Dice 2007-05-21 09:47:44 -06:00
commit 9ed7dbb3d5
2 changed files with 297 additions and 0 deletions

109
src/types.def Normal file
View File

@ -0,0 +1,109 @@
(type class
(uintptr_t id)
(object name)
(object super)
(object objectMask)
(object fieldTable)
(object methodTable)
(object staticTable))
(type objectMask
(uint32_t maskLength)
(uint32_t arrayMaskLength)
(array uint32_t body))
(pod field
(uint16_t flags)
(object name)
(object class))
(type fieldTable
(object index)
(array field body))
(pod method
(uint16_t flags)
(object name)
(object spec)
(object code))
(type methodTable
(object index)
(array method body))
(pod exceptionHandler
(uint16_t start)
(uint16_t end)
(uint16_t handler)
(uint16_t catchType))
(type exceptionHandlerTable
(array exceptionHandler body))
(type code
(object pool)
(object exceptionHandlerTable)
(uint16_t maxStack)
(uint16_t maxLocals)
(array uint8_t body))
(type frame
(object code)
(uint32_t ip)
(array object locals))
(type reference
(object class)
(object name)
(object spec))
(type string
(uint32_t hash)
(uint32_t id)
(array char value))
(type byte
(uint8_t value))
(type short
(uint16_t value))
(type int
(uint32_t value))
(type long
(uint64_t value))
(type float
(uint32_t value))
(type double
(uint64_t value))
(type rawArray
(array object body))
(type objectArray
(object elementClass)
(array object body))
(type byteArray
(array uint8_t body))
(type shortArray
(array uint16_t body))
(type charArray
(array uint16_t body))
(type intArray
(array uint32_t body))
(type longArray
(array uint64_t body))
(type floatArray
(array uint32_t body))
(type doubleArray
(array uint64_t body))

188
src/vm.cpp Normal file
View File

@ -0,0 +1,188 @@
namespace {
object
run(Thread* t)
{
unsigned ip = 0;
#define PUSH(x) t->stack[(t->sp)++] = x
#define POP(x) x = t->stack[--(t->sp)]
#define NEXT ++ ip; goto loop
loop:
switch (codeBody(t->code)[ip]) {
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));
t->exception = makeAIOOBException(t, message);
goto throw_;
}
} else {
t->exception = makeNPException(t, 0);
goto throw_;
}
} NEXT;
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));
t->exception = makeAIOOBException(t, message);
goto throw_;
}
} else {
t->exception = makeNPException(t, 0);
goto throw_;
}
} NEXT;
case aconst_null: {
PUSH(0);
} NEXT;
case aload: {
PUSH(frameBody(t->frame)[codeBody(t->code)[++ip]]);
} NEXT;
case aload_0: {
PUSH(frameBody(t->frame)[0]);
} NEXT;
case aload_1: {
PUSH(frameBody(t->frame)[1]);
} NEXT;
case aload_2: {
PUSH(frameBody(t->frame)[2]);
} NEXT;
case aload_3: {
PUSH(frameBody(t->frame)[3]);
} NEXT;
case anewarray: {
object count; POP(count);
int32_t c = intValue(count);
if (c >= 0) {
uint8_t index1 = codeBody(t->code)[++ip];
uint8_t index2 = codeBody(t->code)[++ip];
uint16_t index = (index1 << 8) | index2;
object class_ = resolvePoolEntry(t, codePool(t->code), index);
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);
t->exception = makeNASException(t, message);
goto throw_;
}
} NEXT;
case areturn: {
object value; POP(value);
if (t->sp) {
POP(t->frame);
t->code = frameCode(t->frame);
ip = frameIp(t->frame);
PUSH(value);
goto loop;
} else {
return value;
}
} NEXT;
case arraylength: {
object array; POP(array);
if (array) {
PUSH(makeInt(t, arrayLength(array)));
} else {
t->exception = makeNPException(t, 0);
goto throw_;
}
} UNREACHABLE;
case astore: {
object value; POP(value);
set(t, frameBody(t->frame)[codeBody(t->code)[++ip]], value);
} NEXT;
case astore_0: {
object value; POP(value);
set(t, frameBody(t->frame)[0], value);
} NEXT;
case astore_1: {
object value; POP(value);
set(t, frameBody(t->frame)[1], value);
} NEXT;
case astore_2: {
object value; POP(value);
set(t, frameBody(t->frame)[2], value);
} NEXT;
case astore_3: {
object value; POP(value);
set(t, frameBody(t->frame)[3], value);
} NEXT;
case athrow: {
POP(t->exception);
goto throw_;
} UNREACHABLE;
}
throw_:
for (; t->sp >= 0; --(t->sp)) {
if (typeOf(t->stack[t->sp]) == FrameType) {
t->frame = t->stack[t->sp];
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))
{
ip = exceptionHandlerHandler(eh);
PUSH(t->exception);
t->exception = 0;
goto loop;
}
}
}
}
}
t->code = defaultExceptionHandler(t);
ip = 0;
PUSH(t->exception);
t->exception = 0;
goto loop;
}
} // namespace