diff --git a/classpath/java/lang/Class.java b/classpath/java/lang/Class.java index f100438489..0ae4019b0c 100644 --- a/classpath/java/lang/Class.java +++ b/classpath/java/lang/Class.java @@ -25,6 +25,10 @@ public final class Class { private Class() { } + public String toString() { + return getName(); + } + public String getName() { return new String(name, 0, name.length - 1, false); } @@ -73,7 +77,7 @@ public final class Class { public Class getComponentType() { if (isArray()) { - return forCanonicalName(new String(name, 1, name.length - 2, false)); + return (Class) (Object) staticTable; } else { return null; } @@ -258,12 +262,14 @@ public final class Class { private int countMethods(boolean publicOnly) { int count = 0; - for (int i = 0; i < methodTable.length; ++i) { - if (((! publicOnly) - || ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0) - && (! methodTable[i].getName().startsWith("<"))) - { - ++ count; + if (methodTable != null) { + for (int i = 0; i < methodTable.length; ++i) { + if (((! publicOnly) + || ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0) + && (! methodTable[i].getName().startsWith("<"))) + { + ++ count; + } } } return count; diff --git a/classpath/java/lang/Double.java b/classpath/java/lang/Double.java index caffeb5177..99d9b2640f 100644 --- a/classpath/java/lang/Double.java +++ b/classpath/java/lang/Double.java @@ -31,7 +31,7 @@ public final class Double extends Number { } public static String toString(double v) { - return "todo"; + return "Double.toString: todo"; } public byte byteValue() { @@ -60,7 +60,7 @@ public final class Double extends Number { public static double parseDouble(String s) { // todo - return 0.0; + throw new NumberFormatException(s); } public static native long doubleToRawLongBits(double value); diff --git a/classpath/java/lang/Float.java b/classpath/java/lang/Float.java index c06bdc9dc9..1c0779de09 100644 --- a/classpath/java/lang/Float.java +++ b/classpath/java/lang/Float.java @@ -26,7 +26,7 @@ public final class Float extends Number { } public static String toString(float v) { - return "todo"; + return "Float.toString: todo"; } public byte byteValue() { diff --git a/classpath/java/lang/Long.java b/classpath/java/lang/Long.java index b289726e1e..feb8c417ee 100644 --- a/classpath/java/lang/Long.java +++ b/classpath/java/lang/Long.java @@ -34,7 +34,10 @@ public final class Long extends Number { return "0"; } - int size = (v < 0 ? 1 : 0); + boolean negative = v < 0; + if (negative) v = -v; + + int size = (negative ? 1 : 0); for (long n = v; n > 0; n /= radix) ++size; char[] array = new char[size]; @@ -50,7 +53,7 @@ public final class Long extends Number { --i; } - if (v < 0) { + if (negative) { array[i] = '-'; } diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index df3f1bf3d1..5a8e0962c2 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -122,7 +122,7 @@ public final class String implements Comparable { } public int indexOf(int c) { - for (int i = 0; i < length - 1; ++i) { + for (int i = 0; i < length; ++i) { if (charAt(i) == c) { return i; } @@ -144,7 +144,7 @@ public final class String implements Comparable { public int indexOf(String s) { if (s.length == 0) return 0; - for (int i = 0; i < length - s.length; ++i) { + for (int i = 0; i < length - s.length + 1; ++i) { int j = 0; for (; j < s.length; ++j) { if (charAt(i + j) != s.charAt(j)) { diff --git a/classpath/java/lang/Throwable.java b/classpath/java/lang/Throwable.java index 01e28fd6e7..1c77a7566a 100644 --- a/classpath/java/lang/Throwable.java +++ b/classpath/java/lang/Throwable.java @@ -36,7 +36,12 @@ public class Throwable { } public String toString() { - return getClass().getName() + ": " + message; + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getName()); + if (message != null) { + sb.append(": ").append(message); + } + return sb.toString(); } private static native Object trace(int skipCount); @@ -69,11 +74,7 @@ public class Throwable { } private void printStackTrace(StringBuilder sb, String nl) { - sb.append(getClass().getName()); - if (message != null) { - sb.append(": ").append(message); - } - sb.append(nl); + sb.append(toString()).append(nl); StackTraceElement[] trace = resolveTrace(); for (int i = 0; i < trace.length; ++i) { diff --git a/classpath/java/lang/reflect/Array.java b/classpath/java/lang/reflect/Array.java index eb4d9abc56..06d99e20d3 100644 --- a/classpath/java/lang/reflect/Array.java +++ b/classpath/java/lang/reflect/Array.java @@ -28,15 +28,13 @@ public final class Array { return Boolean.valueOf(((boolean[]) array)[index]); case 'L': case '[': - return getObject(array, index); + return ((Object[]) array)[index]; default: throw new Error(); } } - private static native Object getObject(Object array, int index); - public static void set(Object array, int index, Object value) { String className = array.getClass().getName(); if (! className.startsWith("[")) { @@ -71,7 +69,7 @@ public final class Array { case 'L': case '[': if (array.getClass().getComponentType().isInstance(value)) { - setObject(array, index, value); + ((Object[]) array)[index] = value; } else { throw new IllegalArgumentException(); } @@ -82,8 +80,6 @@ public final class Array { } } - private static native void setObject(Object array, int index, Object value); - public static native int getLength(Object array); private static native Object makeObjectArray(Class elementType, int length); diff --git a/classpath/java/lang/reflect/Method.java b/classpath/java/lang/reflect/Method.java index d48e843872..606eb4d969 100644 --- a/classpath/java/lang/reflect/Method.java +++ b/classpath/java/lang/reflect/Method.java @@ -73,11 +73,11 @@ public class Method extends AccessibleObject implements Member { types[index++] = Class.forName(name); } else { String name = spec.substring(start, i + 1); - types[index++] = Class.forName(name); + types[index++] = Class.forCanonicalName(name); } } else { String name = spec.substring(i, i + 1); - types[index++] = Class.forName(name); + types[index++] = Class.forCanonicalName(name); } } } catch (ClassNotFoundException e) { diff --git a/makefile b/makefile index 4752f635e1..3ad44f87ef 100644 --- a/makefile +++ b/makefile @@ -233,8 +233,8 @@ $(jni-library): $(jni-objects) $(executable): $(interpreter-objects) $(stdcpp-objects) @echo "linking $(@)" $(cc) $(lflags) $(^) -o $(@) - $(strip) --strip-all $(@) - $(show-size) $(@) + @$(strip) --strip-all $(@) + @$(show-size) $(@) .PHONY: generator generator: $(generator-executable) diff --git a/src/builtin.cpp b/src/builtin.cpp index f8adff3412..1f4cf5f0a6 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -260,7 +260,7 @@ Field_setObject(Thread* t, jclass, jobject instance, jint offset, jobject Constructor_make(Thread* t, jclass, jclass c) { - return pushReference(t, make(t, c)); + return pushReference(t, make(t, *c)); } jobject @@ -281,18 +281,6 @@ Method_invoke(Thread* t, jclass, jobject method, jobject instance, return pushReference(t, v); } -jobject -Array_getObject(Thread* t, jclass, jobject array, int index) -{ - return pushReference(t, objectArrayBody(t, *array, index)); -} - -void -Array_setObject(Thread* t, jclass, jobject array, int index, jobject value) -{ - set(t, objectArrayBody(t, *array, index), (value ? *value : 0)); -} - jint Array_getLength(Thread* t, jclass, jobject array) { @@ -663,10 +651,6 @@ populateBuiltinMap(Thread* t, object map) { "Java_java_lang_Object_clone", reinterpret_cast(::Object_clone) }, - { "Java_java_lang_reflect_Array_getObject", - reinterpret_cast(::Array_getObject) }, - { "Java_java_lang_reflect_Array_setObject", - reinterpret_cast(::Array_setObject) }, { "Java_java_lang_reflect_Array_getLength", reinterpret_cast(::Array_getLength) }, { "Java_java_lang_reflect_Array_makeObjectArray", diff --git a/src/machine.cpp b/src/machine.cpp index 3f5b1b5b03..8ed1ef56f6 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1172,6 +1172,7 @@ object makeArrayClass(Thread* t, unsigned dimensions, object spec, object elementClass) { + // todo: arrays should implement Cloneable and Serializable return makeClass (t, 0, @@ -1182,11 +1183,11 @@ makeArrayClass(Thread* t, unsigned dimensions, object spec, classObjectMask(t, arrayBody(t, t->vm->types, Machine::ArrayType)), spec, arrayBody(t, t->vm->types, Machine::JobjectType), - elementClass, + 0, classVirtualTable(t, arrayBody(t, t->vm->types, Machine::JobjectType)), 0, 0, - 0, + elementClass, t->vm->loader); } @@ -1688,6 +1689,8 @@ stringChars(Thread* t, object string, char* chars) bool isAssignableFrom(Thread* t, object a, object b) { + if (a == b) return true; + if (classFlags(t, a) & ACC_INTERFACE) { for (; b; b = classSuper(t, b)) { object itable = classInterfaceTable(t, b); @@ -1697,6 +1700,11 @@ isAssignableFrom(Thread* t, object a, object b) } } } + } else if (classArrayDimensions(t, a)) { + if (classArrayDimensions(t, b)) { + return isAssignableFrom + (t, classStaticTable(t, a), classStaticTable(t, b)); + } } else { for (; b; b = classSuper(t, b)) { if (b == a) {