From 0ca8601777be0beca7bbcdfe5f7b9228541bf112 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:23:03 -0500 Subject: [PATCH 01/11] Fix getClass().getComponentType() for higher-dimensional arrays When creating an object array with more than two dimensions, the component type was erroneously set to the base type, not the array type of one less dimension. This prevented Collection#toArray(Class[][]) from working properly. Signed-off-by: Johannes Schindelin --- src/machine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/machine.cpp b/src/machine.cpp index e8d60ce2fc..3bf59a6fe9 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2512,7 +2512,11 @@ makeArrayClass(Thread* t, object loader, object spec, bool throw_, ++ s; const char* elementSpecStart = s; while (*s and *s != ';') ++ s; - + if (dimensions > 1) { + elementSpecStart -= dimensions; + ++ s; + } + elementSpec = makeByteArray(t, s - elementSpecStart + 1); memcpy(&byteArrayBody(t, elementSpec, 0), &byteArrayBody(t, spec, elementSpecStart - start), From 6f64e3aaab775981c34d12cfccbe3f2020fd7eb8 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:23:41 -0500 Subject: [PATCH 02/11] Verify that two-dimensional object arrays have the correct component type Signed-off-by: Johannes Schindelin --- test/Reflection.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/Reflection.java b/test/Reflection.java index f71b39e81b..23d34abf7e 100644 --- a/test/Reflection.java +++ b/test/Reflection.java @@ -67,5 +67,10 @@ public class Reflection { expect(7.0 == (Double) Reflection.class.getMethod ("doubleMethod").invoke(null)); + + Class[][] array = new Class[][] { { Class.class } }; + expect("[Ljava.lang.Class;".equals(array[0].getClass().getName())); + expect(Class[].class == array[0].getClass()); + expect(array.getClass().getComponentType() == array[0].getClass()); } } From 2ff0178da481005f2df696d8b10e9c6da76648e8 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 10:51:14 -0500 Subject: [PATCH 03/11] Adjust fromIndex in String#lastIndexOf if necessary If fromIndex 'is greater than or equal to the length of this string, it has the same effect as if it were equal to one less than the length of the string': http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#lastIndexOf%28int,%20int%29 Signed-off-by: Johannes Schindelin --- classpath/java/lang/String.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index d49a347f98..c209c62439 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -602,6 +602,9 @@ public final class String } public int lastIndexOf(int ch, int lastIndex) { + if (lastIndex >= length) { + lastIndex = length - 1; + } for (int i = lastIndex ; i >= 0; --i) { if (charAt(i) == ch) { return i; From c1ec6020a68a64a313d2bd86cf51bc4b2b10951b Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:24:05 -0500 Subject: [PATCH 04/11] Verify that String#lastIndexOf handles large fromIndex correctly Signed-off-by: Johannes Schindelin --- test/Strings.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/Strings.java b/test/Strings.java index 30a85163c9..76815af535 100644 --- a/test/Strings.java +++ b/test/Strings.java @@ -203,6 +203,8 @@ public class Strings { System.getProperty("line.separator").getBytes()))); } + expect("abc".lastIndexOf('b', 100) == 1); + testTrivialPattern(); } } From d04cda30cadc6be40576a3728d03ca940286333b Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:26:12 -0500 Subject: [PATCH 05/11] Add the Integer#decode method Signed-off-by: Johannes Schindelin --- classpath/java/lang/Integer.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/classpath/java/lang/Integer.java b/classpath/java/lang/Integer.java index f5e4052904..fd0483fc37 100644 --- a/classpath/java/lang/Integer.java +++ b/classpath/java/lang/Integer.java @@ -122,4 +122,21 @@ public final class Integer extends Number implements Comparable { public static int parseInt(String s, int radix) { return (int) Long.parseLong(s, radix); } + + public static Integer decode(String string) { + if (string.startsWith("-")) { + if (string.startsWith("-0") || string.startsWith("-#")) { + return new Integer(-decode(string.substring(1))); + } + } else if (string.startsWith("0")) { + char c = string.length() < 2 ? (char)-1 : string.charAt(1); + if (c == 'x' || c == 'X') { + return new Integer(parseInt(string.substring(2), 0x10)); + } + return new Integer(parseInt(string, 010)); + } else if (string.startsWith("#")) { + return new Integer(parseInt(string.substring(1), 0x10)); + } + return new Integer(parseInt(string, 10)); + } } From 95fcc9ac8ef96b8e453eef66f87c21743fb597d4 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 15:24:19 -0500 Subject: [PATCH 06/11] Test the newly-introduced Integer#decode method Signed-off-by: Johannes Schindelin --- test/Integers.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/Integers.java b/test/Integers.java index bbaa710351..7c977d6136 100644 --- a/test/Integers.java +++ b/test/Integers.java @@ -314,5 +314,11 @@ public class Integers { { int b = 0xBE; int x = 0; int y = 0xFF; expect(((b >>> x) & y) == 0xBE); } + + expect(123 == Integer.decode("123").intValue()); + expect(-123 == Integer.decode("-123").intValue()); + expect(-83 == Integer.decode("-0123").intValue()); + expect(-291 == Integer.decode("-0x123").intValue()); + expect(291 == Integer.decode("#123").intValue()); } } From 0e3e719dd6f9592cb8dcb0beaff616c1d99fae03 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:25:46 -0500 Subject: [PATCH 07/11] Add the Boolean#getBoolean method Signed-off-by: Johannes Schindelin --- classpath/java/lang/Boolean.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/classpath/java/lang/Boolean.java b/classpath/java/lang/Boolean.java index 57137d24e8..21b75000f3 100644 --- a/classpath/java/lang/Boolean.java +++ b/classpath/java/lang/Boolean.java @@ -59,6 +59,10 @@ public final class Boolean implements Comparable { return value; } + public static boolean getBoolean(String name) { + return parseBoolean(System.getProperty(name)); + } + public static boolean parseBoolean(String string) { return string != null && string.equalsIgnoreCase("true"); } From 526dd574d96a49722354014eda2bb504028ebe10 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:26:50 -0500 Subject: [PATCH 08/11] Add the Method#isVarArgs method Required by bleeding-edge Beanshell... Signed-off-by: Johannes Schindelin --- classpath/java/lang/reflect/Method.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/classpath/java/lang/reflect/Method.java b/classpath/java/lang/reflect/Method.java index 8f04e7bf2b..51a64c905c 100644 --- a/classpath/java/lang/reflect/Method.java +++ b/classpath/java/lang/reflect/Method.java @@ -138,4 +138,8 @@ public class Method extends AccessibleObject implements Member { public Annotation[] getDeclaredAnnotations() { return getAnnotations(); } + + public boolean isVarArgs() { + return (getModifiers() & 0x80) != 0; + } } From 86c735e649cd94b8c2c7d1d4dd39b4bfef826356 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:27:09 -0500 Subject: [PATCH 09/11] Add Collections#synchronizedSet Signed-off-by: Johannes Schindelin --- classpath/java/util/Collections.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java index c57c190a06..c820ad20d0 100644 --- a/classpath/java/util/Collections.java +++ b/classpath/java/util/Collections.java @@ -245,6 +245,10 @@ public class Collections { } } + public static Set synchronizedSet(Set set) { + return new SynchronizedSet (new Object(), set); + } + static class SynchronizedIterator implements Iterator { private final Object lock; private final Iterator it; From 056c65947e4461b59b063b0971aeab0ac41f8d5f Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:28:18 -0500 Subject: [PATCH 10/11] Add Collections#singletonList This is a very dumb implementation that wastes space and time by constructing a full-blown ArrayList as backend. However, it is better to have a dumb implementation than none at all, and we can always do something about the performance when, and if, that should become necessary. Signed-off-by: Johannes Schindelin --- classpath/java/util/Collections.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/classpath/java/util/Collections.java b/classpath/java/util/Collections.java index c820ad20d0..91fad0964b 100644 --- a/classpath/java/util/Collections.java +++ b/classpath/java/util/Collections.java @@ -659,4 +659,10 @@ public class Collections { return - cmp.compare(o1, o2); } } + + public static List singletonList(T o) { + ArrayList list = new ArrayList(1); + list.add(o); + return new UnmodifiableList(list); + } } From 6c46fe3f1ae88d0ecdb96de3c3804cc4ee5f57a8 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Oct 2013 13:28:32 -0500 Subject: [PATCH 11/11] Make Vector a Cloneable Signed-off-by: Johannes Schindelin --- classpath/java/util/Vector.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/classpath/java/util/Vector.java b/classpath/java/util/Vector.java index e48ac52450..94ba9cbbe6 100644 --- a/classpath/java/util/Vector.java +++ b/classpath/java/util/Vector.java @@ -10,7 +10,7 @@ package java.util; -public class Vector extends AbstractList implements java.io.Serializable { +public class Vector extends AbstractList implements java.io.Serializable, Cloneable { private final ArrayList list; public Vector(int capacity) { @@ -126,5 +126,12 @@ public class Vector extends AbstractList implements java.io.Serializable { public Enumeration elements() { return new Collections.IteratorEnumeration(iterator()); } - + + public synchronized Object clone() { + Vector copy = new Vector(size()); + for (T t : this) { + copy.add(t); + } + return copy; + } }