diff --git a/classpath/avian/Iso88591.java b/classpath/avian/Iso88591.java new file mode 100644 index 0000000000..a94f8e2f2f --- /dev/null +++ b/classpath/avian/Iso88591.java @@ -0,0 +1,26 @@ + +/* Copyright (c) 2011, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package avian; + +import java.io.ByteArrayOutputStream; + +public class Iso88591 { + + public static byte[] encode(char[] s16, int offset, int length) { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + for (int i = offset; i < offset+length; ++i) { + // ISO-88591-1/Latin-1 is the same as UTF-16 under 0x100 + buf.write(s16[i]); + } + return buf.toByteArray(); + } +} diff --git a/classpath/java-io.cpp b/classpath/java-io.cpp index b38b95bc3b..9bcfa88afd 100644 --- a/classpath/java-io.cpp +++ b/classpath/java-io.cpp @@ -314,10 +314,29 @@ Java_java_io_File_toCanonicalPath(JNIEnv* /*e*/, jclass, jstring path) } extern "C" JNIEXPORT jstring JNICALL -Java_java_io_File_toAbsolutePath(JNIEnv* /*e*/, jclass, jstring path) +Java_java_io_File_toAbsolutePath(JNIEnv* e UNUSED, jclass, jstring path) { +#ifdef PLATFORM_WINDOWS // todo return path; +#else + jstring result = path; + string_t chars = getChars(e, path); + if (chars) { + if (chars[0] != '/') { + char* cwd = getcwd(NULL, 0); + if (cwd) { + unsigned size = strlen(cwd) + strlen(chars) + 2; + RUNTIME_ARRAY(char, buffer, size); + snprintf(RUNTIME_ARRAY_BODY(buffer), size, "%s/%s", cwd, chars); + result = e->NewStringUTF(RUNTIME_ARRAY_BODY(buffer)); + free(cwd); + } + } + releaseChars(e, path, chars); + } + return result; +#endif } extern "C" JNIEXPORT jlong JNICALL diff --git a/classpath/java-lang.cpp b/classpath/java-lang.cpp index 8b78a2ec4e..a46b5a93e5 100644 --- a/classpath/java-lang.cpp +++ b/classpath/java-lang.cpp @@ -413,8 +413,8 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass, execvp(argv[0], argv); // Error if here - char c = errno; - ssize_t rv UNUSED = write(msg[1], &c, 1); + int val = errno; + ssize_t rv UNUSED = write(msg[1], &val, sizeof(val)); exit(127); } break; @@ -427,12 +427,13 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass, safeClose(err[1]); safeClose(msg[1]); - char c; - int r = read(msg[0], &c, 1); + int val; + int r = read(msg[0], &val, sizeof(val)); if(r == -1) { throwNewErrno(e, "java/io/IOException"); return; } else if(r) { + errno = val; throwNewErrno(e, "java/io/IOException"); return; } diff --git a/classpath/java/io/File.java b/classpath/java/io/File.java index 3eb8ad2f03..51e006e53f 100644 --- a/classpath/java/io/File.java +++ b/classpath/java/io/File.java @@ -120,6 +120,10 @@ public class File implements Serializable { return toAbsolutePath(path); } + public File getAbsoluteFile() { + return new File(getAbsolutePath()); + } + private static native long length(String path); public long length() { diff --git a/classpath/java/io/ObjectInputStream.java b/classpath/java/io/ObjectInputStream.java index a039046517..45bacc7380 100644 --- a/classpath/java/io/ObjectInputStream.java +++ b/classpath/java/io/ObjectInputStream.java @@ -161,7 +161,7 @@ public class ObjectInputStream extends InputStream { case 'n': return null; case 'z': - return (readLongToken() == 0); + return (readLongToken() != 0); case 'b': return (byte) readLongToken(); case 'c': diff --git a/classpath/java/lang/Runtime.java b/classpath/java/lang/Runtime.java index 30dc0b6612..a24f850bf3 100644 --- a/classpath/java/lang/Runtime.java +++ b/classpath/java/lang/Runtime.java @@ -103,7 +103,8 @@ public class Runtime { if (exception[0] != null) { if (exception[0] instanceof IOException) { - throw new IOException(exception[0]); + String message = "Failed to run \"" + command[0] + "\": " + exception[0].getMessage(); + throw new IOException(message); } else { throw new RuntimeException(exception[0]); } diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index 7f6ff1edfc..83ce12dfa3 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -16,10 +16,16 @@ import java.util.Comparator; import java.util.Locale; import java.io.Serializable; import avian.Utf8; +import avian.Iso88591; public final class String implements Comparable, CharSequence, Serializable { + private static final String UTF_8_ENCODING = "UTF-8"; + private static final String ISO_8859_1_ENCODING = "ISO-8859-1"; + private static final String LATIN_1_ENCODING = "LATIN-1"; + private static final String DEFAULT_ENCODING = UTF_8_ENCODING; + public static Comparator CASE_INSENSITIVE_ORDER = new Comparator() { public int compare(String a, String b) { @@ -52,8 +58,8 @@ public final class String throws UnsupportedEncodingException { this(bytes, offset, length); - if (! (charsetName.equalsIgnoreCase("UTF-8") - || charsetName.equalsIgnoreCase("ISO-8859-1"))) + if (! (charsetName.equalsIgnoreCase(UTF_8_ENCODING) + || charsetName.equalsIgnoreCase(ISO_8859_1_ENCODING))) { throw new UnsupportedEncodingException(charsetName); } @@ -421,18 +427,31 @@ public final class String } public byte[] getBytes() { - if(data instanceof byte[]) { - byte[] b = new byte[length]; - getBytes(0, length, b, 0); - return b; + try { + return getBytes(DEFAULT_ENCODING); + } catch (java.io.UnsupportedEncodingException ex) { + throw new RuntimeException( + "Default '" + DEFAULT_ENCODING + "' encoding not handled", ex); } - return Utf8.encode((char[])data, offset, length); } public byte[] getBytes(String format) throws java.io.UnsupportedEncodingException { - return getBytes(); + if(data instanceof byte[]) { + byte[] b = new byte[length]; + getBytes(0, length, b, 0); + return b; + } + String fmt = format.trim().toUpperCase(); + if (DEFAULT_ENCODING.equals(fmt)) { + return Utf8.encode((char[])data, offset, length); + } else if (ISO_8859_1_ENCODING.equals(fmt) || LATIN_1_ENCODING.equals(fmt)) { + return Iso88591.encode((char[])data, offset, length); + } else { + throw new java.io.UnsupportedEncodingException( + "Encoding " + format + " not supported"); + } } public void getChars(int srcOffset, int srcEnd, diff --git a/classpath/java/util/AbstractList.java b/classpath/java/util/AbstractList.java index fa1abbd65a..e1d4f3c307 100644 --- a/classpath/java/util/AbstractList.java +++ b/classpath/java/util/AbstractList.java @@ -12,4 +12,14 @@ package java.util; public abstract class AbstractList extends AbstractCollection implements List -{ } +{ + protected int modCount; + + public Iterator iterator() { + return listIterator(); + } + + public ListIterator listIterator() { + return new Collections.ArrayListIterator(this); + } +} diff --git a/classpath/java/util/AbstractMap.java b/classpath/java/util/AbstractMap.java new file mode 100644 index 0000000000..6bcdf2e5fa --- /dev/null +++ b/classpath/java/util/AbstractMap.java @@ -0,0 +1,13 @@ +/* Copyright (c) 2008-2011, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.util; + +public abstract class AbstractMap extends Object implements Map { } diff --git a/license.txt b/license.txt index 6e84838c86..4ed92c217a 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2008-2010, Avian Contributors +Copyright (c) 2008-2011, Avian Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/readme.txt b/readme.txt index 224fd2c8ee..0f6a076fa2 100644 --- a/readme.txt +++ b/readme.txt @@ -308,7 +308,7 @@ it on various OSes: # http://download.java.net/openjdk/jdk6/promoted/, e.g.: wget http://download.java.net/openjdk/jdk6/promoted/b21/openjdk-6-src-b21-20_jan_2011.tar.gz mkdir openjdk - (cd openjdk && tar xzf openjdk-6-src-b21-20_jan_2011.tar.gz) + (cd openjdk && tar xzf ../openjdk-6-src-b21-20_jan_2011.tar.gz) make openjdk=/cygdrive/c/OpenSCG/openjdk-6.21 \ openjdk-src=$(pwd)/openjdk/jdk/src \ test diff --git a/src/compile.cpp b/src/compile.cpp index 7531609b0b..afd590fc8f 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -2266,19 +2266,34 @@ resolveMethod(Thread* t, object pair) findMethodInClass, Machine::NoSuchMethodErrorType); } +bool +methodAbstract(Thread* t, object method) +{ + return methodCode(t, method) == 0 + and (methodFlags(t, method) & ACC_NATIVE) == 0; +} + int64_t prepareMethodForCall(MyThread* t, object target) { - if (unresolved(t, methodAddress(t, target))) { - PROTECT(t, target); + if (methodAbstract(t, target)) { + throwNew(t, Machine::AbstractMethodErrorType, "%s.%s%s", + &byteArrayBody(t, className(t, methodClass(t, target)), 0), + &byteArrayBody(t, methodName(t, target), 0), + &byteArrayBody(t, methodSpec(t, target), 0)); + } else { + if (unresolved(t, methodAddress(t, target))) { + PROTECT(t, target); + + compile(t, codeAllocator(t), 0, target); + } - compile(t, codeAllocator(t), 0, target); - } + if (methodFlags(t, target) & ACC_NATIVE) { + t->trace->nativeMethod = target; + } - if (methodFlags(t, target) & ACC_NATIVE) { - t->trace->nativeMethod = target; + return methodAddress(t, target); } - return methodAddress(t, target); } int64_t @@ -2344,24 +2359,10 @@ findVirtualMethodFromReference(MyThread* t, object pair, object instance) return prepareMethodForCall(t, target); } -bool -methodAbstract(Thread* t, object method) -{ - return methodCode(t, method) == 0 - and (methodFlags(t, method) & ACC_NATIVE) == 0; -} - int64_t getMethodAddress(MyThread* t, object target) { - if (methodAbstract(t, target)) { - throwNew(t, Machine::AbstractMethodErrorType, "%s.%s%s", - &byteArrayBody(t, className(t, methodClass(t, target)), 0), - &byteArrayBody(t, methodName(t, target), 0), - &byteArrayBody(t, methodSpec(t, target), 0)); - } else { - return prepareMethodForCall(t, target); - } + return prepareMethodForCall(t, target); } int64_t