From 823d76499850ae2104aeddae63a9127a851a1b8d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 23 Jul 2007 21:16:59 -0600 Subject: [PATCH] working reflection --- classpath/java/lang/String.java | 3 +- classpath/java/lang/reflect/Method.java | 11 +++- src/builtin.cpp | 36 ++++++++---- src/constants.h | 6 +- src/machine.cpp | 49 +++++++++++++++- src/machine.h | 5 +- src/run.cpp | 78 ++++++++----------------- src/types.def | 8 +-- 8 files changed, 116 insertions(+), 80 deletions(-) diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index d7218911d2..c913f27ef9 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -101,7 +101,8 @@ public final class String implements Comparable { return new String(data, offset + start, end - start, false); } } else { - throw new IndexOutOfBoundsException(); + throw new IndexOutOfBoundsException + (start + " not in (0, " + end + ") or " + end + " > " + length); } } diff --git a/classpath/java/lang/reflect/Method.java b/classpath/java/lang/reflect/Method.java index 9dc14bba71..84831c01b6 100644 --- a/classpath/java/lang/reflect/Method.java +++ b/classpath/java/lang/reflect/Method.java @@ -53,15 +53,20 @@ public class Method extends AccessibleObject implements Member { for (int i = 0; i < spec.length(); ++i) { char c = spec.charAt(i); - if (c == 'L') { - String name = spec.substring(i + 1, next(';', spec, i + 1)); + if (c == ')') { + break; + } else if (c == 'L') { + int start = i + 1; + i = next(';', spec, start); + String name = spec.substring(start, i); types[index++] = Class.forName(name); } else if (c == '[') { int start = i; while (spec.charAt(i) == '[') ++i; if (spec.charAt(i) == 'L') { - String name = spec.substring(start, next(';', spec, i + 1)); + i = next(';', spec, i + 1); + String name = spec.substring(start, i); types[index++] = Class.forName(name); } else { String name = spec.substring(start, i + 1); diff --git a/src/builtin.cpp b/src/builtin.cpp index 3ec5b00896..27a5cc4e0b 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -169,23 +169,29 @@ get(Thread* t, jobject this_, jobject instancep) } jobject -invoke(Thread* t, jobject this_, jobject instance, jobjectArray arguments) +invoke(Thread* t, jobject this_, jobject instancep, jobjectArray argumentsp) { object method = *this_; - if (arguments) { + if (argumentsp) { + object arguments = *argumentsp; + if (methodFlags(t, method) & ACC_STATIC) { - if (objectArrayLength(t, arguments) == methodParameterCount(t, method)) { - return pushReference(t, doInvoke(t, method, 0, *arguments)); + if (objectArrayLength(t, arguments) + == methodParameterCount(t, method)) + { + return pushReference(t, doInvoke(t, method, 0, arguments)); } else { t->exception = makeArrayIndexOutOfBoundsException(t, 0); } - } else if (instance) { + } else if (instancep) { + object instance = *instancep; + if (instanceOf(t, methodClass(t, method), instance)) { if (objectArrayLength(t, arguments) == static_cast(methodParameterCount(t, method) - 1)) { - return pushReference(t, doInvoke(t, method, *instance, *arguments)); + return pushReference(t, doInvoke(t, method, instance, arguments)); } else { t->exception = makeArrayIndexOutOfBoundsException(t, 0); } @@ -382,6 +388,10 @@ start(Thread* t, jobject this_) vm::run(t, "java/lang/Thread", "run", "()V", t->javaThread); + if (t->exception) { + printTrace(t, t->exception); + } + t->exit(); } @@ -412,12 +422,8 @@ populate(Thread* t, object map) } builtins[] = { { "Java_java_lang_Class_forName", reinterpret_cast(forName) }, - - { "Java_java_lang_Field_get", - reinterpret_cast(get) }, - - { "Java_java_lang_Method_invoke", - reinterpret_cast(invoke) }, + { "Java_java_lang_Class_isAssignableFrom", + reinterpret_cast(isAssignableFrom) }, { "Java_java_lang_System_arraycopy", reinterpret_cast(arraycopy) }, @@ -452,6 +458,12 @@ populate(Thread* t, object map) { "Java_java_lang_Object_wait", reinterpret_cast(wait) }, + { "Java_java_lang_reflect_Field_get", + reinterpret_cast(get) }, + + { "Java_java_lang_reflect_Method_invoke", + reinterpret_cast(invoke) }, + { 0, 0 } }; diff --git a/src/constants.h b/src/constants.h index e381b2dc09..4f571d0ec1 100644 --- a/src/constants.h +++ b/src/constants.h @@ -99,7 +99,7 @@ enum OpCode { i2s = 0x93, iadd = 0x60, iaload = 0x2e, - iand = 0x73, + iand = 0x7e, iastore = 0x4f, iconst_m1 = 0x02, iconst_0 = 0x03, @@ -113,9 +113,9 @@ enum OpCode { if_acmpne = 0xa6, if_icmpeq = 0x9f, if_icmpne = 0xa0, - if_icmpgt = 0xa1, + if_icmplt = 0xa1, if_icmpge = 0xa2, - if_icmplt = 0xa3, + if_icmpgt = 0xa3, if_icmple = 0xa4, ifeq = 0x99, ifge = 0x9c, diff --git a/src/machine.cpp b/src/machine.cpp index 8f70187e47..856594b89e 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1653,9 +1653,9 @@ instanceOf(Thread* t, object class_, object o) { if (o == 0) { return false; + } else { + return isAssignableFrom(t, class_, objectClass(t, o)); } - - return isAssignableFrom(t, class_, objectClass(t, o)); } unsigned @@ -2346,6 +2346,51 @@ collect(Thread* t, Heap::CollectionType type) killZombies(t, m->rootThread); } +void +printTrace(Thread* t, object exception) +{ + for (object e = exception; e; e = throwableCauseUnsafe(t, e)) { + if (e != exception) { + fprintf(stderr, "caused by: "); + } + + fprintf(stderr, "%s", &byteArrayBody + (t, className(t, objectClass(t, e)), 0)); + + if (throwableMessageUnsafe(t, e)) { + object m = throwableMessageUnsafe(t, e); + char message[stringLength(t, m) + 1]; + stringChars(t, m, message); + fprintf(stderr, ": %s\n", message); + } else { + fprintf(stderr, "\n"); + } + + object trace = throwableTraceUnsafe(t, e); + for (unsigned i = 0; i < arrayLength(t, trace); ++i) { + object e = arrayBody(t, trace, i); + const int8_t* class_ = &byteArrayBody + (t, className(t, methodClass(t, traceElementMethod(t, e))), 0); + const int8_t* method = &byteArrayBody + (t, methodName(t, traceElementMethod(t, e)), 0); + int line = lineNumber(t, traceElementMethod(t, e), traceElementIp(t, e)); + + fprintf(stderr, " at %s.%s ", class_, method); + + switch (line) { + case NativeLine: + fprintf(stderr, "(native)\n"); + break; + case UnknownLine: + fprintf(stderr, "(unknown line)\n"); + break; + default: + fprintf(stderr, "(line %d)\n", line); + } + } + } +} + void noop() { } diff --git a/src/machine.h b/src/machine.h index baddb5788a..49018fdac5 100644 --- a/src/machine.h +++ b/src/machine.h @@ -22,7 +22,7 @@ namespace vm { const bool Verbose = false; -const bool DebugRun = true; +const bool DebugRun = false; const bool DebugStack = false; const bool DebugMonitors = false; @@ -2079,6 +2079,9 @@ vmNotifyAll(Thread* t, object o) notifyAll(t, o); } +void +printTrace(Thread* t, object exception); + void exit(Thread* t); diff --git a/src/run.cpp b/src/run.cpp index 9826db0f1a..f8d4e11432 100644 --- a/src/run.cpp +++ b/src/run.cpp @@ -91,8 +91,7 @@ make(Thread* t, object class_) ACQUIRE(t, t->vm->referenceLock); - // jreferenceNext(t, instance) - cast(instance, BytesPerWord) = t->vm->weakReferences; + jreferenceNextUnsafe(t, instance) = t->vm->weakReferences; t->vm->weakReferences = instance; } @@ -301,6 +300,16 @@ makeNativeMethodData(Thread* t, object method, void* function, bool builtin) case '[': argumentTableSize += BytesPerWord; while (*s == '[') ++ s; + switch (*s) { + case 'L': + while (*s and *s != ';') ++ s; + ++ s; + break; + + default: + ++ s; + break; + } break; default: @@ -1601,16 +1610,16 @@ run(Thread* t) if (objectClass(t, v) == arrayBody(t, t->vm->types, Machine::IntType)) { pushInt(t, intValue(t, v)); - } else if (objectClass(t, v) - == arrayBody(t, t->vm->types, Machine::StringType)) - { - pushObject(t, v); } else if (objectClass(t, v) == arrayBody(t, t->vm->types, Machine::FloatType)) { pushInt(t, floatValue(t, v)); + } else if (objectClass(t, v) + == arrayBody(t, t->vm->types, Machine::StringType)) + { + pushObject(t, v); } else { - abort(t); + pushObject(t, resolveClass(t, v)); } } goto loop; @@ -2123,7 +2132,7 @@ run(Thread* t) pokeInt(t, t->frame + FrameIpOffset, t->ip); for (; frame >= 0; frame = frameNext(t, frame)) { - if (methodFlags(t, frameMethod(t, frame)) & ACC_NATIVE) { + if (frame <= base) { return 0; } @@ -2160,49 +2169,6 @@ run(Thread* t) } } - for (object e = exception; e; e = throwableCause(t, e)) { - if (e == exception) { - fprintf(stderr, "uncaught exception: "); - } else { - fprintf(stderr, "caused by: "); - } - - fprintf(stderr, "%s", &byteArrayBody - (t, className(t, objectClass(t, exception)), 0)); - - if (throwableMessage(t, exception)) { - object m = throwableMessage(t, exception); - char message[stringLength(t, m) + 1]; - stringChars(t, m, message); - fprintf(stderr, ": %s\n", message); - } else { - fprintf(stderr, "\n"); - } - - object trace = throwableTrace(t, e); - for (unsigned i = 0; i < arrayLength(t, trace); ++i) { - object e = arrayBody(t, trace, i); - const int8_t* class_ = &byteArrayBody - (t, className(t, methodClass(t, traceElementMethod(t, e))), 0); - const int8_t* method = &byteArrayBody - (t, methodName(t, traceElementMethod(t, e)), 0); - int line = lineNumber(t, traceElementMethod(t, e), traceElementIp(t, e)); - - fprintf(stderr, " at %s.%s ", class_, method); - - switch (line) { - case NativeLine: - fprintf(stderr, "(native)\n"); - break; - case UnknownLine: - fprintf(stderr, "(unknown line)\n"); - break; - default: - fprintf(stderr, "(line %d)\n", line); - } - } - } - return 0; } @@ -2354,8 +2320,9 @@ invoke(Thread* t, object method) if (LIKELY(t->exception == 0)) { pushFrame(t, method); result = ::run(t); - popFrame(t); - + if (LIKELY(t->exception == 0)) { + popFrame(t); + } } } @@ -2469,7 +2436,10 @@ run(System* system, Heap* heap, ClassFinder* classFinder, ::run(t, className, argc, argv); int exitCode = 0; - if (t->exception) exitCode = -1; + if (t->exception) { + exitCode = -1; + printTrace(t, t->exception); + } exit(t); diff --git a/src/types.def b/src/types.def index 0a62a974e6..155eb4c704 100644 --- a/src/types.def +++ b/src/types.def @@ -139,9 +139,9 @@ (type throwable java/lang/Throwable (extends jobject) - (object message) - (object trace) - (object cause)) + (noassert object message) + (noassert object trace) + (noassert object cause)) (type exception java/lang/Exception (extends throwable)) @@ -237,7 +237,7 @@ (type jreference java/lang/ref/Reference (extends jobject) - (void* next) + (noassert void* next) (void* target) (void* queue) (object jnext))