From 9ed7dbb3d5b3f4aa33441733de35ba2fbc9b53e2 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 21 May 2007 09:47:44 -0600 Subject: [PATCH] initial commit --- src/types.def | 109 +++++++++++++++++++++++++++++ src/vm.cpp | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 src/types.def create mode 100644 src/vm.cpp diff --git a/src/types.def b/src/types.def new file mode 100644 index 0000000000..666b50457f --- /dev/null +++ b/src/types.def @@ -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)) diff --git a/src/vm.cpp b/src/vm.cpp new file mode 100644 index 0000000000..21ff5e8511 --- /dev/null +++ b/src/vm.cpp @@ -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