diff --git a/src/types.def b/src/types.def index 8f6f962ff8..08c0ad9225 100644 --- a/src/types.def +++ b/src/types.def @@ -5,6 +5,7 @@ (object objectMask) (object name) (object super) + (object interfaceTable) (object fieldTable) (object methodTable) (object staticTable)) @@ -48,6 +49,22 @@ (object name) (object spec)) +(type interface + (uint32_t id) + (object name) + (object supers) + (object methodTable) + (object staticTable)) + +(type pair + (object first) + (object second)) + +(type triple + (object first) + (object second) + (object third)) + (type trace (object method) (uint32_t ip) diff --git a/src/vm.cpp b/src/vm.cpp index dbcb956340..86306d7a6a 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -24,7 +24,6 @@ enum ObjectType { class Thread; Type typeOf(object); - object& objectClass(object); void assert(Thread* t, bool v); @@ -418,6 +417,41 @@ makeStackOverflowError(Thread* t) return makeStackOverflowError(t, 0, makeTrace(t)); } +inline bool +isLongOrDouble(object o) +{ + return typeOf(o) == LongType or typeOf(o) == DoubleType; +} + +bool +instanceOf(Thread* t, object class_, object o) +{ + if (o == 0) { + return false; + } + + if (typeOf(class_) == InterfaceType) { + Type id = interfaceId(t, class_); + for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) { + object itable = classInterfaceTable(t, oc); + for (unsigned i = 0; i < rawArrayLength(t, itable); i += 2) { + if (interfaceId(t, rawArrayBody(t, itable)[i]) == id) { + return true; + } + } + } + } else { + Type id = classId(t, class_); + for (object oc = objectClass(o); oc; oc = classSuper(t, oc)) { + if (classId(t, oc) == id) { + return true; + } + } + } + + return false; +} + object run(Thread* t) { @@ -1802,7 +1836,8 @@ run(Thread* t) ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); uint16_t catchType = exceptionHandlerCatchType(eh); if (catchType == 0 or - instanceOf(rawArrayBody(t, codePool(t, code))[catchType], + instanceOf(t, + rawArrayBody(t, codePool(t, code))[catchType], exception)) { sp = frameStackBase(t, frame);