diff --git a/classpath/java/lang/Class.java b/classpath/java/lang/Class.java index ff5072b79f..b2464486eb 100644 --- a/classpath/java/lang/Class.java +++ b/classpath/java/lang/Class.java @@ -32,10 +32,10 @@ public final class Class implements Type, GenericDeclaration { private static final int PrimitiveFlag = 1 << 5; private short flags; - private byte vmFlags; - private byte arrayDimensions; + private short vmFlags; private short fixedSize; - private short arrayElementSize; + private byte arrayElementSize; + private byte arrayDimensions; private int[] objectMask; private byte[] name; private Class super_; @@ -151,6 +151,7 @@ public final class Class implements Type, GenericDeclaration { loader = Class.class.loader; } Class c = loader.loadClass(name); + c.link(loader); if (initialize) { c.initialize(); } @@ -159,6 +160,8 @@ public final class Class implements Type, GenericDeclaration { private static native Class primitiveClass(char name); + private native void link(ClassLoader loader); + private native void initialize(); public static Class forCanonicalName(String name) { @@ -215,6 +218,8 @@ public final class Class implements Type, GenericDeclaration { private Field findField(String name) { if (fieldTable != null) { + link(loader); + for (int i = 0; i < fieldTable.length; ++i) { if (fieldTable[i].getName().equals(name)) { return fieldTable[i]; @@ -258,8 +263,12 @@ public final class Class implements Type, GenericDeclaration { private Method findMethod(String name, Class[] parameterTypes) { if (methodTable != null) { - if (parameterTypes == null) + link(loader); + + if (parameterTypes == null) { parameterTypes = new Class[0]; + } + for (int i = 0; i < methodTable.length; ++i) { if (methodTable[i].getName().equals(name) && match(parameterTypes, methodTable[i].getParameterTypes())) @@ -348,6 +357,8 @@ public final class Class implements Type, GenericDeclaration { public Constructor[] getDeclaredConstructors() { Constructor[] array = new Constructor[countConstructors(false)]; if (methodTable != null) { + link(loader); + int index = 0; for (int i = 0; i < methodTable.length; ++i) { if (methodTable[i].getName().equals("")) { @@ -362,6 +373,8 @@ public final class Class implements Type, GenericDeclaration { public Constructor[] getConstructors() { Constructor[] array = new Constructor[countConstructors(true)]; if (methodTable != null) { + link(loader); + int index = 0; for (int i = 0; i < methodTable.length; ++i) { if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0) @@ -400,6 +413,8 @@ public final class Class implements Type, GenericDeclaration { public Field[] getFields() { Field[] array = new Field[countPublicFields()]; if (fieldTable != null) { + link(loader); + int ai = 0; for (int i = 0; i < fieldTable.length; ++i) { if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) { @@ -428,6 +443,8 @@ public final class Class implements Type, GenericDeclaration { public Method[] getDeclaredMethods() { Method[] array = new Method[countMethods(false)]; if (methodTable != null) { + link(loader); + int ai = 0; for (int i = 0; i < methodTable.length; ++i) { if (! methodTable[i].getName().startsWith("<")) { @@ -442,6 +459,8 @@ public final class Class implements Type, GenericDeclaration { public Method[] getMethods() { Method[] array = new Method[countMethods(true)]; if (methodTable != null) { + link(loader); + int index = 0; for (int i = 0; i < methodTable.length; ++i) { if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0) @@ -457,6 +476,8 @@ public final class Class implements Type, GenericDeclaration { public Class[] getInterfaces() { if (interfaceTable != null) { + link(loader); + Class[] array = new Class[interfaceTable.length / 2]; for (int i = 0; i < array.length; ++i) { array[i] = (Class) interfaceTable[i * 2]; @@ -496,7 +517,7 @@ public final class Class implements Type, GenericDeclaration { } public boolean isArray() { - return this != Class.class && arrayElementSize != 0; + return arrayDimensions != 0; } public boolean isInstance(Object o) { diff --git a/classpath/java/lang/ClassLoader.java b/classpath/java/lang/ClassLoader.java index 31006f21dc..9fe9228dea 100644 --- a/classpath/java/lang/ClassLoader.java +++ b/classpath/java/lang/ClassLoader.java @@ -83,9 +83,7 @@ public abstract class ClassLoader { return c; } - protected void resolveClass(Class c) { - // ignore - } + protected native void resolveClass(Class c); private ClassLoader getParent() { return parent; diff --git a/src/builtin.cpp b/src/builtin.cpp index 6c7dbb74e4..3a126a0312 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -199,6 +199,16 @@ Avian_java_lang_ClassLoader_defineClass return reinterpret_cast(c); } +extern "C" JNIEXPORT void JNICALL +Avian_java_lang_ClassLoader_resolveClass +(Thread* t, object, uintptr_t* arguments) +{ + object loader = reinterpret_cast(arguments[0]); + object class_ = reinterpret_cast(arguments[1]); + + linkClass(t, loader, class_); +} + extern "C" JNIEXPORT int64_t JNICALL Avian_avian_SystemClassLoader_findLoadedClass (Thread* t, object, uintptr_t* arguments) @@ -291,6 +301,16 @@ Avian_java_lang_Class_initialize initClass(t, this_); } +extern "C" JNIEXPORT void JNICALL +Avian_java_lang_Class_link +(Thread* t, object, uintptr_t* arguments) +{ + object this_ = reinterpret_cast(arguments[0]); + object loader = reinterpret_cast(arguments[1]); + + linkClass(t, loader, this_); +} + extern "C" JNIEXPORT int64_t JNICALL Avian_java_lang_Class_isAssignableFrom (Thread* t, object, uintptr_t* arguments) diff --git a/src/compile.cpp b/src/compile.cpp index 4c25fb2d86..97fe3fb21e 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2511,7 +2511,7 @@ bool needsReturnBarrier(MyThread* t, object method) { return (methodFlags(t, method) & ConstructorFlag) - and (classFlags(t, methodClass(t, method)) & HasFinalMemberFlag); + and (classVmFlags(t, methodClass(t, method)) & HasFinalMemberFlag); } bool @@ -3746,7 +3746,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, if (singletonIsObject(t, pool, index - 1)) { object v = singletonObject(t, pool, index - 1); if (objectClass(t, v) - == arrayBody(t, t->m->types, Machine::ByteArrayType)) + == arrayBody(t, t->m->types, Machine::ReferenceType)) { object class_ = resolveClassInPool(t, context->method, index - 1); if (UNLIKELY(t->exception)) return; @@ -6444,10 +6444,10 @@ class MyProcessor: public Processor { virtual object makeClass(vm::Thread* t, uint16_t flags, - uint8_t vmFlags, - uint8_t arrayDimensions, + uint16_t vmFlags, uint16_t fixedSize, - uint16_t arrayElementSize, + uint8_t arrayElementSize, + uint8_t arrayDimensions, object objectMask, object name, object super, @@ -6460,7 +6460,7 @@ class MyProcessor: public Processor { unsigned vtableLength) { return vm::makeClass - (t, flags, vmFlags, arrayDimensions, fixedSize, arrayElementSize, + (t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions, objectMask, name, super, interfaceTable, virtualTable, fieldTable, methodTable, staticTable, loader, vtableLength); } diff --git a/src/interpret.cpp b/src/interpret.cpp index 614a24d60c..19a8981163 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -2246,7 +2246,7 @@ interpret(Thread* t) if (singletonIsObject(t, pool, index - 1)) { object v = singletonObject(t, pool, index - 1); if (objectClass(t, v) - == arrayBody(t, t->m->types, Machine::ByteArrayType)) + == arrayBody(t, t->m->types, Machine::ReferenceType)) { object class_ = resolveClassInPool(t, pool, index - 1); if (UNLIKELY(exception)) goto throw_; @@ -2724,7 +2724,7 @@ interpret(Thread* t) case return_: { object method = frameMethod(t, frame); if ((methodFlags(t, method) & ConstructorFlag) - and (classFlags(t, methodClass(t, method)) & HasFinalMemberFlag)) + and (classVmFlags(t, methodClass(t, method)) & HasFinalMemberFlag)) { storeStoreMemoryBarrier(); } @@ -3100,10 +3100,10 @@ class MyProcessor: public Processor { virtual object makeClass(vm::Thread* t, uint16_t flags, - uint8_t vmFlags, - uint8_t arrayDimensions, + uint16_t vmFlags, uint16_t fixedSize, - uint16_t arrayElementSize, + uint8_t arrayElementSize, + uint8_t arrayDimensions, object objectMask, object name, object super, @@ -3116,7 +3116,7 @@ class MyProcessor: public Processor { unsigned vtableLength UNUSED) { return vm::makeClass - (t, flags, vmFlags, arrayDimensions, fixedSize, arrayElementSize, + (t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions, objectMask, name, super, interfaceTable, virtualTable, fieldTable, methodTable, staticTable, loader, 0); } diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 8be23a8640..7bda0458ad 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -77,6 +77,7 @@ DetachCurrentThread(Machine* m) { Thread* t = static_cast(m->localThread->get()); if (t) { + m->localThread->set(0); t->exit(); return 0; } else { diff --git a/src/machine.cpp b/src/machine.cpp index 53a134393c..122c3c77ad 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -542,6 +542,50 @@ makeByteArray(Thread* t, const char* format, va_list a) return s; } +unsigned +resolveSpec(Thread* t, object loader, object spec, unsigned offset) +{ + int8_t* s = &byteArrayBody(t, spec, offset); + unsigned result; + switch (*s) { + case 'L': + ++ offset; + while (*s and *s != ';') ++ s; + result = s + 1 - &byteArrayBody(t, spec, 0); + break; + + case '[': + while (*s == '[') ++ s; + switch (*s) { + case 'L': + while (*s and *s != ';') ++ s; + ++ s; + break; + + default: + ++ s; + break; + } + result = s - &byteArrayBody(t, spec, 0); + break; + + default: + return offset + 1; + } + + PROTECT(t, spec); + + unsigned length = s - &byteArrayBody(t, spec, offset); + + object name = makeByteArray(t, length + 1); + memcpy(&byteArrayBody(t, name, 0), + &byteArrayBody(t, spec, offset), + length); + resolveClass(t, loader, name); + + return result; +} + unsigned readByte(Stream& s, unsigned* value) { @@ -706,7 +750,7 @@ parsePoolEntry(Thread* t, Stream& s, uint32_t* index, object pool, unsigned i) unsigned si = s.read2() - 1; parsePoolEntry(t, s, index, pool, si); - object value = singletonObject(t, pool, si); + object value = makeReference(t, 0, singletonObject(t, pool, si), 0); set(t, pool, SingletonBody + (i * BytesPerWord), value); } } return 1; @@ -749,7 +793,7 @@ parsePoolEntry(Thread* t, Stream& s, uint32_t* index, object pool, unsigned i) parsePoolEntry(t, s, index, pool, ci); parsePoolEntry(t, s, index, pool, nti); - object class_ = singletonObject(t, pool, ci); + object class_ = referenceName(t, singletonObject(t, pool, ci)); object nameAndType = singletonObject(t, pool, nti); object value = makeReference (t, class_, pairFirst(t, nameAndType), pairSecond(t, nameAndType)); @@ -861,7 +905,7 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool) unsigned count = s.read2(); for (unsigned i = 0; i < count; ++i) { - object name = singletonObject(t, pool, s.read2() - 1); + object name = referenceName(t, singletonObject(t, pool, s.read2() - 1)); PROTECT(t, name); object interface = resolveClass(t, classLoader(t, class_), name); @@ -983,7 +1027,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) staticTypes[staticCount++] = code; } else { if (flags & ACC_FINAL) { - classFlags(t, class_) |= HasFinalMemberFlag; + classVmFlags(t, class_) |= HasFinalMemberFlag; } unsigned excess = (memberOffset % fieldSize(t, code)) % BytesPerWord; @@ -1565,9 +1609,9 @@ makeArrayClass(Thread* t, object loader, unsigned dimensions, object spec, (t, 0, 0, - dimensions, 2 * BytesPerWord, BytesPerWord, + dimensions, classObjectMask(t, arrayBody(t, t->m->types, Machine::ArrayType)), spec, arrayBody(t, t->m->types, Machine::JobjectType), @@ -1704,7 +1748,7 @@ bootClass(Thread* t, Machine::Type type, int superType, uint32_t objectMask, super = (superType >= 0 ? arrayBody(t, t->m->types, superType) : 0); object class_ = t->m->processor->makeClass - (t, 0, BootstrapFlag, 0, fixedSize, arrayElementSize, mask, 0, super, 0, 0, + (t, 0, BootstrapFlag, fixedSize, arrayElementSize, 0, mask, 0, super, 0, 0, 0, 0, 0, t->m->loader, vtableLength); set(t, t->m->types, ArrayBody + (type * BytesPerWord), class_); @@ -1773,10 +1817,10 @@ boot(Thread* t) m->unsafe = false; - classFlags(t, arrayBody(t, m->types, Machine::SingletonType)) + classVmFlags(t, arrayBody(t, m->types, Machine::SingletonType)) |= SingletonFlag; - classFlags(t, arrayBody(t, m->types, Machine::ContinuationType)) + classVmFlags(t, arrayBody(t, m->types, Machine::ContinuationType)) |= ContinuationFlag; classVmFlags(t, arrayBody(t, m->types, Machine::JreferenceType)) @@ -2074,8 +2118,6 @@ Thread::init() m->localThread->set(this); } else { - assert(this, javaThread); - peer = parent->child; parent->child = this; } @@ -2083,11 +2125,16 @@ Thread::init() if (javaThread) { threadPeer(this, javaThread) = reinterpret_cast(this); } else { + object group; + if (parent) { + group = threadGroup(this, parent->javaThread); + } else { + group = makeThreadGroup(this, 0, 0); + } + const unsigned NewState = 0; const unsigned NormalPriority = 5; - object group = makeThreadGroup(this, 0, 0); - this->javaThread = makeThread (this, reinterpret_cast(this), 0, 0, NewState, NormalPriority, 0, 0, 0, m->loader, 0, 0, group); @@ -2663,11 +2710,12 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size) object class_ = makeClass(t, flags, 0, // VM flags - 0, // array dimensions 0, // fixed size 0, // array size + 0, // array dimensions 0, // object mask - singletonObject(t, pool, name - 1), + referenceName + (t, singletonObject(t, pool, name - 1)), 0, // super 0, // interfaces 0, // vtable @@ -2680,7 +2728,8 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size) unsigned super = s.read2(); if (super) { - object sc = resolveClass(t, loader, singletonObject(t, pool, super - 1)); + object sc = resolveClass + (t, loader, referenceName(t, singletonObject(t, pool, super - 1))); if (UNLIKELY(t->exception)) return 0; set(t, class_, ClassSuper, sc); @@ -2706,9 +2755,9 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size) (t, classFlags(t, class_), classVmFlags(t, class_), - classArrayDimensions(t, class_), classFixedSize(t, class_), classArrayElementSize(t, class_), + classArrayDimensions(t, class_), classObjectMask(t, class_), className(t, class_), classSuper(t, class_), @@ -2867,6 +2916,95 @@ resolveClass(Thread* t, object loader, object spec) } } +void +linkClass(Thread* t, object loader, object class_) +{ + PROTECT(t, loader); + PROTECT(t, class_); + + ACQUIRE(t, t->m->classLock); + + if ((classVmFlags(t, class_) & LinkFlag) == 0) { + if (classSuper(t, class_)) { + linkClass(t, loader, classSuper(t, class_)); + } + + if (classInterfaceTable(t, class_)) { + unsigned increment = 2; + if (classFlags(t, class_) & ACC_INTERFACE) { + increment = 1; + } + + for (unsigned i = 0; i < arrayLength(t, classInterfaceTable(t, class_)); + i += increment) + { + linkClass(t, loader, arrayBody(t, classInterfaceTable(t, class_), i)); + } + } + + if (classMethodTable(t, class_)) { + bool resolvedPool = false; + for (unsigned i = 0; + i < arrayLength(t, classMethodTable(t, class_)); ++i) + { + object method = arrayBody(t, classMethodTable(t, class_), i); + PROTECT(t, method); + + object code = methodCode(t, method); + if ((not resolvedPool) + and code + and codePool(t, code) + and objectClass(t, codePool(t, code)) + == arrayBody(t, t->m->types, Machine::SingletonType)) + { + object pool = codePool(t, code); + PROTECT(t, pool); + unsigned count = singletonCount(t, pool); + for (unsigned j = 0; j < count; ++j) { + if (singletonIsObject(t, pool, j)) { + object entry = singletonObject(t, pool, j); + if (objectClass(t, entry) + == arrayBody(t, t->m->types, Machine::ReferenceType)) + { + if (referenceSpec(t, entry) == 0) { + resolveClassInPool(t, loader, method, j); + } else if (byteArrayBody(t, referenceSpec(t, entry), 0) == '(') + { + resolveMethod(t, loader, method, j); + } else { + resolveField(t, loader, method, j); + } + + if (UNLIKELY(t->exception)) return; + } + } + } + + resolvedPool = true; + } + + object spec = methodSpec(t, method); + PROTECT(t, spec); + for (unsigned j = 1; j < byteArrayLength(t, spec);) { + j = resolveSpec(t, loader, spec, j); + if (UNLIKELY(t->exception)) return; + } + } + } + + if (classFieldTable(t, class_)) { + for (unsigned i = 0; i < arrayLength(t, classFieldTable(t, class_)); ++i) + { + resolveSpec(t, loader, fieldSpec + (t, arrayBody(t, classFieldTable(t, class_), i)), 0); + if (UNLIKELY(t->exception)) return; + } + } + + classVmFlags(t, class_) |= LinkFlag; + } +} + object resolveMethod(Thread* t, object class_, const char* methodName, const char* methodSpec) @@ -3286,7 +3424,7 @@ walk(Thread* t, Heap::Walker* w, object o, unsigned start) intArrayLength(t, objectMask) * 4); more = ::walk(t, w, mask, fixedSize, arrayElementSize, arrayLength, start); - } else if (classFlags(t, class_) & SingletonFlag) { + } else if (classVmFlags(t, class_) & SingletonFlag) { unsigned length = singletonLength(t, o); if (length) { more = ::walk(t, w, singletonMask(t, o), @@ -3298,7 +3436,7 @@ walk(Thread* t, Heap::Walker* w, object o, unsigned start) more = w->visit(0); } - if (more and classFlags(t, class_) & ContinuationFlag) { + if (more and classVmFlags(t, class_) & ContinuationFlag) { t->m->processor->walkContinuationBody(t, w, o, start); } } diff --git a/src/machine.h b/src/machine.h index 38063626e0..1539b80af0 100644 --- a/src/machine.h +++ b/src/machine.h @@ -74,12 +74,6 @@ enum StackTag { const int NativeLine = -1; const int UnknownLine = -2; -// class flags (note that we must be careful not to overlap the -// standard ACC_* flags): -const unsigned HasFinalMemberFlag = 1 << 13; -const unsigned SingletonFlag = 1 << 14; -const unsigned ContinuationFlag = 1 << 15; - // class vmFlags: const unsigned ReferenceFlag = 1 << 0; const unsigned WeakReferenceFlag = 1 << 1; @@ -89,6 +83,10 @@ const unsigned InitErrorFlag = 1 << 4; const unsigned PrimitiveFlag = 1 << 5; const unsigned BootstrapFlag = 1 << 6; const unsigned HasFinalizerFlag = 1 << 7; +const unsigned LinkFlag = 1 << 8; +const unsigned HasFinalMemberFlag = 1 << 9; +const unsigned SingletonFlag = 1 << 10; +const unsigned ContinuationFlag = 1 << 11; // method vmFlags: const unsigned ClassInitFlag = 1 << 0; @@ -1816,6 +1814,7 @@ makeNew(Thread* t, object class_) PROTECT(t, class_); unsigned sizeInBytes = pad(classFixedSize(t, class_)); + assert(t, sizeInBytes); object instance = allocate(t, sizeInBytes, classObjectMask(t, class_)); setObjectClass(t, instance, class_); @@ -2103,6 +2102,9 @@ resolveSystemClass(Thread* t, const char* name) return resolveSystemClass(t, makeByteArray(t, "%s", name)); } +void +linkClass(Thread* t, object loader, object class_); + object resolveMethod(Thread* t, object class_, const char* methodName, const char* methodSpec); @@ -2444,6 +2446,101 @@ makeSingletonOfSize(Thread* t, unsigned count) return o; } +inline object +resolveClassInObject(Thread* t, object loader, object container, + unsigned classOffset) +{ + object o = cast(container, classOffset); + if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) { + PROTECT(t, container); + + o = resolveClass(t, loader, o); + if (UNLIKELY(t->exception)) return 0; + + set(t, container, classOffset, o); + } + return o; +} + +inline object +resolveClassInPool(Thread* t, object loader, object method, unsigned index) +{ + object o = singletonObject(t, codePool(t, methodCode(t, method)), index); + if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType)) { + PROTECT(t, method); + + o = resolveClass(t, loader, referenceName(t, o)); + if (UNLIKELY(t->exception)) return 0; + + set(t, codePool(t, methodCode(t, method)), + SingletonBody + (index * BytesPerWord), o); + } + return o; +} + +inline object +resolveClassInPool(Thread* t, object method, unsigned index) +{ + return resolveClassInPool(t, classLoader(t, methodClass(t, method)), + method, index); +} + +inline object +resolve(Thread* t, object loader, object method, unsigned index, + object (*find)(vm::Thread*, object, object, object), + object (*makeError)(vm::Thread*, object)) +{ + object o = singletonObject(t, codePool(t, methodCode(t, method)), index); + if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType)) + { + PROTECT(t, method); + + object reference = o; + PROTECT(t, reference); + + object class_ = resolveClassInObject(t, loader, o, ReferenceClass); + if (UNLIKELY(t->exception)) return 0; + + o = findInHierarchy + (t, class_, referenceName(t, reference), referenceSpec(t, reference), + find, makeError); + if (UNLIKELY(t->exception)) return 0; + + set(t, codePool(t, methodCode(t, method)), + SingletonBody + (index * BytesPerWord), o); + } + + return o; +} + +inline object +resolveField(Thread* t, object loader, object method, unsigned index) +{ + return resolve(t, loader, method, index, findFieldInClass, + makeNoSuchFieldError); +} + +inline object +resolveField(Thread* t, object method, unsigned index) +{ + return resolveField + (t, classLoader(t, methodClass(t, method)), method, index); +} + +inline object +resolveMethod(Thread* t, object loader, object method, unsigned index) +{ + return resolve(t, loader, method, index, findMethodInClass, + makeNoSuchMethodError); +} + +inline object +resolveMethod(Thread* t, object method, unsigned index) +{ + return resolveMethod + (t, classLoader(t, methodClass(t, method)), method, index); +} + void dumpHeap(Thread* t, FILE* out); diff --git a/src/posix.cpp b/src/posix.cpp index 48096dac52..5f2fbf11c4 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -129,7 +129,7 @@ class MySystem: public System { virtual void join() { int rv UNUSED = pthread_join(thread, 0); - expect(s, rv == 0); + //expect(s, rv == 0); } virtual void dispose() { diff --git a/src/process.h b/src/process.h index bc7b987ad8..97e6e88450 100644 --- a/src/process.h +++ b/src/process.h @@ -36,79 +36,6 @@ codeReadInt32(Thread* t, object code, unsigned& ip) return ((v1 << 24) | (v2 << 16) | (v3 << 8) | v4); } -inline object -resolveClassInObject(Thread* t, object loader, object container, - unsigned classOffset) -{ - object o = cast(container, classOffset); - if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) { - PROTECT(t, container); - - o = resolveClass(t, loader, o); - if (UNLIKELY(t->exception)) return 0; - - set(t, container, classOffset, o); - } - return o; -} - -inline object -resolveClassInPool(Thread* t, object method, unsigned index) -{ - object o = singletonObject(t, codePool(t, methodCode(t, method)), index); - if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) { - PROTECT(t, method); - - o = resolveClass(t, classLoader(t, methodClass(t, method)), o); - if (UNLIKELY(t->exception)) return 0; - - set(t, codePool(t, methodCode(t, method)), - SingletonBody + (index * BytesPerWord), o); - } - return o; -} - -inline object -resolve(Thread* t, object method, unsigned index, - object (*find)(vm::Thread*, object, object, object), - object (*makeError)(vm::Thread*, object)) -{ - object o = singletonObject(t, codePool(t, methodCode(t, method)), index); - if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType)) - { - PROTECT(t, method); - - object reference = o; - PROTECT(t, reference); - - object class_ = resolveClassInObject - (t, classLoader(t, methodClass(t, method)), o, ReferenceClass); - if (UNLIKELY(t->exception)) return 0; - - o = findInHierarchy - (t, class_, referenceName(t, reference), referenceSpec(t, reference), - find, makeError); - if (UNLIKELY(t->exception)) return 0; - - set(t, codePool(t, methodCode(t, method)), - SingletonBody + (index * BytesPerWord), o); - } - - return o; -} - -inline object -resolveField(Thread* t, object method, unsigned index) -{ - return resolve(t, method, index, findFieldInClass, makeNoSuchFieldError); -} - -inline object -resolveMethod(Thread* t, object method, unsigned index) -{ - return resolve(t, method, index, findMethodInClass, makeNoSuchMethodError); -} - inline bool isSuperclass(Thread* t, object class_, object base) { diff --git a/src/processor.h b/src/processor.h index f7de71b425..dddf9006f5 100644 --- a/src/processor.h +++ b/src/processor.h @@ -60,10 +60,10 @@ class Processor { virtual object makeClass(Thread* t, uint16_t flags, - uint8_t vmFlags, - uint8_t arrayDimensions, + uint16_t vmFlags, uint16_t fixedSize, - uint16_t arrayElementSize, + uint8_t arrayElementSize, + uint8_t arrayDimensions, object objectMask, object name, object super,