From 94e9bd0fd27a48d09f931e0d946e52285f9de808 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 4 Nov 2007 14:15:28 -0700 Subject: [PATCH] clean up bootstrap type generation to eliminate redundancy (broken) --- classpath/java/lang/ArrayStoreException.java | 11 + classpath/java/lang/Boolean.java | 1 + .../lang/ExceptionInInitializerError.java | 11 + .../lang/IllegalMonitorStateException.java | 11 + classpath/java/lang/NoSuchMethodError.java | 11 + classpath/java/lang/StackOverflowError.java | 11 + classpath/java/lang/String.java | 8 +- classpath/java/lang/ref/Reference.java | 5 +- classpath/java/lang/ref/ReferenceQueue.java | 8 +- makefile | 13 +- src/input.h | 134 ---- src/interpret.cpp | 6 + src/jnienv.cpp | 11 + src/machine.cpp | 109 ++- src/machine.h | 13 +- src/output.h | 60 -- src/process.h | 3 +- src/type-generator.cpp | 702 ++++++++++++++---- src/types.def | 196 ++--- test/Misc.java | 2 + 20 files changed, 755 insertions(+), 571 deletions(-) create mode 100644 classpath/java/lang/ArrayStoreException.java create mode 100644 classpath/java/lang/ExceptionInInitializerError.java create mode 100644 classpath/java/lang/IllegalMonitorStateException.java create mode 100644 classpath/java/lang/NoSuchMethodError.java create mode 100644 classpath/java/lang/StackOverflowError.java delete mode 100644 src/input.h delete mode 100644 src/output.h diff --git a/classpath/java/lang/ArrayStoreException.java b/classpath/java/lang/ArrayStoreException.java new file mode 100644 index 0000000000..d876941214 --- /dev/null +++ b/classpath/java/lang/ArrayStoreException.java @@ -0,0 +1,11 @@ +package java.lang; + +public class ArrayStoreException extends RuntimeException { + public ArrayStoreException(String message) { + super(message, null); + } + + public ArrayStoreException() { + this(null); + } +} diff --git a/classpath/java/lang/Boolean.java b/classpath/java/lang/Boolean.java index e2b6a10fbf..34ea68ee6a 100644 --- a/classpath/java/lang/Boolean.java +++ b/classpath/java/lang/Boolean.java @@ -21,6 +21,7 @@ public final class Boolean implements Comparable { } public static Boolean valueOf(String s) { + Boolean.TRUE.booleanValue(); return ("true".equals(s) ? Boolean.TRUE : Boolean.FALSE); } diff --git a/classpath/java/lang/ExceptionInInitializerError.java b/classpath/java/lang/ExceptionInInitializerError.java new file mode 100644 index 0000000000..64026efff3 --- /dev/null +++ b/classpath/java/lang/ExceptionInInitializerError.java @@ -0,0 +1,11 @@ +package java.lang; + +public class ExceptionInInitializerError extends Error { + public ExceptionInInitializerError(String message) { + super(message); + } + + public ExceptionInInitializerError() { + super(); + } +} diff --git a/classpath/java/lang/IllegalMonitorStateException.java b/classpath/java/lang/IllegalMonitorStateException.java new file mode 100644 index 0000000000..84f71be13c --- /dev/null +++ b/classpath/java/lang/IllegalMonitorStateException.java @@ -0,0 +1,11 @@ +package java.lang; + +public class IllegalMonitorStateException extends RuntimeException { + public IllegalMonitorStateException(String message) { + super(message, null); + } + + public IllegalMonitorStateException() { + this(null); + } +} diff --git a/classpath/java/lang/NoSuchMethodError.java b/classpath/java/lang/NoSuchMethodError.java new file mode 100644 index 0000000000..43672b513d --- /dev/null +++ b/classpath/java/lang/NoSuchMethodError.java @@ -0,0 +1,11 @@ +package java.lang; + +public class NoSuchMethodError extends IncompatibleClassChangeError { + public NoSuchMethodError(String message) { + super(message); + } + + public NoSuchMethodError() { + super(); + } +} diff --git a/classpath/java/lang/StackOverflowError.java b/classpath/java/lang/StackOverflowError.java new file mode 100644 index 0000000000..cedd18bcaa --- /dev/null +++ b/classpath/java/lang/StackOverflowError.java @@ -0,0 +1,11 @@ +package java.lang; + +public class StackOverflowError extends Error { + public StackOverflowError(String message) { + super(message, null); + } + + public StackOverflowError() { + this(null); + } +} diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index 921522a34e..340c591b87 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -4,7 +4,7 @@ public final class String implements Comparable { private Object data; private int offset; private int length; - private int hash; + private int hashCode; public String(char[] data, int offset, int length, boolean copy) { this((Object) data, offset, length, copy); @@ -70,12 +70,12 @@ public final class String implements Comparable { } public int hashCode() { - if (hash == 0) { + if (hashCode == 0) { int h = 0; for (int i = 0; i < length; ++i) h = (h * 31) + charAt(i); - hash = h; + hashCode = h; } - return hash; + return hashCode; } public boolean equals(Object o) { diff --git a/classpath/java/lang/ref/Reference.java b/classpath/java/lang/ref/Reference.java index b015112c32..35a1b2c83a 100644 --- a/classpath/java/lang/ref/Reference.java +++ b/classpath/java/lang/ref/Reference.java @@ -4,7 +4,8 @@ public abstract class Reference { private Object vmNext; private T target; private ReferenceQueue queue; - Reference next; + + Reference jNext; protected Reference(T target, ReferenceQueue queue) { this.target = target; @@ -20,7 +21,7 @@ public abstract class Reference { } public boolean isEnqueued() { - return next != null; + return jNext != null; } public boolean enqueue() { diff --git a/classpath/java/lang/ref/ReferenceQueue.java b/classpath/java/lang/ref/ReferenceQueue.java index dcf92cd42e..3183882274 100644 --- a/classpath/java/lang/ref/ReferenceQueue.java +++ b/classpath/java/lang/ref/ReferenceQueue.java @@ -7,21 +7,21 @@ public class ReferenceQueue { public Reference poll() { Reference r = front; if (front != null) { - if (front == front.next) { + if (front == front.jNext) { front = rear = null; } else { - front = front.next; + front = front.jNext; } } return r; } void add(Reference r) { - r.next = r; + r.jNext = r; if (front == null) { front = r; } else { - rear.next = r; + rear.jNext = r; } rear = r; } diff --git a/makefile b/makefile index 13bc64155c..a8e418a08e 100644 --- a/makefile +++ b/makefile @@ -28,7 +28,7 @@ src = src classpath = classpath test = test -input = $(test-build)/Hello.class +input = $(test-build)/Reflection.class build-cxx = g++ build-cc = gcc @@ -174,9 +174,7 @@ driver-sources = $(src)/main.cpp driver-object = $(call cpp-objects,$(driver-sources),$(src),$(native-build)) -generator-headers = \ - $(src)/input.h \ - $(src)/output.h +generator-headers = $(src)/constants.h generator-sources = $(src)/type-generator.cpp generator-objects = \ $(call cpp-objects,$(generator-sources),$(src),$(native-build)) @@ -239,10 +237,10 @@ clean-native: rm -rf $(native-build) gen-arg = $(shell echo $(1) | sed -e 's:$(native-build)/type-\(.*\)\.cpp:\1:') -$(generated-code): %.cpp: $(src)/types.def $(generator) +$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep) @echo "generating $(@)" @mkdir -p $(dir $(@)) - $(generator) $(call gen-arg,$(@)) < $(<) > $(@) + $(generator) $(classpath-build) $(call gen-arg,$(@)) < $(<) > $(@) $(native-build)/type-generator.o: \ $(generator-headers) @@ -297,7 +295,8 @@ $(classpath-object): $(build)/classpath.jar $(generator-objects): $(native-build)/%.o: $(src)/%.cpp @echo "compiling $(@)" @mkdir -p $(dir $(@)) - $(build-cxx) -DPOINTER_SIZE=$(pointer-size) $(build-cflags) -c $(<) -o $(@) + $(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \ + -c $(<) -o $(@) $(jni-objects): $(native-build)/%.o: $(classpath)/%.cpp @echo "compiling $(@)" diff --git a/src/input.h b/src/input.h deleted file mode 100644 index 59e3eea719..0000000000 --- a/src/input.h +++ /dev/null @@ -1,134 +0,0 @@ -#include - -#ifndef INPUT_H -#define INPUT_H - -// input ////////////////////////////////////////////////////////////////////// - -class Input { - public: - virtual ~Input() { } - - virtual void dispose() = 0; - - virtual int peek() = 0; - - virtual int read() = 0; - - virtual unsigned line() = 0; - - virtual unsigned column() = 0; - - void skipSpace() { - bool quit = false; - while (not quit) { - int c = peek(); - switch (c) { - case ' ': case '\t': case '\n': - read(); - break; - - default: quit = true; - } - } - } -}; - -// file input ///////////////////////////////////////////////////////////////// - -class FileInput : public Input { - public: - const char* file; - FILE* stream; - unsigned line_; - unsigned column_; - bool close; - - FileInput(const char* file, FILE* stream = 0, bool close = true): - file(file), stream(stream), line_(1), column_(1), close(close) - { } - - virtual ~FileInput() { - dispose(); - } - - virtual void dispose() { - if (stream and close) { - fclose(stream); - stream = 0; - } - } - - virtual int peek() { - int c = getc(stream); - ungetc(c, stream); - return c; - } - - virtual int read() { - int c = getc(stream); - if (c == '\n') { - ++ line_; - column_ = 1; - } else { - ++ column_; - } - return c; - } - - virtual unsigned line() { - return line_; - } - - virtual unsigned column() { - return column_; - } -}; - -// string input /////////////////////////////////////////////////////////////// - -class StringInput : public Input { - public: - const char* string; - unsigned position; - unsigned limit; - unsigned line_; - unsigned column_; - - StringInput(const char* string); - - virtual ~StringInput() { } - - virtual void dispose() { - // do nothing - } - - virtual int peek() { - if (position == limit) return -1; - return string[position]; - } - - virtual int read() { - int c = peek(); - if (c >= 0) { - if (c == '\n') { - ++ line_; - column_ = 1; - } else { - ++ column_; - } - ++ position; - } - return c; - } - - virtual unsigned line() { - return line_; - } - - virtual unsigned column() { - return column_; - } -}; - -#endif//INPUT_H diff --git a/src/interpret.cpp b/src/interpret.cpp index ee5bf22475..41a2e16caf 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -2569,6 +2569,12 @@ interpret(Thread* t) case wide: goto wide; + case impdep1: { + // this means we're invoking a virtual method on an instance of a + // bootstrap class, so we need to load the real class. + abort(t); + } break; + default: abort(t); } diff --git a/src/jnienv.cpp b/src/jnienv.cpp index db1cd6b0d8..b9bdcf909c 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -11,6 +11,9 @@ namespace { const uintptr_t InterfaceMethodID = (static_cast(1) << (BitsPerWord - 1)); +const uintptr_t NonVirtualMethodID += (static_cast(1) << (BitsPerWord - 2)); + jint JNICALL DestroyJavaVM(Machine* m) { @@ -228,6 +231,8 @@ 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 { return methodOffset(t, method) + 1; } @@ -249,6 +254,9 @@ getMethod(Thread* t, object o, jmethodID m) { if (m & InterfaceMethodID) { return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID)); + } else if (m & NonVirtualMethodID) { + return arrayBody(t, classMethodTable(t, objectClass(t, o)), + m & (~NonVirtualMethodID)); } else { return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); } @@ -1890,5 +1898,8 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args) *t = p->makeThread(*m, 0, 0); + enter(*t, Thread::ActiveState); + enter(*t, Thread::IdleState); + return 0; } diff --git a/src/machine.cpp b/src/machine.cpp index 67bc16b860..c4dcc1ff50 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -250,9 +250,9 @@ referenceTargetUnreachable(Thread* t, Heap::Visitor* v, object* p) object q = jreferenceQueue(t, *p); - set(t, *p, JreferenceJnext, *p); + set(t, *p, JreferenceJNext, *p); if (referenceQueueFront(t, q)) { - set(t, referenceQueueRear(t, q), JreferenceJnext, *p); + set(t, referenceQueueRear(t, q), JreferenceJNext, *p); } else { set(t, q, ReferenceQueueFront, *p); } @@ -261,7 +261,7 @@ referenceTargetUnreachable(Thread* t, Heap::Visitor* v, object* p) jreferenceQueue(t, *p) = 0; } - *p = jreferenceNext(t, *p); + *p = jreferenceVmNext(t, *p); } void @@ -278,7 +278,7 @@ referenceUnreachable(Thread* t, Heap::Visitor* v, object* p) // queue is reachable - add the reference referenceTargetUnreachable(t, v, p); } else { - *p = jreferenceNext(t, *p); + *p = jreferenceVmNext(t, *p); } } @@ -373,11 +373,11 @@ postVisit(Thread* t, Heap::Visitor* v) } object reference = *p; - *p = jreferenceNext(t, reference); - jreferenceNext(t, reference) = firstNewTenuredWeakReference; + *p = jreferenceVmNext(t, reference); + jreferenceVmNext(t, reference) = firstNewTenuredWeakReference; firstNewTenuredWeakReference = reference; } else { - p = &jreferenceNext(t, *p); + p = &jreferenceVmNext(t, *p); } } } @@ -408,7 +408,7 @@ postVisit(Thread* t, Heap::Visitor* v) } else { // both reference and target are reachable referenceTargetReachable(t, v, p); - p = &jreferenceNext(t, *p); + p = &jreferenceVmNext(t, *p); } } } @@ -419,7 +419,7 @@ postVisit(Thread* t, Heap::Visitor* v) } if (lastNewTenuredWeakReference) { - jreferenceNext(t, lastNewTenuredWeakReference) = m->tenuredWeakReferences; + jreferenceVmNext(t, lastNewTenuredWeakReference) = m->tenuredWeakReferences; m->tenuredWeakReferences = firstNewTenuredWeakReference; } } @@ -1224,7 +1224,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) compiled); PROTECT(t, method); - if (flags & ACC_STATIC) { + if (flags & (ACC_STATIC | ACC_PRIVATE)) { methodOffset(t, method) = i; if (strcmp(reinterpret_cast(""), @@ -1377,9 +1377,8 @@ updateBootstrapClass(Thread* t, object bootstrapClass, object class_) ENTER(t, Thread::ExclusiveState); + classVmFlags(t, bootstrapClass) = classVmFlags(t, class_); classFlags(t, bootstrapClass) = classFlags(t, class_); - classVmFlags(t, bootstrapClass) - |= (classVmFlags(t, class_) & ~BootstrapFlag); set(t, bootstrapClass, ClassSuper, classSuper(t, class_)); set(t, bootstrapClass, ClassInterfaceTable, classInterfaceTable(t, class_)); @@ -1515,6 +1514,48 @@ invoke(Thread* t, const char* className, int argc, const char** argv) (t, className, "main", "([Ljava/lang/String;)V", 0, args); } +void +bootClass(Thread* t, Machine::Type type, int superType, uint32_t objectMask, + unsigned fixedSize, unsigned arrayElementSize) +{ + object mask; + if (objectMask) { + mask = makeIntArray(t, 1, false); + intArrayBody(t, mask, 0) = objectMask; + } else { + mask = 0; + } + + object super = (superType >= 0 ? arrayBody(t, t->m->types, superType) : 0); + + object class_ = makeClass(t, 0, 0, 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) +{ + 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; + } + + set(t, class_, ClassVirtualTable, vtable); + + hashMapInsert(t, t->m->bootstrapClassMap, n, class_, byteArrayHash); +} + class HeapClient: public Heap::Client { public: HeapClient(Machine* m): m(m) { } @@ -1729,6 +1770,10 @@ Thread::init() t->m->loader = allocate(t, sizeof(void*) * 3, true); memset(t->m->loader, 0, sizeof(void*) * 2); + t->m->types = allocate(t, pad((TypeCount + 2) * BytesPerWord), true); + arrayLength(t, t->m->types) = TypeCount; + memset(&arrayBody(t, t->m->types, 0), 0, TypeCount * BytesPerWord); + #include "type-initializations.cpp" object arrayClass = arrayBody(t, t->m->types, Machine::ArrayType); @@ -1781,8 +1826,9 @@ Thread::init() m->bootstrapClassMap = makeHashMap(this, 0, 0); - object loaderMap = makeHashMap(this, 0, 0); - set(t, m->loader, SystemClassLoaderMap, loaderMap); + { object loaderMap = makeHashMap(this, 0, 0); + set(t, m->loader, SystemClassLoaderMap, loaderMap); + } m->monitorMap = makeWeakHashMap(this, 0, 0); m->stringMap = makeWeakHashMap(this, 0, 0); @@ -1791,19 +1837,14 @@ Thread::init() m->localThread->set(this); + { object bootCode = makeCode(t, 0, 0, 0, 0, 0, 1, false); + codeBody(t, bootCode, 0) = impdep1; + object bootMethod = makeMethod + (t, 0, 0, 0, 0, 0, 0, 0, 0, 0, bootCode, 0); + PROTECT(t, bootMethod); + #include "type-java-initializations.cpp" - - enter(t, Thread::ActiveState); - - resolveClass - (t, className(t, arrayBody(t, m->types, - Machine::SystemClassLoaderType))); - resolveClass - (t, className(t, arrayBody(t, m->types, Machine::ClassType))); - resolveClass - (t, className(t, arrayBody(t, m->types, Machine::IntArrayType))); - resolveClass - (t, className(t, arrayBody(t, m->types, Machine::ByteArrayType))); + } } else { parent->child = this; } @@ -1814,10 +1855,6 @@ Thread::init() this->javaThread = makeThread (this, reinterpret_cast(this), 0, 0, 0, 0, m->loader); } - - if (parent == 0) { - enter(this, Thread::IdleState); - } } void @@ -2072,7 +2109,7 @@ stringChars(Thread* t, object string, char* chars) &byteArrayBody(t, data, stringOffset(t, string)), stringLength(t, string)); } else { - for (int i = 0; i < stringLength(t, string); ++i) { + for (unsigned i = 0; i < stringLength(t, string); ++i) { chars[i] = charArrayBody(t, data, stringOffset(t, string) + i); } } @@ -2235,7 +2272,7 @@ hashMapInsert(Thread* t, object map, object key, object value, object r = makeWeakReference(t, 0, 0, 0, 0); jreferenceTarget(t, r) = key; - jreferenceNext(t, r) = t->m->weakReferences; + jreferenceVmNext(t, r) = t->m->weakReferences; key = t->m->weakReferences = r; } @@ -2810,7 +2847,7 @@ printTrace(Thread* t, object exception) exception = makeNullPointerException(t, 0, makeTrace(t), 0); } - for (object e = exception; e; e = throwableCauseUnsafe(t, e)) { + for (object e = exception; e; e = throwableCause(t, e)) { if (e != exception) { fprintf(stderr, "caused by: "); } @@ -2818,8 +2855,8 @@ printTrace(Thread* t, object exception) fprintf(stderr, "%s", &byteArrayBody (t, className(t, objectClass(t, e)), 0)); - if (throwableMessageUnsafe(t, e)) { - object m = throwableMessageUnsafe(t, e); + if (throwableMessage(t, e)) { + object m = throwableMessage(t, e); char message[stringLength(t, m) + 1]; stringChars(t, m, message); fprintf(stderr, ": %s\n", message); @@ -2827,7 +2864,7 @@ printTrace(Thread* t, object exception) fprintf(stderr, "\n"); } - object trace = throwableTraceUnsafe(t, e); + 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 diff --git a/src/machine.h b/src/machine.h index 98e0fc182f..3d4e4cf74b 100644 --- a/src/machine.h +++ b/src/machine.h @@ -61,8 +61,7 @@ const unsigned WeakReferenceFlag = 1 << 1; const unsigned NeedInitFlag = 1 << 2; const unsigned InitFlag = 1 << 3; const unsigned PrimitiveFlag = 1 << 4; -const unsigned BootstrapFlag = 1 << 5; -const unsigned SingletonFlag = 1 << 6; +const unsigned SingletonFlag = 1 << 5; // method flags: const unsigned ClassInitFlag = 1 << 0; @@ -1471,6 +1470,9 @@ setObjectClass(Thread* t, object o, object value) object& arrayBodyUnsafe(Thread*, object, unsigned); +bool +instanceOf(Thread* t, object class_, object o); + #include "type-declarations.cpp" inline bool @@ -1654,7 +1656,7 @@ makeNewWeakReference(Thread* t, object class_) ACQUIRE(t, t->m->referenceLock); - jreferenceNextUnsafe(t, instance) = t->m->weakReferences; + jreferenceVmNext(t, instance) = t->m->weakReferences; t->m->weakReferences = instance; return instance; @@ -1682,9 +1684,6 @@ stringChars(Thread* t, object string, char* chars); bool isAssignableFrom(Thread* t, object a, object b); -bool -instanceOf(Thread* t, object class_, object o); - object classInitializer(Thread* t, object class_); @@ -1799,7 +1798,7 @@ stringEqual(Thread* t, object a, object b) if (a == b) { return true; } else if (stringLength(t, a) == stringLength(t, b)) { - for (int i = 0; i < stringLength(t, a); ++i) { + for (unsigned i = 0; i < stringLength(t, a); ++i) { if (stringCharAt(t, a, i) != stringCharAt(t, b, i)) { return false; } diff --git a/src/output.h b/src/output.h deleted file mode 100644 index 06b6fac40e..0000000000 --- a/src/output.h +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include - -#ifndef OUTPUT_H -#define OUTPUT_H - -#define UNUSED __attribute__((unused)) - -// output ///////////////////////////////////////////////////////////////////// - -class Output { - public: - virtual ~Output() { } - - virtual void dispose() = 0; - - virtual void write(const char* s) = 0; - - void write(int i) { - static const int Size = 32; - char s[Size]; - int c UNUSED = snprintf(s, Size, "%d", i); - assert(c > 0 and c < Size); - write(s); - } -}; - -// file output //////////////////////////////////////////////////////////////// - -class FileOutput : public Output { - public: - const char* file; - FILE* stream; - bool close; - - FileOutput(const char* file, FILE* stream = 0, bool close = true): - file(file), stream(stream), close(close) - { } - - virtual ~FileOutput() { - dispose(); - } - - virtual void dispose() { - if (stream and close) { - fclose(stream); - stream = 0; - } - } - - virtual void write(const char* s) { - fputs(s, stream); - } - - const char* filename() { - return file; - } -}; - -#endif//OUTPUT_H diff --git a/src/process.h b/src/process.h index 4dc27a51dc..6cc2ef3636 100644 --- a/src/process.h +++ b/src/process.h @@ -127,8 +127,7 @@ findMethod(Thread* t, object method, object class_) inline bool methodVirtual(Thread* t, object method) { - return (methodFlags(t, method) & (ACC_STATIC | ACC_FINAL | ACC_PRIVATE)) - == 0; + return (methodFlags(t, method) & (ACC_STATIC | ACC_PRIVATE)) == 0; } inline void* diff --git a/src/type-generator.cpp b/src/type-generator.cpp index 8835184610..1daeae21de 100644 --- a/src/type-generator.cpp +++ b/src/type-generator.cpp @@ -1,17 +1,21 @@ -#include -#include -#include -#include +#include "stdlib.h" +#include "stdio.h" +#include "stdint.h" +#include "string.h" +#include "assert.h" -#include "input.h" -#include "output.h" +#include "constants.h" #define UNREACHABLE abort() +#define UNUSED __attribute__((unused)) + inline void operator delete(void*) { abort(); } extern "C" void __cxa_pure_virtual(void) { abort(); } +using namespace vm; + namespace { #ifndef POINTER_SIZE @@ -74,11 +78,194 @@ take(unsigned n, const char* c) return r; } +class Input { + public: + virtual ~Input() { } + + virtual void dispose() = 0; + + virtual int peek() = 0; + + virtual int read() = 0; + + virtual unsigned line() = 0; + + virtual unsigned column() = 0; + + void skipSpace() { + bool quit = false; + while (not quit) { + int c = peek(); + switch (c) { + case ' ': case '\t': case '\n': + read(); + break; + + default: quit = true; + } + } + } +}; + +class FileInput : public Input { + public: + const char* file; + FILE* stream; + unsigned line_; + unsigned column_; + bool close; + + FileInput(const char* file, FILE* stream = 0, bool close = true): + file(file), stream(stream), line_(1), column_(1), close(close) + { } + + virtual ~FileInput() { + dispose(); + } + + virtual void dispose() { + if (stream and close) { + fclose(stream); + stream = 0; + } + } + + virtual int peek() { + int c = getc(stream); + ungetc(c, stream); + return c; + } + + virtual int read() { + int c = getc(stream); + if (c == '\n') { + ++ line_; + column_ = 1; + } else { + ++ column_; + } + return c; + } + + virtual unsigned line() { + return line_; + } + + virtual unsigned column() { + return column_; + } +}; + +class Output { + public: + virtual ~Output() { } + + virtual void dispose() = 0; + + virtual void write(const char* s) = 0; + + void write(int i) { + static const int Size = 32; + char s[Size]; + int c UNUSED = snprintf(s, Size, "%d", i); + assert(c > 0 and c < Size); + write(s); + } +}; + +class FileOutput : public Output { + public: + const char* file; + FILE* stream; + bool close; + + FileOutput(const char* file, FILE* stream = 0, bool close = true): + file(file), stream(stream), close(close) + { } + + virtual ~FileOutput() { + dispose(); + } + + virtual void dispose() { + if (stream and close) { + fclose(stream); + stream = 0; + } + } + + virtual void write(const char* s) { + fputs(s, stream); + } + + const char* filename() { + return file; + } +}; + +class Stream { + public: + Stream(FILE* stream, bool close): + stream(stream), close(close) + { + assert(stream); + } + + ~Stream() { + if (close) fclose(stream); + } + + void skip(unsigned size) { + fseek(stream, size, SEEK_CUR); + } + + void read(uint8_t* data, unsigned size) { + fread(data, 1, size, stream); + } + + uint8_t read1() { + uint8_t v; + read(&v, 1); + return v; + } + + uint16_t read2() { + uint16_t a = read1(); + uint16_t b = read1(); + return (a << 8) | b; + } + + uint32_t read4() { + uint32_t a = read2(); + uint32_t b = read2(); + return (a << 16) | b; + } + + uint64_t read8() { + uint64_t a = read4(); + uint64_t b = read4(); + return (a << 32) | b; + } + + uint32_t readFloat() { + return read4(); + } + + uint64_t readDouble() { + return read8(); + } + + private: + FILE* stream; + bool close; +}; + class Object { public: typedef enum { Scalar, Array, + Method, Pod, Type, Pair, @@ -118,6 +305,13 @@ car(Object* o) return static_cast(o)->car; } +void +setCar(Object* o, Object* v) +{ + assert(o->type == Object::Pair); + static_cast(o)->car = v; +} + Object*& cdr(Object* o) { @@ -336,13 +530,54 @@ memberHide(Object* o) } } +class Method : public Object { + public: + Object* owner; + const char* name; + const char* spec; + + static Method* make(Object* owner, const char* name, const char* spec) + { + Method* o = allocate(); + o->type = Object::Method; + o->owner = owner; + o->name = name; + o->spec = spec; + return o; + } +}; + +const char* +methodName(Object* o) +{ + switch (o->type) { + case Object::Method: + return static_cast(o)->name; + + default: + UNREACHABLE; + } +} + +const char* +methodSpec(Object* o) +{ + switch (o->type) { + case Object::Method: + return static_cast(o)->spec; + + default: + UNREACHABLE; + } +} + class Type : public Object { public: const char* name; const char* javaName; Object* super; List members; - List subtypes; + List methods; bool hideConstructor; static Type* make(Object::ObjectType type, const char* name, @@ -354,7 +589,7 @@ class Type : public Object { o->javaName = javaName; o->super = 0; o->members.first = o->members.last = 0; - o->subtypes.first = o->subtypes.last = 0; + o->methods.first = o->methods.last = 0; o->hideConstructor = false; return o; } @@ -396,6 +631,18 @@ typeMembers(Object* o) } } +Object* +typeMethods(Object* o) +{ + switch (o->type) { + case Object::Type: + return static_cast(o)->methods.first; + + default: + UNREACHABLE; + } +} + void addMember(Object* o, Object* member) { @@ -414,11 +661,20 @@ addMember(Object* o, Object* member) } void -addSubtype(Object* o, Object* subtype) +addMethod(Object* o, Object* method) { switch (o->type) { case Object::Type: - static_cast(o)->subtypes.append(subtype); + for (Object* p = typeMethods(o); p; p = cdr(p)) { + Object* m = car(p); + if (equal(methodName(m), methodName(method)) + and equal(methodSpec(m), methodSpec(method))) + { + setCar(p, method); + return; + } + } + static_cast(o)->methods.append(method); break; default: @@ -426,18 +682,6 @@ addSubtype(Object* o, Object* subtype) } } -Object* -typeSubtypes(Object* o) -{ - switch (o->type) { - case Object::Type: - return static_cast(o)->subtypes.first; - - default: - UNREACHABLE; - } -} - Object*& typeSuper(Object* o) { @@ -642,6 +886,25 @@ declaration(const char* name, Object* declarations) return 0; } +Object* +javaDeclaration(const char* name, Object* declarations) +{ + for (Object* p = declarations; p; p = cdr(p)) { + Object* o = car(p); + switch (o->type) { + case Object::Type: + if (typeJavaName(o) and equal(name, typeJavaName(o))) return o; + break; + + case Object::Pod: + break; + + default: UNREACHABLE; + } + } + return 0; +} + Object* derivationChain(Object* o) { @@ -868,7 +1131,6 @@ parseSubdeclaration(Object* t, Object* p, Object* declarations) typeSuper(t) = declaration(string(car(cdr(p))), declarations); assert(typeSuper(t)); assert(typeSuper(t)->type == Object::Type); - addSubtype(typeSuper(t), t); } else { Object* member = parseMember(t, p, declarations); addMember(t, member); @@ -923,23 +1185,185 @@ specEqual(Object* a, Object* b) } } +const char* +append(const char* a, const char* b, const char* c, const char* d) +{ + unsigned al = strlen(a); + unsigned bl = strlen(b); + unsigned cl = strlen(c); + unsigned dl = strlen(d); + char* p = static_cast(malloc(al + bl + cl + dl + 1)); + memcpy(p, a, al); + memcpy(p + al, b, bl); + memcpy(p + al + bl, c, cl); + memcpy(p + al + bl + cl, d, dl + 1); + return p; +} + const char* append(const char* a, const char* b) { - assert(a and b); - unsigned aLength = strlen(a); - unsigned bLength = strlen(b); - assert(aLength + bLength); - char* r = static_cast(malloc(aLength + bLength + 1)); - assert(r); - - memcpy(r, a, aLength); - memcpy(r + aLength, b, bLength + 1); - return r; + return append(a, b, "", ""); +} + +const char* +fieldType(const char* spec) +{ + switch (*spec) { + case 'B': + case 'Z': + return "uint8_t"; + case 'C': + case 'S': + return "uint16_t"; + case 'D': + case 'J': + return "uint64_t"; + case 'F': + case 'I': + return "uint32_t"; + case 'L': + case '[': + return "object"; + + default: abort(); + } +} + +void +parseJavaClass(Object* type, Stream* s, Object* declarations) +{ + uint32_t magic = s->read4(); + assert(magic == 0xCAFEBABE); + s->read2(); // minor version + s->read2(); // major version + + unsigned poolCount = s->read2() - 1; + uintptr_t pool[poolCount]; + for (unsigned i = 0; i < poolCount; ++i) { + unsigned c = s->read1(); + + switch (c) { + case CONSTANT_Integer: + case CONSTANT_Float: + pool[i] = s->read4(); + break; + + case CONSTANT_Long: + case CONSTANT_Double: + pool[i++] = s->read4(); + pool[i] = s->read4(); + break; + + case CONSTANT_Utf8: { + unsigned length = s->read2(); + uint8_t* p = static_cast(malloc(length + 1)); + s->read(p, length); + p[length] = 0; + pool[i] = reinterpret_cast(p); + } break; + + case CONSTANT_Class: + case CONSTANT_String: + pool[i] = s->read2(); + break; + + case CONSTANT_NameAndType: + pool[i] = s->read4(); + break; + + case CONSTANT_Fieldref: + case CONSTANT_Methodref: + case CONSTANT_InterfaceMethodref: + pool[i] = s->read4(); + break; + + default: abort(); + } + } + + s->read2(); // flags + s->read2(); // name + + unsigned superIndex = s->read2(); + if (superIndex) { + const char* name = reinterpret_cast + (pool[pool[superIndex - 1] - 1]); + typeSuper(type) = javaDeclaration(name, declarations); + assert(typeSuper(type)); + } + + unsigned interfaceCount = s->read2(); + s->skip(interfaceCount * 2); + + unsigned fieldCount = s->read2(); + for (unsigned i = 0; i < fieldCount; ++i) { + unsigned flags = s->read2(); + unsigned nameIndex = s->read2(); + unsigned specIndex = s->read2(); + + unsigned attributeCount = s->read2(); + for (unsigned j = 0; j < attributeCount; ++j) { + s->read2(); + s->skip(s->read4()); + } + + if ((flags & ACC_STATIC) == 0) { + char* name = reinterpret_cast(pool[nameIndex - 1]); + unsigned nameLength = strlen(name); + if (nameLength > 0 and name[nameLength - 1] == '_') { + name[nameLength - 1] = 0; + } + + const char* spec = reinterpret_cast(pool[specIndex - 1]); + const char* memberType = fieldType(spec); + + Object* member = Scalar::make + (type, 0, memberType, name, sizeOf(memberType, declarations)); + + if (equal(typeJavaName(type), "java/lang/ref/Reference") + and (equal(name, "vmNext") + or equal(name, "target") + or equal(name, "queue"))) + { + memberNoGC(member) = true; + } + + addMember(type, member); + } + } + + if (typeSuper(type)) { + for (Object* p = typeMethods(typeSuper(type)); p; p = cdr(p)) { + addMethod(type, car(p)); + } + } + + unsigned methodCount = s->read2(); + for (unsigned i = 0; i < methodCount; ++i) { + unsigned flags = s->read2(); + unsigned nameIndex = s->read2(); + unsigned specIndex = s->read2(); + + unsigned attributeCount = s->read2(); + for (unsigned j = 0; j < attributeCount; ++j) { + s->read2(); + 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]); + + Object* method = Method::make(type, name, spec); + addMethod(type, method); + } + } } Object* -parseType(Object::ObjectType type, Object* p, Object* declarations) +parseType(Object::ObjectType type, Object* p, Object* declarations, + const char* javaClassDirectory) { const char* name = string(car(p)); @@ -951,13 +1375,27 @@ parseType(Object::ObjectType type, Object* p, Object* declarations) Type* t = Type::make(type, name, javaName); - for (p = cdr(p); p; p = cdr(p)) { - if (type == Object::Type) { - parseSubdeclaration(t, car(p), declarations); - } else { - Object* member = parseMember(t, car(p), declarations); - assert(member->type == Object::Scalar); - addMember(t, member); + if (javaName and *javaName != '[') { + assert(cdr(p) == 0); + + const char* file = append(javaClassDirectory, "/", javaName, ".class"); + Stream s(fopen(file, "rb"), true); + parseJavaClass(t, &s, declarations); + } else { + for (p = cdr(p); p; p = cdr(p)) { + if (type == Object::Type) { + parseSubdeclaration(t, car(p), declarations); + } else { + Object* member = parseMember(t, car(p), declarations); + assert(member->type == Object::Scalar); + addMember(t, member); + } + } + + if (type == Object::Type and typeSuper(t)) { + for (Object* p = typeMethods(typeSuper(t)); p; p = cdr(p)) { + addMethod(t, car(p)); + } } } @@ -965,13 +1403,14 @@ parseType(Object::ObjectType type, Object* p, Object* declarations) } Object* -parseDeclaration(Object* p, Object* declarations) +parseDeclaration(Object* p, Object* declarations, + const char* javaClassDirectory) { const char* spec = string(car(p)); if (equal(spec, "type")) { - return parseType(Object::Type, cdr(p), declarations); + return parseType(Object::Type, cdr(p), declarations, javaClassDirectory); } else if (equal(spec, "pod")) { - return parseType(Object::Pod, cdr(p), declarations); + return parseType(Object::Pod, cdr(p), declarations, javaClassDirectory); } else { fprintf(stderr, "unexpected declaration spec: %s\n", spec); abort(); @@ -979,14 +1418,15 @@ parseDeclaration(Object* p, Object* declarations) } Object* -parse(Input* in) +parse(Input* in, const char* javaClassDirectory) { Object* eos = Singleton::make(Object::Eos); List declarations; Object* o; while ((o = read(in, eos, 0)) != eos) { - declarations.append(parseDeclaration(o, declarations.first)); + declarations.append + (parseDeclaration(o, declarations.first, javaClassDirectory)); } return declarations.first; @@ -1052,19 +1492,6 @@ writeOffset(Output* out, Object* offset, bool allocationStyle = false) } } -void -writeSubtypeAssertions(Output* out, Object* o) -{ - for (Object* p = typeSubtypes(o); p; p = cdr(p)) { - Object* st = car(p); - out->write(" or objectClass(t, o) == arrayBodyUnsafe"); - out->write("(t, t->m->types, Machine::"); - out->write(capitalize(typeName(st))); - out->write("Type)"); - writeSubtypeAssertions(out, st); - } -} - void writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) { @@ -1110,16 +1537,13 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false) out->write(") {\n"); if (memberOwner(member)->type == Object::Type) { - if (unsafe) { - out->write(" assert(t, true);"); - } else { + if (not unsafe) { out->write(" assert(t, t->m->unsafe or "); - out->write("objectClass(t, o) == arrayBodyUnsafe"); + out->write("instanceOf(t, arrayBodyUnsafe"); out->write("(t, t->m->types, Machine::"); out->write(capitalize(::typeName(memberOwner(member)))); out->write("Type)"); - writeSubtypeAssertions(out, memberOwner(member)); - out->write(");\n"); + out->write(", o));\n"); if (member->type != Object::Scalar) { out->write(" assert(t, i < "); @@ -1506,32 +1930,6 @@ writeConstructors(Output* out, Object* declarations) } } - if (typeJavaName(o) - and not equal("class", typeName(o)) - and startsWith("java/", typeJavaName(o))) - { - out->write(" object class__ "); - out->write("= arrayBody(t, t->m->types, Machine::"); - out->write(capitalize(typeName(o))); - out->write("Type);\n"); - - out->write(" if (classVmFlags(t, class__) & BootstrapFlag) {\n"); - out->write(" classVmFlags(t, class__) &= ~BootstrapFlag;\n"); - out->write("#ifndef NDEBUG\n"); - out->write(" object e = t->exception;\n"); - out->write(" PROTECT(t, e);\n"); - out->write("#endif\n"); - out->write(" resolveClass(t, className(t, class__));\n"); - - if (equal("classNotFoundException", typeName(o))) { - out->write(" t->exception = 0;\n"); - } else { - out->write(" assert(t, t->exception == e);\n"); - } - - out->write(" }\n"); - } - out->write(" object o = allocate(t, "); writeOffset(out, typeOffset(o), true); if (hasObjectMask) { @@ -1593,6 +1991,14 @@ memberCount(Object* o) return c; } +unsigned +methodCount(Object* o) +{ + unsigned c = 0; + for (Object* p = typeMethods(o); p; p = cdr(p)) ++c; + return c; +} + void set(uint32_t* mask, unsigned index) { @@ -1665,49 +2071,31 @@ typeObjectMask(Object* type) void writeInitialization(Output* out, Object* type) { - out->write("{\n"); + out->write("bootClass(t, Machine::"); + out->write(capitalize(typeName(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(", "); if (typeObjectMask(type) != 1) { - out->write(" object mask = makeIntArray(t, 1, false);\n"); - - out->write(" intArrayBody(t, mask, 0) = "); out->write(typeObjectMask(type)); - out->write(";\n"); } else { - out->write(" object mask = 0;\n"); + out->write("0"); } + out->write(", "); - if (typeJavaName(type) and typeSuper(type)) { - out->write(" object super = arrayBody(t, t->m->types, Machine::"); - out->write(capitalize(typeName(typeSuper(type)))); - out->write("Type);\n"); - } else { - out->write(" object super = 0;\n"); - } - - out->write(" object class_ = makeClass"); - out->write("(t, 0, "); - - if (typeJavaName(type) - and not equal("class", typeName(type)) - and startsWith("java/", typeJavaName(type))) - { - out->write("BootstrapFlag"); - } else { - out->write("0"); - } - - out->write(", 0, "); out->write(typeFixedSize(type)); out->write(", "); + out->write(typeArrayElementSize(type)); - out->write(", mask, 0, super, 0, 0, 0, 0, 0, t->m->loader);\n"); - - out->write(" set(t, t->m->types, ArrayBody + (Machine::"); - out->write(capitalize(typeName(type))); - out->write("Type * BytesPerWord), class_);\n"); - - out->write("}\n\n"); + out->write(");\n"); } unsigned @@ -1751,18 +2139,6 @@ reorder(Object* declarations) void writeInitializations(Output* out, Object* declarations) { - unsigned count = typeCount(declarations); - - out->write("t->m->types = allocate(t, pad(("); - out->write(count); - out->write(" * BytesPerWord) + (BytesPerWord * 2)), true);\n"); - out->write("arrayLength(t, t->m->types) = "); - out->write(count); - out->write(";\n"); - out->write("memset(&arrayBody(t, t->m->types, 0), 0, "); - out->write(count); - out->write(" * BytesPerWord);\n\n"); - declarations = reorder(declarations); for (Object* p = declarations; p; p = cdr(p)) { @@ -1776,22 +2152,15 @@ writeInitializations(Output* out, Object* declarations) void writeJavaInitialization(Output* out, Object* type) { - out->write("{\n"); - - out->write(" object name = ::makeByteArray(t, \""); - out->write(typeJavaName(type)); - out->write("\");\n"); - - out->write(" object class_ = arrayBody(t, t->m->types, Machine::"); + out->write("bootJavaClass(t, Machine::"); out->write(capitalize(typeName(type))); - out->write("Type);\n"); + out->write("Type, \""); - out->write(" set(t, class_, ClassName, name);\n"); + out->write(typeJavaName(type)); + out->write("\", "); - out->write(" hashMapInsert(t, t->m->bootstrapClassMap, "); - out->write("name, class_, byteArrayHash);\n"); - - out->write("}\n\n"); + out->write(methodCount(type)); + out->write(", bootMethod);\n"); } void @@ -1809,7 +2178,8 @@ void usageAndExit(const char* command) { fprintf(stderr, - "usage: %s {enums,declarations,constructors,initializations," + "usage: %s " + "{enums,declarations,constructors,initializations," "java-initializations}\n", command); exit(-1); @@ -1820,44 +2190,48 @@ usageAndExit(const char* command) int main(int ac, char** av) { - if ((ac != 1 and ac != 2) - or (ac == 2 - and not equal(av[1], "enums") - and not equal(av[1], "declarations") - and not equal(av[1], "constructors") - and not equal(av[1], "initializations") - and not equal(av[1], "java-initializations"))) + if ((ac != 2 and ac != 3) + or (ac == 3 + and not equal(av[2], "enums") + and not equal(av[2], "declarations") + and not equal(av[2], "constructors") + and not equal(av[2], "initializations") + and not equal(av[2], "java-initializations"))) { usageAndExit(av[0]); } FileInput in(0, stdin, false); - Object* declarations = parse(&in); + Object* declarations = parse(&in, av[1]); FileOutput out(0, stdout, false); - if (ac == 1 or equal(av[1], "enums")) { + if (ac == 2 or equal(av[2], "enums")) { writeEnums(&out, declarations); } - if (ac == 1 or equal(av[1], "declarations")) { + if (ac == 2 or equal(av[2], "declarations")) { + out.write("const unsigned TypeCount = "); + out.Output::write(typeCount(declarations)); + out.write(";\n\n"); + writePods(&out, declarations); writeAccessors(&out, declarations); writeInitializerDeclarations(&out, declarations); writeConstructorDeclarations(&out, declarations); } - if (ac == 1 or equal(av[1], "constructors")) { + if (ac == 2 or equal(av[2], "constructors")) { writeInitializers(&out, declarations); writeConstructors(&out, declarations); } - if (ac == 1 or equal(av[1], "initializations")) { + if (ac == 2 or equal(av[2], "initializations")) { writeInitializations(&out, declarations); } - if (ac == 1 or equal(av[1], "java-initializations")) { + if (ac == 2 or equal(av[2], "java-initializations")) { writeJavaInitializations(&out, declarations); } diff --git a/src/types.def b/src/types.def index 2e9d7c451a..6dfb15246e 100644 --- a/src/types.def +++ b/src/types.def @@ -1,45 +1,17 @@ (type jobject java/lang/Object) -(type class java/lang/Class - (extends jobject) - (uint16_t flags) - (uint8_t vmFlags) - (uint8_t arrayDimensions) - (uint16_t fixedSize) - (uint16_t arrayElementSize) - (object objectMask) - (object name) - (object super) - (object interfaceTable) - (object virtualTable) - (object fieldTable) - (object methodTable) - (object staticTable) - (object loader)) +(type class java/lang/Class) (type singleton (array uintptr_t body)) -(type classLoader java/lang/ClassLoader - (extends jobject) - (object parent)) +(type classLoader java/lang/ClassLoader) -(type systemClassLoader java/lang/SystemClassLoader - (extends classLoader) - (object map)) +(type systemClassLoader java/lang/SystemClassLoader) -(type accessibleObject java/lang/reflect/AccessibleObject - (extends jobject)) +(type accessibleObject java/lang/reflect/AccessibleObject) -(type field java/lang/reflect/Field - (extends accessibleObject) - (uint8_t vmFlags) - (uint8_t code) - (uint16_t flags) - (uint16_t offset) - (object name) - (object spec) - (object class)) +(type field java/lang/reflect/Field) (pod compiled (uint16_t maxLocals) @@ -51,19 +23,7 @@ (uint32_t stackMapTableLength) (uint8_t[0] body)) -(type method java/lang/reflect/Method - (extends accessibleObject) - (uint8_t vmFlags) - (uint8_t returnCode) - (uint8_t parameterCount) - (uint8_t parameterFootprint) - (uint16_t flags) - (uint16_t offset) - (object name) - (object spec) - (object class) - (object code) - (object compiled)) +(type method java/lang/reflect/Method) (type nativeMethodData (void* function) @@ -154,148 +114,82 @@ (type array (noassert array object body)) -(type string java/lang/String - (extends jobject) - (object data) - (int32_t offset) - (int32_t length) - (int32_t hashCode)) +(type string java/lang/String) -(type thread java/lang/Thread - (extends jobject) - (int64_t peer) - (object task) - (object locals) - (uint8_t interrupted) - (object sleepLock) - (object classLoader)) +(type thread java/lang/Thread) -(type stackTraceElement java/lang/StackTraceElement - (extends jobject) - (object class) - (object method) - (object file) - (int32_t line)) +(type stackTraceElement java/lang/StackTraceElement) -(type throwable java/lang/Throwable - (extends jobject) - (noassert object message) - (noassert object trace) - (noassert object cause)) +(type throwable java/lang/Throwable) -(type exception java/lang/Exception - (extends throwable)) +(type exception java/lang/Exception) -(type runtimeException java/lang/RuntimeException - (extends exception)) +(type runtimeException java/lang/RuntimeException) -(type nullPointerException java/lang/NullPointerException - (extends runtimeException)) +(type nullPointerException java/lang/NullPointerException) -(type illegalStateException java/lang/IllegalStateException - (extends runtimeException)) +(type illegalStateException java/lang/IllegalStateException) -(type illegalArgumentException java/lang/IllegalArgumentException - (extends runtimeException)) +(type illegalArgumentException java/lang/IllegalArgumentException) -(type illegalMonitorStateException java/lang/IllegalMonitorStateException - (extends runtimeException)) +(type illegalMonitorStateException java/lang/IllegalMonitorStateException) (type arrayIndexOutOfBoundsException - java/lang/ArrayIndexOutOfBoundsException - (extends runtimeException)) + java/lang/ArrayIndexOutOfBoundsException) -(type arrayStoreException java/lang/ArrayStoreException - (extends runtimeException)) +(type arrayStoreException java/lang/ArrayStoreException) -(type negativeArraySizeException java/lang/NegativeArraySizeException - (extends runtimeException)) +(type negativeArraySizeException java/lang/NegativeArraySizeException) -(type classCastException java/lang/ClassCastException - (extends runtimeException)) +(type classCastException java/lang/ClassCastException) -(type classNotFoundException java/lang/ClassNotFoundException - (extends exception)) +(type classNotFoundException java/lang/ClassNotFoundException) -(type invocationTargetException java/lang/InvocationTargetException - (extends exception)) +(type invocationTargetException java/lang/reflect/InvocationTargetException) -(type interruptedException java/lang/InterruptedException - (extends exception)) +(type interruptedException java/lang/InterruptedException) -(type error java/lang/Error - (extends throwable)) +(type error java/lang/Error) -(type stackOverflowError java/lang/StackOverflowError - (extends error)) +(type stackOverflowError java/lang/StackOverflowError) -(type noSuchFieldError java/lang/NoSuchFieldError - (extends error)) +(type linkageError java/lang/LinkageError) -(type noSuchMethodError java/lang/NoSuchMethodError - (extends error)) +(type incompatibleClassChangeError java/lang/IncompatibleClassChangeError) -(type linkageError java/lang/LinkageError - (extends error)) +(type noSuchFieldError java/lang/NoSuchFieldError) -(type unsatisfiedLinkError java/lang/UnsatisfiedLinkError - (extends linkageError)) +(type noSuchMethodError java/lang/NoSuchMethodError) -(type exceptionInInitializerError java/lang/ExceptionInInitializerError - (extends error)) +(type unsatisfiedLinkError java/lang/UnsatisfiedLinkError) -(type number java/lang/Number - (extends jobject)) +(type exceptionInInitializerError java/lang/ExceptionInInitializerError) -(type byte java/lang/Byte - (extends number) - (int8_t value)) +(type number java/lang/Number) -(type boolean java/lang/Boolean - (extends jobject) - (uint8_t value)) +(type byte java/lang/Byte) -(type short java/lang/Short - (extends number) - (int16_t value)) +(type boolean java/lang/Boolean) -(type char java/lang/Character - (extends jobject) - (uint16_t value)) +(type short java/lang/Short) -(type int java/lang/Integer - (extends number) - (int32_t value)) +(type char java/lang/Character) -(type long java/lang/Long - (extends number) - (int64_t value)) +(type int java/lang/Integer) -(type float java/lang/Float - (extends number) - (uint32_t value)) +(type long java/lang/Long) -(type double java/lang/Double - (extends number) - (uint64_t value)) +(type float java/lang/Float) -(type referenceQueue java/lang/ref/ReferenceQueue - (extends jobject) - (object front) - (object rear)) +(type double java/lang/Double) -(type jreference java/lang/ref/Reference - (extends jobject) - (noassert nogc object next) - (nogc object target) - (nogc object queue) - (object jnext)) +(type referenceQueue java/lang/ref/ReferenceQueue) -(type weakReference java/lang/ref/WeakReference - (extends jreference)) +(type jreference java/lang/ref/Reference) -(type phantomReference java/lang/ref/PhantomReference - (extends jreference)) +(type weakReference java/lang/ref/WeakReference) + +(type phantomReference java/lang/ref/PhantomReference) (type byteArray [B (extends jobject) diff --git a/test/Misc.java b/test/Misc.java index f44fc6a37a..3321647f20 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -15,6 +15,8 @@ public class Misc { } public static void main(String[] args) { + boolean v = Boolean.valueOf("true"); + int a = 2; int b = 2; int c = a + b;