diff --git a/makefile b/makefile index 16f0bda40c..a8e418a08e 100644 --- a/makefile +++ b/makefile @@ -28,7 +28,7 @@ src = src classpath = classpath test = test -input = $(test-build)/Misc.class +input = $(test-build)/Reflection.class build-cxx = g++ build-cc = gcc diff --git a/src/interpret.cpp b/src/interpret.cpp index 41a2e16caf..28901b357a 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -2563,7 +2563,7 @@ interpret(Thread* t) unsigned index = ip + ((key - bottom) * 4); ip = base + codeReadInt32(t, code, index); } else { - ip = base + default_; + ip = base + default_; } } goto loop; diff --git a/src/jnienv.cpp b/src/jnienv.cpp index b9bdcf909c..5f5b72accc 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -231,10 +231,10 @@ GetMethodID(Thread* t, jclass c, const char* name, const char* spec) = vectorAppend(t, t->m->jniInterfaceTable, method); return (vectorSize(t, t->m->jniInterfaceTable) - 1) | InterfaceMethodID; - } else if (methodFlags(t, method) & ACC_PRIVATE) { - return methodOffset(t, method) | NonVirtualMethodID; - } else { + } else if (methodVirtual(t, method)) { return methodOffset(t, method) + 1; + } else { + return methodOffset(t, method) | NonVirtualMethodID; } } diff --git a/src/machine.cpp b/src/machine.cpp index 57fc157108..5b8dd4fe9d 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1224,16 +1224,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) compiled); PROTECT(t, method); - if (flags & (ACC_STATIC | ACC_PRIVATE)) { - methodOffset(t, method) = i; - - if (strcmp(reinterpret_cast(""), - &byteArrayBody(t, methodName(t, method), 0)) == 0) - { - methodVmFlags(t, method) |= ClassInitFlag; - classVmFlags(t, class_) |= NeedInitFlag; - } - } else { + if (methodVirtual(t, method)) { ++ declaredVirtualCount; object p = hashMapFindNode @@ -1250,6 +1241,15 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) hashMapInsert(t, virtualMap, method, method, methodHash); } + } else { + methodOffset(t, method) = i; + + if (strcmp(reinterpret_cast(""), + &byteArrayBody(t, methodName(t, method), 0)) == 0) + { + methodVmFlags(t, method) |= ClassInitFlag; + classVmFlags(t, class_) |= NeedInitFlag; + } } if (flags & ACC_NATIVE) { @@ -1371,8 +1371,6 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_) and classObjectMask(t, class_) == 0) or intArrayEqual(t, classObjectMask(t, bootstrapClass), classObjectMask(t, class_))); - expect(t, arrayLength(t, classVirtualTable(t, bootstrapClass)) - == arrayLength(t, classVirtualTable(t, class_))); PROTECT(t, bootstrapClass); PROTECT(t, class_); @@ -1531,27 +1529,33 @@ bootClass(Thread* t, Machine::Type type, int superType, uint32_t objectMask, object super = (superType >= 0 ? arrayBody(t, t->m->types, superType) : 0); object class_ = makeClass - (t, 0, BootstrapFlag, 0, fixedSize, arrayElementSize, mask, 0, super, 0, 0 - , 0, 0, 0, t->m->loader); + (t, 0, BootstrapFlag, 0, fixedSize, arrayElementSize, mask, 0, super, 0, 0, + 0, 0, 0, t->m->loader); set(t, t->m->types, ArrayBody + (type * BytesPerWord), class_); } void -bootJavaClass(Thread* t, Machine::Type type, const char* name, - unsigned vtableLength, object bootMethod) +bootJavaClass(Thread* t, Machine::Type type, int superType, const char* name, + int vtableLength, object bootMethod) { PROTECT(t, bootMethod); object n = makeByteArray(t, name); object class_ = arrayBody(t, t->m->types, type); - PROTECT(t, class_); set(t, class_, ClassName, n); - object vtable = makeArray(t, vtableLength, false); - for (unsigned i = 0; i < vtableLength; ++ i) { - arrayBody(t, vtable, i) = bootMethod; + object vtable; + if (vtableLength >= 0) { + PROTECT(t, class_); + + vtable = makeArray(t, vtableLength, false); + for (int i = 0; i < vtableLength; ++ i) { + arrayBody(t, vtable, i) = bootMethod; + } + } else { + vtable = classVirtualTable(t, arrayBody(t, t->m->types, superType)); } set(t, class_, ClassVirtualTable, vtable); @@ -2122,9 +2126,9 @@ stringChars(Thread* t, object string, char* chars) bool isAssignableFrom(Thread* t, object a, object b) { - if (a == b) { - return true; - } else if (classFlags(t, a) & ACC_INTERFACE) { + if (a == b) return true; + + if (classFlags(t, a) & ACC_INTERFACE) { if (classVmFlags(t, b) & BootstrapFlag) { resolveClass(t, className(t, b)); } diff --git a/src/machine.h b/src/machine.h index 37861d085c..f6bbb6181a 100644 --- a/src/machine.h +++ b/src/machine.h @@ -6,6 +6,7 @@ #include "heap.h" #include "finder.h" #include "processor.h" +#include "constants.h" #ifdef __MINGW32__ # define JNICALL __stdcall @@ -2180,6 +2181,13 @@ disposeLocalReference(Thread* t, jobject r) t->m->processor->disposeLocalReference(t, r); } +inline bool +methodVirtual(Thread* t, object method) +{ + return (methodFlags(t, method) & (ACC_STATIC | ACC_PRIVATE)) == 0 + and byteArrayBody(t, methodName(t, method), 0) != '<'; +} + } // namespace vm #endif//MACHINE_H diff --git a/src/process.h b/src/process.h index 6cc2ef3636..3f0c96355a 100644 --- a/src/process.h +++ b/src/process.h @@ -124,12 +124,6 @@ findMethod(Thread* t, object method, object class_) methodOffset(t, method)); } -inline bool -methodVirtual(Thread* t, object method) -{ - return (methodFlags(t, method) & (ACC_STATIC | ACC_PRIVATE)) == 0; -} - inline void* resolveNativeMethod(Thread* t, object method) { @@ -168,6 +162,8 @@ resolveNativeMethod(Thread* t, object method) inline object findInterfaceMethod(Thread* t, object method, object class_) { + assert(t, (classVmFlags(t, class_) & BootstrapFlag) == 0); + object interface = methodClass(t, method); object itable = classInterfaceTable(t, class_); for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { diff --git a/src/type-generator.cpp b/src/type-generator.cpp index 928d837896..83349e57b1 100644 --- a/src/type-generator.cpp +++ b/src/type-generator.cpp @@ -579,6 +579,7 @@ class Type : public Object { List members; List methods; bool hideConstructor; + bool overridesMethods; static Type* make(Object::ObjectType type, const char* name, const char* javaName) @@ -591,6 +592,7 @@ class Type : public Object { o->members.first = o->members.last = 0; o->methods.first = o->methods.last = 0; o->hideConstructor = false; + o->overridesMethods = false; return o; } }; @@ -643,6 +645,18 @@ typeMethods(Object* o) } } +bool& +typeOverridesMethods(Object* o) +{ + switch (o->type) { + case Object::Type: + return static_cast(o)->overridesMethods; + + default: + UNREACHABLE; + } +} + void addMember(Object* o, Object* member) { @@ -1295,12 +1309,6 @@ parseJavaClass(Object* type, Stream* s, Object* declarations) unsigned interfaceCount = s->read2(); s->skip(interfaceCount * 2); -// for (unsigned i = 0; i < interfaceCount; ++i) { -// const char* name = reinterpret_cast -// (pool[pool[s->read2() - 1] - 1]); - -// fprintf(stderr, "%s implements %s\n", typeJavaName(type), name); -// } unsigned fieldCount = s->read2(); for (unsigned i = 0; i < fieldCount; ++i) { @@ -1357,12 +1365,13 @@ parseJavaClass(Object* type, Stream* s, Object* declarations) s->skip(s->read4()); } - if ((flags & (ACC_STATIC | ACC_PRIVATE)) == 0) { - const char* name = reinterpret_cast(pool[nameIndex - 1]); - const char* spec = reinterpret_cast(pool[specIndex - 1]); + const char* name = reinterpret_cast(pool[nameIndex - 1]); + const char* spec = reinterpret_cast(pool[specIndex - 1]); + if ((flags & (ACC_STATIC | ACC_PRIVATE)) == 0 and *name != '<') { Object* method = Method::make(type, name, spec); addMethod(type, method); + typeOverridesMethods(type) = true; } } } @@ -2160,12 +2169,25 @@ writeJavaInitialization(Output* out, Object* type) { out->write("bootJavaClass(t, Machine::"); out->write(capitalize(typeName(type))); - out->write("Type, \""); + out->write("Type, "); + + if (typeSuper(type)) { + out->write("Machine::"); + out->write(capitalize(typeName(typeSuper(type)))); + out->write("Type"); + } else { + out->write("-1"); + } + out->write(", \""); out->write(typeJavaName(type)); out->write("\", "); - out->write(methodCount(type)); + if (typeOverridesMethods(type)) { + out->write(methodCount(type)); + } else { + out->write("-1"); + } out->write(", bootMethod);\n"); } diff --git a/test/Misc.java b/test/Misc.java index 2c584ce254..3321647f20 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -14,11 +14,9 @@ public class Misc { return s; } - public static void main(String[] args) throws Exception { + public static void main(String[] args) { boolean v = Boolean.valueOf("true"); - ClassLoader.getSystemClassLoader().toString(); - int a = 2; int b = 2; int c = a + b;