diff --git a/src/constants.h b/src/constants.h index 5b4e0801e2..262cecbe07 100644 --- a/src/constants.h +++ b/src/constants.h @@ -200,4 +200,10 @@ enum TypeCode { T_LONG = 11 }; +const unsigned ACC_PUBLIC = 1 << 0; +const unsigned ACC_FINAL = 1 << 4; +const unsigned ACC_SUPER = 1 << 5; +const unsigned ACC_INTERFACE = 1 << 9; +const unsigned ACC_ABSTRACT = 1 << 10; + #endif//CONSTANTS_H diff --git a/src/types.def b/src/types.def index eaac458325..0561796d16 100644 --- a/src/types.def +++ b/src/types.def @@ -3,6 +3,7 @@ (uint16_t fixedSize) (uint16_t arrayElementSize) (object objectMask) + (uint16_t flags) (object name) (object super) (object interfaceTable) @@ -75,6 +76,10 @@ (uint32_t ip) (object next)) +(type thread + (object localMap) + (object exceptionHandler)) + (type string (object bytes) (int32_t offset) diff --git a/src/vm.cpp b/src/vm.cpp index 0a78d7154c..2723166ee3 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -39,7 +39,6 @@ class Machine { unsigned liveCount; System::Monitor* stateLock; System::Monitor* heapLock; - object jstringClass; }; class Thread { @@ -75,6 +74,7 @@ class Thread { Thread* next; Thread* child; State state; + object thread; object frame; object code; object exception; @@ -133,6 +133,7 @@ iterate(Thread* t, Heap::Visitor* v) { t->heapIndex = 0; + v->visit(&(t->thread)); v->visit(&(t->frame)); v->visit(&(t->code)); v->visit(&(t->exception)); @@ -492,11 +493,38 @@ findInterfaceMethod(Thread* t, object method, object o) abort(t); } +inline object +findMethod(Thread* t, object method, object class_) +{ + return rawArrayBody(t, classMethodTable(t, class_)) + [methodOffset(t, method)]; +} + inline object findVirtualMethod(Thread* t, object method, object o) { - return rawArrayBody(t, classMethodTable(t, objectClass(o))) - [methodOffset(t, method)]; + return findMethod(t, method, objectClass(o)); +} + +bool +isSuperclass(Thread* t, object class_, object base) +{ + Type id = classId(t, class_); + for (object oc = classSuper(t, base); oc; oc = classSuper(t, oc)) { + if (classId(t, oc) == id) { + return true; + } + } + return false; +} + +inline bool +isSpecialMethod(Thread* t, object method, object class_) +{ + return (classFlags(t, class_) & ACC_SUPER) + and strcmp("", reinterpret_cast + (byteArrayBody(t, methodName(t, method)))) != 0 + and isSuperclass(t, methodClass(t, method), class_); } object @@ -1317,8 +1345,9 @@ run(Thread* t) parameterCount = methodParameterCount(t, method); if (LIKELY(stack[sp - parameterCount])) { - if (isSpecialMethod(method, stack[sp - parameterCount])) { - code = findSpecialMethod(t, method, stack[sp - parameterCount]); + object class_ = methodClass(t, frameMethod(t, t->frame)); + if (isSpecialMethod(t, method, class_)) { + code = findMethod(t, method, classSuper(t, class_)); if (UNLIKELY(exception)) goto throw_; } else { code = method; @@ -1905,7 +1934,7 @@ run(Thread* t) } } - object method = defaultExceptionHandler(t); + object method = threadExceptionHandler(t, t->thread); code = methodCode(t, method); frame = makeFrame(t, method, 0, 0, 0, codeMaxLocals(t, code)); sp = 0;