Skip to content
Permalink
Browse files

initial commit

  • Loading branch information...
Joel Dice
Joel Dice committed May 21, 2007
0 parents commit 9ed7dbb3d5b3f4aa33441733de35ba2fbc9b53e2
Showing with 297 additions and 0 deletions.
  1. +109 −0 src/types.def
  2. +188 −0 src/vm.cpp
@@ -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))
@@ -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

0 comments on commit 9ed7dbb

Please sign in to comment.
You can’t perform that action at this time.