mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
Merge branch 'master' of oss.readytalk.com:/var/local/git/avian
This commit is contained in:
commit
1528a9dddf
@ -26,7 +26,7 @@ public abstract class Writer {
|
|||||||
|
|
||||||
public void write(String s, int offset, int length) throws IOException {
|
public void write(String s, int offset, int length) throws IOException {
|
||||||
char[] b = new char[length];
|
char[] b = new char[length];
|
||||||
s.getChars(offset, length, b, 0);
|
s.getChars(offset, offset + length, b, 0);
|
||||||
write(b);
|
write(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
private static final int PrimitiveFlag = 1 << 5;
|
private static final int PrimitiveFlag = 1 << 5;
|
||||||
|
|
||||||
private short flags;
|
private short flags;
|
||||||
private byte vmFlags;
|
private short vmFlags;
|
||||||
private byte arrayDimensions;
|
|
||||||
private short fixedSize;
|
private short fixedSize;
|
||||||
private short arrayElementSize;
|
private byte arrayElementSize;
|
||||||
|
private byte arrayDimensions;
|
||||||
private int[] objectMask;
|
private int[] objectMask;
|
||||||
private byte[] name;
|
private byte[] name;
|
||||||
private Class super_;
|
private Class super_;
|
||||||
@ -96,6 +96,32 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
(replace('/', '.', name, 0, name.length - 1), 0, name.length - 1, false);
|
(replace('/', '.', name, 0, name.length - 1), 0, name.length - 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCanonicalName() {
|
||||||
|
if ((vmFlags & PrimitiveFlag) != 0) {
|
||||||
|
return getName();
|
||||||
|
} else if (isArray()) {
|
||||||
|
return getComponentType().getCanonicalName() + "[]";
|
||||||
|
} else {
|
||||||
|
return getName().replace('$', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSimpleName() {
|
||||||
|
if ((vmFlags & PrimitiveFlag) != 0) {
|
||||||
|
return getName();
|
||||||
|
} else if (isArray()) {
|
||||||
|
return getComponentType().getSimpleName() + "[]";
|
||||||
|
} else {
|
||||||
|
String name = getCanonicalName();
|
||||||
|
int index = name.lastIndexOf('.');
|
||||||
|
if (index >= 0) {
|
||||||
|
return name.substring(index + 1);
|
||||||
|
} else {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Object staticTable() {
|
public Object staticTable() {
|
||||||
return staticTable;
|
return staticTable;
|
||||||
}
|
}
|
||||||
@ -125,6 +151,7 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
loader = Class.class.loader;
|
loader = Class.class.loader;
|
||||||
}
|
}
|
||||||
Class c = loader.loadClass(name);
|
Class c = loader.loadClass(name);
|
||||||
|
c.link(loader);
|
||||||
if (initialize) {
|
if (initialize) {
|
||||||
c.initialize();
|
c.initialize();
|
||||||
}
|
}
|
||||||
@ -133,6 +160,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
|
|
||||||
private static native Class primitiveClass(char name);
|
private static native Class primitiveClass(char name);
|
||||||
|
|
||||||
|
private native void link(ClassLoader loader);
|
||||||
|
|
||||||
private native void initialize();
|
private native void initialize();
|
||||||
|
|
||||||
public static Class forCanonicalName(String name) {
|
public static Class forCanonicalName(String name) {
|
||||||
@ -159,6 +188,26 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
|
|
||||||
public Class getComponentType() {
|
public Class getComponentType() {
|
||||||
if (isArray()) {
|
if (isArray()) {
|
||||||
|
String n = getName();
|
||||||
|
if ("[Z".equals(n)) {
|
||||||
|
return primitiveClass('Z');
|
||||||
|
} else if ("[B".equals(n)) {
|
||||||
|
return primitiveClass('B');
|
||||||
|
} else if ("[S".equals(n)) {
|
||||||
|
return primitiveClass('S');
|
||||||
|
} else if ("[C".equals(n)) {
|
||||||
|
return primitiveClass('C');
|
||||||
|
} else if ("[I".equals(n)) {
|
||||||
|
return primitiveClass('I');
|
||||||
|
} else if ("[F".equals(n)) {
|
||||||
|
return primitiveClass('F');
|
||||||
|
} else if ("[J".equals(n)) {
|
||||||
|
return primitiveClass('J');
|
||||||
|
} else if ("[D".equals(n)) {
|
||||||
|
return primitiveClass('D');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (staticTable == null) throw new AssertionError(name);
|
||||||
return (Class) staticTable;
|
return (Class) staticTable;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
@ -169,6 +218,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
|
|
||||||
private Field findField(String name) {
|
private Field findField(String name) {
|
||||||
if (fieldTable != null) {
|
if (fieldTable != null) {
|
||||||
|
link(loader);
|
||||||
|
|
||||||
for (int i = 0; i < fieldTable.length; ++i) {
|
for (int i = 0; i < fieldTable.length; ++i) {
|
||||||
if (fieldTable[i].getName().equals(name)) {
|
if (fieldTable[i].getName().equals(name)) {
|
||||||
return fieldTable[i];
|
return fieldTable[i];
|
||||||
@ -212,8 +263,12 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
|
|
||||||
private Method findMethod(String name, Class[] parameterTypes) {
|
private Method findMethod(String name, Class[] parameterTypes) {
|
||||||
if (methodTable != null) {
|
if (methodTable != null) {
|
||||||
if (parameterTypes == null)
|
link(loader);
|
||||||
|
|
||||||
|
if (parameterTypes == null) {
|
||||||
parameterTypes = new Class[0];
|
parameterTypes = new Class[0];
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (methodTable[i].getName().equals(name)
|
if (methodTable[i].getName().equals(name)
|
||||||
&& match(parameterTypes, methodTable[i].getParameterTypes()))
|
&& match(parameterTypes, methodTable[i].getParameterTypes()))
|
||||||
@ -302,6 +357,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
public Constructor[] getDeclaredConstructors() {
|
public Constructor[] getDeclaredConstructors() {
|
||||||
Constructor[] array = new Constructor[countConstructors(false)];
|
Constructor[] array = new Constructor[countConstructors(false)];
|
||||||
if (methodTable != null) {
|
if (methodTable != null) {
|
||||||
|
link(loader);
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (methodTable[i].getName().equals("<init>")) {
|
if (methodTable[i].getName().equals("<init>")) {
|
||||||
@ -316,6 +373,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
public Constructor[] getConstructors() {
|
public Constructor[] getConstructors() {
|
||||||
Constructor[] array = new Constructor[countConstructors(true)];
|
Constructor[] array = new Constructor[countConstructors(true)];
|
||||||
if (methodTable != null) {
|
if (methodTable != null) {
|
||||||
|
link(loader);
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
||||||
@ -354,6 +413,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
public Field[] getFields() {
|
public Field[] getFields() {
|
||||||
Field[] array = new Field[countPublicFields()];
|
Field[] array = new Field[countPublicFields()];
|
||||||
if (fieldTable != null) {
|
if (fieldTable != null) {
|
||||||
|
link(loader);
|
||||||
|
|
||||||
int ai = 0;
|
int ai = 0;
|
||||||
for (int i = 0; i < fieldTable.length; ++i) {
|
for (int i = 0; i < fieldTable.length; ++i) {
|
||||||
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
||||||
@ -382,6 +443,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
public Method[] getDeclaredMethods() {
|
public Method[] getDeclaredMethods() {
|
||||||
Method[] array = new Method[countMethods(false)];
|
Method[] array = new Method[countMethods(false)];
|
||||||
if (methodTable != null) {
|
if (methodTable != null) {
|
||||||
|
link(loader);
|
||||||
|
|
||||||
int ai = 0;
|
int ai = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (! methodTable[i].getName().startsWith("<")) {
|
if (! methodTable[i].getName().startsWith("<")) {
|
||||||
@ -396,6 +459,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
public Method[] getMethods() {
|
public Method[] getMethods() {
|
||||||
Method[] array = new Method[countMethods(true)];
|
Method[] array = new Method[countMethods(true)];
|
||||||
if (methodTable != null) {
|
if (methodTable != null) {
|
||||||
|
link(loader);
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
||||||
@ -411,6 +476,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
|
|
||||||
public Class[] getInterfaces() {
|
public Class[] getInterfaces() {
|
||||||
if (interfaceTable != null) {
|
if (interfaceTable != null) {
|
||||||
|
link(loader);
|
||||||
|
|
||||||
Class[] array = new Class[interfaceTable.length / 2];
|
Class[] array = new Class[interfaceTable.length / 2];
|
||||||
for (int i = 0; i < array.length; ++i) {
|
for (int i = 0; i < array.length; ++i) {
|
||||||
array[i] = (Class) interfaceTable[i * 2];
|
array[i] = (Class) interfaceTable[i * 2];
|
||||||
@ -450,7 +517,7 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArray() {
|
public boolean isArray() {
|
||||||
return this != Class.class && arrayElementSize != 0;
|
return arrayDimensions != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInstance(Object o) {
|
public boolean isInstance(Object o) {
|
||||||
@ -485,6 +552,14 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> Class<? extends T> asSubclass(Class<T> c) {
|
||||||
|
if (! c.isAssignableFrom(this)) {
|
||||||
|
throw new ClassCastException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Class<? extends T>) this;
|
||||||
|
}
|
||||||
|
|
||||||
public T cast(Object o) {
|
public T cast(Object o) {
|
||||||
return (T) o;
|
return (T) o;
|
||||||
}
|
}
|
||||||
@ -493,6 +568,21 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
return Static.signers.get(this);
|
return Static.signers.get(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Package getPackage() {
|
||||||
|
if ((vmFlags & PrimitiveFlag) != 0 || isArray()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
String name = getCanonicalName();
|
||||||
|
int index = name.lastIndexOf('.');
|
||||||
|
if (index >= 0) {
|
||||||
|
return new Package(name.substring(0, index),
|
||||||
|
null, null, null, null, null, null, null, null);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Annotation[] getDeclaredAnnotations() {
|
public Annotation[] getDeclaredAnnotations() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
@ -505,10 +595,6 @@ public final class Class <T> implements Type, GenericDeclaration {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSimpleName() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Method getEnclosingMethod() {
|
public Method getEnclosingMethod() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
@ -83,9 +83,7 @@ public abstract class ClassLoader {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resolveClass(Class c) {
|
protected native void resolveClass(Class c);
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getParent() {
|
private ClassLoader getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
|
@ -26,20 +26,21 @@ public abstract class Enum<E extends Enum<E>> implements Comparable<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
|
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
|
||||||
if (name != null) {
|
if (name == null) throw new NullPointerException();
|
||||||
try {
|
|
||||||
Method method = enumType.getMethod("values");
|
try {
|
||||||
Enum values[] = (Enum[])(method.invoke(null));
|
Method method = enumType.getMethod("values");
|
||||||
for (Enum value : values) {
|
Enum values[] = (Enum[]) (method.invoke(null));
|
||||||
if (name.equals(value.name)) {
|
for (Enum value: values) {
|
||||||
return (T) value;
|
if (name.equals(value.name)) {
|
||||||
}
|
return (T) value;
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
throw new IllegalArgumentException(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ordinal() {
|
public int ordinal() {
|
||||||
|
46
classpath/java/lang/Package.java
Normal file
46
classpath/java/lang/Package.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* Copyright (c) 2008, 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.lang;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class Package {
|
||||||
|
private final String name;
|
||||||
|
private final String implementationTitle;
|
||||||
|
private final String implementationVendor;
|
||||||
|
private final String implementationVersion;
|
||||||
|
private final String specementationTitle;
|
||||||
|
private final String specementationVendor;
|
||||||
|
private final String specementationVersion;
|
||||||
|
private final URL sealed;
|
||||||
|
private final ClassLoader loader;
|
||||||
|
|
||||||
|
Package(String name,
|
||||||
|
String implementationTitle,
|
||||||
|
String implementationVendor,
|
||||||
|
String implementationVersion,
|
||||||
|
String specementationTitle,
|
||||||
|
String specementationVendor,
|
||||||
|
String specementationVersion,
|
||||||
|
URL sealed,
|
||||||
|
ClassLoader loader)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.implementationTitle = implementationTitle;
|
||||||
|
this.implementationVendor = implementationVendor;
|
||||||
|
this.implementationVersion = implementationVersion;
|
||||||
|
this.specementationTitle = specementationTitle;
|
||||||
|
this.specementationVendor = specementationVendor;
|
||||||
|
this.specementationVersion = specementationVersion;
|
||||||
|
this.sealed = sealed;
|
||||||
|
this.loader = loader;
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ package java.lang;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Formatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@ -52,7 +53,9 @@ public final class String
|
|||||||
throws UnsupportedEncodingException
|
throws UnsupportedEncodingException
|
||||||
{
|
{
|
||||||
this(bytes, offset, length);
|
this(bytes, offset, length);
|
||||||
if (! charsetName.equalsIgnoreCase("UTF-8")) {
|
if (! (charsetName.equalsIgnoreCase("UTF-8")
|
||||||
|
|| charsetName.equalsIgnoreCase("ISO-8859-1")))
|
||||||
|
{
|
||||||
throw new UnsupportedEncodingException(charsetName);
|
throw new UnsupportedEncodingException(charsetName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,10 +79,7 @@ public final class String
|
|||||||
public String(byte[] data, String charset)
|
public String(byte[] data, String charset)
|
||||||
throws UnsupportedEncodingException
|
throws UnsupportedEncodingException
|
||||||
{
|
{
|
||||||
this(data);
|
this(data, 0, data.length, charset);
|
||||||
if (! charset.equals("UTF-8")) {
|
|
||||||
throw new UnsupportedEncodingException(charset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String(byte bytes[], int highByte, int offset, int length) {
|
public String(byte bytes[], int highByte, int offset, int length) {
|
||||||
@ -540,6 +540,10 @@ public final class String
|
|||||||
public boolean matches(String regex) {
|
public boolean matches(String regex) {
|
||||||
return Pattern.matches(regex, this);
|
return Pattern.matches(regex, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String replaceFirst(String regex, String replacement) {
|
||||||
|
return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
|
||||||
|
}
|
||||||
|
|
||||||
public String replaceAll(String regex, String replacement) {
|
public String replaceAll(String regex, String replacement) {
|
||||||
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
|
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
|
||||||
@ -625,8 +629,8 @@ public final class String
|
|||||||
return length == 0;
|
return length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(String match) {
|
public boolean contains(CharSequence match) {
|
||||||
return indexOf(match) != -1;
|
return indexOf(match.toString()) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int codePointAt(int offset) {
|
public int codePointAt(int offset) {
|
||||||
@ -649,6 +653,14 @@ public final class String
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String format(Locale locale, String format, Object ... args) {
|
||||||
|
return new Formatter(locale).format(format, args).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(String format, Object ... args) {
|
||||||
|
return format(Locale.getDefault(), format, args);
|
||||||
|
}
|
||||||
|
|
||||||
// for GNU Classpath compatibility:
|
// for GNU Classpath compatibility:
|
||||||
static char[] zeroBasedStringValue(String s) {
|
static char[] zeroBasedStringValue(String s) {
|
||||||
if (s.offset == 0) {
|
if (s.offset == 0) {
|
||||||
|
@ -129,10 +129,10 @@ public class StringBuffer implements CharSequence {
|
|||||||
sb.setCharAt(index, ch);
|
sb.setCharAt(index, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void getChars(int srcOffset, int srcLength, char[] dst,
|
public synchronized void getChars(int srcStart, int srcEnd, char[] dst,
|
||||||
int dstOffset)
|
int dstStart)
|
||||||
{
|
{
|
||||||
sb.getChars(srcOffset, srcLength, dst, dstOffset);
|
sb.getChars(srcStart, srcEnd, dst, dstStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized String toString() {
|
public synchronized String toString() {
|
||||||
|
@ -248,6 +248,29 @@ public class StringBuilder implements CharSequence, Appendable {
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(String s) {
|
||||||
|
return lastIndexOf(s, length - s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(String s, int lastIndex) {
|
||||||
|
int slength = s.length();
|
||||||
|
if (slength == 0) return lastIndex;
|
||||||
|
|
||||||
|
for (int i = Math.min(length - slength, lastIndex); i >= 0; --i) {
|
||||||
|
int j = 0;
|
||||||
|
for (; j < slength && i + j < length; ++j) {
|
||||||
|
if (charAt(i + j) != s.charAt(j)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == slength) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public int length() {
|
public int length() {
|
||||||
return length;
|
return length;
|
||||||
@ -283,9 +306,8 @@ public class StringBuilder implements CharSequence, Appendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getChars(int srcOffset, int srcLength, char[] dst, int dstOffset)
|
public void getChars(int srcStart, int srcEnd, char[] dst, int dstStart) {
|
||||||
{
|
if (srcStart < 0 || srcEnd > length) {
|
||||||
if (srcOffset < 0 || srcOffset + srcLength > length) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,17 +319,17 @@ public class StringBuilder implements CharSequence, Appendable {
|
|||||||
int end = index;
|
int end = index;
|
||||||
index = start;
|
index = start;
|
||||||
|
|
||||||
if (start < srcOffset) {
|
if (start < srcStart) {
|
||||||
start = srcOffset;
|
start = srcStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end > srcOffset + srcLength) {
|
if (end > srcEnd) {
|
||||||
end = srcOffset + srcLength;
|
end = srcEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start < end) {
|
if (start < end) {
|
||||||
c.value.getChars(start - index, end - start,
|
c.value.getChars(start - index, end - index,
|
||||||
dst, dstOffset + (start - srcOffset));
|
dst, dstStart + (start - srcStart));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,10 +350,14 @@ public class StringBuilder implements CharSequence, Appendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String substring(int start) {
|
||||||
|
return substring(start, length);
|
||||||
|
}
|
||||||
|
|
||||||
public String substring(int start, int end) {
|
public String substring(int start, int end) {
|
||||||
int len = end-start;
|
int len = end-start;
|
||||||
char[] buf = new char[len];
|
char[] buf = new char[len];
|
||||||
getChars(start, len, buf,0 );
|
getChars(start, end, buf, 0);
|
||||||
return new String(buf, 0, len, false);
|
return new String(buf, 0, len, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@ public class ThreadGroup implements Thread.UncaughtExceptionHandler {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ThreadGroup(String name) {
|
||||||
|
this(Thread.currentThread().getThreadGroup(), name);
|
||||||
|
}
|
||||||
|
|
||||||
public void uncaughtException(Thread t, Throwable e) {
|
public void uncaughtException(Thread t, Throwable e) {
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
parent.uncaughtException(t, e);
|
parent.uncaughtException(t, e);
|
||||||
|
@ -55,6 +55,10 @@ public class Throwable implements Serializable {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLocalizedMessage() {
|
||||||
|
return getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(getClass().getName());
|
sb.append(getClass().getName());
|
||||||
@ -79,6 +83,10 @@ public class Throwable implements Serializable {
|
|||||||
return resolveTrace();
|
return resolveTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStackTrace(StackTraceElement[] trace) {
|
||||||
|
this.trace = trace;
|
||||||
|
}
|
||||||
|
|
||||||
public void printStackTrace(PrintStream out) {
|
public void printStackTrace(PrintStream out) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
printStackTrace(sb, System.getProperty("line.separator"));
|
printStackTrace(sb, System.getProperty("line.separator"));
|
||||||
|
21
classpath/java/lang/ref/SoftReference.java
Normal file
21
classpath/java/lang/ref/SoftReference.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* Copyright (c) 2009, 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.lang.ref;
|
||||||
|
|
||||||
|
public class SoftReference<T> extends Reference<T> {
|
||||||
|
public SoftReference(T target, ReferenceQueue<? super T> queue) {
|
||||||
|
super(target, queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoftReference(T target) {
|
||||||
|
this(target, null);
|
||||||
|
}
|
||||||
|
}
|
@ -16,4 +16,8 @@ public abstract class AccessibleObject {
|
|||||||
public abstract boolean isAccessible();
|
public abstract boolean isAccessible();
|
||||||
|
|
||||||
public abstract void setAccessible(boolean v);
|
public abstract void setAccessible(boolean v);
|
||||||
|
|
||||||
|
public static void setAccessible(AccessibleObject[] array, boolean v) {
|
||||||
|
for (AccessibleObject o: array) o.setAccessible(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
23
classpath/java/util/Formatter.java
Normal file
23
classpath/java/util/Formatter.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* Copyright (c) 2009, 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 class Formatter {
|
||||||
|
private final Locale locale;
|
||||||
|
|
||||||
|
public Formatter(Locale locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Formatter format(String format, Object ... args) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
1
makefile
1
makefile
@ -393,6 +393,7 @@ gnu-overrides = \
|
|||||||
java/lang/ref/PhantomReference.class \
|
java/lang/ref/PhantomReference.class \
|
||||||
java/lang/ref/Reference.class \
|
java/lang/ref/Reference.class \
|
||||||
java/lang/ref/ReferenceQueue.class \
|
java/lang/ref/ReferenceQueue.class \
|
||||||
|
java/lang/ref/SoftReference.class \
|
||||||
java/lang/ref/WeakReference.class \
|
java/lang/ref/WeakReference.class \
|
||||||
java/lang/reflect/AccessibleObject.class \
|
java/lang/reflect/AccessibleObject.class \
|
||||||
java/lang/reflect/Constructor.class \
|
java/lang/reflect/Constructor.class \
|
||||||
|
@ -199,6 +199,16 @@ Avian_java_lang_ClassLoader_defineClass
|
|||||||
return reinterpret_cast<int64_t>(c);
|
return reinterpret_cast<int64_t>(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_java_lang_ClassLoader_resolveClass
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object loader = reinterpret_cast<object>(arguments[0]);
|
||||||
|
object class_ = reinterpret_cast<object>(arguments[1]);
|
||||||
|
|
||||||
|
linkClass(t, loader, class_);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_avian_SystemClassLoader_findLoadedClass
|
Avian_avian_SystemClassLoader_findLoadedClass
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
@ -291,6 +301,16 @@ Avian_java_lang_Class_initialize
|
|||||||
initClass(t, this_);
|
initClass(t, this_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Avian_java_lang_Class_link
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object this_ = reinterpret_cast<object>(arguments[0]);
|
||||||
|
object loader = reinterpret_cast<object>(arguments[1]);
|
||||||
|
|
||||||
|
linkClass(t, loader, this_);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT int64_t JNICALL
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
Avian_java_lang_Class_isAssignableFrom
|
Avian_java_lang_Class_isAssignableFrom
|
||||||
(Thread* t, object, uintptr_t* arguments)
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
@ -138,6 +138,19 @@ resolveThisPointer(MyThread* t, void* stack)
|
|||||||
[t->arch->frameFooterSize() + t->arch->frameReturnAddressSize()];
|
[t->arch->frameFooterSize() + t->arch->frameReturnAddressSize()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
findMethod(Thread* t, object method, object instance)
|
||||||
|
{
|
||||||
|
if ((methodFlags(t, method) & ACC_STATIC) == 0) {
|
||||||
|
if (methodVirtual(t, method)) {
|
||||||
|
return findVirtualMethod(t, method, objectClass(t, instance));
|
||||||
|
} else if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
||||||
|
return findInterfaceMethod(t, method, objectClass(t, instance));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
resolveTarget(MyThread* t, void* stack, object method)
|
resolveTarget(MyThread* t, void* stack, object method)
|
||||||
{
|
{
|
||||||
@ -154,7 +167,7 @@ resolveTarget(MyThread* t, void* stack, object method)
|
|||||||
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
||||||
return findInterfaceMethod(t, method, class_);
|
return findInterfaceMethod(t, method, class_);
|
||||||
} else {
|
} else {
|
||||||
return findMethod(t, method, class_);
|
return findVirtualMethod(t, method, class_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2498,7 +2511,7 @@ bool
|
|||||||
needsReturnBarrier(MyThread* t, object method)
|
needsReturnBarrier(MyThread* t, object method)
|
||||||
{
|
{
|
||||||
return (methodFlags(t, method) & ConstructorFlag)
|
return (methodFlags(t, method) & ConstructorFlag)
|
||||||
and (classFlags(t, methodClass(t, method)) & HasFinalMemberFlag);
|
and (classVmFlags(t, methodClass(t, method)) & HasFinalMemberFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -3513,7 +3526,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
object class_ = methodClass(t, context->method);
|
object class_ = methodClass(t, context->method);
|
||||||
if (isSpecialMethod(t, target, class_)) {
|
if (isSpecialMethod(t, target, class_)) {
|
||||||
target = findMethod(t, target, classSuper(t, class_));
|
target = findVirtualMethod(t, target, classSuper(t, class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
assert(t, (methodFlags(t, target) & ACC_STATIC) == 0);
|
||||||
@ -3733,7 +3746,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
if (singletonIsObject(t, pool, index - 1)) {
|
if (singletonIsObject(t, pool, index - 1)) {
|
||||||
object v = singletonObject(t, pool, index - 1);
|
object v = singletonObject(t, pool, index - 1);
|
||||||
if (objectClass(t, v)
|
if (objectClass(t, v)
|
||||||
== arrayBody(t, t->m->types, Machine::ByteArrayType))
|
== arrayBody(t, t->m->types, Machine::ReferenceType))
|
||||||
{
|
{
|
||||||
object class_ = resolveClassInPool(t, context->method, index - 1);
|
object class_ = resolveClassInPool(t, context->method, index - 1);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
@ -6333,6 +6346,8 @@ class SegFaultHandler: public System::SignalHandler {
|
|||||||
t->exception = makeNullPointerException(t);
|
t->exception = makeNullPointerException(t);
|
||||||
t->tracing = false;
|
t->tracing = false;
|
||||||
|
|
||||||
|
// printTrace(t, t->exception);
|
||||||
|
|
||||||
findUnwindTarget(t, ip, base, stack);
|
findUnwindTarget(t, ip, base, stack);
|
||||||
|
|
||||||
t->ip = oldIp;
|
t->ip = oldIp;
|
||||||
@ -6429,10 +6444,10 @@ class MyProcessor: public Processor {
|
|||||||
virtual object
|
virtual object
|
||||||
makeClass(vm::Thread* t,
|
makeClass(vm::Thread* t,
|
||||||
uint16_t flags,
|
uint16_t flags,
|
||||||
uint8_t vmFlags,
|
uint16_t vmFlags,
|
||||||
uint8_t arrayDimensions,
|
|
||||||
uint16_t fixedSize,
|
uint16_t fixedSize,
|
||||||
uint16_t arrayElementSize,
|
uint8_t arrayElementSize,
|
||||||
|
uint8_t arrayDimensions,
|
||||||
object objectMask,
|
object objectMask,
|
||||||
object name,
|
object name,
|
||||||
object super,
|
object super,
|
||||||
@ -6445,7 +6460,7 @@ class MyProcessor: public Processor {
|
|||||||
unsigned vtableLength)
|
unsigned vtableLength)
|
||||||
{
|
{
|
||||||
return vm::makeClass
|
return vm::makeClass
|
||||||
(t, flags, vmFlags, arrayDimensions, fixedSize, arrayElementSize,
|
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions,
|
||||||
objectMask, name, super, interfaceTable, virtualTable, fieldTable,
|
objectMask, name, super, interfaceTable, virtualTable, fieldTable,
|
||||||
methodTable, staticTable, loader, vtableLength);
|
methodTable, staticTable, loader, vtableLength);
|
||||||
}
|
}
|
||||||
@ -6543,6 +6558,8 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
||||||
|
|
||||||
|
method = findMethod(t, method, this_);
|
||||||
|
|
||||||
const char* spec = reinterpret_cast<char*>
|
const char* spec = reinterpret_cast<char*>
|
||||||
(&byteArrayBody(t, methodSpec(t, method), 0));
|
(&byteArrayBody(t, methodSpec(t, method), 0));
|
||||||
|
|
||||||
@ -6574,6 +6591,8 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
||||||
|
|
||||||
|
method = findMethod(t, method, this_);
|
||||||
|
|
||||||
const char* spec = reinterpret_cast<char*>
|
const char* spec = reinterpret_cast<char*>
|
||||||
(&byteArrayBody(t, methodSpec(t, method), 0));
|
(&byteArrayBody(t, methodSpec(t, method), 0));
|
||||||
|
|
||||||
|
49
src/gnu.cpp
49
src/gnu.cpp
@ -183,20 +183,17 @@ Avian_gnu_classpath_VMSystemProperties_preInit
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
|
setProperty(t, method, properties, "gnu.cpu.endian", "little");
|
||||||
setProperty(t, method, properties, "os.arch", "x86");
|
setProperty(t, method, properties, "os.arch", "x86");
|
||||||
#elif defined __x86_64__
|
#elif defined __x86_64__
|
||||||
|
setProperty(t, method, properties, "gnu.cpu.endian", "little");
|
||||||
setProperty(t, method, properties, "os.arch", "x86_64");
|
setProperty(t, method, properties, "os.arch", "x86_64");
|
||||||
#elif defined(__ppc__) || defined(__powerpc__) \
|
#elif defined(__ppc__) || defined(__powerpc__) \
|
||||||
|| defined(__ppc64__) || defined(__powerpc64__)
|
|| defined(__ppc64__) || defined(__powerpc64__)
|
||||||
|
setProperty(t, method, properties, "gnu.cpu.endian", "big");
|
||||||
setProperty(t, method, properties, "os.arch", "ppc");
|
setProperty(t, method, properties, "os.arch", "ppc");
|
||||||
#elif defined __ia64__
|
|
||||||
setProperty(t, method, properties, "os.arch", "ia64");
|
|
||||||
#elif defined __arm__
|
#elif defined __arm__
|
||||||
setProperty(t, method, properties, "os.arch", "arm");
|
setProperty(t, method, properties, "os.arch", "arm");
|
||||||
#elif defined __alpha__
|
|
||||||
setProperty(t, method, properties, "os.arch", "alpha");
|
|
||||||
#elif defined __sparc64__
|
|
||||||
setProperty(t, method, properties, "os.arch", "sparc64");
|
|
||||||
#else
|
#else
|
||||||
setProperty(t, method, properties, "os.arch", "unknown");
|
setProperty(t, method, properties, "os.arch", "unknown");
|
||||||
#endif
|
#endif
|
||||||
@ -461,3 +458,43 @@ Avian_java_lang_VMClassLoader_findLoadedClass
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_compareAndSwapInt
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object target = reinterpret_cast<object>(arguments[1]);
|
||||||
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
||||||
|
int32_t expect = arguments[4];
|
||||||
|
int32_t update = arguments[5];
|
||||||
|
|
||||||
|
return __sync_bool_compare_and_swap
|
||||||
|
(&cast<int32_t>(target, offset), expect, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_compareAndSwapLong
|
||||||
|
(Thread*, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
object target = reinterpret_cast<object>(arguments[1]);
|
||||||
|
int64_t offset; memcpy(&offset, arguments + 2, 8);
|
||||||
|
int64_t expect; memcpy(&expect, arguments + 4, 8);
|
||||||
|
int64_t update; memcpy(&update, arguments + 6, 8);
|
||||||
|
|
||||||
|
return __sync_bool_compare_and_swap
|
||||||
|
(&cast<int64_t>(target, offset), expect, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_sun_misc_Unsafe_objectFieldOffset
|
||||||
|
(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
return fieldOffset(t, reinterpret_cast<object>(arguments[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT int64_t JNICALL
|
||||||
|
Avian_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8
|
||||||
|
(Thread*, object, uintptr_t*)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -844,8 +844,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip)
|
|||||||
|
|
||||||
PROTECT(t, eht);
|
PROTECT(t, eht);
|
||||||
catchType = resolveClassInPool
|
catchType = resolveClassInPool
|
||||||
(t, codePool(t, methodCode(t, method)),
|
(t, method, exceptionHandlerCatchType(eh) - 1);
|
||||||
exceptionHandlerCatchType(eh) - 1);
|
|
||||||
|
|
||||||
if (catchType) {
|
if (catchType) {
|
||||||
eh = exceptionHandlerTableBody(t, eht, i);
|
eh = exceptionHandlerTableBody(t, eht, i);
|
||||||
@ -1025,10 +1024,12 @@ interpret(Thread* t)
|
|||||||
if (LIKELY(count >= 0)) {
|
if (LIKELY(count >= 0)) {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
|
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
pushObject(t, makeObjectArray(t, class_, count));
|
pushObject(t, makeObjectArray
|
||||||
|
(t, classLoader(t, methodClass(t, frameMethod(t, frame))),
|
||||||
|
class_, count));
|
||||||
} else {
|
} else {
|
||||||
object message = makeString(t, "%d", count);
|
object message = makeString(t, "%d", count);
|
||||||
exception = makeNegativeArraySizeException(t, message);
|
exception = makeNegativeArraySizeException(t, message);
|
||||||
@ -1211,7 +1212,7 @@ interpret(Thread* t)
|
|||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
if (peekObject(t, sp - 1)) {
|
if (peekObject(t, sp - 1)) {
|
||||||
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
|
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
if (not instanceOf(t, class_, peekObject(t, sp - 1))) {
|
if (not instanceOf(t, class_, peekObject(t, sp - 1))) {
|
||||||
@ -1568,7 +1569,7 @@ interpret(Thread* t)
|
|||||||
if (LIKELY(peekObject(t, sp - 1))) {
|
if (LIKELY(peekObject(t, sp - 1))) {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object field = resolveField(t, codePool(t, code), index - 1);
|
object field = resolveField(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
||||||
@ -1602,7 +1603,7 @@ interpret(Thread* t)
|
|||||||
case getstatic: {
|
case getstatic: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object field = resolveField(t, codePool(t, code), index - 1);
|
object field = resolveField(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
assert(t, fieldFlags(t, field) & ACC_STATIC);
|
assert(t, fieldFlags(t, field) & ACC_STATIC);
|
||||||
@ -1958,7 +1959,7 @@ interpret(Thread* t)
|
|||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
if (peekObject(t, sp - 1)) {
|
if (peekObject(t, sp - 1)) {
|
||||||
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
|
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
if (instanceOf(t, class_, popObject(t))) {
|
if (instanceOf(t, class_, popObject(t))) {
|
||||||
@ -1977,7 +1978,7 @@ interpret(Thread* t)
|
|||||||
|
|
||||||
ip += 2;
|
ip += 2;
|
||||||
|
|
||||||
object method = resolveMethod(t, codePool(t, code), index - 1);
|
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
@ -1994,7 +1995,7 @@ interpret(Thread* t)
|
|||||||
case invokespecial: {
|
case invokespecial: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object method = resolveMethod(t, codePool(t, code), index - 1);
|
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
@ -2004,7 +2005,7 @@ interpret(Thread* t)
|
|||||||
class_ = classSuper(t, class_);
|
class_ = classSuper(t, class_);
|
||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||||
|
|
||||||
code = findMethod(t, method, class_);
|
code = findVirtualMethod(t, method, class_);
|
||||||
} else {
|
} else {
|
||||||
code = method;
|
code = method;
|
||||||
}
|
}
|
||||||
@ -2019,7 +2020,7 @@ interpret(Thread* t)
|
|||||||
case invokestatic: {
|
case invokestatic: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object method = resolveMethod(t, codePool(t, code), index - 1);
|
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
|
|
||||||
@ -2031,7 +2032,7 @@ interpret(Thread* t)
|
|||||||
case invokevirtual: {
|
case invokevirtual: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object method = resolveMethod(t, codePool(t, code), index - 1);
|
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
@ -2039,7 +2040,7 @@ interpret(Thread* t)
|
|||||||
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||||
|
|
||||||
code = findMethod(t, method, class_);
|
code = findVirtualMethod(t, method, class_);
|
||||||
goto invoke;
|
goto invoke;
|
||||||
} else {
|
} else {
|
||||||
exception = makeNullPointerException(t);
|
exception = makeNullPointerException(t);
|
||||||
@ -2246,9 +2247,10 @@ interpret(Thread* t)
|
|||||||
if (singletonIsObject(t, pool, index - 1)) {
|
if (singletonIsObject(t, pool, index - 1)) {
|
||||||
object v = singletonObject(t, pool, index - 1);
|
object v = singletonObject(t, pool, index - 1);
|
||||||
if (objectClass(t, v)
|
if (objectClass(t, v)
|
||||||
== arrayBody(t, t->m->types, Machine::ByteArrayType))
|
== arrayBody(t, t->m->types, Machine::ReferenceType))
|
||||||
{
|
{
|
||||||
object class_ = resolveClassInPool(t, pool, index - 1);
|
object class_ = resolveClassInPool
|
||||||
|
(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
pushObject(t, class_);
|
pushObject(t, class_);
|
||||||
@ -2455,7 +2457,7 @@ interpret(Thread* t)
|
|||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
uint8_t dimensions = codeBody(t, code, ip++);
|
uint8_t dimensions = codeBody(t, code, ip++);
|
||||||
|
|
||||||
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
|
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
@ -2481,7 +2483,7 @@ interpret(Thread* t)
|
|||||||
case new_: {
|
case new_: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
|
object class_ = resolveClassInPool(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
@ -2555,7 +2557,7 @@ interpret(Thread* t)
|
|||||||
case putfield: {
|
case putfield: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object field = resolveField(t, codePool(t, code), index - 1);
|
object field = resolveField(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||||
@ -2645,7 +2647,7 @@ interpret(Thread* t)
|
|||||||
case putstatic: {
|
case putstatic: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
object field = resolveField(t, codePool(t, code), index - 1);
|
object field = resolveField(t, frameMethod(t, frame), index - 1);
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||||
@ -2724,7 +2726,7 @@ interpret(Thread* t)
|
|||||||
case return_: {
|
case return_: {
|
||||||
object method = frameMethod(t, frame);
|
object method = frameMethod(t, frame);
|
||||||
if ((methodFlags(t, method) & ConstructorFlag)
|
if ((methodFlags(t, method) & ConstructorFlag)
|
||||||
and (classFlags(t, methodClass(t, method)) & HasFinalMemberFlag))
|
and (classVmFlags(t, methodClass(t, method)) & HasFinalMemberFlag))
|
||||||
{
|
{
|
||||||
storeStoreMemoryBarrier();
|
storeStoreMemoryBarrier();
|
||||||
}
|
}
|
||||||
@ -2825,13 +2827,14 @@ interpret(Thread* t)
|
|||||||
ip -= 2;
|
ip -= 2;
|
||||||
|
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
object method = resolveMethod(t, codePool(t, code), index - 1);
|
object method = resolveMethod(t, frameMethod(t, frame), index - 1);
|
||||||
|
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
||||||
assert(t, classVmFlags(t, class_) & BootstrapFlag);
|
assert(t, classVmFlags(t, class_) & BootstrapFlag);
|
||||||
|
|
||||||
resolveClass(t, className(t, class_));
|
resolveClass(t, classLoader(t, methodClass(t, frameMethod(t, frame))),
|
||||||
|
className(t, class_));
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
if (UNLIKELY(exception)) goto throw_;
|
||||||
|
|
||||||
ip -= 3;
|
ip -= 3;
|
||||||
@ -2999,13 +3002,13 @@ invoke(Thread* t, object method)
|
|||||||
class_ = objectClass(t, peekObject(t, t->sp - parameterFootprint));
|
class_ = objectClass(t, peekObject(t, t->sp - parameterFootprint));
|
||||||
|
|
||||||
if (classVmFlags(t, class_) & BootstrapFlag) {
|
if (classVmFlags(t, class_) & BootstrapFlag) {
|
||||||
resolveClass(t, className(t, class_));
|
resolveClass(t, t->m->loader, className(t, class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
||||||
method = findInterfaceMethod(t, method, class_);
|
method = findInterfaceMethod(t, method, class_);
|
||||||
} else {
|
} else {
|
||||||
method = findMethod(t, method, class_);
|
method = findVirtualMethod(t, method, class_);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
class_ = methodClass(t, method);
|
class_ = methodClass(t, method);
|
||||||
@ -3100,10 +3103,10 @@ class MyProcessor: public Processor {
|
|||||||
virtual object
|
virtual object
|
||||||
makeClass(vm::Thread* t,
|
makeClass(vm::Thread* t,
|
||||||
uint16_t flags,
|
uint16_t flags,
|
||||||
uint8_t vmFlags,
|
uint16_t vmFlags,
|
||||||
uint8_t arrayDimensions,
|
|
||||||
uint16_t fixedSize,
|
uint16_t fixedSize,
|
||||||
uint16_t arrayElementSize,
|
uint8_t arrayElementSize,
|
||||||
|
uint8_t arrayDimensions,
|
||||||
object objectMask,
|
object objectMask,
|
||||||
object name,
|
object name,
|
||||||
object super,
|
object super,
|
||||||
@ -3116,7 +3119,7 @@ class MyProcessor: public Processor {
|
|||||||
unsigned vtableLength UNUSED)
|
unsigned vtableLength UNUSED)
|
||||||
{
|
{
|
||||||
return vm::makeClass
|
return vm::makeClass
|
||||||
(t, flags, vmFlags, arrayDimensions, fixedSize, arrayElementSize,
|
(t, flags, vmFlags, fixedSize, arrayElementSize, arrayDimensions,
|
||||||
objectMask, name, super, interfaceTable, virtualTable, fieldTable,
|
objectMask, name, super, interfaceTable, virtualTable, fieldTable,
|
||||||
methodTable, staticTable, loader, 0);
|
methodTable, staticTable, loader, 0);
|
||||||
}
|
}
|
||||||
@ -3230,8 +3233,9 @@ class MyProcessor: public Processor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual object
|
virtual object
|
||||||
invokeList(vm::Thread* vmt, const char* className, const char* methodName,
|
invokeList(vm::Thread* vmt, object loader, const char* className,
|
||||||
const char* methodSpec, object this_, va_list arguments)
|
const char* methodName, const char* methodSpec, object this_,
|
||||||
|
va_list arguments)
|
||||||
{
|
{
|
||||||
Thread* t = static_cast<Thread*>(vmt);
|
Thread* t = static_cast<Thread*>(vmt);
|
||||||
|
|
||||||
@ -3247,7 +3251,9 @@ class MyProcessor: public Processor {
|
|||||||
|
|
||||||
pushArguments(t, this_, methodSpec, false, arguments);
|
pushArguments(t, this_, methodSpec, false, arguments);
|
||||||
|
|
||||||
object method = resolveMethod(t, className, methodName, methodSpec);
|
object method = resolveMethod
|
||||||
|
(t, loader, className, methodName, methodSpec);
|
||||||
|
|
||||||
if (LIKELY(t->exception == 0)) {
|
if (LIKELY(t->exception == 0)) {
|
||||||
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
assert(t, ((methodFlags(t, method) & ACC_STATIC) == 0) xor (this_ == 0));
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ DetachCurrentThread(Machine* m)
|
|||||||
{
|
{
|
||||||
Thread* t = static_cast<Thread*>(m->localThread->get());
|
Thread* t = static_cast<Thread*>(m->localThread->get());
|
||||||
if (t) {
|
if (t) {
|
||||||
|
m->localThread->set(0);
|
||||||
t->exit();
|
t->exit();
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -2003,6 +2004,7 @@ populateJNITables(JavaVMVTable* vmTable, JNIEnvVTable* envTable)
|
|||||||
envTable->SetStaticFloatField = ::SetStaticFloatField;
|
envTable->SetStaticFloatField = ::SetStaticFloatField;
|
||||||
envTable->SetStaticDoubleField = ::SetStaticDoubleField;
|
envTable->SetStaticDoubleField = ::SetStaticDoubleField;
|
||||||
envTable->NewGlobalRef = ::NewGlobalRef;
|
envTable->NewGlobalRef = ::NewGlobalRef;
|
||||||
|
envTable->NewWeakGlobalRef = ::NewGlobalRef;
|
||||||
envTable->DeleteGlobalRef = ::DeleteGlobalRef;
|
envTable->DeleteGlobalRef = ::DeleteGlobalRef;
|
||||||
envTable->ExceptionOccurred = ::ExceptionOccurred;
|
envTable->ExceptionOccurred = ::ExceptionOccurred;
|
||||||
envTable->ExceptionDescribe = ::ExceptionDescribe;
|
envTable->ExceptionDescribe = ::ExceptionDescribe;
|
||||||
|
260
src/machine.cpp
260
src/machine.cpp
@ -19,6 +19,8 @@ using namespace vm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const unsigned NoByte = 0xFFFF;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
find(Thread* t, Thread* o)
|
find(Thread* t, Thread* o)
|
||||||
{
|
{
|
||||||
@ -540,9 +542,65 @@ makeByteArray(Thread* t, const char* format, va_list a)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
resolveSpec(Thread* t, object loader, object spec, unsigned offset)
|
||||||
|
{
|
||||||
|
int8_t* s = &byteArrayBody(t, spec, offset);
|
||||||
|
unsigned result;
|
||||||
|
switch (*s) {
|
||||||
|
case 'L':
|
||||||
|
++ offset;
|
||||||
|
while (*s and *s != ';') ++ s;
|
||||||
|
result = s + 1 - &byteArrayBody(t, spec, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
while (*s == '[') ++ s;
|
||||||
|
switch (*s) {
|
||||||
|
case 'L':
|
||||||
|
while (*s and *s != ';') ++ s;
|
||||||
|
++ s;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
++ s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = s - &byteArrayBody(t, spec, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return offset + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROTECT(t, spec);
|
||||||
|
|
||||||
|
unsigned length = s - &byteArrayBody(t, spec, offset);
|
||||||
|
|
||||||
|
object name = makeByteArray(t, length + 1);
|
||||||
|
memcpy(&byteArrayBody(t, name, 0),
|
||||||
|
&byteArrayBody(t, spec, offset),
|
||||||
|
length);
|
||||||
|
resolveClass(t, loader, name);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
readByte(Stream& s, unsigned* value)
|
||||||
|
{
|
||||||
|
if (*value == NoByte) {
|
||||||
|
return s.read1();
|
||||||
|
} else {
|
||||||
|
unsigned r = *value;
|
||||||
|
*value = NoByte;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
|
parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
|
||||||
unsigned sourceIndex, unsigned lastByteRead)
|
unsigned sourceIndex, unsigned byteA, unsigned byteB)
|
||||||
{
|
{
|
||||||
PROTECT(t, bytesSoFar);
|
PROTECT(t, bytesSoFar);
|
||||||
|
|
||||||
@ -554,15 +612,14 @@ parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
|
|||||||
charArrayBody(t, value, vi) = byteArrayBody(t, bytesSoFar, vi);
|
charArrayBody(t, value, vi) = byteArrayBody(t, bytesSoFar, vi);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned a = lastByteRead;
|
for (unsigned si = sourceIndex; si < length; ++si) {
|
||||||
unsigned si = sourceIndex;
|
unsigned a = readByte(s, &byteA);
|
||||||
while (true) {
|
|
||||||
if (a & 0x80) {
|
if (a & 0x80) {
|
||||||
if (a & 0x20) {
|
if (a & 0x20) {
|
||||||
// 3 bytes
|
// 3 bytes
|
||||||
si += 2;
|
si += 2;
|
||||||
assert(t, si < length);
|
assert(t, si < length);
|
||||||
unsigned b = s.read1();
|
unsigned b = readByte(s, &byteB);
|
||||||
unsigned c = s.read1();
|
unsigned c = s.read1();
|
||||||
charArrayBody(t, value, vi++)
|
charArrayBody(t, value, vi++)
|
||||||
= ((a & 0xf) << 12) | ((b & 0x3f) << 6) | (c & 0x3f);
|
= ((a & 0xf) << 12) | ((b & 0x3f) << 6) | (c & 0x3f);
|
||||||
@ -570,7 +627,7 @@ parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
|
|||||||
// 2 bytes
|
// 2 bytes
|
||||||
++ si;
|
++ si;
|
||||||
assert(t, si < length);
|
assert(t, si < length);
|
||||||
unsigned b = s.read1();
|
unsigned b = readByte(s, &byteB);
|
||||||
|
|
||||||
if (a == 0xC0 and b == 0x80) {
|
if (a == 0xC0 and b == 0x80) {
|
||||||
charArrayBody(t, value, vi++) = 0;
|
charArrayBody(t, value, vi++) = 0;
|
||||||
@ -580,12 +637,6 @@ parseUtf8NonAscii(Thread* t, Stream& s, object bytesSoFar, unsigned byteCount,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
charArrayBody(t, value, vi++) = a;
|
charArrayBody(t, value, vi++) = a;
|
||||||
}
|
|
||||||
|
|
||||||
if (++si < length) {
|
|
||||||
a = s.read1();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,7 +662,7 @@ parseUtf8(Thread* t, Stream& s, unsigned length)
|
|||||||
if (a & 0x80) {
|
if (a & 0x80) {
|
||||||
if (a & 0x20) {
|
if (a & 0x20) {
|
||||||
// 3 bytes
|
// 3 bytes
|
||||||
return parseUtf8NonAscii(t, s, value, vi, si, a);
|
return parseUtf8NonAscii(t, s, value, vi, si, a, NoByte);
|
||||||
} else {
|
} else {
|
||||||
// 2 bytes
|
// 2 bytes
|
||||||
unsigned b = s.read1();
|
unsigned b = s.read1();
|
||||||
@ -621,7 +672,7 @@ parseUtf8(Thread* t, Stream& s, unsigned length)
|
|||||||
assert(t, si < length);
|
assert(t, si < length);
|
||||||
byteArrayBody(t, value, vi++) = 0;
|
byteArrayBody(t, value, vi++) = 0;
|
||||||
} else {
|
} else {
|
||||||
return parseUtf8NonAscii(t, s, value, vi, si, a);
|
return parseUtf8NonAscii(t, s, value, vi, si, a, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -699,7 +750,7 @@ parsePoolEntry(Thread* t, Stream& s, uint32_t* index, object pool, unsigned i)
|
|||||||
unsigned si = s.read2() - 1;
|
unsigned si = s.read2() - 1;
|
||||||
parsePoolEntry(t, s, index, pool, si);
|
parsePoolEntry(t, s, index, pool, si);
|
||||||
|
|
||||||
object value = singletonObject(t, pool, si);
|
object value = makeReference(t, 0, singletonObject(t, pool, si), 0);
|
||||||
set(t, pool, SingletonBody + (i * BytesPerWord), value);
|
set(t, pool, SingletonBody + (i * BytesPerWord), value);
|
||||||
}
|
}
|
||||||
} return 1;
|
} return 1;
|
||||||
@ -742,7 +793,7 @@ parsePoolEntry(Thread* t, Stream& s, uint32_t* index, object pool, unsigned i)
|
|||||||
parsePoolEntry(t, s, index, pool, ci);
|
parsePoolEntry(t, s, index, pool, ci);
|
||||||
parsePoolEntry(t, s, index, pool, nti);
|
parsePoolEntry(t, s, index, pool, nti);
|
||||||
|
|
||||||
object class_ = singletonObject(t, pool, ci);
|
object class_ = referenceName(t, singletonObject(t, pool, ci));
|
||||||
object nameAndType = singletonObject(t, pool, nti);
|
object nameAndType = singletonObject(t, pool, nti);
|
||||||
object value = makeReference
|
object value = makeReference
|
||||||
(t, class_, pairFirst(t, nameAndType), pairSecond(t, nameAndType));
|
(t, class_, pairFirst(t, nameAndType), pairSecond(t, nameAndType));
|
||||||
@ -854,7 +905,7 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
|
|
||||||
unsigned count = s.read2();
|
unsigned count = s.read2();
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
object name = singletonObject(t, pool, s.read2() - 1);
|
object name = referenceName(t, singletonObject(t, pool, s.read2() - 1));
|
||||||
PROTECT(t, name);
|
PROTECT(t, name);
|
||||||
|
|
||||||
object interface = resolveClass(t, classLoader(t, class_), name);
|
object interface = resolveClass(t, classLoader(t, class_), name);
|
||||||
@ -976,7 +1027,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
staticTypes[staticCount++] = code;
|
staticTypes[staticCount++] = code;
|
||||||
} else {
|
} else {
|
||||||
if (flags & ACC_FINAL) {
|
if (flags & ACC_FINAL) {
|
||||||
classFlags(t, class_) |= HasFinalMemberFlag;
|
classVmFlags(t, class_) |= HasFinalMemberFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned excess = (memberOffset % fieldSize(t, code)) % BytesPerWord;
|
unsigned excess = (memberOffset % fieldSize(t, code)) % BytesPerWord;
|
||||||
@ -1326,7 +1377,8 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
hashMapInsert(t, virtualMap, method, method, methodHash);
|
hashMapInsert(t, virtualMap, method, method, methodHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(strcmp
|
if (UNLIKELY((classFlags(t, class_) & ACC_INTERFACE) == 0
|
||||||
|
and strcmp
|
||||||
(reinterpret_cast<const int8_t*>("finalize"),
|
(reinterpret_cast<const int8_t*>("finalize"),
|
||||||
&byteArrayBody(t, methodName(t, method), 0)) == 0
|
&byteArrayBody(t, methodName(t, method), 0)) == 0
|
||||||
and strcmp
|
and strcmp
|
||||||
@ -1557,9 +1609,9 @@ makeArrayClass(Thread* t, object loader, unsigned dimensions, object spec,
|
|||||||
(t,
|
(t,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
dimensions,
|
|
||||||
2 * BytesPerWord,
|
2 * BytesPerWord,
|
||||||
BytesPerWord,
|
BytesPerWord,
|
||||||
|
dimensions,
|
||||||
classObjectMask(t, arrayBody(t, t->m->types, Machine::ArrayType)),
|
classObjectMask(t, arrayBody(t, t->m->types, Machine::ArrayType)),
|
||||||
spec,
|
spec,
|
||||||
arrayBody(t, t->m->types, Machine::JobjectType),
|
arrayBody(t, t->m->types, Machine::JobjectType),
|
||||||
@ -1696,7 +1748,7 @@ bootClass(Thread* t, Machine::Type type, int superType, uint32_t objectMask,
|
|||||||
super = (superType >= 0 ? arrayBody(t, t->m->types, superType) : 0);
|
super = (superType >= 0 ? arrayBody(t, t->m->types, superType) : 0);
|
||||||
|
|
||||||
object class_ = t->m->processor->makeClass
|
object class_ = t->m->processor->makeClass
|
||||||
(t, 0, BootstrapFlag, 0, fixedSize, arrayElementSize, mask, 0, super, 0, 0,
|
(t, 0, BootstrapFlag, fixedSize, arrayElementSize, 0, mask, 0, super, 0, 0,
|
||||||
0, 0, 0, t->m->loader, vtableLength);
|
0, 0, 0, t->m->loader, vtableLength);
|
||||||
|
|
||||||
set(t, t->m->types, ArrayBody + (type * BytesPerWord), class_);
|
set(t, t->m->types, ArrayBody + (type * BytesPerWord), class_);
|
||||||
@ -1765,16 +1817,18 @@ boot(Thread* t)
|
|||||||
|
|
||||||
m->unsafe = false;
|
m->unsafe = false;
|
||||||
|
|
||||||
classFlags(t, arrayBody(t, m->types, Machine::SingletonType))
|
classVmFlags(t, arrayBody(t, m->types, Machine::SingletonType))
|
||||||
|= SingletonFlag;
|
|= SingletonFlag;
|
||||||
|
|
||||||
classFlags(t, arrayBody(t, m->types, Machine::ContinuationType))
|
classVmFlags(t, arrayBody(t, m->types, Machine::ContinuationType))
|
||||||
|= ContinuationFlag;
|
|= ContinuationFlag;
|
||||||
|
|
||||||
classVmFlags(t, arrayBody(t, m->types, Machine::JreferenceType))
|
classVmFlags(t, arrayBody(t, m->types, Machine::JreferenceType))
|
||||||
|= ReferenceFlag;
|
|= ReferenceFlag;
|
||||||
classVmFlags(t, arrayBody(t, m->types, Machine::WeakReferenceType))
|
classVmFlags(t, arrayBody(t, m->types, Machine::WeakReferenceType))
|
||||||
|= ReferenceFlag | WeakReferenceFlag;
|
|= ReferenceFlag | WeakReferenceFlag;
|
||||||
|
classVmFlags(t, arrayBody(t, m->types, Machine::SoftReferenceType))
|
||||||
|
|= ReferenceFlag | WeakReferenceFlag;
|
||||||
classVmFlags(t, arrayBody(t, m->types, Machine::PhantomReferenceType))
|
classVmFlags(t, arrayBody(t, m->types, Machine::PhantomReferenceType))
|
||||||
|= ReferenceFlag | WeakReferenceFlag;
|
|= ReferenceFlag | WeakReferenceFlag;
|
||||||
|
|
||||||
@ -2064,8 +2118,6 @@ Thread::init()
|
|||||||
|
|
||||||
m->localThread->set(this);
|
m->localThread->set(this);
|
||||||
} else {
|
} else {
|
||||||
assert(this, javaThread);
|
|
||||||
|
|
||||||
peer = parent->child;
|
peer = parent->child;
|
||||||
parent->child = this;
|
parent->child = this;
|
||||||
}
|
}
|
||||||
@ -2073,11 +2125,16 @@ Thread::init()
|
|||||||
if (javaThread) {
|
if (javaThread) {
|
||||||
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
|
threadPeer(this, javaThread) = reinterpret_cast<jlong>(this);
|
||||||
} else {
|
} else {
|
||||||
|
object group;
|
||||||
|
if (parent) {
|
||||||
|
group = threadGroup(this, parent->javaThread);
|
||||||
|
} else {
|
||||||
|
group = makeThreadGroup(this, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned NewState = 0;
|
const unsigned NewState = 0;
|
||||||
const unsigned NormalPriority = 5;
|
const unsigned NormalPriority = 5;
|
||||||
|
|
||||||
object group = makeThreadGroup(this, 0, 0);
|
|
||||||
|
|
||||||
this->javaThread = makeThread
|
this->javaThread = makeThread
|
||||||
(this, reinterpret_cast<int64_t>(this), 0, 0, NewState, NormalPriority,
|
(this, reinterpret_cast<int64_t>(this), 0, 0, NewState, NormalPriority,
|
||||||
0, 0, 0, m->loader, 0, 0, group);
|
0, 0, 0, m->loader, 0, 0, group);
|
||||||
@ -2428,16 +2485,18 @@ makeString(Thread* t, const char* format, ...)
|
|||||||
void
|
void
|
||||||
stringChars(Thread* t, object string, char* chars)
|
stringChars(Thread* t, object string, char* chars)
|
||||||
{
|
{
|
||||||
object data = stringData(t, string);
|
if (stringLength(t, string)) {
|
||||||
if (objectClass(t, data)
|
object data = stringData(t, string);
|
||||||
== arrayBody(t, t->m->types, Machine::ByteArrayType))
|
if (objectClass(t, data)
|
||||||
{
|
== arrayBody(t, t->m->types, Machine::ByteArrayType))
|
||||||
memcpy(chars,
|
{
|
||||||
&byteArrayBody(t, data, stringOffset(t, string)),
|
memcpy(chars,
|
||||||
stringLength(t, string));
|
&byteArrayBody(t, data, stringOffset(t, string)),
|
||||||
} else {
|
stringLength(t, string));
|
||||||
for (unsigned i = 0; i < stringLength(t, string); ++i) {
|
} else {
|
||||||
chars[i] = charArrayBody(t, data, stringOffset(t, string) + i);
|
for (unsigned i = 0; i < stringLength(t, string); ++i) {
|
||||||
|
chars[i] = charArrayBody(t, data, stringOffset(t, string) + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chars[stringLength(t, string)] = 0;
|
chars[stringLength(t, string)] = 0;
|
||||||
@ -2446,17 +2505,19 @@ stringChars(Thread* t, object string, char* chars)
|
|||||||
void
|
void
|
||||||
stringChars(Thread* t, object string, uint16_t* chars)
|
stringChars(Thread* t, object string, uint16_t* chars)
|
||||||
{
|
{
|
||||||
object data = stringData(t, string);
|
if (stringLength(t, string)) {
|
||||||
if (objectClass(t, data)
|
object data = stringData(t, string);
|
||||||
== arrayBody(t, t->m->types, Machine::ByteArrayType))
|
if (objectClass(t, data)
|
||||||
{
|
== arrayBody(t, t->m->types, Machine::ByteArrayType))
|
||||||
for (unsigned i = 0; i < stringLength(t, string); ++i) {
|
{
|
||||||
chars[i] = byteArrayBody(t, data, stringOffset(t, string) + i);
|
for (unsigned i = 0; i < stringLength(t, string); ++i) {
|
||||||
|
chars[i] = byteArrayBody(t, data, stringOffset(t, string) + i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(chars,
|
||||||
|
&charArrayBody(t, data, stringOffset(t, string)),
|
||||||
|
stringLength(t, string) * sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
memcpy(chars,
|
|
||||||
&charArrayBody(t, data, stringOffset(t, string)),
|
|
||||||
stringLength(t, string) * sizeof(uint16_t));
|
|
||||||
}
|
}
|
||||||
chars[stringLength(t, string)] = 0;
|
chars[stringLength(t, string)] = 0;
|
||||||
}
|
}
|
||||||
@ -2649,11 +2710,12 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
|
|||||||
object class_ = makeClass(t,
|
object class_ = makeClass(t,
|
||||||
flags,
|
flags,
|
||||||
0, // VM flags
|
0, // VM flags
|
||||||
0, // array dimensions
|
|
||||||
0, // fixed size
|
0, // fixed size
|
||||||
0, // array size
|
0, // array size
|
||||||
|
0, // array dimensions
|
||||||
0, // object mask
|
0, // object mask
|
||||||
singletonObject(t, pool, name - 1),
|
referenceName
|
||||||
|
(t, singletonObject(t, pool, name - 1)),
|
||||||
0, // super
|
0, // super
|
||||||
0, // interfaces
|
0, // interfaces
|
||||||
0, // vtable
|
0, // vtable
|
||||||
@ -2666,7 +2728,8 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
|
|||||||
|
|
||||||
unsigned super = s.read2();
|
unsigned super = s.read2();
|
||||||
if (super) {
|
if (super) {
|
||||||
object sc = resolveClass(t, loader, singletonObject(t, pool, super - 1));
|
object sc = resolveClass
|
||||||
|
(t, loader, referenceName(t, singletonObject(t, pool, super - 1)));
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
set(t, class_, ClassSuper, sc);
|
set(t, class_, ClassSuper, sc);
|
||||||
@ -2692,9 +2755,9 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size)
|
|||||||
(t,
|
(t,
|
||||||
classFlags(t, class_),
|
classFlags(t, class_),
|
||||||
classVmFlags(t, class_),
|
classVmFlags(t, class_),
|
||||||
classArrayDimensions(t, class_),
|
|
||||||
classFixedSize(t, class_),
|
classFixedSize(t, class_),
|
||||||
classArrayElementSize(t, class_),
|
classArrayElementSize(t, class_),
|
||||||
|
classArrayDimensions(t, class_),
|
||||||
classObjectMask(t, class_),
|
classObjectMask(t, class_),
|
||||||
className(t, class_),
|
className(t, class_),
|
||||||
classSuper(t, class_),
|
classSuper(t, class_),
|
||||||
@ -2821,7 +2884,7 @@ resolveClass(Thread* t, object loader, object spec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (LIKELY(t->exception == 0)) {
|
if (LIKELY(t->exception == 0)) {
|
||||||
object method = findMethod
|
object method = findVirtualMethod
|
||||||
(t, t->m->loadClassMethod, objectClass(t, loader));
|
(t, t->m->loadClassMethod, objectClass(t, loader));
|
||||||
|
|
||||||
if (LIKELY(t->exception == 0)) {
|
if (LIKELY(t->exception == 0)) {
|
||||||
@ -2853,6 +2916,95 @@ resolveClass(Thread* t, object loader, object spec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
linkClass(Thread* t, object loader, object class_)
|
||||||
|
{
|
||||||
|
PROTECT(t, loader);
|
||||||
|
PROTECT(t, class_);
|
||||||
|
|
||||||
|
ACQUIRE(t, t->m->classLock);
|
||||||
|
|
||||||
|
if ((classVmFlags(t, class_) & LinkFlag) == 0) {
|
||||||
|
if (classSuper(t, class_)) {
|
||||||
|
linkClass(t, loader, classSuper(t, class_));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classInterfaceTable(t, class_)) {
|
||||||
|
unsigned increment = 2;
|
||||||
|
if (classFlags(t, class_) & ACC_INTERFACE) {
|
||||||
|
increment = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, classInterfaceTable(t, class_));
|
||||||
|
i += increment)
|
||||||
|
{
|
||||||
|
linkClass(t, loader, arrayBody(t, classInterfaceTable(t, class_), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classMethodTable(t, class_)) {
|
||||||
|
bool resolvedPool = false;
|
||||||
|
for (unsigned i = 0;
|
||||||
|
i < arrayLength(t, classMethodTable(t, class_)); ++i)
|
||||||
|
{
|
||||||
|
object method = arrayBody(t, classMethodTable(t, class_), i);
|
||||||
|
PROTECT(t, method);
|
||||||
|
|
||||||
|
object code = methodCode(t, method);
|
||||||
|
if ((not resolvedPool)
|
||||||
|
and code
|
||||||
|
and codePool(t, code)
|
||||||
|
and objectClass(t, codePool(t, code))
|
||||||
|
== arrayBody(t, t->m->types, Machine::SingletonType))
|
||||||
|
{
|
||||||
|
object pool = codePool(t, code);
|
||||||
|
PROTECT(t, pool);
|
||||||
|
unsigned count = singletonCount(t, pool);
|
||||||
|
for (unsigned j = 0; j < count; ++j) {
|
||||||
|
if (singletonIsObject(t, pool, j)) {
|
||||||
|
object entry = singletonObject(t, pool, j);
|
||||||
|
if (objectClass(t, entry)
|
||||||
|
== arrayBody(t, t->m->types, Machine::ReferenceType))
|
||||||
|
{
|
||||||
|
if (referenceSpec(t, entry) == 0) {
|
||||||
|
resolveClassInPool(t, loader, method, j);
|
||||||
|
} else if (byteArrayBody(t, referenceSpec(t, entry), 0) == '(')
|
||||||
|
{
|
||||||
|
resolveMethod(t, loader, method, j);
|
||||||
|
} else {
|
||||||
|
resolveField(t, loader, method, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedPool = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
object spec = methodSpec(t, method);
|
||||||
|
PROTECT(t, spec);
|
||||||
|
for (unsigned j = 1; j < byteArrayLength(t, spec);) {
|
||||||
|
j = resolveSpec(t, loader, spec, j);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classFieldTable(t, class_)) {
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, classFieldTable(t, class_)); ++i)
|
||||||
|
{
|
||||||
|
resolveSpec(t, loader, fieldSpec
|
||||||
|
(t, arrayBody(t, classFieldTable(t, class_), i)), 0);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
classVmFlags(t, class_) |= LinkFlag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object
|
object
|
||||||
resolveMethod(Thread* t, object class_, const char* methodName,
|
resolveMethod(Thread* t, object class_, const char* methodName,
|
||||||
const char* methodSpec)
|
const char* methodSpec)
|
||||||
@ -3272,7 +3424,7 @@ walk(Thread* t, Heap::Walker* w, object o, unsigned start)
|
|||||||
intArrayLength(t, objectMask) * 4);
|
intArrayLength(t, objectMask) * 4);
|
||||||
|
|
||||||
more = ::walk(t, w, mask, fixedSize, arrayElementSize, arrayLength, start);
|
more = ::walk(t, w, mask, fixedSize, arrayElementSize, arrayLength, start);
|
||||||
} else if (classFlags(t, class_) & SingletonFlag) {
|
} else if (classVmFlags(t, class_) & SingletonFlag) {
|
||||||
unsigned length = singletonLength(t, o);
|
unsigned length = singletonLength(t, o);
|
||||||
if (length) {
|
if (length) {
|
||||||
more = ::walk(t, w, singletonMask(t, o),
|
more = ::walk(t, w, singletonMask(t, o),
|
||||||
@ -3284,7 +3436,7 @@ walk(Thread* t, Heap::Walker* w, object o, unsigned start)
|
|||||||
more = w->visit(0);
|
more = w->visit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (more and classFlags(t, class_) & ContinuationFlag) {
|
if (more and classVmFlags(t, class_) & ContinuationFlag) {
|
||||||
t->m->processor->walkContinuationBody(t, w, o, start);
|
t->m->processor->walkContinuationBody(t, w, o, start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
111
src/machine.h
111
src/machine.h
@ -74,12 +74,6 @@ enum StackTag {
|
|||||||
const int NativeLine = -1;
|
const int NativeLine = -1;
|
||||||
const int UnknownLine = -2;
|
const int UnknownLine = -2;
|
||||||
|
|
||||||
// class flags (note that we must be careful not to overlap the
|
|
||||||
// standard ACC_* flags):
|
|
||||||
const unsigned HasFinalMemberFlag = 1 << 13;
|
|
||||||
const unsigned SingletonFlag = 1 << 14;
|
|
||||||
const unsigned ContinuationFlag = 1 << 15;
|
|
||||||
|
|
||||||
// class vmFlags:
|
// class vmFlags:
|
||||||
const unsigned ReferenceFlag = 1 << 0;
|
const unsigned ReferenceFlag = 1 << 0;
|
||||||
const unsigned WeakReferenceFlag = 1 << 1;
|
const unsigned WeakReferenceFlag = 1 << 1;
|
||||||
@ -89,6 +83,10 @@ const unsigned InitErrorFlag = 1 << 4;
|
|||||||
const unsigned PrimitiveFlag = 1 << 5;
|
const unsigned PrimitiveFlag = 1 << 5;
|
||||||
const unsigned BootstrapFlag = 1 << 6;
|
const unsigned BootstrapFlag = 1 << 6;
|
||||||
const unsigned HasFinalizerFlag = 1 << 7;
|
const unsigned HasFinalizerFlag = 1 << 7;
|
||||||
|
const unsigned LinkFlag = 1 << 8;
|
||||||
|
const unsigned HasFinalMemberFlag = 1 << 9;
|
||||||
|
const unsigned SingletonFlag = 1 << 10;
|
||||||
|
const unsigned ContinuationFlag = 1 << 11;
|
||||||
|
|
||||||
// method vmFlags:
|
// method vmFlags:
|
||||||
const unsigned ClassInitFlag = 1 << 0;
|
const unsigned ClassInitFlag = 1 << 0;
|
||||||
@ -1816,6 +1814,7 @@ makeNew(Thread* t, object class_)
|
|||||||
|
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
unsigned sizeInBytes = pad(classFixedSize(t, class_));
|
unsigned sizeInBytes = pad(classFixedSize(t, class_));
|
||||||
|
assert(t, sizeInBytes);
|
||||||
object instance = allocate(t, sizeInBytes, classObjectMask(t, class_));
|
object instance = allocate(t, sizeInBytes, classObjectMask(t, class_));
|
||||||
setObjectClass(t, instance, class_);
|
setObjectClass(t, instance, class_);
|
||||||
|
|
||||||
@ -2103,6 +2102,9 @@ resolveSystemClass(Thread* t, const char* name)
|
|||||||
return resolveSystemClass(t, makeByteArray(t, "%s", name));
|
return resolveSystemClass(t, makeByteArray(t, "%s", name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
linkClass(Thread* t, object loader, object class_);
|
||||||
|
|
||||||
object
|
object
|
||||||
resolveMethod(Thread* t, object class_, const char* methodName,
|
resolveMethod(Thread* t, object class_, const char* methodName,
|
||||||
const char* methodSpec);
|
const char* methodSpec);
|
||||||
@ -2185,7 +2187,7 @@ findMethod(Thread* t, object class_, object name, object spec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
inline object
|
||||||
findMethod(Thread* t, object method, object class_)
|
findVirtualMethod(Thread* t, object method, object class_)
|
||||||
{
|
{
|
||||||
return arrayBody(t, classVirtualTable(t, class_),
|
return arrayBody(t, classVirtualTable(t, class_),
|
||||||
methodOffset(t, method));
|
methodOffset(t, method));
|
||||||
@ -2444,6 +2446,101 @@ makeSingletonOfSize(Thread* t, unsigned count)
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveClassInObject(Thread* t, object loader, object container,
|
||||||
|
unsigned classOffset)
|
||||||
|
{
|
||||||
|
object o = cast<object>(container, classOffset);
|
||||||
|
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) {
|
||||||
|
PROTECT(t, container);
|
||||||
|
|
||||||
|
o = resolveClass(t, loader, o);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
set(t, container, classOffset, o);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveClassInPool(Thread* t, object loader, object method, unsigned index)
|
||||||
|
{
|
||||||
|
object o = singletonObject(t, codePool(t, methodCode(t, method)), index);
|
||||||
|
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType)) {
|
||||||
|
PROTECT(t, method);
|
||||||
|
|
||||||
|
o = resolveClass(t, loader, referenceName(t, o));
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
set(t, codePool(t, methodCode(t, method)),
|
||||||
|
SingletonBody + (index * BytesPerWord), o);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveClassInPool(Thread* t, object method, unsigned index)
|
||||||
|
{
|
||||||
|
return resolveClassInPool(t, classLoader(t, methodClass(t, method)),
|
||||||
|
method, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolve(Thread* t, object loader, object method, unsigned index,
|
||||||
|
object (*find)(vm::Thread*, object, object, object),
|
||||||
|
object (*makeError)(vm::Thread*, object))
|
||||||
|
{
|
||||||
|
object o = singletonObject(t, codePool(t, methodCode(t, method)), index);
|
||||||
|
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType))
|
||||||
|
{
|
||||||
|
PROTECT(t, method);
|
||||||
|
|
||||||
|
object reference = o;
|
||||||
|
PROTECT(t, reference);
|
||||||
|
|
||||||
|
object class_ = resolveClassInObject(t, loader, o, ReferenceClass);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
o = findInHierarchy
|
||||||
|
(t, class_, referenceName(t, reference), referenceSpec(t, reference),
|
||||||
|
find, makeError);
|
||||||
|
if (UNLIKELY(t->exception)) return 0;
|
||||||
|
|
||||||
|
set(t, codePool(t, methodCode(t, method)),
|
||||||
|
SingletonBody + (index * BytesPerWord), o);
|
||||||
|
}
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveField(Thread* t, object loader, object method, unsigned index)
|
||||||
|
{
|
||||||
|
return resolve(t, loader, method, index, findFieldInClass,
|
||||||
|
makeNoSuchFieldError);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveField(Thread* t, object method, unsigned index)
|
||||||
|
{
|
||||||
|
return resolveField
|
||||||
|
(t, classLoader(t, methodClass(t, method)), method, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveMethod(Thread* t, object loader, object method, unsigned index)
|
||||||
|
{
|
||||||
|
return resolve(t, loader, method, index, findMethodInClass,
|
||||||
|
makeNoSuchMethodError);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline object
|
||||||
|
resolveMethod(Thread* t, object method, unsigned index)
|
||||||
|
{
|
||||||
|
return resolveMethod
|
||||||
|
(t, classLoader(t, methodClass(t, method)), method, index);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dumpHeap(Thread* t, FILE* out);
|
dumpHeap(Thread* t, FILE* out);
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ class MySystem: public System {
|
|||||||
|
|
||||||
virtual void join() {
|
virtual void join() {
|
||||||
int rv UNUSED = pthread_join(thread, 0);
|
int rv UNUSED = pthread_join(thread, 0);
|
||||||
expect(s, rv == 0);
|
//expect(s, rv == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
|
@ -36,79 +36,6 @@ codeReadInt32(Thread* t, object code, unsigned& ip)
|
|||||||
return ((v1 << 24) | (v2 << 16) | (v3 << 8) | v4);
|
return ((v1 << 24) | (v2 << 16) | (v3 << 8) | v4);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object
|
|
||||||
resolveClassInObject(Thread* t, object loader, object container,
|
|
||||||
unsigned classOffset)
|
|
||||||
{
|
|
||||||
object o = cast<object>(container, classOffset);
|
|
||||||
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) {
|
|
||||||
PROTECT(t, container);
|
|
||||||
|
|
||||||
o = resolveClass(t, loader, o);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
set(t, container, classOffset, o);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline object
|
|
||||||
resolveClassInPool(Thread* t, object method, unsigned index)
|
|
||||||
{
|
|
||||||
object o = singletonObject(t, codePool(t, methodCode(t, method)), index);
|
|
||||||
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ByteArrayType)) {
|
|
||||||
PROTECT(t, method);
|
|
||||||
|
|
||||||
o = resolveClass(t, classLoader(t, methodClass(t, method)), o);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
set(t, codePool(t, methodCode(t, method)),
|
|
||||||
SingletonBody + (index * BytesPerWord), o);
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline object
|
|
||||||
resolve(Thread* t, object method, unsigned index,
|
|
||||||
object (*find)(vm::Thread*, object, object, object),
|
|
||||||
object (*makeError)(vm::Thread*, object))
|
|
||||||
{
|
|
||||||
object o = singletonObject(t, codePool(t, methodCode(t, method)), index);
|
|
||||||
if (objectClass(t, o) == arrayBody(t, t->m->types, Machine::ReferenceType))
|
|
||||||
{
|
|
||||||
PROTECT(t, method);
|
|
||||||
|
|
||||||
object reference = o;
|
|
||||||
PROTECT(t, reference);
|
|
||||||
|
|
||||||
object class_ = resolveClassInObject
|
|
||||||
(t, classLoader(t, methodClass(t, method)), o, ReferenceClass);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
o = findInHierarchy
|
|
||||||
(t, class_, referenceName(t, reference), referenceSpec(t, reference),
|
|
||||||
find, makeError);
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
|
|
||||||
set(t, codePool(t, methodCode(t, method)),
|
|
||||||
SingletonBody + (index * BytesPerWord), o);
|
|
||||||
}
|
|
||||||
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline object
|
|
||||||
resolveField(Thread* t, object method, unsigned index)
|
|
||||||
{
|
|
||||||
return resolve(t, method, index, findFieldInClass, makeNoSuchFieldError);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline object
|
|
||||||
resolveMethod(Thread* t, object method, unsigned index)
|
|
||||||
{
|
|
||||||
return resolve(t, method, index, findMethodInClass, makeNoSuchMethodError);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
isSuperclass(Thread* t, object class_, object base)
|
isSuperclass(Thread* t, object class_, object base)
|
||||||
{
|
{
|
||||||
|
@ -60,10 +60,10 @@ class Processor {
|
|||||||
virtual object
|
virtual object
|
||||||
makeClass(Thread* t,
|
makeClass(Thread* t,
|
||||||
uint16_t flags,
|
uint16_t flags,
|
||||||
uint8_t vmFlags,
|
uint16_t vmFlags,
|
||||||
uint8_t arrayDimensions,
|
|
||||||
uint16_t fixedSize,
|
uint16_t fixedSize,
|
||||||
uint16_t arrayElementSize,
|
uint8_t arrayElementSize,
|
||||||
|
uint8_t arrayDimensions,
|
||||||
object objectMask,
|
object objectMask,
|
||||||
object name,
|
object name,
|
||||||
object super,
|
object super,
|
||||||
|
@ -210,6 +210,8 @@
|
|||||||
|
|
||||||
(type weakReference java/lang/ref/WeakReference)
|
(type weakReference java/lang/ref/WeakReference)
|
||||||
|
|
||||||
|
(type softReference java/lang/ref/SoftReference)
|
||||||
|
|
||||||
(type phantomReference java/lang/ref/PhantomReference)
|
(type phantomReference java/lang/ref/PhantomReference)
|
||||||
|
|
||||||
(type byteArray [B
|
(type byteArray [B
|
||||||
|
@ -873,10 +873,10 @@ handleException(LPEXCEPTION_POINTERS e)
|
|||||||
if (jump) {
|
if (jump) {
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (system->crashDumpDirectory) {
|
if (system->crashDumpDirectory) {
|
||||||
dump(e, system->crashDumpDirectory);
|
dump(e, system->crashDumpDirectory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
@ -91,11 +91,6 @@ public class Misc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
expect(new String(new byte[] { 99, 111, 109, 46, 101, 99, 111, 118, 97,
|
|
||||||
116, 101, 46, 110, 97, 116, 46, 98, 117,
|
|
||||||
115, 46, 83, 121, 109, 98, 111, 108 })
|
|
||||||
.equals("com.ecovate.nat.bus.Symbol"));
|
|
||||||
|
|
||||||
expect(queryDefault(new Object()) != null);
|
expect(queryDefault(new Object()) != null);
|
||||||
|
|
||||||
{ Foo foo = new Foo();
|
{ Foo foo = new Foo();
|
||||||
|
21
test/Strings.java
Normal file
21
test/Strings.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
public class Strings {
|
||||||
|
private static void expect(boolean v) {
|
||||||
|
if (! v) throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
expect(new String(new byte[] { 99, 111, 109, 46, 101, 99, 111, 118, 97,
|
||||||
|
116, 101, 46, 110, 97, 116, 46, 98, 117,
|
||||||
|
115, 46, 83, 121, 109, 98, 111, 108 })
|
||||||
|
.equals("com.ecovate.nat.bus.Symbol"));
|
||||||
|
|
||||||
|
// We don't yet have a regex implementation, so this test will fail:
|
||||||
|
// final String months = "Jan\u00aeFeb\u00aeMar\u00ae";
|
||||||
|
// expect(months.split("\u00ae").length == 3);
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append('$');
|
||||||
|
sb.append('2');
|
||||||
|
expect(sb.substring(1).equals("2"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user