Merge branch 'master' into localization

This commit is contained in:
JET 2011-02-21 17:58:50 -07:00
commit f6e2f4af21
165 changed files with 17444 additions and 6907 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -0,0 +1,116 @@
/* Copyright (c) 2011, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
import static avian.Stream.write1;
import static avian.Stream.write2;
import static avian.Stream.write4;
import avian.ConstantPool.PoolEntry;
import java.util.List;
import java.io.OutputStream;
import java.io.IOException;
public class Assembler {
public static final int ACC_PUBLIC = 1 << 0;
public static final int ACC_STATIC = 1 << 3;
public static final int aaload = 0x32;
public static final int aastore = 0x53;
public static final int aload = 0x19;
public static final int aload_0 = 0x2a;
public static final int aload_1 = 0x2b;
public static final int astore_0 = 0x4b;
public static final int anewarray = 0xbd;
public static final int areturn = 0xb0;
public static final int dload = 0x18;
public static final int dreturn = 0xaf;
public static final int dup = 0x59;
public static final int fload = 0x17;
public static final int freturn = 0xae;
public static final int getfield = 0xb4;
public static final int goto_ = 0xa7;
public static final int iload = 0x15;
public static final int invokeinterface = 0xb9;
public static final int invokespecial = 0xb7;
public static final int invokestatic = 0xb8;
public static final int invokevirtual = 0xb6;
public static final int ireturn = 0xac;
public static final int jsr = 0xa8;
public static final int ldc_w = 0x13;
public static final int lload = 0x16;
public static final int lreturn = 0xad;
public static final int new_ = 0xbb;
public static final int pop = 0x57;
public static final int putfield = 0xb5;
public static final int ret = 0xa9;
public static final int return_ = 0xb1;
public static void writeClass(OutputStream out,
List<PoolEntry> pool,
int name,
int super_,
int[] interfaces,
MethodData[] methods)
throws IOException
{
int codeAttributeName = ConstantPool.addUtf8(pool, "Code");
write4(out, 0xCAFEBABE);
write2(out, 0); // minor version
write2(out, 0); // major version
write2(out, pool.size() + 1);
for (PoolEntry e: pool) {
e.writeTo(out);
}
write2(out, ACC_PUBLIC); // flags
write2(out, name + 1);
write2(out, super_ + 1);
write2(out, interfaces.length);
for (int i: interfaces) {
write2(out, i + 1);
}
write2(out, 0); // field count
write2(out, methods.length);
for (MethodData m: methods) {
write2(out, m.flags);
write2(out, m.nameIndex + 1);
write2(out, m.specIndex + 1);
write2(out, 1); // attribute count
write2(out, codeAttributeName + 1);
write4(out, m.code.length);
out.write(m.code);
}
write2(out, 0); // attribute count
}
public static class MethodData {
public final int flags;
public final int nameIndex;
public final int specIndex;
public final byte[] code;
public MethodData(int flags, int nameIndex, int specIndex, byte[] code) {
this.flags = flags;
this.nameIndex = nameIndex;
this.specIndex = specIndex;
this.code = code;
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,6 +10,4 @@
package avian;
public class ClassAddendum extends Addendum {
public Object[] signers;
}
public class ClassAddendum extends Addendum { }

View File

@ -0,0 +1,270 @@
/* Copyright (c) 2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
import static avian.Stream.read1;
import static avian.Stream.read2;
import java.lang.reflect.Modifier;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class Classes {
private static final int LinkFlag = 1 << 8;
public static native VMClass defineVMClass
(ClassLoader loader, byte[] b, int offset, int length);
public static native VMClass vmClass(Object o);
public static native VMClass primitiveClass(char name);
public static native void initialize(VMClass vmClass);
public static native boolean isAssignableFrom(VMClass a, VMClass b);
public static native VMClass getVMClass(Object o);
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
throws ClassNotFoundException;
private static VMClass loadVMClass(ClassLoader loader,
byte[] nameBytes, int offset, int length)
{
byte[] spec = new byte[length + 1];
System.arraycopy(nameBytes, offset, spec, 0, length);
try {
VMClass c = resolveVMClass(loader, spec);
if (c == null) {
throw new NoClassDefFoundError();
}
return c;
} catch (ClassNotFoundException e) {
NoClassDefFoundError error = new NoClassDefFoundError
(new String(nameBytes, offset, length, false));
error.initCause(e);
throw error;
}
}
private static Object parseAnnotationValue(ClassLoader loader,
Object pool,
InputStream in)
throws IOException
{
switch (read1(in)) {
case 'Z':
return Boolean.valueOf(Singleton.getInt(pool, read2(in) - 1) != 0);
case 'B':
return Byte.valueOf((byte) Singleton.getInt(pool, read2(in) - 1));
case 'C':
return Character.valueOf((char) Singleton.getInt(pool, read2(in) - 1));
case 'S':
return Short.valueOf((short) Singleton.getInt(pool, read2(in) - 1));
case 'I':
return Integer.valueOf(Singleton.getInt(pool, read2(in) - 1));
case 'F':
return Float.valueOf
(Float.intBitsToFloat(Singleton.getInt(pool, read2(in) - 1)));
case 'J': {
return Long.valueOf(Singleton.getLong(pool, read2(in) - 1));
}
case 'D': {
return Double.valueOf
(Double.longBitsToDouble(Singleton.getLong(pool, read2(in) - 1)));
}
case 's': {
byte[] data = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return new String(data, 0, data.length - 1, false);
}
case 'e': {
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return Enum.valueOf
(SystemClassLoader.getClass
(loadVMClass(loader, typeName, 1, typeName.length - 3)),
new String(name, 0, name.length - 1, false));
}
case 'c':{
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return SystemClassLoader.getClass
(loadVMClass(loader, name, 1, name.length - 3));
}
case '@':
return parseAnnotation(loader, pool, in);
case '[': {
Object[] array = new Object[read2(in)];
for (int i = 0; i < array.length; ++i) {
array[i] = parseAnnotationValue(loader, pool, in);
}
return array;
}
default: throw new AssertionError();
}
}
private static Object[] parseAnnotation(ClassLoader loader,
Object pool,
InputStream in)
throws IOException
{
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
Object[] annotation = new Object[(read2(in) + 1) * 2];
annotation[1] = SystemClassLoader.getClass
(loadVMClass(loader, typeName, 1, typeName.length - 3));
for (int i = 2; i < annotation.length; i += 2) {
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
annotation[i] = new String(name, 0, name.length - 1, false);
annotation[i + 1] = parseAnnotationValue(loader, pool, in);
}
return annotation;
}
private static Object[] parseAnnotationTable(ClassLoader loader,
Object pool,
InputStream in)
throws IOException
{
Object[] table = new Object[read2(in)];
for (int i = 0; i < table.length; ++i) {
table[i] = parseAnnotation(loader, pool, in);
}
return table;
}
private static void parseAnnotationTable(ClassLoader loader,
Addendum addendum)
{
if (addendum != null && addendum.annotationTable instanceof byte[]) {
try {
addendum.annotationTable = parseAnnotationTable
(loader, addendum.pool, new ByteArrayInputStream
((byte[]) addendum.annotationTable));
} catch (IOException e) {
AssertionError error = new AssertionError();
error.initCause(e);
throw error;
}
}
}
private static int resolveSpec(ClassLoader loader, byte[] spec, int start) {
int result;
int end;
switch (spec[start]) {
case 'L':
++ start;
end = start;
while (spec[end] != ';') ++ end;
result = end + 1;
break;
case '[':
end = start + 1;
while (spec[end] == '[') ++ end;
switch (spec[end]) {
case 'L':
++ end;
while (spec[end] != ';') ++ end;
++ end;
break;
default:
++ end;
}
result = end;
break;
default:
return start + 1;
}
loadVMClass(loader, spec, start, end - start);
return result;
}
public static void link(VMClass c, ClassLoader loader) {
acquireClassLock();
try {
if ((c.vmFlags & LinkFlag) == 0) {
if (c.super_ != null) {
link(c.super_, loader);
}
parseAnnotationTable(loader, c.addendum);
if (c.interfaceTable != null) {
int stride = ((c.flags & Modifier.INTERFACE) != 0 ? 1 : 2);
for (int i = 0; i < c.interfaceTable.length; i += stride) {
link((VMClass) c.interfaceTable[i], loader);
}
}
if (c.methodTable != null) {
for (int i = 0; i < c.methodTable.length; ++i) {
VMMethod m = c.methodTable[i];
for (int j = 1; j < m.spec.length;) {
j = resolveSpec(loader, m.spec, j);
}
parseAnnotationTable(loader, m.addendum);
}
}
if (c.fieldTable != null) {
for (int i = 0; i < c.fieldTable.length; ++i) {
VMField f = c.fieldTable[i];
resolveSpec(loader, f.spec, 0);
parseAnnotationTable(loader, f.addendum);
}
}
c.vmFlags |= LinkFlag;
}
} finally {
releaseClassLock();
}
}
public static void link(VMClass c) {
link(c, c.loader);
}
private static native void acquireClassLock();
private static native void releaseClassLock();
}

View File

@ -0,0 +1,242 @@
/* Copyright (c) 2011, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
import static avian.Stream.write1;
import static avian.Stream.write2;
import static avian.Stream.write4;
import java.util.List;
import java.io.OutputStream;
import java.io.IOException;
public class ConstantPool {
private static final int CONSTANT_Integer = 3;
private static final int CONSTANT_Utf8 = 1;
private static final int CONSTANT_String = 8;
private static final int CONSTANT_Class = 7;
private static final int CONSTANT_NameAndType = 12;
private static final int CONSTANT_Fieldref = 9;
private static final int CONSTANT_Methodref = 10;
public static int add(List<PoolEntry> pool, PoolEntry e) {
int i = 0;
for (PoolEntry existing: pool) {
if (existing.equals(e)) {
return i;
} else {
++i;
}
}
pool.add(e);
return pool.size() - 1;
}
public static int addInteger(List<PoolEntry> pool, int value) {
return add(pool, new IntegerPoolEntry(value));
}
public static int addUtf8(List<PoolEntry> pool, String value) {
return add(pool, new Utf8PoolEntry(value));
}
public static int addString(List<PoolEntry> pool, String value) {
return add(pool, new StringPoolEntry(addUtf8(pool, value)));
}
public static int addClass(List<PoolEntry> pool, String name) {
return add(pool, new ClassPoolEntry(addUtf8(pool, name)));
}
public static int addNameAndType(List<PoolEntry> pool,
String name,
String type)
{
return add(pool, new NameAndTypePoolEntry
(addUtf8(pool, name),
addUtf8(pool, type)));
}
public static int addFieldRef(List<PoolEntry> pool,
String className,
String name,
String spec)
{
return add(pool, new FieldRefPoolEntry
(addClass(pool, className),
addNameAndType(pool, name, spec)));
}
public static int addMethodRef(List<PoolEntry> pool,
String className,
String name,
String spec)
{
return add(pool, new MethodRefPoolEntry
(addClass(pool, className),
addNameAndType(pool, name, spec)));
}
public interface PoolEntry {
public void writeTo(OutputStream out) throws IOException;
}
private static class IntegerPoolEntry implements PoolEntry {
private final int value;
public IntegerPoolEntry(int value) {
this.value = value;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Integer);
write4(out, value);
}
public boolean equals(Object o) {
return o instanceof IntegerPoolEntry
&& ((IntegerPoolEntry) o).value == value;
}
}
private static class Utf8PoolEntry implements PoolEntry {
private final String data;
public Utf8PoolEntry(String data) {
this.data = data;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Utf8);
byte[] bytes = data.getBytes();
write2(out, bytes.length);
out.write(bytes);
}
public boolean equals(Object o) {
return o instanceof Utf8PoolEntry
&& ((Utf8PoolEntry) o).data.equals(data);
}
}
private static class StringPoolEntry implements PoolEntry {
private final int valueIndex;
public StringPoolEntry(int valueIndex) {
this.valueIndex = valueIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_String);
write2(out, valueIndex + 1);
}
public boolean equals(Object o) {
return o instanceof StringPoolEntry
&& ((StringPoolEntry) o).valueIndex == valueIndex;
}
}
private static class ClassPoolEntry implements PoolEntry {
private final int nameIndex;
public ClassPoolEntry(int nameIndex) {
this.nameIndex = nameIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Class);
write2(out, nameIndex + 1);
}
public boolean equals(Object o) {
return o instanceof ClassPoolEntry
&& ((ClassPoolEntry) o).nameIndex == nameIndex;
}
}
private static class NameAndTypePoolEntry implements PoolEntry {
private final int nameIndex;
private final int typeIndex;
public NameAndTypePoolEntry(int nameIndex, int typeIndex) {
this.nameIndex = nameIndex;
this.typeIndex = typeIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_NameAndType);
write2(out, nameIndex + 1);
write2(out, typeIndex + 1);
}
public boolean equals(Object o) {
if (o instanceof NameAndTypePoolEntry) {
NameAndTypePoolEntry other = (NameAndTypePoolEntry) o;
return other.nameIndex == nameIndex && other.typeIndex == typeIndex;
} else {
return false;
}
}
}
private static class FieldRefPoolEntry implements PoolEntry {
private final int classIndex;
private final int nameAndTypeIndex;
public FieldRefPoolEntry(int classIndex, int nameAndTypeIndex) {
this.classIndex = classIndex;
this.nameAndTypeIndex = nameAndTypeIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Fieldref);
write2(out, classIndex + 1);
write2(out, nameAndTypeIndex + 1);
}
public boolean equals(Object o) {
if (o instanceof FieldRefPoolEntry) {
FieldRefPoolEntry other = (FieldRefPoolEntry) o;
return other.classIndex == classIndex
&& other.nameAndTypeIndex == nameAndTypeIndex;
} else {
return false;
}
}
}
private static class MethodRefPoolEntry implements PoolEntry {
private final int classIndex;
private final int nameAndTypeIndex;
public MethodRefPoolEntry(int classIndex, int nameAndTypeIndex) {
this.classIndex = classIndex;
this.nameAndTypeIndex = nameAndTypeIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Methodref);
write2(out, classIndex + 1);
write2(out, nameAndTypeIndex + 1);
}
public boolean equals(Object o) {
if (o instanceof MethodRefPoolEntry) {
MethodRefPoolEntry other = (MethodRefPoolEntry) o;
return other.classIndex == classIndex
&& other.nameAndTypeIndex == nameAndTypeIndex;
} else {
return false;
}
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -53,8 +53,8 @@ import java.util.concurrent.Callable;
* causes the current continuation to be replaced with the calling
* continuation. When the last method in this new continuation
* returns, it returns to the native frame which created the current
* context, which may not be the same as the context in which that
* continuation was created.
* context, which may or may not be the same as the context in which
* that continuation was created.
*
* <p>We define the return type of a continuation context as the
* return type of the first method called in that context. A
@ -128,7 +128,7 @@ public class Continuations {
* <code>receiver.receive(Callback)</code>, propagate the exception
* thrown by that method, return the result passed to the
* handleResult(T) method of the continuation, or throw the
* exception passed to the handleException(Throwable) of the
* exception passed to the handleException(Throwable) method of the
* continuation.
*/
public static native <T> T callWithCurrentContinuation

View File

@ -0,0 +1,13 @@
/* Copyright (c) 2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class FieldAddendum extends Addendum { }

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -8,8 +8,8 @@
There is NO WARRANTY for this software. See license.txt for
details. */
package java.lang.reflect;
package avian;
public interface GenericDeclaration {
public TypeVariable<?>[] getTypeParameters();
public class MethodAddendum extends Addendum {
public Object exceptionTable;
}

View File

@ -0,0 +1,23 @@
/* Copyright (c) 2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
import java.security.AllPermission;
import java.security.Permissions;
import java.security.ProtectionDomain;
public class OpenJDK {
public static ProtectionDomain getProtectionDomain() {
Permissions p = new Permissions();
p.add(new AllPermission());
return new ProtectionDomain(null, p);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -71,4 +71,10 @@ public abstract class Stream {
(b5 << 24) | (b6 << 16) | (b7 << 8) | (b8));
}
public static void set4(byte[] array, int offset, int v) {
array[offset ] = (byte) ((v >>> 24) & 0xFF);
array[offset + 1] = (byte) ((v >>> 16) & 0xFF);
array[offset + 2] = (byte) ((v >>> 8) & 0xFF);
array[offset + 3] = (byte) ((v ) & 0xFF);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,32 +10,32 @@
package avian;
import static avian.Stream.read1;
import static avian.Stream.read2;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Enumeration;
public class SystemClassLoader extends ClassLoader {
private static final int LinkFlag = 1 << 8;
private native VMClass findVMClass(String name)
throws ClassNotFoundException;
public static native Class defineClass
(ClassLoader loader, byte[] b, int offset, int length);
protected Class findClass(String name) throws ClassNotFoundException {
return getClass(findVMClass(name));
}
protected native Class findClass(String name) throws ClassNotFoundException;
public static native Class getClass(VMClass vmClass);
protected native Class reallyFindLoadedClass(String name);
private native VMClass findLoadedVMClass(String name);
protected Class reallyFindLoadedClass(String name){
VMClass c = findLoadedVMClass(name);
return c == null ? null : getClass(c);
}
private native boolean resourceExists(String name);
private static native Class resolveClass(ClassLoader loader, byte[] spec)
throws ClassNotFoundException;
protected URL findResource(String name) {
if (resourceExists(name)) {
try {
@ -45,231 +45,12 @@ public class SystemClassLoader extends ClassLoader {
return null;
}
private static Class loadClass(ClassLoader loader,
byte[] nameBytes, int offset, int length)
{
byte[] spec = new byte[length + 1];
System.arraycopy(nameBytes, offset, spec, 0, length);
try {
Class c = resolveClass(loader, spec);
if (c == null) {
throw new NoClassDefFoundError();
}
return c;
} catch (ClassNotFoundException e) {
NoClassDefFoundError error = new NoClassDefFoundError
(new String(nameBytes, offset, length, false));
error.initCause(e);
throw error;
protected Enumeration<URL> findResources(String name) {
Collection<URL> urls = new ArrayList(1);
URL url = findResource(name);
if (url != null) {
urls.add(url);
}
}
private static Object parseAnnotationValue(ClassLoader loader,
Object pool,
InputStream in)
throws IOException
{
switch (read1(in)) {
case 'Z':
return Boolean.valueOf(Singleton.getInt(pool, read2(in) - 1) != 0);
case 'B':
return Byte.valueOf((byte) Singleton.getInt(pool, read2(in) - 1));
case 'C':
return Character.valueOf((char) Singleton.getInt(pool, read2(in) - 1));
case 'S':
return Short.valueOf((short) Singleton.getInt(pool, read2(in) - 1));
case 'I':
return Integer.valueOf(Singleton.getInt(pool, read2(in) - 1));
case 'F':
return Float.valueOf
(Float.intBitsToFloat(Singleton.getInt(pool, read2(in) - 1)));
case 'J': {
return Long.valueOf(Singleton.getLong(pool, read2(in) - 1));
}
case 'D': {
return Double.valueOf
(Double.longBitsToDouble(Singleton.getLong(pool, read2(in) - 1)));
}
case 's': {
byte[] data = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return new String(data, 0, data.length - 1, false);
}
case 'e': {
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return Enum.valueOf
(loadClass(loader, typeName, 1, typeName.length - 3),
new String(name, 0, name.length - 1, false));
}
case 'c':{
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return loadClass(loader, name, 1, name.length - 3);
}
case '@':
return parseAnnotation(loader, pool, in);
case '[': {
Object[] array = new Object[read2(in)];
for (int i = 0; i < array.length; ++i) {
array[i] = parseAnnotationValue(loader, pool, in);
}
return array;
}
default: throw new AssertionError();
}
}
private static Object[] parseAnnotation(ClassLoader loader,
Object pool,
InputStream in)
throws IOException
{
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
Object[] annotation = new Object[(read2(in) + 1) * 2];
annotation[1] = loadClass(loader, typeName, 1, typeName.length - 3);
for (int i = 2; i < annotation.length; i += 2) {
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
annotation[i] = new String(name, 0, name.length - 1, false);
annotation[i + 1] = parseAnnotationValue(loader, pool, in);
}
return annotation;
}
private static Object[] parseAnnotationTable(ClassLoader loader,
Object pool,
InputStream in)
throws IOException
{
Object[] table = new Object[read2(in)];
for (int i = 0; i < table.length; ++i) {
table[i] = parseAnnotation(loader, pool, in);
}
return table;
}
private static void parseAnnotationTable(ClassLoader loader,
Addendum addendum)
{
if (addendum != null && addendum.annotationTable instanceof byte[]) {
try {
addendum.annotationTable = parseAnnotationTable
(loader, addendum.pool, new ByteArrayInputStream
((byte[]) addendum.annotationTable));
} catch (IOException e) {
AssertionError error = new AssertionError();
error.initCause(e);
throw error;
}
addendum.pool = null;
}
}
private static int resolveSpec(ClassLoader loader, byte[] spec, int start) {
int result;
int end;
switch (spec[start]) {
case 'L':
++ start;
end = start;
while (spec[end] != ';') ++ end;
result = end + 1;
break;
case '[':
end = start + 1;
while (spec[end] == '[') ++ end;
switch (spec[end]) {
case 'L':
++ end;
while (spec[end] != ';') ++ end;
++ end;
break;
default:
++ end;
}
result = end;
break;
default:
return start + 1;
}
loadClass(loader, spec, start, end - start);
return result;
}
private static native void acquireClassLock();
private static native void releaseClassLock();
public static void link(Class c, ClassLoader loader) {
acquireClassLock();
try {
if ((c.vmFlags & LinkFlag) == 0) {
if (c.super_ != null) {
link(c.super_, loader);
}
parseAnnotationTable(loader, c.addendum);
if (c.interfaceTable != null) {
int stride = (c.isInterface() ? 1 : 2);
for (int i = 0; i < c.interfaceTable.length; i += stride) {
link((Class) c.interfaceTable[i], loader);
}
}
if (c.methodTable != null) {
for (int i = 0; i < c.methodTable.length; ++i) {
Method m = c.methodTable[i];
for (int j = 1; j < m.spec.length;) {
j = resolveSpec(loader, m.spec, j);
}
parseAnnotationTable(loader, m.addendum);
}
}
if (c.fieldTable != null) {
for (int i = 0; i < c.fieldTable.length; ++i) {
Field f = c.fieldTable[i];
resolveSpec(loader, f.spec, 0);
parseAnnotationTable(loader, f.addendum);
}
}
c.vmFlags |= LinkFlag;
}
} finally {
releaseClassLock();
}
}
public static void link(Class c) {
link(c, c.getClassLoader());
return Collections.enumeration(urls);
}
}

View File

@ -0,0 +1,31 @@
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class VMClass {
public short flags;
public short vmFlags;
public short fixedSize;
public byte arrayElementSize;
public byte arrayDimensions;
public int runtimeDataIndex;
public int[] objectMask;
public byte[] name;
public byte[] sourceFile;
public VMClass super_;
public Object[] interfaceTable;
public VMMethod[] virtualTable;
public VMField[] fieldTable;
public VMMethod[] methodTable;
public avian.ClassAddendum addendum;
public Object staticTable;
public ClassLoader loader;
}

View File

@ -0,0 +1,22 @@
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class VMField {
public byte vmFlags;
public byte code;
public short flags;
public short offset;
public byte[] name;
public byte[] spec;
public FieldAddendum addendum;
public VMClass class_;
}

View File

@ -0,0 +1,27 @@
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class VMMethod {
public byte vmFlags;
public byte returnCode;
public byte parameterCount;
public byte parameterFootprint;
public short flags;
public short offset;
public int nativeID;
public int runtimeDataIndex;
public byte[] name;
public byte[] spec;
public MethodAddendum addendum;
public VMClass class_;
public Object code;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -34,6 +34,10 @@ public class Handler extends URLStreamHandler {
public InputStream getInputStream() throws IOException {
return new ResourceInputStream(url.getFile());
}
public void connect() {
// ignore
}
}
private static class ResourceInputStream extends InputStream {
@ -59,6 +63,12 @@ public class Handler extends URLStreamHandler {
public static native void close(long peer) throws IOException;
public static native int available(long peer, int position);
public int available() {
return available(peer, position);
}
public int read() throws IOException {
if (peer != 0) {
int c = read(peer, position);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -25,6 +25,7 @@
# include <direct.h>
# include <share.h>
# define ACCESS _waccess
# define CLOSE _close
# define READ _read
# define WRITE _write
@ -36,10 +37,12 @@
# define OPEN_MASK O_BINARY
# ifdef _MSC_VER
# define S_ISREG(x) ((x) | _S_IFREG)
# define S_ISDIR(x) ((x) | _S_IFDIR)
# define S_ISREG(x) ((x) & _S_IFREG)
# define S_ISDIR(x) ((x) & _S_IFDIR)
# define S_IRUSR _S_IREAD
# define S_IWUSR _S_IWRITE
# define W_OK 2
# define R_OK 4
# else
# define OPEN _wopen
# define CREAT _wcreat
@ -56,6 +59,7 @@ typedef wchar_t char_t;
# include <unistd.h>
# include "sys/mman.h"
# define ACCESS access
# define OPEN open
# define CLOSE close
# define READ read
@ -323,13 +327,13 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
if (chars) {
STRUCT_STAT s;
int r = STAT(chars, &s);
releaseChars(e, path, chars);
if (r == 0) {
return s.st_size;
}
releaseChars(e, path, chars);
}
return -1;
return 0;
}
extern "C" JNIEXPORT void JNICALL
@ -377,6 +381,31 @@ Java_java_io_File_delete(JNIEnv* e, jclass, jstring path)
}
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_canRead(JNIEnv* e, jclass, jstring path)
{
string_t chars = getChars(e, path);
if (chars) {
int r = ACCESS(chars, R_OK);
releaseChars(e, path, chars);
return (r == 0);
}
return false;
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_canWrite(JNIEnv* e, jclass, jstring path)
{
string_t chars = getChars(e, path);
if (chars) {
int r = ACCESS(chars, W_OK);
releaseChars(e, path, chars);
return (r == 0);
}
return false;
}
extern "C" JNIEXPORT jboolean JNICALL
Java_java_io_File_rename(JNIEnv* e, jclass, jstring old, jstring new_)
{
@ -593,11 +622,13 @@ Java_java_io_FileInputStream_close(JNIEnv* e, jclass, jint fd)
}
extern "C" JNIEXPORT jint JNICALL
Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path)
Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path, jboolean append)
{
string_t chars = getChars(e, path);
if (chars) {
int fd = doOpen(e, chars, O_WRONLY | O_CREAT | O_TRUNC);
int fd = doOpen(e, chars, append
? (O_WRONLY | O_CREAT | O_APPEND)
: (O_WRONLY | O_CREAT | O_TRUNC));
releaseChars(e, path, chars);
return fd;
} else {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -11,7 +11,6 @@
#include "math.h"
#include "stdlib.h"
#include "time.h"
#include "time.h"
#include "string.h"
#include "stdio.h"
#include "jni.h"
@ -37,9 +36,6 @@
# define isnan _isnan
# define isfinite _finite
# define strtof strtod
# define FTIME _ftime_s
# else
# define FTIME _ftime
# endif
#else // not PLATFORM_WINDOWS
@ -224,17 +220,17 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0]));
if(e->ExceptionCheck()) return;
e->SetLongArrayRegion(process, 1, 1, &inDescriptor);
e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
makePipe(e, out);
SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
if(e->ExceptionCheck()) return;
e->SetLongArrayRegion(process, 2, 1, &outDescriptor);
e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
makePipe(e, err);
SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
if(e->ExceptionCheck()) return;
e->SetLongArrayRegion(process, 3, 1, &errDescriptor);
e->SetLongArrayRegion(process, 4, 1, &errDescriptor);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
@ -251,6 +247,10 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
0, 0, &si, &pi);
CloseHandle(in[1]);
CloseHandle(out[0]);
CloseHandle(err[1]);
if (not success) {
throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
return;
@ -258,24 +258,12 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
jlong pid = reinterpret_cast<jlong>(pi.hProcess);
e->SetLongArrayRegion(process, 0, 1, &pid);
jlong tid = reinterpret_cast<jlong>(pi.hThread);
e->SetLongArrayRegion(process, 1, 1, &tid);
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
{
DWORD exitCode;
BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
if(not success){
throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
} else if(exitCode == STILL_ACTIVE){
throwNew(e, "java/lang/IllegalThreadStateException", "Process is still active");
}
return exitCode;
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid)
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
DWORD exitCode;
WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
@ -283,6 +271,10 @@ Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid)
if(not success){
throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
}
CloseHandle(reinterpret_cast<HANDLE>(pid));
CloseHandle(reinterpret_cast<HANDLE>(tid));
return exitCode;
}
@ -366,7 +358,8 @@ extern "C" JNIEXPORT void JNICALL
Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
jobjectArray command, jlongArray process)
{
char** argv = static_cast<char**>(malloc((e->GetArrayLength(command) + 1) * sizeof(char*)));
char** argv = static_cast<char**>
(malloc((e->GetArrayLength(command) + 1) * sizeof(char*)));
int i;
for(i = 0; i < e->GetArrayLength(command); i++){
jstring element = (jstring) e->GetObjectArrayElement(command, i);
@ -383,15 +376,15 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
makePipe(e, in);
if(e->ExceptionCheck()) return;
jlong inDescriptor = static_cast<jlong>(in[0]);
e->SetLongArrayRegion(process, 1, 1, &inDescriptor);
e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
makePipe(e, out);
if(e->ExceptionCheck()) return;
jlong outDescriptor = static_cast<jlong>(out[1]);
e->SetLongArrayRegion(process, 1, 1, &outDescriptor);
e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
makePipe(e, err);
if(e->ExceptionCheck()) return;
jlong errDescriptor = static_cast<jlong>(err[0]);
e->SetLongArrayRegion(process, 1, 1, &errDescriptor);
e->SetLongArrayRegion(process, 4, 1, &errDescriptor);
makePipe(e, msg);
if(e->ExceptionCheck()) return;
if(fcntl(msg[1], F_SETFD, FD_CLOEXEC) != 0) {
@ -452,21 +445,7 @@ Java_java_lang_Runtime_exec(JNIEnv* e, jclass,
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_exitValue(JNIEnv* e, jclass, jlong pid)
{
int status;
pid_t returned = waitpid(pid, &status, WNOHANG);
if(returned == 0){
throwNewErrno(e, "java/lang/IllegalThreadStateException");
} else if(returned == -1){
throwNewErrno(e, "java/lang/Exception");
}
return WEXITSTATUS(status);
}
extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid)
Java_java_lang_Runtime_waitFor(JNIEnv*, jclass, jlong pid, jlong)
{
bool finished = false;
int status;
@ -548,6 +527,10 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
TCHAR buffer[MAX_PATH];
GetTempPath(MAX_PATH, buffer);
r = e->NewStringUTF(buffer);
} else if (strcmp(chars, "user.dir") == 0) {
TCHAR buffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, buffer);
r = e->NewStringUTF(buffer);
} else if (strcmp(chars, "user.home") == 0) {
# ifdef _MSC_VER
WCHAR buffer[MAX_PATH];
@ -606,6 +589,8 @@ Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring name,
#endif
} else if (strcmp(chars, "java.io.tmpdir") == 0) {
r = e->NewStringUTF("/tmp");
} else if (strcmp(chars, "user.dir") == 0) {
r = e->NewStringUTF(getenv("PWD"));
} else if (strcmp(chars, "user.home") == 0) {
r = e->NewStringUTF(getenv("HOME"));
}
@ -633,9 +618,13 @@ extern "C" JNIEXPORT jlong JNICALL
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
{
#ifdef PLATFORM_WINDOWS
_timeb tb;
FTIME(&tb);
return (static_cast<jlong>(tb.time) * 1000) + static_cast<jlong>(tb.millitm);
// We used to use _ftime here, but that only gives us 1-second
// resolution on Windows 7. _ftime_s might work better, but MinGW
// doesn't have it as of this writing. So we use this mess instead:
FILETIME time;
GetSystemTimeAsFileTime(&time);
return (((static_cast<jlong>(time.dwHighDateTime) << 32)
| time.dwLowDateTime) / 10000) - 11644473600000LL;
#else
timeval tv = { 0, 0 };
gettimeofday(&tv, 0);

View File

@ -29,6 +29,8 @@ Java_java_net_Socket_init(JNIEnv* ONLY_ON_WINDOWS(e), jclass)
int r = WSAStartup(MAKEWORD(2, 2), &data);
if (r or LOBYTE(data.wVersion) != 2 or HIBYTE(data.wVersion) != 2) {
throwNew(e, "java/io/IOException", "WSAStartup failed");
} else {
wsaInitialized = true;
}
}
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -279,7 +279,7 @@ doListen(JNIEnv* e, int s, sockaddr_in* address)
}
}
bool
void
doFinishConnect(JNIEnv* e, int socket)
{
int error;
@ -289,12 +289,9 @@ doFinishConnect(JNIEnv* e, int socket)
if (r != 0 or size != sizeof(int)) {
throwIOException(e);
} else if (einProgress(error)) {
return false;
} else if (error != 0) {
} else if (error and not einProgress(error)) {
throwIOException(e, socketErrorString(e, error));
}
return true;
}
bool
@ -426,12 +423,12 @@ Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e,
return s;
}
extern "C" JNIEXPORT jboolean JNICALL
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e,
jclass,
jint socket)
{
return doFinishConnect(e, socket);
doFinishConnect(e, socket);
}
extern "C" JNIEXPORT jint JNICALL

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -58,14 +58,21 @@ public class BufferedInputStream extends InputStream {
length -= remaining;
}
if (length > 0) {
while (length > 0) {
int c = in.read(b, offset, length);
if (c == -1) {
if (count == 0) {
count = -1;
}
break;
} else {
offset += c;
count += c;
length -= c;
if (in.available() <= 0) {
break;
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -61,6 +61,18 @@ public class File {
return isFile(path);
}
private static native boolean canRead(String path);
public boolean canRead() {
return canRead(path);
}
private static native boolean canWrite(String path);
public boolean canWrite() {
return canWrite(path);
}
public String getName() {
int index = path.lastIndexOf(FileSeparator);
if (index >= 0) {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -22,14 +22,19 @@ public class FileOutputStream extends OutputStream {
}
public FileOutputStream(String path) throws IOException {
fd = open(path);
this(path, false);
}
public FileOutputStream(String path, boolean append) throws IOException {
fd = open(path, append);
}
public FileOutputStream(File file) throws IOException {
this(file.getPath());
}
private static native int open(String path) throws IOException;
private static native int open(String path, boolean append) throws IOException;
private static native void write(int fd, int c) throws IOException;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -80,6 +80,10 @@ public class ObjectInputStream extends InputStream {
return readDoubleToken();
}
public void defaultReadObject() throws IOException {
throw new UnsupportedOperationException();
}
private void skipSpace() throws IOException {
int c;
while ((c = r.read()) != -1 && Character.isWhitespace((char) c));

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -82,6 +82,10 @@ public class ObjectOutputStream extends OutputStream {
out.print(v);
}
public void defaultWriteObject() throws IOException {
throw new UnsupportedOperationException();
}
private void writeObject(Object o, IdentityHashMap<Object, Integer> map,
int nextId)
throws IOException

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -31,6 +31,7 @@ public class PrintStream extends OutputStream {
public synchronized void print(String s) {
try {
out.write(s.getBytes());
if (autoFlush) flush();
} catch (IOException e) { }
}
@ -38,10 +39,34 @@ public class PrintStream extends OutputStream {
print(String.valueOf(o));
}
public void print(boolean v) {
print(String.valueOf(v));
}
public void print(char c) {
print(String.valueOf(c));
}
public void print(int v) {
print(String.valueOf(v));
}
public void print(long v) {
print(String.valueOf(v));
}
public void print(float v) {
print(String.valueOf(v));
}
public void print(double v) {
print(String.valueOf(v));
}
public void print(char[] s) {
print(String.valueOf(s));
}
public synchronized void println(String s) {
try {
out.write(s.getBytes());
@ -61,10 +86,34 @@ public class PrintStream extends OutputStream {
println(String.valueOf(o));
}
public void println(boolean v) {
println(String.valueOf(v));
}
public void println(char c) {
println(String.valueOf(c));
}
public void println(int v) {
println(String.valueOf(v));
}
public void println(long v) {
println(String.valueOf(v));
}
public void println(float v) {
println(String.valueOf(v));
}
public void println(double v) {
println(String.valueOf(v));
}
public void println(char[] s) {
println(String.valueOf(s));
}
public void write(int c) throws IOException {
out.write(c);
if (autoFlush && c == '\n') flush();

View File

@ -28,5 +28,17 @@ public abstract class Reader {
public abstract int read(char[] buffer, int offset, int length)
throws IOException;
public boolean markSupported() {
return false;
}
public void mark(int readAheadLimit) throws IOException {
throw new IOException("mark not supported");
}
public void reset() throws IOException {
throw new IOException("reset not supported");
}
public abstract void close() throws IOException;
}

View File

@ -109,6 +109,15 @@ public final class Character implements Comparable<Character> {
}
}
public static char forDigit(int digit, int radix) {
if (MIN_RADIX <= radix && radix <= MAX_RADIX) {
if (0 <= digit && digit < radix) {
return (char) (digit < 10 ? digit + '0' : digit + 'a' - 10);
}
}
return 0;
}
public static boolean isLetter(int c) {
return canCastToChar(c) && isLetter((char) c);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,18 +10,20 @@
package java.lang;
import avian.VMClass;
import avian.ClassAddendum;
import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader;
import avian.Classes;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.AnnotatedElement;
import java.lang.annotation.Annotation;
import java.io.InputStream;
@ -33,29 +35,14 @@ import java.security.ProtectionDomain;
import java.security.Permissions;
import java.security.AllPermission;
public final class Class <T>
implements Type, GenericDeclaration, AnnotatedElement
{
public final class Class <T> implements Type, AnnotatedElement {
private static final int PrimitiveFlag = 1 << 5;
private short flags;
public short vmFlags;
private short fixedSize;
private byte arrayElementSize;
private byte arrayDimensions;
private int[] objectMask;
private byte[] name;
private byte[] sourceFile;
public Class super_;
public Object[] interfaceTable;
public Method[] virtualTable;
public Field[] fieldTable;
public Method[] methodTable;
public avian.ClassAddendum addendum;
private Object staticTable;
private ClassLoader loader;
public final VMClass vmClass;
private Class() { }
public Class(VMClass vmClass) {
this.vmClass = vmClass;
}
public String toString() {
return getName();
@ -73,26 +60,30 @@ public final class Class <T>
}
public String getName() {
if (name == null) {
if ((vmFlags & PrimitiveFlag) != 0) {
if (this == primitiveClass('V')) {
name = "void\0".getBytes();
} else if (this == primitiveClass('Z')) {
name = "boolean\0".getBytes();
} else if (this == primitiveClass('B')) {
name = "byte\0".getBytes();
} else if (this == primitiveClass('C')) {
name = "char\0".getBytes();
} else if (this == primitiveClass('S')) {
name = "short\0".getBytes();
} else if (this == primitiveClass('I')) {
name = "int\0".getBytes();
} else if (this == primitiveClass('F')) {
name = "float\0".getBytes();
} else if (this == primitiveClass('J')) {
name = "long\0".getBytes();
} else if (this == primitiveClass('D')) {
name = "double\0".getBytes();
return getName(vmClass);
}
public static String getName(VMClass c) {
if (c.name == null) {
if ((c.vmFlags & PrimitiveFlag) != 0) {
if (c == Classes.primitiveClass('V')) {
c.name = "void\0".getBytes();
} else if (c == Classes.primitiveClass('Z')) {
c.name = "boolean\0".getBytes();
} else if (c == Classes.primitiveClass('B')) {
c.name = "byte\0".getBytes();
} else if (c == Classes.primitiveClass('C')) {
c.name = "char\0".getBytes();
} else if (c == Classes.primitiveClass('S')) {
c.name = "short\0".getBytes();
} else if (c == Classes.primitiveClass('I')) {
c.name = "int\0".getBytes();
} else if (c == Classes.primitiveClass('F')) {
c.name = "float\0".getBytes();
} else if (c == Classes.primitiveClass('J')) {
c.name = "long\0".getBytes();
} else if (c == Classes.primitiveClass('D')) {
c.name = "double\0".getBytes();
} else {
throw new AssertionError();
}
@ -102,11 +93,12 @@ public final class Class <T>
}
return new String
(replace('/', '.', name, 0, name.length - 1), 0, name.length - 1, false);
(replace('/', '.', c.name, 0, c.name.length - 1), 0, c.name.length - 1,
false);
}
public String getCanonicalName() {
if ((vmFlags & PrimitiveFlag) != 0) {
if ((vmClass.vmFlags & PrimitiveFlag) != 0) {
return getName();
} else if (isArray()) {
return getComponentType().getCanonicalName() + "[]";
@ -116,7 +108,7 @@ public final class Class <T>
}
public String getSimpleName() {
if ((vmFlags & PrimitiveFlag) != 0) {
if ((vmClass.vmFlags & PrimitiveFlag) != 0) {
return getName();
} else if (isArray()) {
return getComponentType().getSimpleName() + "[]";
@ -131,10 +123,6 @@ public final class Class <T>
}
}
public Object staticTable() {
return staticTable;
}
public T newInstance()
throws IllegalAccessException, InstantiationException
{
@ -148,8 +136,7 @@ public final class Class <T>
}
public static Class forName(String name) throws ClassNotFoundException {
return forName
(name, true, Method.getCaller().getDeclaringClass().getClassLoader());
return forName(name, true, Method.getCaller().class_.loader);
}
public static Class forName(String name, boolean initialize,
@ -157,20 +144,16 @@ public final class Class <T>
throws ClassNotFoundException
{
if (loader == null) {
loader = Class.class.loader;
loader = Class.class.vmClass.loader;
}
Class c = loader.loadClass(name);
avian.SystemClassLoader.link(c, loader);
Classes.link(c.vmClass, loader);
if (initialize) {
c.initialize();
Classes.initialize(c.vmClass);
}
return c;
}
private static native Class primitiveClass(char name);
private native void initialize();
public static Class forCanonicalName(String name) {
return forCanonicalName(null, name);
}
@ -183,7 +166,8 @@ public final class Class <T>
return forName(name.substring(1, name.length() - 1), true, loader);
} else {
if (name.length() == 1) {
return primitiveClass(name.charAt(0));
return SystemClassLoader.getClass
(Classes.primitiveClass(name.charAt(0)));
} else {
throw new ClassNotFoundException(name);
}
@ -197,39 +181,41 @@ public final class Class <T>
if (isArray()) {
String n = getName();
if ("[Z".equals(n)) {
return primitiveClass('Z');
return SystemClassLoader.getClass(Classes.primitiveClass('Z'));
} else if ("[B".equals(n)) {
return primitiveClass('B');
return SystemClassLoader.getClass(Classes.primitiveClass('B'));
} else if ("[S".equals(n)) {
return primitiveClass('S');
return SystemClassLoader.getClass(Classes.primitiveClass('S'));
} else if ("[C".equals(n)) {
return primitiveClass('C');
return SystemClassLoader.getClass(Classes.primitiveClass('C'));
} else if ("[I".equals(n)) {
return primitiveClass('I');
return SystemClassLoader.getClass(Classes.primitiveClass('I'));
} else if ("[F".equals(n)) {
return primitiveClass('F');
return SystemClassLoader.getClass(Classes.primitiveClass('F'));
} else if ("[J".equals(n)) {
return primitiveClass('J');
return SystemClassLoader.getClass(Classes.primitiveClass('J'));
} else if ("[D".equals(n)) {
return primitiveClass('D');
return SystemClassLoader.getClass(Classes.primitiveClass('D'));
}
if (staticTable == null) throw new AssertionError(name);
return (Class) staticTable;
if (vmClass.staticTable == null) throw new AssertionError();
return SystemClassLoader.getClass((VMClass) vmClass.staticTable);
} else {
return null;
}
}
public native boolean isAssignableFrom(Class c);
public boolean isAssignableFrom(Class c) {
return Classes.isAssignableFrom(vmClass, c.vmClass);
}
private Field findField(String name) {
if (fieldTable != null) {
avian.SystemClassLoader.link(this);
private static Field findField(VMClass vmClass, String name) {
if (vmClass.fieldTable != null) {
Classes.link(vmClass);
for (int i = 0; i < fieldTable.length; ++i) {
if (fieldTable[i].getName().equals(name)) {
return fieldTable[i];
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (Field.getName(vmClass.fieldTable[i]).equals(name)) {
return new Field(vmClass.fieldTable[i]);
}
}
}
@ -237,7 +223,7 @@ public final class Class <T>
}
public Field getDeclaredField(String name) throws NoSuchFieldException {
Field f = findField(name);
Field f = findField(vmClass, name);
if (f == null) {
throw new NoSuchFieldException(name);
} else {
@ -246,8 +232,8 @@ public final class Class <T>
}
public Field getField(String name) throws NoSuchFieldException {
for (Class c = this; c != null; c = c.super_) {
Field f = c.findField(name);
for (VMClass c = vmClass; c != null; c = c.super_) {
Field f = findField(c, name);
if (f != null) {
return f;
}
@ -268,19 +254,22 @@ public final class Class <T>
}
}
private Method findMethod(String name, Class[] parameterTypes) {
if (methodTable != null) {
avian.SystemClassLoader.link(this);
private static Method findMethod(VMClass vmClass, String name,
Class[] parameterTypes)
{
if (vmClass.methodTable != null) {
Classes.link(vmClass);
if (parameterTypes == null) {
parameterTypes = new Class[0];
}
for (int i = 0; i < methodTable.length; ++i) {
if (methodTable[i].getName().equals(name)
&& match(parameterTypes, methodTable[i].getParameterTypes()))
for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (Method.getName(vmClass.methodTable[i]).equals(name)
&& match(parameterTypes,
Method.getParameterTypes(vmClass.methodTable[i])))
{
return methodTable[i];
return new Method(vmClass.methodTable[i]);
}
}
}
@ -293,7 +282,7 @@ public final class Class <T>
if (name.startsWith("<")) {
throw new NoSuchMethodException(name);
}
Method m = findMethod(name, parameterTypes);
Method m = findMethod(vmClass, name, parameterTypes);
if (m == null) {
throw new NoSuchMethodException(name);
} else {
@ -307,8 +296,8 @@ public final class Class <T>
if (name.startsWith("<")) {
throw new NoSuchMethodException(name);
}
for (Class c = this; c != null; c = c.super_) {
Method m = c.findMethod(name, parameterTypes);
for (VMClass c = vmClass; c != null; c = c.super_) {
Method m = findMethod(c, name, parameterTypes);
if (m != null) {
return m;
}
@ -319,7 +308,7 @@ public final class Class <T>
public Constructor getConstructor(Class ... parameterTypes)
throws NoSuchMethodException
{
Method m = findMethod("<init>", parameterTypes);
Method m = findMethod(vmClass, "<init>", parameterTypes);
if (m == null) {
throw new NoSuchMethodException();
} else {
@ -348,11 +337,12 @@ public final class Class <T>
private int countConstructors(boolean publicOnly) {
int count = 0;
if (methodTable != null) {
for (int i = 0; i < methodTable.length; ++i) {
if (vmClass.methodTable != null) {
for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((! publicOnly)
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0)
&& methodTable[i].getName().equals("<init>"))
|| ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
!= 0)
&& Method.getName(vmClass.methodTable[i]).equals("<init>"))
{
++ count;
}
@ -363,13 +353,13 @@ public final class Class <T>
public Constructor[] getDeclaredConstructors() {
Constructor[] array = new Constructor[countConstructors(false)];
if (methodTable != null) {
avian.SystemClassLoader.link(this);
if (vmClass.methodTable != null) {
Classes.link(vmClass);
int index = 0;
for (int i = 0; i < methodTable.length; ++i) {
if (methodTable[i].getName().equals("<init>")) {
array[index++] = new Constructor(methodTable[i]);
for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (Method.getName(vmClass.methodTable[i]).equals("<init>")) {
array[index++] = new Constructor(new Method(vmClass.methodTable[i]));
}
}
}
@ -379,15 +369,15 @@ public final class Class <T>
public Constructor[] getConstructors() {
Constructor[] array = new Constructor[countConstructors(true)];
if (methodTable != null) {
avian.SystemClassLoader.link(this);
if (vmClass.methodTable != null) {
Classes.link(vmClass);
int index = 0;
for (int i = 0; i < methodTable.length; ++i) {
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
&& methodTable[i].getName().equals("<init>"))
for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
&& Method.getName(vmClass.methodTable[i]).equals("<init>"))
{
array[index++] = new Constructor(methodTable[i]);
array[index++] = new Constructor(new Method(vmClass.methodTable[i]));
}
}
}
@ -396,9 +386,11 @@ public final class Class <T>
}
public Field[] getDeclaredFields() {
if (fieldTable != null) {
Field[] array = new Field[fieldTable.length];
System.arraycopy(fieldTable, 0, array, 0, fieldTable.length);
if (vmClass.fieldTable != null) {
Field[] array = new Field[vmClass.fieldTable.length];
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
array[i] = new Field(vmClass.fieldTable[i]);
}
return array;
} else {
return new Field[0];
@ -407,9 +399,9 @@ public final class Class <T>
private int countPublicFields() {
int count = 0;
if (fieldTable != null) {
for (int i = 0; i < fieldTable.length; ++i) {
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
if (vmClass.fieldTable != null) {
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (((vmClass.fieldTable[i].flags & Modifier.PUBLIC)) != 0) {
++ count;
}
}
@ -419,13 +411,13 @@ public final class Class <T>
public Field[] getFields() {
Field[] array = new Field[countPublicFields()];
if (fieldTable != null) {
avian.SystemClassLoader.link(this);
if (vmClass.fieldTable != null) {
Classes.link(vmClass);
int ai = 0;
for (int i = 0; i < fieldTable.length; ++i) {
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
array[ai++] = fieldTable[i];
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (((vmClass.fieldTable[i].flags & Modifier.PUBLIC)) != 0) {
array[ai++] = new Field(vmClass.fieldTable[i]);
}
}
}
@ -434,11 +426,12 @@ public final class Class <T>
private int countMethods(boolean publicOnly) {
int count = 0;
if (methodTable != null) {
for (int i = 0; i < methodTable.length; ++i) {
if (vmClass.methodTable != null) {
for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((! publicOnly)
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0)
&& (! methodTable[i].getName().startsWith("<")))
|| ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
!= 0)
&& (! Method.getName(vmClass.methodTable[i]).startsWith("<")))
{
++ count;
}
@ -449,13 +442,13 @@ public final class Class <T>
public Method[] getDeclaredMethods() {
Method[] array = new Method[countMethods(false)];
if (methodTable != null) {
avian.SystemClassLoader.link(this);
if (vmClass.methodTable != null) {
Classes.link(vmClass);
int ai = 0;
for (int i = 0; i < methodTable.length; ++i) {
if (! methodTable[i].getName().startsWith("<")) {
array[ai++] = methodTable[i];
for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (! Method.getName(vmClass.methodTable[i]).startsWith("<")) {
array[ai++] = new Method(vmClass.methodTable[i]);
}
}
}
@ -465,15 +458,15 @@ public final class Class <T>
public Method[] getMethods() {
Method[] array = new Method[countMethods(true)];
if (methodTable != null) {
avian.SystemClassLoader.link(this);
if (vmClass.methodTable != null) {
Classes.link(vmClass);
int index = 0;
for (int i = 0; i < methodTable.length; ++i) {
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
&& (! methodTable[i].getName().startsWith("<")))
for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
&& (! Method.getName(vmClass.methodTable[i]).startsWith("<")))
{
array[index++] = methodTable[i];
array[index++] = new Method(vmClass.methodTable[i]);
}
}
}
@ -482,13 +475,14 @@ public final class Class <T>
}
public Class[] getInterfaces() {
if (interfaceTable != null) {
avian.SystemClassLoader.link(this);
if (vmClass.interfaceTable != null) {
Classes.link(vmClass);
int stride = (isInterface() ? 1 : 2);
Class[] array = new Class[interfaceTable.length / stride];
Class[] array = new Class[vmClass.interfaceTable.length / stride];
for (int i = 0; i < array.length; ++i) {
array[i] = (Class) interfaceTable[i * stride];
array[i] = SystemClassLoader.getClass
((VMClass) vmClass.interfaceTable[i * stride]);
}
return array;
} else {
@ -509,36 +503,42 @@ public final class Class <T>
}
public ClassLoader getClassLoader() {
return loader;
return vmClass.loader;
}
public int getModifiers() {
return flags;
return vmClass.flags;
}
public boolean isInterface() {
return (flags & Modifier.INTERFACE) != 0;
return (vmClass.flags & Modifier.INTERFACE) != 0;
}
public Class getSuperclass() {
return super_;
return SystemClassLoader.getClass(vmClass.super_);
}
public boolean isArray() {
return arrayDimensions != 0;
return vmClass.arrayDimensions != 0;
}
public static boolean isInstance(VMClass c, Object o) {
return o != null && Classes.isAssignableFrom
(c, Classes.getVMClass(o));
}
public boolean isInstance(Object o) {
return o != null && isAssignableFrom(o.getClass());
return isInstance(vmClass, o);
}
public boolean isPrimitive() {
return (vmFlags & PrimitiveFlag) != 0;
return (vmClass.vmFlags & PrimitiveFlag) != 0;
}
public URL getResource(String path) {
if (! path.startsWith("/")) {
String name = new String(this.name, 0, this.name.length - 1, false);
String name = new String
(vmClass.name, 0, vmClass.name.length - 1, false);
int index = name.lastIndexOf('/');
if (index >= 0) {
path = name.substring(0, index) + "/" + path;
@ -572,12 +572,8 @@ public final class Class <T>
return (T) o;
}
public Object[] getSigners() {
return addendum == null ? null : addendum.signers;
}
public Package getPackage() {
if ((vmFlags & PrimitiveFlag) != 0 || isArray()) {
if ((vmClass.vmFlags & PrimitiveFlag) != 0 || isArray()) {
return null;
} else {
String name = getCanonicalName();
@ -597,25 +593,25 @@ public final class Class <T>
return getAnnotation(class_) != null;
}
private Annotation getAnnotation(Object[] a) {
private static Annotation getAnnotation(VMClass c, Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
(loader, new Class[] { (Class) a[1] },
(c.loader, new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a));
}
return (Annotation) a[0];
}
public <T extends Annotation> T getAnnotation(Class<T> class_) {
for (Class c = this; c != null; c = c.super_) {
for (VMClass c = vmClass; c != null; c = c.super_) {
if (c.addendum != null && c.addendum.annotationTable != null) {
avian.SystemClassLoader.link(c, c.loader);
Classes.link(c, c.loader);
Object[] table = (Object[]) c.addendum.annotationTable;
for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i];
if (a[1] == class_) {
return (T) c.getAnnotation(a);
return (T) getAnnotation(c, a);
}
}
}
@ -624,13 +620,13 @@ public final class Class <T>
}
public Annotation[] getDeclaredAnnotations() {
if (addendum != null && addendum.annotationTable != null) {
avian.SystemClassLoader.link(this);
if (vmClass.addendum.annotationTable != null) {
Classes.link(vmClass);
Object[] table = (Object[]) addendum.annotationTable;
Object[] table = (Object[]) vmClass.addendum.annotationTable;
Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]);
array[i] = getAnnotation(vmClass, (Object[]) table[i]);
}
return array;
} else {
@ -640,7 +636,7 @@ public final class Class <T>
private int countAnnotations() {
int count = 0;
for (Class c = this; c != null; c = c.super_) {
for (VMClass c = vmClass; c != null; c = c.super_) {
if (c.addendum != null && c.addendum.annotationTable != null) {
count += ((Object[]) c.addendum.annotationTable).length;
}
@ -651,11 +647,11 @@ public final class Class <T>
public Annotation[] getAnnotations() {
Annotation[] array = new Annotation[countMethods(true)];
int i = 0;
for (Class c = this; c != null; c = c.super_) {
for (VMClass c = vmClass; c != null; c = c.super_) {
if (c.addendum != null && c.addendum.annotationTable != null) {
Object[] table = (Object[]) c.addendum.annotationTable;
for (int j = 0; j < table.length; ++j) {
array[i++] = getAnnotation((Object[]) table[j]);
array[i++] = getAnnotation(vmClass, (Object[]) table[j]);
}
}
}
@ -663,43 +659,9 @@ public final class Class <T>
return array;
}
public boolean isEnum() {
throw new UnsupportedOperationException();
}
public TypeVariable<Class<T>>[] getTypeParameters() {
throw new UnsupportedOperationException();
}
public Method getEnclosingMethod() {
throw new UnsupportedOperationException();
}
public Constructor getEnclosingConstructor() {
throw new UnsupportedOperationException();
}
public Class getEnclosingClass() {
throw new UnsupportedOperationException();
}
public Class[] getDeclaredClasses() {
throw new UnsupportedOperationException();
}
public ProtectionDomain getProtectionDomain() {
Permissions p = new Permissions();
p.add(new AllPermission());
return new ProtectionDomain(null, p);
}
// for GNU Classpath compatibility:
void setSigners(Object[] signers) {
if (signers != null && signers.length > 0) {
if (addendum == null) {
addendum = new avian.ClassAddendum();
}
addendum.signers = signers;
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -13,6 +13,10 @@ package java.lang;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
public abstract class ClassLoader {
private final ClassLoader parent;
@ -42,14 +46,17 @@ public abstract class ClassLoader {
throw new IndexOutOfBoundsException();
}
return avian.SystemClassLoader.defineClass(this, b, offset, length);
return avian.SystemClassLoader.getClass
(avian.Classes.defineVMClass(this, b, offset, length));
}
protected Class findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException();
}
protected abstract Class reallyFindLoadedClass(String name);
protected Class reallyFindLoadedClass(String name) {
return null;
}
protected final Class findLoadedClass(String name) {
return reallyFindLoadedClass(name);
@ -83,7 +90,7 @@ public abstract class ClassLoader {
}
protected void resolveClass(Class c) {
avian.SystemClassLoader.link(c, this);
avian.Classes.link(c.vmClass, this);
}
private ClassLoader getParent() {
@ -94,6 +101,10 @@ public abstract class ClassLoader {
return null;
}
protected Enumeration<URL> findResources(String name) throws IOException {
return Collections.enumeration(new ArrayList<URL>(0));
}
public URL getResource(String path) {
URL url = null;
if (parent != null) {
@ -123,4 +134,24 @@ public abstract class ClassLoader {
public static InputStream getSystemResourceAsStream(String path) {
return getSystemClassLoader().getResourceAsStream(path);
}
public static Enumeration<URL> getSystemResources(String name) throws IOException {
return getSystemClassLoader().getResources(name);
}
public Enumeration<URL> getResources(String name)
throws IOException {
Collection<URL> resources = collectResources(name);
return Collections.enumeration(resources);
}
private Collection<URL> collectResources(String name) {
Collection<URL> urls = parent != null ? parent.collectResources(name) : new ArrayList<URL>(5);
URL url = findResource(name);
if (url != null) {
urls.add(url);
}
return urls;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -34,7 +34,7 @@ public abstract class Enum<E extends Enum<E>> implements Comparable<E> {
try {
Method method = enumType.getMethod("values");
Enum values[] = (Enum[]) (method.invoke(null));
Enum values[] = (Enum[]) method.invoke(null);
for (Enum value: values) {
if (name.equals(value.name)) {
return (T) value;

View File

@ -0,0 +1,26 @@
/* Copyright (c) 2010, 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;
/**
* TODO : current Avian runtime doesn't check, need to be implemented.
*
*/
public class IllegalAccessError extends IncompatibleClassChangeError {
public IllegalAccessError(String message) {
super(message);
}
public IllegalAccessError() {
}
}

View File

@ -0,0 +1,26 @@
/* Copyright (c) 2010, 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;
/**
* TODO : current Avian runtime doesn't check, need to be implemented.
*
*/
public class InstantiationError extends IncompatibleClassChangeError {
public InstantiationError(String message) {
super(message);
}
public InstantiationError() {
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -27,7 +27,11 @@ public class Object {
protected void finalize() throws Throwable { }
public native final Class<? extends Object> getClass();
public final Class<? extends Object> getClass() {
return avian.SystemClassLoader.getClass(getVMClass(this));
}
private static native avian.VMClass getVMClass(Object o);
public native int hashCode();

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,9 +10,9 @@
package java.lang;
public class OutOfMemoryError extends Error {
public class OutOfMemoryError extends VirtualMachineError {
public OutOfMemoryError(String message) {
super(message, null);
super(message);
}
public OutOfMemoryError() {

View File

@ -43,4 +43,8 @@ public class Package {
this.sealed = sealed;
this.loader = loader;
}
public String getName() {
return name;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -44,28 +44,80 @@ public class Runtime {
}
public Process exec(String command) throws IOException {
long[] process = new long[4];
StringTokenizer t = new StringTokenizer(command);
String[] cmd = new String[t.countTokens()];
for (int i = 0; i < cmd.length; i++)
cmd[i] = t.nextToken();
exec(cmd, process);
return new MyProcess(process[0], (int) process[1], (int) process[2], (int) process[3]);
return exec(cmd);
}
public Process exec(String[] command) {
long[] process = new long[4];
exec(command, process);
return new MyProcess(process[0], (int) process[1], (int) process[2], (int) process[3]);
public Process exec(final String[] command) throws IOException {
final MyProcess[] process = new MyProcess[1];
final Throwable[] exception = new Throwable[1];
synchronized (process) {
Thread t = new Thread() {
public void run() {
synchronized (process) {
try {
long[] info = new long[5];
exec(command, info);
process[0] = new MyProcess
(info[0], info[1], (int) info[2], (int) info[3],
(int) info[4]);
} catch (Throwable e) {
exception[0] = e;
} finally {
process.notifyAll();
}
}
MyProcess p = process[0];
if (p != null) {
synchronized (p) {
try {
if (p.pid != 0) {
p.exitCode = Runtime.waitFor(p.pid, p.tid);
p.pid = 0;
p.tid = 0;
}
} finally {
p.notifyAll();
}
}
}
}
};
t.setDaemon(true);
t.start();
while (process[0] == null && exception[0] == null) {
try {
process.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
if (exception[0] != null) {
if (exception[0] instanceof IOException) {
throw new IOException(exception[0]);
} else {
throw new RuntimeException(exception[0]);
}
}
return process[0];
}
public native void addShutdownHook(Thread t);
private static native void exec(String[] command, long[] process);
private static native void exec(String[] command, long[] process)
throws IOException;
private static native int exitValue(long pid);
private static native int waitFor(long pid);
private static native int waitFor(long pid, long tid);
private static native void load(String name, boolean mapName);
@ -79,13 +131,15 @@ public class Runtime {
private static class MyProcess extends Process {
private long pid;
private long tid;
private final int in;
private final int out;
private final int err;
private int exitCode;
public MyProcess(long pid, int in, int out, int err) {
public MyProcess(long pid, long tid, int in, int out, int err) {
this.pid = pid;
this.tid = tid;
this.in = in;
this.out = out;
this.err = err;
@ -95,13 +149,6 @@ public class Runtime {
throw new RuntimeException("not implemented");
}
public int exitValue() {
if (pid != 0) {
exitCode = Runtime.exitValue(pid);
}
return exitCode;
}
public InputStream getInputStream() {
return new FileInputStream(new FileDescriptor(in));
}
@ -114,11 +161,19 @@ public class Runtime {
return new FileInputStream(new FileDescriptor(err));
}
public int waitFor() throws InterruptedException {
public synchronized int exitValue() {
if (pid != 0) {
exitCode = Runtime.waitFor(pid);
pid = 0;
throw new IllegalThreadStateException();
}
return exitCode;
}
public synchronized int waitFor() throws InterruptedException {
while (pid != 0) {
wait();
}
return exitCode;
}
}

View File

@ -0,0 +1,30 @@
/* Copyright (c) 2010, 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.security.AccessController;
import java.security.Permission;
import java.security.SecurityPermission;
public class SecurityManager {
public SecurityManager() {
}
public void checkPermission(Permission perm) {
AccessController.checkPermission(perm);
}
public void checkSecurityAccess(String target) {
checkPermission(new SecurityPermission(target));
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -56,7 +56,7 @@ public class StackTraceElement {
}
public String getClassName() {
return class_.replace('/', '.');
return class_;
}
public String getMethodName() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -13,7 +13,6 @@ package java.lang;
import java.io.UnsupportedEncodingException;
import java.util.regex.Pattern;
import java.util.Comparator;
import java.util.Formatter;
import java.util.Locale;
import java.io.Serializable;
import avian.Utf8;
@ -236,19 +235,31 @@ public final class String
}
public String toLowerCase() {
char[] b = new char[length];
for (int i = 0; i < length; ++i) {
b[i] = Character.toLowerCase(charAt(i));
for (int j = 0; j < length; ++j) {
char ch = charAt(j);
if (Character.toLowerCase(ch) != ch) {
char[] b = new char[length];
for (int i = 0; i < length; ++i) {
b[i] = Character.toLowerCase(charAt(i));
}
return new String(b, 0, length, false);
}
}
return new String(b, 0, length, false);
return this;
}
public String toUpperCase() {
char[] b = new char[length];
for (int i = 0; i < length; ++i) {
b[i] = Character.toUpperCase(charAt(i));
for (int j = 0; j < length; ++j) {
char ch = charAt(j);
if (Character.toUpperCase(ch) != ch) {
char[] b = new char[length];
for (int i = 0; i < length; ++i) {
b[i] = Character.toUpperCase(charAt(i));
}
return new String(b, 0, length, false);
}
}
return new String(b, 0, length, false);
return this;
}
public int indexOf(int c) {
@ -507,9 +518,7 @@ public final class String
}
public static String valueOf(int v) {
// use Integer.toString(int, int), because GNU Classpath's
// Integer.toString(int) just calls String.valueOf(int):
return Integer.toString(v, 10);
return Integer.toString(v);
}
public static String valueOf(long v) {
@ -576,36 +585,19 @@ public final class String
return Character.codePointCount(this, start, end);
}
public String replace(CharSequence match, CharSequence replacement) {
throw new UnsupportedOperationException();
}
public String toUpperCase(Locale locale) {
throw new UnsupportedOperationException();
if (locale == Locale.ENGLISH) {
return toUpperCase();
} else {
throw new UnsupportedOperationException("toUpperCase("+locale+')');
}
}
public String toLowerCase(Locale locale) {
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:
static char[] zeroBasedStringValue(String s) {
if (s.offset == 0) {
if (s.data instanceof char[]) {
char[] data = (char[]) s.data;
if (data.length == s.length) {
return data;
}
}
if (locale == Locale.ENGLISH) {
return toLowerCase();
} else {
throw new UnsupportedOperationException("toLowerCase("+locale+')');
}
return s.toCharArray();
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -22,6 +22,7 @@ import java.util.Properties;
public abstract class System {
private static Property properties;
private static SecurityManager securityManager;
// static {
// loadLibrary("natives");
// }
@ -119,6 +120,14 @@ public abstract class System {
Runtime.getRuntime().exit(code);
}
public static SecurityManager getSecurityManager() {
return securityManager;
}
public static void setSecurityManager(SecurityManager securityManager) {
System.securityManager = securityManager;
}
private static class Property {
public final String name;
public String value;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -15,7 +15,8 @@ import java.util.WeakHashMap;
public class Thread implements Runnable {
private long peer;
private boolean interrupted;
private volatile boolean interrupted;
private volatile boolean unparked;
private boolean daemon;
private byte state;
private byte priority;
@ -24,11 +25,8 @@ public class Thread implements Runnable {
private Object sleepLock;
private ClassLoader classLoader;
private UncaughtExceptionHandler exceptionHandler;
// package private for GNU Classpath, which inexplicably bypasses
// the accessor methods:
String name;
ThreadGroup group;
private String name;
private ThreadGroup group;
private static UncaughtExceptionHandler defaultExceptionHandler;
@ -141,25 +139,9 @@ public class Thread implements Runnable {
public static native Thread currentThread();
private static native void interrupt(long peer);
public native void interrupt();
public synchronized void interrupt() {
if (peer != 0) {
interrupt(peer);
} else {
interrupted = true;
}
}
public static boolean interrupted() {
Thread t = currentThread();
synchronized (t) {
boolean v = t.interrupted;
t.interrupted = false;
return v;
}
}
public native boolean interrupted();
public static boolean isInterrupted() {
return currentThread().interrupted;
@ -257,12 +239,12 @@ public class Thread implements Runnable {
}
public synchronized void setDaemon(boolean v) {
if (v != daemon) {
setDaemon(this, v);
if (getState() != State.NEW) {
throw new IllegalStateException();
}
}
private static native void setDaemon(Thread t, boolean increment);
daemon = v;
}
public static native void yield();
@ -303,22 +285,6 @@ public class Thread implements Runnable {
return peer;
}
public void stop() {
throw new UnsupportedOperationException();
}
public void stop(Throwable t) {
throw new UnsupportedOperationException();
}
public void suspend() {
throw new UnsupportedOperationException();
}
public void resume() {
throw new UnsupportedOperationException();
}
public interface UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -13,7 +13,7 @@ package java.lang;
import avian.Cell;
public class ThreadGroup implements Thread.UncaughtExceptionHandler {
final ThreadGroup parent; // package private for GNU Classpath compatibility
private final ThreadGroup parent;
private final String name;
private Cell<ThreadGroup> subgroups;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -12,13 +12,12 @@ package java.lang.ref;
public class ReferenceQueue<T> {
private Reference<? extends T> front;
private Reference<? extends T> rear;
public Reference<? extends T> poll() {
Reference<? extends T> r = front;
if (front != null) {
if (front == front.jNext) {
front = rear = null;
front = null;
} else {
front = front.jNext;
}
@ -27,12 +26,11 @@ public class ReferenceQueue<T> {
}
void add(Reference<? extends T> r) {
r.jNext = r;
if (front == null) {
front = r;
r.jNext = r;
} else {
rear.jNext = r;
r.jNext = front;
}
rear = r;
front = r;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -12,9 +12,7 @@ package java.lang.reflect;
import java.lang.annotation.Annotation;
public class Constructor<T> extends AccessibleObject
implements Member, GenericDeclaration
{
public class Constructor<T> extends AccessibleObject implements Member {
private Method<T> method;
public Constructor(Method<T> method) {
@ -42,10 +40,6 @@ public class Constructor<T> extends AccessibleObject
return method.getParameterTypes();
}
public Class[] getExceptionTypes() {
return method.getExceptionTypes();
}
public int getModifiers() {
return method.getModifiers();
}
@ -54,10 +48,6 @@ public class Constructor<T> extends AccessibleObject
return method.getName();
}
public boolean isSynthetic() {
return method.isSynthetic();
}
public <T extends Annotation> T getAnnotation(Class<T> class_) {
return method.getAnnotation(class_);
}
@ -70,21 +60,13 @@ public class Constructor<T> extends AccessibleObject
return method.getDeclaredAnnotations();
}
public TypeVariable<Constructor<T>>[] getTypeParameters() {
throw new UnsupportedOperationException();
}
public Type[] getGenericParameterTypes() {
return method.getGenericParameterTypes();
}
private static native <T> T make(Class<T> c);
private static native Object make(avian.VMClass c);
public T newInstance(Object ... arguments)
throws InvocationTargetException, InstantiationException,
IllegalAccessException
{
T v = make(method.getDeclaringClass());
T v = (T) make(method.getDeclaringClass().vmClass);
method.invoke(v, arguments);
return v;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,7 +10,10 @@
package java.lang.reflect;
import avian.VMField;
import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader;
import avian.Classes;
import java.lang.annotation.Annotation;
@ -26,81 +29,90 @@ public class Field<T> extends AccessibleObject {
private static final int BooleanField = 8;
private static final int ObjectField = 9;
private byte vmFlags;
private byte code;
private short flags;
private short offset;
private byte[] name;
public byte[] spec;
public avian.Addendum addendum;
private Class<T> class_;
private final VMField vmField;
private boolean accessible = true;
private Field() { }
public Field(VMField vmField) {
this.vmField = vmField;
}
public boolean isAccessible() {
return (vmFlags & Accessible) != 0;
return accessible;
}
public void setAccessible(boolean v) {
if (v) vmFlags |= Accessible; else vmFlags &= ~Accessible;
accessible = v;
}
public Class<T> getDeclaringClass() {
return class_;
return SystemClassLoader.getClass(vmField.class_);
}
public int getModifiers() {
return flags;
return vmField.flags;
}
public String getName() {
return new String(name, 0, name.length - 1, false);
return getName(vmField);
}
public static String getName(VMField vmField) {
return new String(vmField.name, 0, vmField.name.length - 1, false);
}
public Class getType() {
return Class.forCanonicalName(class_.getClassLoader(),
new String(spec, 0, spec.length - 1, false));
return Class.forCanonicalName
(vmField.class_.loader,
new String(vmField.spec, 0, vmField.spec.length - 1, false));
}
public Object get(Object instance) throws IllegalAccessException {
Object target;
if ((flags & Modifier.STATIC) != 0) {
target = class_.staticTable();
} else if (class_.isInstance(instance)) {
if ((vmField.flags & Modifier.STATIC) != 0) {
target = vmField.class_.staticTable;
} else if (Class.isInstance(vmField.class_, instance)) {
target = instance;
} else {
throw new IllegalArgumentException();
}
switch (code) {
switch (vmField.code) {
case ByteField:
return Byte.valueOf((byte) getPrimitive(target, code, offset));
return Byte.valueOf
((byte) getPrimitive(target, vmField.code, vmField.offset));
case BooleanField:
return Boolean.valueOf(getPrimitive(target, code, offset) != 0);
return Boolean.valueOf
(getPrimitive(target, vmField.code, vmField.offset) != 0);
case CharField:
return Character.valueOf((char) getPrimitive(target, code, offset));
return Character.valueOf
((char) getPrimitive(target, vmField.code, vmField.offset));
case ShortField:
return Short.valueOf((short) getPrimitive(target, code, offset));
return Short.valueOf
((short) getPrimitive(target, vmField.code, vmField.offset));
case IntField:
return Integer.valueOf((int) getPrimitive(target, code, offset));
return Integer.valueOf
((int) getPrimitive(target, vmField.code, vmField.offset));
case LongField:
return Long.valueOf((int) getPrimitive(target, code, offset));
return Long.valueOf
((int) getPrimitive(target, vmField.code, vmField.offset));
case FloatField:
return Float.valueOf
(Float.intBitsToFloat((int) getPrimitive(target, code, offset)));
(Float.intBitsToFloat
((int) getPrimitive(target, vmField.code, vmField.offset)));
case DoubleField:
return Double.valueOf
(Double.longBitsToDouble(getPrimitive(target, code, offset)));
(Double.longBitsToDouble
(getPrimitive(target, vmField.code, vmField.offset)));
case ObjectField:
return getObject(target, offset);
return getObject(target, vmField.offset);
default:
throw new Error();
@ -143,56 +155,58 @@ public class Field<T> extends AccessibleObject {
throws IllegalAccessException
{
Object target;
if ((flags & Modifier.STATIC) != 0) {
target = class_.staticTable();
} else if (class_.isInstance(instance)) {
if ((vmField.flags & Modifier.STATIC) != 0) {
target = vmField.class_.staticTable;
} else if (Class.isInstance(vmField.class_, instance)) {
target = instance;
} else {
throw new IllegalArgumentException();
}
switch (code) {
switch (vmField.code) {
case ByteField:
setPrimitive(target, code, offset, (Byte) value);
setPrimitive(target, vmField.code, vmField.offset, (Byte) value);
break;
case BooleanField:
setPrimitive(target, code, offset, ((Boolean) value) ? 1 : 0);
setPrimitive
(target, vmField.code, vmField.offset, ((Boolean) value) ? 1 : 0);
break;
case CharField:
setPrimitive(target, code, offset, (Character) value);
setPrimitive(target, vmField.code, vmField.offset, (Character) value);
break;
case ShortField:
setPrimitive(target, code, offset, (Short) value);
setPrimitive(target, vmField.code, vmField.offset, (Short) value);
break;
case IntField:
setPrimitive(target, code, offset, (Integer) value);
setPrimitive(target, vmField.code, vmField.offset, (Integer) value);
break;
case LongField:
setPrimitive(target, code, offset, (Long) value);
setPrimitive(target, vmField.code, vmField.offset, (Long) value);
break;
case FloatField:
setPrimitive(target, code, offset,
setPrimitive(target, vmField.code, vmField.offset,
Float.floatToRawIntBits((Float) value));
break;
case DoubleField:
setPrimitive(target, code, offset,
setPrimitive(target, vmField.code, vmField.offset,
Double.doubleToRawLongBits((Double) value));
break;
case ObjectField:
if (value == null || getType().isInstance(value)) {
setObject(target, offset, value);
setObject(target, vmField.offset, value);
} else {
throw new IllegalArgumentException
("needed " + getType() + ", got " + value.getClass().getName() +
" when setting " + class_.getName() + "." + getName());
("needed " + getType() + ", got "
+ Class.getName(Classes.vmClass(target)) +
" when setting " + Class.getName(vmField.class_) + "." + getName());
}
break;
@ -204,15 +218,15 @@ public class Field<T> extends AccessibleObject {
private Annotation getAnnotation(Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
(class_.getClassLoader(), new Class[] { (Class) a[1] },
(vmField.class_.loader, new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a));
}
return (Annotation) a[0];
}
public <T extends Annotation> T getAnnotation(Class<T> class_) {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable;
if (vmField.addendum.annotationTable != null) {
Object[] table = (Object[]) vmField.addendum.annotationTable;
for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i];
if (a[1] == class_) {
@ -224,8 +238,8 @@ public class Field<T> extends AccessibleObject {
}
public Annotation[] getAnnotations() {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable;
if (vmField.addendum.annotationTable != null) {
Object[] table = (Object[]) vmField.addendum.annotationTable;
Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]);
@ -240,10 +254,6 @@ public class Field<T> extends AccessibleObject {
return getAnnotations();
}
public boolean isEnumConstant() {
throw new UnsupportedOperationException();
}
private static native long getPrimitive
(Object instance, int code, int offset);
@ -255,9 +265,4 @@ public class Field<T> extends AccessibleObject {
private static native void setObject
(Object instance, int offset, Object value);
public static class Addendum {
public Object pool;
public Object annotationTable;
}
}

View File

@ -19,6 +19,4 @@ public interface Member {
public int getModifiers();
public String getName();
public boolean isSynthetic();
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,53 +10,52 @@
package java.lang.reflect;
import avian.VMMethod;
import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader;
import java.lang.annotation.Annotation;
public class Method<T> extends AccessibleObject
implements Member, GenericDeclaration
{
private byte vmFlags;
private byte returnCode;
public byte parameterCount;
public byte parameterFootprint;
private short flags;
private short offset;
private int nativeID;
private byte[] name;
public byte[] spec;
public avian.Addendum addendum;
private Class<T> class_;
private Object code;
private long compiled;
public class Method<T> extends AccessibleObject implements Member {
private final VMMethod vmMethod;
private boolean accessible;
private Method() { }
public Method(VMMethod vmMethod) {
this.vmMethod = vmMethod;
}
public boolean isAccessible() {
return (vmFlags & Accessible) != 0;
return accessible;
}
public void setAccessible(boolean v) {
if (v) vmFlags |= Accessible; else vmFlags &= ~Accessible;
accessible = v;
}
public static native Method getCaller();
public static native VMMethod getCaller();
public Class<T> getDeclaringClass() {
return class_;
return SystemClassLoader.getClass(vmMethod.class_);
}
public int getModifiers() {
return flags;
return vmMethod.flags;
}
public String getName() {
return new String(name, 0, name.length - 1, false);
return getName(vmMethod);
}
String getSpec() {
return new String(spec, 0, spec.length - 1, false);
public static String getName(VMMethod vmMethod) {
return new String(vmMethod.name, 0, vmMethod.name.length - 1, false);
}
private String getSpec() {
return getSpec(vmMethod);
}
public static String getSpec(VMMethod vmMethod) {
return new String(vmMethod.spec, 0, vmMethod.spec.length - 1, false);
}
private static int next(char c, String s, int start) {
@ -67,12 +66,17 @@ public class Method<T> extends AccessibleObject
}
public Class[] getParameterTypes() {
int count = parameterCount;
return getParameterTypes(vmMethod);
}
public static Class[] getParameterTypes(VMMethod vmMethod) {
int count = vmMethod.parameterCount;
Class[] types = new Class[count];
int index = 0;
String spec = new String(this.spec, 1, this.spec.length - 1, false);
String spec = new String
(vmMethod.spec, 1, vmMethod.spec.length - 1, false);
try {
for (int i = 0; i < spec.length(); ++i) {
@ -83,7 +87,7 @@ public class Method<T> extends AccessibleObject
int start = i + 1;
i = next(';', spec, start);
String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName(name, true, class_.getClassLoader());
types[index++] = Class.forName(name, true, vmMethod.class_.loader);
} else if (c == '[') {
int start = i;
while (spec.charAt(i) == '[') ++i;
@ -92,16 +96,16 @@ public class Method<T> extends AccessibleObject
i = next(';', spec, i + 1);
String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName
(name, true, class_.getClassLoader());
(name, true, vmMethod.class_.loader);
} else {
String name = spec.substring(start, i + 1);
types[index++] = Class.forCanonicalName
(class_.getClassLoader(), name);
(vmMethod.class_.loader, name);
}
} else {
String name = spec.substring(i, i + 1);
types[index++] = Class.forCanonicalName
(class_.getClassLoader(), name);
(vmMethod.class_.loader, name);
}
}
} catch (ClassNotFoundException e) {
@ -114,38 +118,43 @@ public class Method<T> extends AccessibleObject
public Object invoke(Object instance, Object ... arguments)
throws InvocationTargetException, IllegalAccessException
{
if ((flags & Modifier.STATIC) != 0 || class_.isInstance(instance)) {
if ((flags & Modifier.STATIC) != 0) {
if ((vmMethod.flags & Modifier.STATIC) != 0
|| Class.isInstance(vmMethod.class_, instance))
{
if ((vmMethod.flags & Modifier.STATIC) != 0) {
instance = null;
}
if (arguments == null) {
if (parameterCount > 0) {
if (vmMethod.parameterCount > 0) {
throw new NullPointerException();
}
arguments = new Object[0];
}
if (arguments.length == parameterCount) {
return invoke(this, instance, arguments);
if (arguments.length == vmMethod.parameterCount) {
return invoke(vmMethod, instance, arguments);
} else {
throw new ArrayIndexOutOfBoundsException();
}
} else {
// System.out.println
// (getDeclaringClass() + "." + getName() + " flags: " + vmMethod.flags + " vm flags: " + vmMethod.vmFlags + " return code: " + vmMethod.returnCode);
throw new IllegalArgumentException();
}
}
private static native Object invoke(Method method, Object instance,
private static native Object invoke(VMMethod method, Object instance,
Object ... arguments)
throws InvocationTargetException, IllegalAccessException;
public Class getReturnType() {
for (int i = 0; i < spec.length - 1; ++i) {
if (spec[i] == ')') {
for (int i = 0; i < vmMethod.spec.length - 1; ++i) {
if (vmMethod.spec[i] == ')') {
return Class.forCanonicalName
(class_.getClassLoader(),
new String(spec, i + 1, spec.length - i - 2, false));
(vmMethod.class_.loader,
new String
(vmMethod.spec, i + 1, vmMethod.spec.length - i - 2, false));
}
}
throw new RuntimeException();
@ -154,15 +163,15 @@ public class Method<T> extends AccessibleObject
private Annotation getAnnotation(Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
(class_.getClassLoader(), new Class[] { (Class) a[1] },
(vmMethod.class_.loader, new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a));
}
return (Annotation) a[0];
}
public <T extends Annotation> T getAnnotation(Class<T> class_) {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable;
if (vmMethod.addendum.annotationTable != null) {
Object[] table = (Object[]) vmMethod.addendum.annotationTable;
for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i];
if (a[1] == class_) {
@ -174,8 +183,8 @@ public class Method<T> extends AccessibleObject
}
public Annotation[] getAnnotations() {
if (addendum != null && addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable;
if (vmMethod.addendum.annotationTable != null) {
Object[] table = (Object[]) vmMethod.addendum.annotationTable;
Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]);
@ -189,28 +198,4 @@ public class Method<T> extends AccessibleObject
public Annotation[] getDeclaredAnnotations() {
return getAnnotations();
}
public boolean isSynthetic() {
throw new UnsupportedOperationException();
}
public Object getDefaultValue() {
throw new UnsupportedOperationException();
}
public Type[] getGenericParameterTypes() {
throw new UnsupportedOperationException();
}
public Type getGenericReturnType() {
throw new UnsupportedOperationException();
}
public Class[] getExceptionTypes() {
throw new UnsupportedOperationException();
}
public TypeVariable<Method<T>>[] getTypeParameters() {
throw new UnsupportedOperationException();
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -13,6 +13,14 @@ package java.lang.reflect;
import static avian.Stream.write1;
import static avian.Stream.write2;
import static avian.Stream.write4;
import static avian.Stream.set4;
import static avian.Assembler.*;
import avian.ConstantPool;
import avian.ConstantPool.PoolEntry;
import avian.Assembler;
import avian.Assembler.MethodData;
import java.util.List;
import java.util.ArrayList;
@ -23,38 +31,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class Proxy {
private static final int CONSTANT_Integer = 3;
private static final int CONSTANT_Utf8 = 1;
private static final int CONSTANT_Class = 7;
private static final int CONSTANT_NameAndType = 12;
private static final int CONSTANT_Fieldref = 9;
private static final int CONSTANT_Methodref = 10;
private static final int aaload = 0x32;
private static final int aastore = 0x53;
private static final int aload = 0x19;
private static final int aload_0 = 0x2a;
private static final int aload_1 = 0x2b;
private static final int anewarray = 0xbd;
private static final int areturn = 0xb0;
private static final int dload = 0x18;
private static final int dreturn = 0xaf;
private static final int dup = 0x59;
private static final int fload = 0x17;
private static final int freturn = 0xae;
private static final int getfield = 0xb4;
private static final int iload = 0x15;
private static final int invokeinterface = 0xb9;
private static final int invokestatic = 0xb8;
private static final int invokevirtual = 0xb6;
private static final int ireturn = 0xac;
private static final int ldc_w = 0x13;
private static final int lload = 0x16;
private static final int lreturn = 0xad;
private static final int pop = 0x57;
private static final int putfield = 0xb5;
private static final int return_ = 0xb1;
private static int nextNumber;
protected InvocationHandler h;
@ -90,67 +66,6 @@ public class Proxy {
return ((Proxy) proxy).h;
}
private static void set4(byte[] array, int offset, int v) {
array[offset ] = (byte) ((v >>> 24) & 0xFF);
array[offset + 1] = (byte) ((v >>> 16) & 0xFF);
array[offset + 2] = (byte) ((v >>> 8) & 0xFF);
array[offset + 3] = (byte) ((v ) & 0xFF);
}
private static int poolAdd(List<PoolEntry> pool, PoolEntry e) {
int i = 0;
for (PoolEntry existing: pool) {
if (existing.equals(e)) {
return i;
} else {
++i;
}
}
pool.add(e);
return pool.size() - 1;
}
private static int poolAddInteger(List<PoolEntry> pool, int value) {
return poolAdd(pool, new IntegerPoolEntry(value));
}
private static int poolAddUtf8(List<PoolEntry> pool, String value) {
return poolAdd(pool, new Utf8PoolEntry(value));
}
private static int poolAddClass(List<PoolEntry> pool, String name) {
return poolAdd(pool, new ClassPoolEntry(poolAddUtf8(pool, name)));
}
private static int poolAddNameAndType(List<PoolEntry> pool,
String name,
String type)
{
return poolAdd(pool, new NameAndTypePoolEntry
(poolAddUtf8(pool, name),
poolAddUtf8(pool, type)));
}
private static int poolAddFieldRef(List<PoolEntry> pool,
String className,
String name,
String spec)
{
return poolAdd(pool, new FieldRefPoolEntry
(poolAddClass(pool, className),
poolAddNameAndType(pool, name, spec)));
}
private static int poolAddMethodRef(List<PoolEntry> pool,
String className,
String name,
String spec)
{
return poolAdd(pool, new MethodRefPoolEntry
(poolAddClass(pool, className),
poolAddNameAndType(pool, name, spec)));
}
private static byte[] makeInvokeCode(List<PoolEntry> pool,
String className,
byte[] spec,
@ -166,26 +81,37 @@ public class Proxy {
write1(out, aload_0);
write1(out, getfield);
write2(out, poolAddFieldRef
write2(out, ConstantPool.addFieldRef
(pool, "java/lang/reflect/Proxy",
"h", "Ljava/lang/reflect/InvocationHandler;") + 1);
write1(out, aload_0);
write1(out, new_);
write2(out, ConstantPool.addClass(pool, "java/lang/reflect/Method") + 1);
write1(out, dup);
write1(out, ldc_w);
write2(out, poolAddClass(pool, className) + 1);
write2(out, ConstantPool.addClass(pool, className) + 1);
write1(out, getfield);
write2(out, poolAddFieldRef
write2(out, ConstantPool.addFieldRef
(pool, "java/lang/Class",
"methodTable", "[Ljava/lang/reflect/Method;") + 1);
"vmClass", "Lavian/VMClass;") + 1);
write1(out, getfield);
write2(out, ConstantPool.addFieldRef
(pool, "avian/VMClass",
"methodTable", "[Lavian/VMMethod;") + 1);
write1(out, ldc_w);
write2(out, poolAddInteger(pool, index) + 1);
write2(out, ConstantPool.addInteger(pool, index) + 1);
write1(out, aaload);
write1(out, invokespecial);
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/reflect/Method",
"<init>", "(Lavian/VMMethod;)V") + 1);
write1(out, ldc_w);
write2(out, poolAddInteger(pool, parameterCount) + 1);
write2(out, ConstantPool.addInteger(pool, parameterCount) + 1);
write1(out, anewarray);
write2(out, poolAddClass(pool, "java/lang/Object") + 1);
write2(out, ConstantPool.addClass(pool, "java/lang/Object") + 1);
int ai = 0;
int si;
@ -193,7 +119,7 @@ public class Proxy {
write1(out, dup);
write1(out, ldc_w);
write2(out, poolAddInteger(pool, ai) + 1);
write2(out, ConstantPool.addInteger(pool, ai) + 1);
switch (spec[si]) {
case 'L':
@ -226,7 +152,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Boolean",
"valueOf", "(Z)Ljava/lang/Boolean;") + 1);
break;
@ -236,7 +162,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Byte",
"valueOf", "(B)Ljava/lang/Byte;") + 1);
break;
@ -246,7 +172,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Short",
"valueOf", "(S)Ljava/lang/Short;") + 1);
break;
@ -256,7 +182,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Character",
"valueOf", "(C)Ljava/lang/Character;") + 1);
break;
@ -266,7 +192,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Integer",
"valueOf", "(I)Ljava/lang/Integer;") + 1);
break;
@ -276,7 +202,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Float",
"valueOf", "(F)Ljava/lang/Float;") + 1);
break;
@ -286,7 +212,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Long",
"valueOf", "(J)Ljava/lang/Long;") + 1);
++ ai;
@ -297,7 +223,7 @@ public class Proxy {
write1(out, ai + 1);
write1(out, invokestatic);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Double",
"valueOf", "(D)Ljava/lang/Double;") + 1);
++ ai;
@ -312,7 +238,7 @@ public class Proxy {
}
write1(out, invokeinterface);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/reflect/InvocationHandler",
"invoke",
"(Ljava/lang/Object;"
@ -329,56 +255,56 @@ public class Proxy {
case 'Z':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Boolean", "booleanValue", "()Z") + 1);
write1(out, ireturn);
break;
case 'B':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Byte", "byteValue", "()B") + 1);
write1(out, ireturn);
break;
case 'C':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Character", "charValue", "()C") + 1);
write1(out, ireturn);
break;
case 'S':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Short", "shortValue", "()S") + 1);
write1(out, ireturn);
break;
case 'I':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Integer", "intValue", "()I") + 1);
write1(out, ireturn);
break;
case 'F':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Float", "floatValue", "()F") + 1);
write1(out, freturn);
break;
case 'J':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Long", "longValue", "()J") + 1);
write1(out, lreturn);
break;
case 'D':
write1(out, invokevirtual);
write2(out, poolAddMethodRef
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/Double", "doubleValue", "()D") + 1);
write1(out, dreturn);
break;
@ -411,7 +337,7 @@ public class Proxy {
write1(out, aload_0);
write1(out, aload_1);
write1(out, putfield);
write2(out, poolAddFieldRef
write2(out, ConstantPool.addFieldRef
(pool, "java/lang/reflect/Proxy",
"h", "Ljava/lang/reflect/InvocationHandler;") + 1);
write1(out, return_);
@ -431,78 +357,50 @@ public class Proxy {
int[] interfaceIndexes = new int[interfaces.length];
for (int i = 0; i < interfaces.length; ++i) {
interfaceIndexes[i] = poolAddClass(pool, interfaces[i].getName());
interfaceIndexes[i] = ConstantPool.addClass
(pool, interfaces[i].getName());
}
Map<String,Method> virtualMap = new HashMap();
Map<String,avian.VMMethod> virtualMap = new HashMap();
for (Class c: interfaces) {
Method[] ivtable = c.virtualTable;
avian.VMMethod[] ivtable = c.vmClass.virtualTable;
if (ivtable != null) {
for (Method m: ivtable) {
virtualMap.put(m.getName() + m.getSpec(), m);
for (avian.VMMethod m: ivtable) {
virtualMap.put(Method.getName(m) + Method.getSpec(m), m);
}
}
}
MethodData[] methodTable = new MethodData[virtualMap.size() + 1];
{ int i = 0;
for (Method m: virtualMap.values()) {
for (avian.VMMethod m: virtualMap.values()) {
methodTable[i] = new MethodData
(poolAddUtf8(pool, m.getName()),
poolAddUtf8(pool, m.getSpec()),
(0,
ConstantPool.addUtf8(pool, Method.getName(m)),
ConstantPool.addUtf8(pool, Method.getSpec(m)),
makeInvokeCode(pool, name, m.spec, m.parameterCount,
m.parameterFootprint, i));
++ i;
}
methodTable[i++] = new MethodData
(poolAddUtf8(pool, "<init>"),
poolAddUtf8(pool, "(Ljava/lang/reflect/InvocationHandler;)V"),
(0,
ConstantPool.addUtf8(pool, "<init>"),
ConstantPool.addUtf8
(pool, "(Ljava/lang/reflect/InvocationHandler;)V"),
makeConstructorCode(pool));
}
int nameIndex = poolAddClass(pool, name);
int superIndex = poolAddClass(pool, "java/lang/reflect/Proxy");
int codeAttributeNameIndex = poolAddUtf8(pool, "Code");
int nameIndex = ConstantPool.addClass(pool, name);
int superIndex = ConstantPool.addClass(pool, "java/lang/reflect/Proxy");
ByteArrayOutputStream out = new ByteArrayOutputStream();
write4(out, 0xCAFEBABE);
write2(out, 0); // minor version
write2(out, 0); // major version
write2(out, pool.size() + 1);
for (PoolEntry e: pool) {
e.writeTo(out);
}
write2(out, 0); // flags
write2(out, nameIndex + 1);
write2(out, superIndex + 1);
write2(out, interfaces.length);
for (int i: interfaceIndexes) {
write2(out, i + 1);
}
write2(out, 0); // field count
write2(out, methodTable.length);
for (MethodData m: methodTable) {
write2(out, 0); // flags
write2(out, m.nameIndex + 1);
write2(out, m.specIndex + 1);
write2(out, 1); // attribute count
write2(out, codeAttributeNameIndex + 1);
write4(out, m.code.length);
out.write(m.code);
}
write2(out, 0); // attribute count
Assembler.writeClass
(out, pool, nameIndex, superIndex, interfaceIndexes, methodTable);
byte[] classData = out.toByteArray();
return avian.SystemClassLoader.defineClass
(loader, classData, 0, classData.length);
return avian.SystemClassLoader.getClass
(avian.Classes.defineVMClass(loader, classData, 0, classData.length));
}
public static Object newProxyInstance(ClassLoader loader,
@ -519,153 +417,4 @@ public class Proxy {
throw error;
}
}
private static class MethodData {
public final int nameIndex;
public final int specIndex;
public final byte[] code;
public MethodData(int nameIndex, int specIndex, byte[] code) {
this.nameIndex = nameIndex;
this.specIndex = specIndex;
this.code = code;
}
}
public interface PoolEntry {
public void writeTo(OutputStream out) throws IOException;
}
public static class IntegerPoolEntry implements PoolEntry {
private final int value;
public IntegerPoolEntry(int value) {
this.value = value;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Integer);
write4(out, value);
}
public boolean equals(Object o) {
return o instanceof IntegerPoolEntry
&& ((IntegerPoolEntry) o).value == value;
}
}
public static class Utf8PoolEntry implements PoolEntry {
private final String data;
public Utf8PoolEntry(String data) {
this.data = data;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Utf8);
byte[] bytes = data.getBytes();
write2(out, bytes.length);
out.write(bytes);
}
public boolean equals(Object o) {
return o instanceof Utf8PoolEntry
&& ((Utf8PoolEntry) o).data.equals(data);
}
}
public static class ClassPoolEntry implements PoolEntry {
private final int nameIndex;
public ClassPoolEntry(int nameIndex) {
this.nameIndex = nameIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Class);
write2(out, nameIndex + 1);
}
public boolean equals(Object o) {
return o instanceof ClassPoolEntry
&& ((ClassPoolEntry) o).nameIndex == nameIndex;
}
}
public static class NameAndTypePoolEntry implements PoolEntry {
private final int nameIndex;
private final int typeIndex;
public NameAndTypePoolEntry(int nameIndex, int typeIndex) {
this.nameIndex = nameIndex;
this.typeIndex = typeIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_NameAndType);
write2(out, nameIndex + 1);
write2(out, typeIndex + 1);
}
public boolean equals(Object o) {
if (o instanceof NameAndTypePoolEntry) {
NameAndTypePoolEntry other = (NameAndTypePoolEntry) o;
return other.nameIndex == nameIndex && other.typeIndex == typeIndex;
} else {
return false;
}
}
}
public static class FieldRefPoolEntry implements PoolEntry {
private final int classIndex;
private final int nameAndTypeIndex;
public FieldRefPoolEntry(int classIndex, int nameAndTypeIndex) {
this.classIndex = classIndex;
this.nameAndTypeIndex = nameAndTypeIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Fieldref);
write2(out, classIndex + 1);
write2(out, nameAndTypeIndex + 1);
}
public boolean equals(Object o) {
if (o instanceof FieldRefPoolEntry) {
FieldRefPoolEntry other = (FieldRefPoolEntry) o;
return other.classIndex == classIndex
&& other.nameAndTypeIndex == nameAndTypeIndex;
} else {
return false;
}
}
}
public static class MethodRefPoolEntry implements PoolEntry {
private final int classIndex;
private final int nameAndTypeIndex;
public MethodRefPoolEntry(int classIndex, int nameAndTypeIndex) {
this.classIndex = classIndex;
this.nameAndTypeIndex = nameAndTypeIndex;
}
public void writeTo(OutputStream out) throws IOException {
write1(out, CONSTANT_Methodref);
write2(out, classIndex + 1);
write2(out, nameAndTypeIndex + 1);
}
public boolean equals(Object o) {
if (o instanceof MethodRefPoolEntry) {
MethodRefPoolEntry other = (MethodRefPoolEntry) o;
return other.classIndex == classIndex
&& other.nameAndTypeIndex == nameAndTypeIndex;
} else {
return false;
}
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -16,6 +16,9 @@ import java.io.OutputStream;
public abstract class URLConnection {
protected final URL url;
protected boolean doInput = true;
protected boolean doOutput = false;
protected boolean useCaches = true;
protected URLConnection(URL url) {
this.url = url;
@ -29,6 +32,8 @@ public abstract class URLConnection {
return -1;
}
public abstract void connect() throws IOException;
public InputStream getInputStream() throws IOException {
throw new UnknownServiceException();
}
@ -36,4 +41,24 @@ public abstract class URLConnection {
public OutputStream getOutputStream() throws IOException {
throw new UnknownServiceException();
}
public boolean getDoInput() {
return doInput;
}
public boolean getDoOutput() {
return doOutput;
}
public void setDoInput(boolean v) {
doInput = v;
}
public void setDoOutput(boolean v) {
doInput = v;
}
public void setUseCaches(boolean v) {
useCaches = v;
}
}

View File

@ -24,6 +24,14 @@ public class Channels {
return new MyOutputStream(channel);
}
public static ReadableByteChannel newChannel(InputStream stream) {
return new InputStreamChannel(stream);
}
public static WritableByteChannel newChannel(OutputStream stream) {
return new OutputStreamChannel(stream);
}
private static class MyInputStream extends InputStream {
private final ReadableByteChannel channel;
@ -72,4 +80,63 @@ public class Channels {
channel.close();
}
}
private static class InputStreamChannel implements ReadableByteChannel {
private InputStream stream;
public InputStreamChannel(InputStream stream) {
this.stream = stream;
}
public void close() throws IOException {
if (stream != null) {
stream.close();
stream = null;
}
}
public boolean isOpen() {
return stream != null;
}
public int read(ByteBuffer b) throws IOException {
int c = stream.read
(b.array(), b.arrayOffset() + b.position(), b.remaining());
if (c > 0) {
b.position(b.position() + c);
}
return c;
}
}
private static class OutputStreamChannel implements WritableByteChannel {
private OutputStream stream;
public OutputStreamChannel(OutputStream stream) {
this.stream = stream;
}
public void close() throws IOException {
if (stream != null) {
stream.close();
stream = null;
}
}
public boolean isOpen() {
return stream != null;
}
public int write(ByteBuffer b) throws IOException {
stream.write(b.array(), b.arrayOffset() + b.position(), b.remaining());
int c = b.remaining();
b.position(b.limit());
return c;
}
}
}

View File

@ -0,0 +1,20 @@
/* Copyright (c) 2011, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
public interface GatheringByteChannel extends WritableByteChannel {
public long write(ByteBuffer[] srcs) throws IOException;
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -19,6 +19,8 @@ public abstract class SelectableChannel implements Channel {
abstract int socketFD();
abstract void handleReadyOps(int ops);
public abstract SelectableChannel configureBlocking(boolean v)
throws IOException;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -32,6 +32,10 @@ public class ServerSocketChannel extends SelectableChannel {
return channel.socketFD();
}
public void handleReadyOps(int ops) {
channel.handleReadyOps(ops);
}
public SelectableChannel configureBlocking(boolean v) throws IOException {
return channel.configureBlocking(v);
}
@ -40,7 +44,7 @@ public class ServerSocketChannel extends SelectableChannel {
channel.close();
}
public SocketChannel accept() throws Exception {
public SocketChannel accept() throws IOException {
SocketChannel c = new SocketChannel();
c.socket = doAccept();
c.connected = true;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -18,12 +18,13 @@ import java.net.Socket;
import java.nio.ByteBuffer;
public class SocketChannel extends SelectableChannel
implements ReadableByteChannel, WritableByteChannel
implements ReadableByteChannel, GatheringByteChannel
{
public static final int InvalidSocket = -1;
int socket = InvalidSocket;
boolean connected = false;
boolean readyToConnect = false;
boolean blocking = true;
public static SocketChannel open() throws IOException {
@ -66,8 +67,23 @@ public class SocketChannel extends SelectableChannel
public boolean finishConnect() throws IOException {
if (! connected) {
connected = natFinishConnect(socket);
while (! readyToConnect) {
Selector selector = Selector.open();
SelectionKey key = register(selector, SelectionKey.OP_CONNECT, null);
if (blocking) {
selector.select();
} else {
selector.selectNow();
break;
}
}
natFinishConnect(socket);
connected = readyToConnect;
}
return connected;
}
@ -117,6 +133,23 @@ public class SocketChannel extends SelectableChannel
return w;
}
public long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
long total = 0;
for (int i = offset; i < offset + length; ++i) {
total += write(srcs[i]);
if (srcs[i].hasRemaining()) {
return total;
}
}
return total;
}
private void closeSocket() {
natCloseSocket(socket);
}
@ -125,6 +158,12 @@ public class SocketChannel extends SelectableChannel
return socket;
}
void handleReadyOps(int ops) {
if ((ops & SelectionKey.OP_CONNECT) != 0) {
readyToConnect = true;
}
}
public class Handle extends Socket {
public void setTcpNoDelay(boolean on) throws SocketException {
natSetTcpNoDelay(socket, on);
@ -139,7 +178,7 @@ public class SocketChannel extends SelectableChannel
private static native int natDoConnect(String host, int port, boolean blocking, boolean[] connected)
throws IOException;
private static native boolean natFinishConnect(int socket)
private static native void natFinishConnect(int socket)
throws IOException;
private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking)
throws IOException;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -96,6 +96,7 @@ class SocketSelector extends Selector {
int ready = natUpdateReadySet(socket, key.interestOps(), state);
key.readyOps(ready);
if (ready != 0) {
c.handleReadyOps(ready);
selectedKeys.add(key);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008, 2010 Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -22,4 +22,8 @@ public class AccessController {
return action.run();
}
public static void checkPermission(Permission perm) throws AccessControlException {
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,4 +10,10 @@
package java.security;
public class AllPermission extends Permission { }
public class AllPermission extends Permission {
public AllPermission() {
super("<all>");
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -8,12 +8,12 @@
There is NO WARRANTY for this software. See license.txt for
details. */
package java.lang.reflect;
package java.security;
public class BasicPermission extends Permission {
public BasicPermission(String name) {
super(name);
}
public interface TypeVariable<T extends GenericDeclaration>
extends Type
{
public Type[] getBounds();
public T getGenericDeclaration();
public String getName();
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -11,6 +11,22 @@
package java.security;
public abstract class Permission {
protected String name;
public Permission(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return this.getClass().getSimpleName() + '['+name+']';
}
public PermissionCollection newPermissionCollection() {
return null;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -8,16 +8,12 @@
There is NO WARRANTY for this software. See license.txt for
details. */
package java.util;
package java.security;
public class Formatter {
private final Locale locale;
public class SecurityPermission extends BasicPermission {
public Formatter(Locale locale) {
this.locale = locale;
public SecurityPermission(String name) {
super(name);
}
public Formatter format(String format, Object ... args) {
throw new UnsupportedOperationException();
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -149,4 +149,10 @@ public class Arrays {
}
}
public static <T> void fill(T[] array, T value) {
for (int i=0;i<array.length;i++) {
array[i] = value;
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -11,6 +11,7 @@
package java.util;
public class Collections {
private Collections() { }
public static void shuffle(List list, Random random) {
@ -80,6 +81,14 @@ public class Collections {
return sb.toString();
}
public static <T> Enumeration<T> enumeration(Collection<T> c) {
return new IteratorEnumeration<T> (c.iterator());
}
public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
return new ReverseComparator<T>(cmp);
}
static class IteratorEnumeration<T> implements Enumeration<T> {
private final Iterator<T> it;
@ -375,4 +384,19 @@ public class Collections {
it.remove();
}
}
private static final class ReverseComparator<T> implements Comparator<T> {
Comparator<T> cmp;
public ReverseComparator(Comparator<T> cmp) {
this.cmp = cmp;
}
public int compare(T o1, T o2) {
return - cmp.compare(o1, o2);
}
}
}

View File

@ -0,0 +1,47 @@
/* Copyright (c) 2010, 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;
/**
* @author zsombor
*
*/
public class ConcurrentModificationException extends RuntimeException {
/**
* @param message
* @param cause
*/
public ConcurrentModificationException(String message, Throwable cause) {
super(message, cause);
}
/**
* @param message
*/
public ConcurrentModificationException(String message) {
super(message);
}
/**
* @param cause
*/
public ConcurrentModificationException(Throwable cause) {
super(cause);
}
/**
*
*/
public ConcurrentModificationException() {
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -149,16 +149,17 @@ public class HashMap<K, V> implements Map<K, V> {
}
public boolean containsValue(Object value) {
if (array != null) {
int index = array.length - 1;
for (Cell<K, V> c = array[index]; c != null; c = c.next()) {
if (helper.equal(value, c.getValue())) {
return true;
if (array != null) {
for (int i = 0; i < array.length; ++i) {
for (Cell<K, V> c = array[i]; c != null; c = c.next()) {
if (helper.equal(value, c.getValue())) {
return true;
}
}
}
}
return false;
return false;
}
public V get(Object key) {
@ -269,8 +270,10 @@ public class HashMap<K, V> implements Map<K, V> {
return value;
}
public void setValue(V value) {
public V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
public HashMap.Cell<K, V> next() {
@ -448,10 +451,12 @@ public class HashMap<K, V> implements Map<K, V> {
public Entry<K, V> next() {
if (hasNext()) {
if (currentCell != null && currentCell.next() != null) {
previousCell = currentCell;
} else {
previousCell = null;
if (currentCell != null) {
if (currentCell.next() != null) {
previousCell = currentCell;
} else {
previousCell = null;
}
}
currentCell = nextCell;
@ -488,6 +493,7 @@ public class HashMap<K, V> implements Map<K, V> {
}
}
currentCell = null;
-- size;
} else {
throw new IllegalStateException();
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -40,6 +40,6 @@ public interface Map<K, V> {
public V getValue();
public void setValue(V value);
public V setValue(V value);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -14,10 +14,15 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.io.Reader;
public class Properties extends Hashtable {
public void load(InputStream in) throws IOException {
new Parser().parse(in, this);
new InputStreamParser(in).parse(this);
}
public void load(Reader reader) throws IOException {
new ReaderParser(reader).parse(this);
}
public void store(OutputStream out, String comment) throws IOException {
@ -49,7 +54,11 @@ public class Properties extends Hashtable {
return put(key, value);
}
private static class Parser {
public Enumeration<?> propertyNames() {
return keys();
}
private abstract static class Parser {
private StringBuilder key = null;
private StringBuilder value = null;
private StringBuilder current = null;
@ -75,13 +84,15 @@ public class Properties extends Hashtable {
key = value = current = null;
}
private void parse(InputStream in, Map map)
abstract int readCharacter() throws IOException;
void parse(Map map)
throws IOException
{
boolean escaped = false;
int c;
while ((c = in.read()) != -1) {
while ((c = readCharacter()) != -1) {
if (c == '\\') {
if (escaped) {
escaped = false;
@ -94,7 +105,7 @@ public class Properties extends Hashtable {
case '#':
case '!':
if (key == null) {
while ((c = in.read()) != -1 && c != '\n');
while ((c = readCharacter()) != -1 && c != '\n');
} else {
append(c);
}
@ -162,4 +173,32 @@ public class Properties extends Hashtable {
finishLine(map);
}
}
static class InputStreamParser extends Parser {
InputStream in;
public InputStreamParser(InputStream in) {
this.in = in;
}
@Override
int readCharacter() throws IOException {
return in.read();
}
}
static class ReaderParser extends Parser {
Reader in;
public ReaderParser(Reader in) {
this.in = in;
}
@Override
int readCharacter() throws IOException {
return in.read();
}
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -94,13 +94,12 @@ public abstract class ResourceBundle {
}
public static ResourceBundle getBundle(String name, Locale locale) {
return getBundle(name, locale,
Method.getCaller().getDeclaringClass().getClassLoader());
return getBundle(name, locale, Method.getCaller().class_.loader);
}
public static ResourceBundle getBundle(String name) {
return getBundle(name, Locale.getDefault(),
Method.getCaller().getDeclaringClass().getClassLoader());
return getBundle
(name, Locale.getDefault(), Method.getCaller().class_.loader);
}
public Object getObject(String key) {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -112,9 +112,12 @@ public class TreeMap<K,V> implements Map<K,V> {
return value;
}
public void setValue(V value) {
public V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
}
private class KeySet implements Set<K> {

View File

@ -34,6 +34,14 @@ public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
});
}
public TreeSet(Collection<? extends T> collection) {
this();
for (T item: collection) {
add(item);
}
}
public Iterator<T> iterator() {
return new MyIterator<T>(set.first());
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -114,8 +114,10 @@ public class WeakHashMap<K, V> implements Map<K, V> {
return value;
}
public void setValue(V value) {
public V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
public HashMap.Cell<K, V> next() {

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -107,15 +107,15 @@ public class Logger {
return logger.getLevel();
}
private void log(Level level, Method caller, String message,
private void log(Level level, avian.VMMethod caller, String message,
Throwable exception) {
if (level.intValue() < getEffectiveLevel().intValue()) {
return;
}
LogRecord r = new LogRecord
(name, caller == null ? "<unknown>" : caller.getName(), level, message,
exception);
(name, caller == null ? "<unknown>" : Method.getName(caller), level,
message, exception);
publish(r);
}

View File

@ -36,18 +36,6 @@ public class Matcher {
}
}
public boolean requireEnd() {
throw new UnsupportedOperationException();
}
public boolean hitEnd() {
throw new UnsupportedOperationException();
}
public boolean lookingAt() {
throw new UnsupportedOperationException();
}
public Matcher reset() {
return reset(input);
}
@ -63,26 +51,6 @@ public class Matcher {
return start;
}
public int start(int group) {
throw new UnsupportedOperationException();
}
public Pattern pattern() {
throw new UnsupportedOperationException();
}
public Matcher region(int start, int end) {
throw new UnsupportedOperationException();
}
public int regionEnd() {
throw new UnsupportedOperationException();
}
public int regionStart() {
throw new UnsupportedOperationException();
}
public String replaceAll(String replacement) {
return replace(replacement, Integer.MAX_VALUE);
}
@ -124,10 +92,6 @@ public class Matcher {
return end;
}
public int end(int group) {
throw new UnsupportedOperationException();
}
public boolean find() {
return find(end);
}
@ -143,16 +107,4 @@ public class Matcher {
return false;
}
}
public int groupCount() {
throw new UnsupportedOperationException();
}
public String group() {
throw new UnsupportedOperationException();
}
public String group(int group) {
throw new UnsupportedOperationException();
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -92,10 +92,6 @@ public class Pattern {
return pattern;
}
public static String quote(String s) {
throw new UnsupportedOperationException();
}
public String[] split(CharSequence input) {
return split(input, 0);
}
@ -115,23 +111,34 @@ public class Pattern {
List<CharSequence> list = new LinkedList();
int index = 0;
int trailing = 0;
while (index < input.length() && list.size() < limit) {
int i = indexOf(input, pattern, index);
int patternLength = pattern.length();
while (index < input.length() && list.size() < limit - 1) {
int i;
if (patternLength == 0) {
if (list.size() == 0) {
i = 0;
} else {
i = index + 1;
}
} else {
i = indexOf(input, pattern, index);
}
if (i >= 0) {
if (i == index) {
if (patternLength != 0 && i == index) {
++ trailing;
} else {
trailing = 0;
}
list.add(input.subSequence(index, i));
index = i + pattern.length();
index = i + patternLength;
} else {
break;
}
}
if (strip && index == input.length()) {
if (strip && index > 0 && index == input.length()) {
++ trailing;
} else {
trailing = 0;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided

View File

@ -0,0 +1,13 @@
/* Copyright (c) 2010, 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 sun.reflect;
public class ConstantPool { }

View File

@ -1,4 +1,4 @@
Copyright (c) 2008-2009, Avian Contributors
Copyright (c) 2008-2010, 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

638
makefile
View File

@ -1,7 +1,7 @@
MAKEFLAGS = -s
name = avian
version = 0.3
version = 0.4
build-arch := $(shell uname -m | sed 's/^i.86$$/i386/' | sed 's/^arm.*$$/arm/')
ifeq (Power,$(filter Power,$(build-arch)))
@ -39,37 +39,76 @@ endif
ifeq ($(continuations),true)
options := $(options)-continuations
endif
ifdef gnu
options := $(options)-gnu
gnu-sources = $(src)/gnu.cpp
gnu-jar = $(gnu)/share/classpath/glibj.zip
gnu-libraries = \
$(gnu)/lib/classpath/libjavaio.a \
$(gnu)/lib/classpath/libjavalang.a \
$(gnu)/lib/classpath/libjavalangreflect.a \
$(gnu)/lib/classpath/libjavamath.a \
$(gnu)/lib/classpath/libjavanet.a \
$(gnu)/lib/classpath/libjavanio.a \
$(gnu)/lib/classpath/libjavautil.a
gnu-object-dep = $(build)/gnu-object.dep
gnu-cflags = -DBOOT_BUILTINS=\"javaio,javalang,javalangreflect,javamath,javanet,javanio,javautil\" -DAVIAN_GNU
gnu-lflags = -lgmp
gnu-objects = $(shell find $(build)/gnu-objects -name "*.o")
endif
root := $(shell (cd .. && pwd))
build = build
native-build = $(build)/$(platform)-$(arch)$(options)
build = build/$(platform)-$(arch)$(options)
classpath-build = $(build)/classpath
test-build = $(build)/test
src = src
classpath = classpath
classpath-src = classpath
test = test
ifdef gnu
avian-classpath-build = $(build)/avian-classpath
else
avian-classpath-build = $(classpath-build)
classpath = avian
test-executable = $(executable)
boot-classpath = $(classpath-build)
embed-prefix = /avian-embedded
native-path = echo
ifeq ($(build-platform),cygwin)
native-path = cygpath -m
endif
path-separator = :
ifneq (,$(filter mingw32 cygwin,$(build-platform)))
path-separator = ;
endif
library-path-variable = LD_LIBRARY_PATH
ifeq ($(build-platform),darwin)
library-path-variable = DYLD_LIBRARY_PATH
endif
ifneq ($(openjdk),)
openjdk-arch = $(arch)
ifeq ($(arch),x86_64)
openjdk-arch = amd64
endif
ifneq ($(openjdk-src),)
include openjdk-src.mk
options := $(options)-openjdk-src
classpath-objects = $(openjdk-objects) $(openjdk-local-objects)
classpath-cflags = -DAVIAN_OPENJDK_SRC -DBOOT_JAVAHOME
openjdk-jar-dep = $(build)/openjdk-jar.dep
classpath-jar-dep = $(openjdk-jar-dep)
javahome = $(embed-prefix)/javahomeJar
javahome-files = lib/zi lib/currency.data
ifeq ($(platform),windows)
javahome-files += lib/tzmappings
endif
javahome-object = $(build)/javahome-jar.o
boot-javahome-object = $(build)/boot-javahome.o
else
options := $(options)-openjdk
test-executable = $(executable-dynamic)
library-path = \
$(library-path-variable)=$(build):$(openjdk)/jre/lib/$(openjdk-arch)
javahome = "$$($(native-path) "$(openjdk)/jre")"
endif
classpath = openjdk
boot-classpath := "$(boot-classpath)$(path-separator)$$($(native-path) "$(openjdk)/jre/lib/rt.jar")"
build-javahome = $(openjdk)/jre
endif
ifeq ($(classpath),avian)
jni-sources := $(shell find $(classpath-src) -name '*.cpp')
jni-objects = $(call cpp-objects,$(jni-sources),$(classpath-src),$(build))
classpath-objects = $(jni-objects)
endif
input = List
@ -79,12 +118,12 @@ build-cc = gcc
mflag =
ifneq ($(platform),darwin)
ifeq ($(arch),i386)
mflag = -m32
endif
ifeq ($(arch),x86_64)
mflag = -m64
endif
ifeq ($(arch),i386)
mflag = -m32
endif
ifeq ($(arch),x86_64)
mflag = -m64
endif
endif
cxx = $(build-cxx) $(mflag)
@ -97,6 +136,7 @@ vg = nice valgrind --num-callers=32 --db-attach=yes --freelist-vol=100000000
vg += --leak-check=full --suppressions=valgrind.supp
db = gdb --args
javac = "$(JAVA_HOME)/bin/javac"
javah = "$(JAVA_HOME)/bin/javah"
jar = "$(JAVA_HOME)/bin/jar"
strip = strip
strip-all = --strip-all
@ -109,22 +149,36 @@ rdynamic = -rdynamic
warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
-Wno-non-virtual-dtor
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(native-build) \
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
-DUSE_ATOMIC_OPERATIONS $(gnu-cflags)
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\"
ifneq (,$(filter i386 x86_64,$(arch)))
ifeq ($(use-frame-pointer),true)
common-cflags += -fno-omit-frame-pointer -DAVIAN_USE_FRAME_POINTER
asmflags += -DAVIAN_USE_FRAME_POINTER
endif
endif
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
converter-cflags = -D__STDC_CONSTANT_MACROS
cflags = $(build-cflags)
common-lflags = -lm -lz $(gnu-lflags)
common-lflags = -lm -lz $(classpath-lflags)
build-lflags =
build-lflags = -lz -lpthread -ldl
lflags = $(common-lflags) -lpthread -ldl
version-script-flag = -Wl,--version-script=openjdk.ld
build-system = posix
system = posix
asm = x86
@ -135,7 +189,7 @@ so-suffix = .so
shared = -shared
native-path = echo
openjdk-extra-cflags = -fvisibility=hidden
ifeq ($(arch),i386)
pointer-size = 4
@ -145,34 +199,69 @@ ifeq ($(arch),powerpc)
pointer-size = 4
endif
ifeq ($(arch),arm)
asm = arm
pointer-size = 4
asm = arm
pointer-size = 4
cflags += -marm -Wno-psabi
ifneq ($(arch),$(build-arch))
cxx = arm-linux-gnueabi-g++
cc = arm-linux-gnueabi-gcc
ar = arm-linux-gnueabi-ar
ranlib = arm-linux-gnueabi-ranlib
strip = arm-linux-gnueabi-strip
endif
endif
ifeq ($(platform),darwin)
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src)
lflags = $(common-lflags) -ldl -framework CoreFoundation -framework CoreServices
ifneq ($(build-platform),darwin)
cxx = i686-apple-darwin8-g++ $(mflag)
cc = i686-apple-darwin8-gcc $(mflag)
ar = i686-apple-darwin8-ar
ranlib = i686-apple-darwin8-ranlib
strip = i686-apple-darwin8-strip
extra-cflags = -I$(JAVA_HOME)/include/linux
else
build-lflags += -framework CoreFoundation
endif
build-cflags = $(common-cflags) $(extra-cflags) -fPIC -fvisibility=hidden \
-I$(src)
version-script-flag =
lflags = $(common-lflags) -ldl -framework CoreFoundation \
-framework CoreServices
ifeq ($(bootimage),true)
bootimage-lflags = -Wl,-segprot,__RWX,rwx,rwx
endif
rdynamic =
strip-all = -S -x
so-suffix = .jnilib
so-suffix = .dylib
shared = -dynamiclib
ifeq ($(arch),powerpc)
cflags += -arch ppc
asmflags += -arch ppc
lflags += -arch ppc
ifneq (,$(filter i386 x86_64,$(build-arch)))
converter-cflags += -DOPPOSITE_ENDIAN
endif
openjdk-extra-cflags += -arch ppc -mmacosx-version-min=10.4
cflags += -arch ppc -mmacosx-version-min=10.4
asmflags += -arch ppc -mmacosx-version-min=10.4
lflags += -arch ppc -mmacosx-version-min=10.4
endif
ifeq ($(arch),i386)
cflags += -arch i386
asmflags += -arch i386
lflags += -arch i386
ifeq ($(build-arch),powerpc)
converter-cflags += -DOPPOSITE_ENDIAN
endif
openjdk-extra-cflags += -arch i386 -mmacosx-version-min=10.4
cflags += -arch i386 -mmacosx-version-min=10.4
asmflags += -arch i386 -mmacosx-version-min=10.4
lflags += -arch i386 -mmacosx-version-min=10.4
endif
ifeq ($(arch),x86_64)
ifeq ($(build-arch),powerpc)
converter-cflags += -DOPPOSITE_ENDIAN
endif
openjdk-extra-cflags += -arch x86_64
cflags += -arch x86_64
asmflags += -arch x86_64
lflags += -arch x86_64
@ -183,6 +272,8 @@ ifeq ($(platform),windows)
inc = "$(root)/win32/include"
lib = "$(root)/win32/lib"
embed-prefix = c:/avian-embedded
system = windows
so-prefix =
@ -193,21 +284,25 @@ ifeq ($(platform),windows)
cflags = -I$(inc) $(common-cflags) -DWINVER=0x0500
ifeq (,$(filter mingw32 cygwin,$(build-platform)))
cxx = i586-mingw32msvc-g++
cc = i586-mingw32msvc-gcc
dlltool = i586-mingw32msvc-dlltool
ar = i586-mingw32msvc-ar
ranlib = i586-mingw32msvc-ranlib
strip = i586-mingw32msvc-strip
openjdk-extra-cflags += -I$(src)/openjdk/caseSensitive
cxx = x86_64-w64-mingw32-g++ -m32
cc = x86_64-w64-mingw32-gcc -m32
dlltool = x86_64-w64-mingw32-dlltool -mi386 --as-flags=--32
ar = x86_64-w64-mingw32-ar
ranlib = x86_64-w64-mingw32-ranlib
strip = x86_64-w64-mingw32-strip --strip-all
else
build-system = windows
common-cflags += "-I$(JAVA_HOME)/include/win32"
build-cflags = $(common-cflags) -I$(src) -mthreads
build-cflags = $(common-cflags) -I$(src) -I$(inc) -mthreads
openjdk-extra-cflags =
build-lflags = -L$(lib) $(common-lflags)
ifeq ($(build-platform),cygwin)
build-lflags += -mno-cygwin
build-cflags += -mno-cygwin
openjdk-extra-cflags += -mno-cygwin
lflags += -mno-cygwin
cflags += -mno-cygwin
native-path = cygpath -m
endif
endif
@ -224,32 +319,34 @@ ifeq ($(platform),windows)
endif
ifeq ($(mode),debug)
cflags += -O0 -g3
optimization-cflags = -O0 -g3
strip = :
endif
ifeq ($(mode),debug-fast)
cflags += -O0 -g3 -DNDEBUG
optimization-cflags = -O0 -g3 -DNDEBUG
strip = :
endif
ifeq ($(mode),stress)
cflags += -O0 -g3 -DVM_STRESS
optimization-cflags = -O0 -g3 -DVM_STRESS
strip = :
endif
ifeq ($(mode),stress-major)
cflags += -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
optimization-cflags = -O0 -g3 -DVM_STRESS -DVM_STRESS_MAJOR
strip = :
endif
ifeq ($(mode),fast)
cflags += -O3 -g3 -DNDEBUG
optimization-cflags = -O3 -g3 -DNDEBUG
endif
ifeq ($(mode),small)
cflags += -Os -g3 -DNDEBUG
optimization-cflags = -Os -g3 -DNDEBUG
endif
cflags += $(optimization-cflags)
ifneq ($(platform),darwin)
ifeq ($(arch),i386)
# this is necessary to support __sync_bool_compare_and_swap:
cflags += -march=i486
cflags += -march=i586
endif
endif
@ -266,10 +363,10 @@ ifdef msvc
ld = "$(msvc)/BIN/link.exe"
mt = "mt.exe"
cflags = -nologo -DAVIAN_VERSION=\"$(version)\" -D_JNI_IMPLEMENTATION_ \
-DUSE_ATOMIC_OPERATIONS \
-Fd$(native-build)/$(name).pdb -I"$(zlib)/include" -I$(src) \
-I"$(native-build)" -I"$(windows-java-home)/include" \
-I"$(windows-java-home)/include/win32"
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
-Fd$(build)/$(name).pdb -I"$(zlib)/include" -I$(src) -I"$(build)" \
-I"$(windows-java-home)/include" -I"$(windows-java-home)/include/win32"
shared = -dll
lflags = -nologo -LIBPATH:"$(zlib)/lib" -DEFAULTLIB:ws2_32 \
-DEFAULTLIB:zlib -MANIFEST -debug
@ -297,36 +394,15 @@ cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x)))
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(3)/%-asm.o,$(x)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
jni-sources := $(shell find $(classpath) -name '*.cpp')
jni-objects = $(call cpp-objects,$(jni-sources),$(classpath),$(native-build))
generated-code = \
$(native-build)/type-enums.cpp \
$(native-build)/type-declarations.cpp \
$(native-build)/type-constructors.cpp \
$(native-build)/type-initializations.cpp \
$(native-build)/type-java-initializations.cpp
$(build)/type-enums.cpp \
$(build)/type-declarations.cpp \
$(build)/type-constructors.cpp \
$(build)/type-initializations.cpp \
$(build)/type-java-initializations.cpp \
$(build)/type-name-initializations.cpp
vm-depends = \
$(generated-code) \
$(src)/allocator.h \
$(src)/common.h \
$(src)/system.h \
$(src)/heap.h \
$(src)/finder.h \
$(src)/processor.h \
$(src)/process.h \
$(src)/stream.h \
$(src)/constants.h \
$(src)/jnienv.h \
$(src)/machine.h \
$(src)/util.h \
$(src)/zone.h \
$(src)/assembler.h \
$(src)/compiler.h \
$(src)/$(asm).h \
$(src)/heapwalk.h \
$(src)/bootimage.h
vm-depends := $(generated-code) $(wildcard $(src)/*.h)
vm-sources = \
$(src)/$(system).cpp \
@ -335,18 +411,14 @@ vm-sources = \
$(src)/util.cpp \
$(src)/heap.cpp \
$(src)/$(process).cpp \
$(src)/classpath-$(classpath).cpp \
$(src)/builtin.cpp \
$(src)/jnienv.cpp \
$(src)/process.cpp \
$(gnu-sources)
$(src)/process.cpp
vm-asm-sources = $(src)/$(asm).S
ifeq ($(process),compile)
vm-depends += \
$(src)/compiler.h \
$(src)/vector.h
vm-sources += \
$(src)/compiler.cpp \
$(src)/$(asm).cpp
@ -354,13 +426,13 @@ ifeq ($(process),compile)
vm-asm-sources += $(src)/compile-$(asm).S
endif
vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(native-build))
vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(native-build))
vm-cpp-objects = $(call cpp-objects,$(vm-sources),$(src),$(build))
vm-asm-objects = $(call asm-objects,$(vm-asm-sources),$(src),$(build))
vm-objects = $(vm-cpp-objects) $(vm-asm-objects)
heapwalk-sources = $(src)/heapwalk.cpp
heapwalk-objects = \
$(call cpp-objects,$(heapwalk-sources),$(src),$(native-build))
$(call cpp-objects,$(heapwalk-sources),$(src),$(build))
ifeq ($(heapdump),true)
vm-sources += $(src)/heapdump.cpp
@ -379,12 +451,11 @@ endif
bootimage-generator-sources = $(src)/bootimage.cpp
bootimage-generator-objects = \
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(native-build))
bootimage-generator = \
$(build)/$(bootimage-platform)-$(build-arch)$(options)/bootimage-generator
$(call cpp-objects,$(bootimage-generator-sources),$(src),$(build))
bootimage-generator = $(build)/bootimage-generator
bootimage-bin = $(native-build)/bootimage.bin
bootimage-object = $(native-build)/bootimage-bin.o
bootimage-bin = $(build)/bootimage.bin
bootimage-object = $(build)/bootimage-bin.o
ifeq ($(bootimage),true)
ifneq ($(build-arch),$(arch))
@ -398,78 +469,87 @@ $(error "bootimage cross-builds not yet supported")
endif
vm-classpath-object = $(bootimage-object)
cflags += -DBOOT_IMAGE=\"bootimageBin\"
cflags += -DBOOT_IMAGE=\"bootimageBin\" -DAVIAN_CLASSPATH=\"\"
else
vm-classpath-object = $(classpath-object)
cflags += -DBOOT_CLASSPATH=\"[classpathJar]\"
cflags += -DBOOT_CLASSPATH=\"[classpathJar]\" \
-DAVIAN_CLASSPATH=\"[classpathJar]\"
endif
driver-source = $(src)/main.cpp
driver-object = $(native-build)/main.o
driver-dynamic-object = $(native-build)/main-dynamic.o
driver-object = $(build)/main.o
driver-dynamic-objects = \
$(build)/main-dynamic.o \
$(build)/$(system).o \
$(build)/finder.o
boot-source = $(src)/boot.cpp
boot-object = $(native-build)/boot.o
boot-object = $(build)/boot.o
generator-headers = $(src)/constants.h
generator-sources = $(src)/type-generator.cpp
generator-depends := $(wildcard $(src)/*.h)
generator-sources = \
$(src)/type-generator.cpp \
$(src)/$(build-system).cpp \
$(src)/finder.cpp
generator-cpp-objects = \
$(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%-build.o,$(x)))
generator-objects = \
$(call cpp-objects,$(generator-sources),$(src),$(native-build))
generator = $(native-build)/generator
$(call generator-cpp-objects,$(generator-sources),$(src),$(build))
generator = $(build)/generator
converter-objects = \
$(native-build)/binaryToObject-main.o \
$(native-build)/binaryToObject-elf64.o \
$(native-build)/binaryToObject-elf32.o \
$(native-build)/binaryToObject-mach-o64.o \
$(native-build)/binaryToObject-mach-o32.o \
$(native-build)/binaryToObject-pe.o
converter = $(native-build)/binaryToObject
$(build)/binaryToObject-main.o \
$(build)/binaryToObject-elf64.o \
$(build)/binaryToObject-elf32.o \
$(build)/binaryToObject-mach-o64.o \
$(build)/binaryToObject-mach-o32.o \
$(build)/binaryToObject-pe.o
converter = $(build)/binaryToObject
static-library = $(native-build)/lib$(name).a
executable = $(native-build)/$(name)${exe-suffix}
dynamic-library = $(native-build)/$(so-prefix)$(name)$(so-suffix)
executable-dynamic = $(native-build)/$(name)-dynamic${exe-suffix}
static-library = $(build)/lib$(name).a
executable = $(build)/$(name)${exe-suffix}
dynamic-library = $(build)/$(so-prefix)jvm$(so-suffix)
executable-dynamic = $(build)/$(name)-dynamic${exe-suffix}
ifneq ($(classpath),avian)
# Assembler, ConstantPool, and Stream are not technically needed for a
# working build, but we include them since our Subroutine test uses
# them to synthesize a class:
classpath-sources := \
$(classpath-src)/avian/Addendum.java \
$(classpath-src)/avian/Assembler.java \
$(classpath-src)/avian/Callback.java \
$(classpath-src)/avian/CallbackReceiver.java \
$(classpath-src)/avian/ClassAddendum.java \
$(classpath-src)/avian/ConstantPool.java \
$(classpath-src)/avian/Continuations.java \
$(classpath-src)/avian/FieldAddendum.java \
$(classpath-src)/avian/IncompatibleContinuationException.java \
$(classpath-src)/avian/Machine.java \
$(classpath-src)/avian/MethodAddendum.java \
$(classpath-src)/avian/Stream.java \
$(classpath-src)/avian/SystemClassLoader.java \
$(classpath-src)/avian/VMClass.java \
$(classpath-src)/avian/VMField.java \
$(classpath-src)/avian/VMMethod.java \
$(classpath-src)/avian/resource/Handler.java
ifneq ($(openjdk),)
classpath-sources := $(classpath-sources) \
$(classpath-src)/avian/OpenJDK.java
endif
else
classpath-sources := $(shell find $(classpath-src) -name '*.java')
endif
classpath-sources := $(shell find $(classpath) -name '*.java')
classpath-classes = \
$(call java-classes,$(classpath-sources),$(classpath),$(classpath-build))
classpath-object = $(native-build)/classpath-jar.o
$(call java-classes,$(classpath-sources),$(classpath-src),$(classpath-build))
classpath-object = $(build)/classpath-jar.o
classpath-dep = $(classpath-build).dep
gnu-blacklist = \
java/lang/AbstractStringBuffer.class \
java/lang/reflect/Proxy.class
gnu-overrides = \
vm-classes = \
avian/*.class \
avian/resource/*.class \
java/lang/Class.class \
java/lang/Enum.class \
java/lang/InheritableThreadLocal.class \
java/lang/Object.class \
java/lang/StackTraceElement.class \
java/lang/String.class \
java/lang/String\$$*.class \
java/lang/StringBuffer.class \
java/lang/StringBuilder.class \
java/lang/StringBuilder\$$*.class \
java/lang/Thread.class \
java/lang/Thread\$$*.class \
java/lang/ThreadGroup.class \
java/lang/ThreadLocal.class \
java/lang/Throwable.class \
java/lang/ref/PhantomReference.class \
java/lang/ref/Reference.class \
java/lang/ref/ReferenceQueue.class \
java/lang/ref/SoftReference.class \
java/lang/ref/WeakReference.class \
java/lang/reflect/AccessibleObject.class \
java/lang/reflect/Constructor.class \
java/lang/reflect/Field.class \
java/lang/reflect/Method.class \
java/lang/reflect/Proxy.class \
java/lang/reflect/Proxy\$$*.class
avian/resource/*.class
test-sources = $(wildcard $(test)/*.java)
test-classes = $(call java-classes,$(test-sources),$(test),$(test-build))
@ -480,12 +560,19 @@ test-extra-classes = \
$(call java-classes,$(test-extra-sources),$(test),$(test-build))
test-extra-dep = $(test-build)-extra.dep
ifeq ($(continuations),true)
continuation-tests = \
extra.Continuations \
extra.Coroutines \
extra.DynamicWind
endif
class-name = $(patsubst $(1)/%.class,%,$(2))
class-names = $(foreach x,$(2),$(call class-name,$(1),$(x)))
flags = -cp $(test-build)
test-flags = -cp $(build)/test
args = $(flags) $(input)
test-args = $(test-flags) $(input)
.PHONY: build
build: $(static-library) $(executable) $(dynamic-library) \
@ -497,21 +584,22 @@ $(test-extra-dep): $(classpath-dep)
.PHONY: run
run: build
$(executable) $(args)
$(library-path) $(test-executable) $(test-args)
.PHONY: debug
debug: build
gdb --args $(executable) $(args)
$(library-path) gdb --args $(test-executable) $(test-args)
.PHONY: vg
vg: build
$(vg) $(executable) $(args)
$(library-path) $(vg) $(test-executable) $(test-args)
.PHONY: test
test: build
/bin/sh $(test)/test.sh 2>/dev/null \
$(executable) $(mode) "$(flags)" \
$(call class-names,$(test-build),$(test-classes))
$(library-path) /bin/sh $(test)/test.sh 2>/dev/null \
$(test-executable) $(mode) "$(test-flags)" \
$(call class-names,$(test-build),$(test-classes)) \
$(continuation-tests)
.PHONY: tarball
tarball:
@ -533,43 +621,23 @@ clean:
@echo "removing build"
rm -rf build
.PHONY: clean-native
clean-native:
@echo "removing $(native-build)"
rm -rf $(native-build)
$(build)/compile-x86-asm.o: $(src)/continuations-x86.S
$(native-build)/compile-x86-asm.o: $(src)/continuations-x86.S
gen-arg = $(shell echo $(1) | sed -e 's:$(native-build)/type-\(.*\)\.cpp:\1:')
gen-arg = $(shell echo $(1) | sed -e 's:$(build)/type-\(.*\)\.cpp:\1:')
$(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
@echo "generating $(@)"
@mkdir -p $(dir $(@))
$(generator) $(classpath-build) $(call gen-arg,$(@)) < $(<) > $(@)
$(generator) $(boot-classpath) $(<) $(@) $(call gen-arg,$(@))
$(native-build)/type-generator.o: \
$(generator-headers)
$(classpath-build)/%.class: $(classpath)/%.java
$(classpath-build)/%.class: $(classpath-src)/%.java
@echo $(<)
$(classpath-dep): $(classpath-sources) $(gnu-jar)
$(classpath-dep): $(classpath-sources)
@echo "compiling classpath classes"
@mkdir -p $(avian-classpath-build)
$(javac) -d $(avian-classpath-build) \
-bootclasspath $(avian-classpath-build) \
$(shell $(MAKE) -s --no-print-directory $(classpath-classes))
ifdef gnu
(wd=$$(pwd) && \
cd $(avian-classpath-build) && \
$(jar) c0f "$$($(native-path) "$${wd}/$(build)/overrides.jar")" \
$(gnu-overrides))
@mkdir -p $(classpath-build)
(wd=$$(pwd) && \
cd $(classpath-build) && \
$(jar) xf $(gnu-jar) && \
rm $(gnu-blacklist) && \
jar xf "$$($(native-path) "$${wd}/$(build)/overrides.jar")")
endif
$(javac) -d $(classpath-build) -bootclasspath $(boot-classpath) \
$(shell $(MAKE) -s --no-print-directory build=$(build) \
$(classpath-classes))
@touch $(@)
$(test-build)/%.class: $(test)/%.java
@ -578,20 +646,20 @@ $(test-build)/%.class: $(test)/%.java
$(test-dep): $(test-sources)
@echo "compiling test classes"
@mkdir -p $(test-build)
files="$(shell $(MAKE) -s --no-print-directory $(test-classes))"; \
files="$(shell $(MAKE) -s --no-print-directory build=$(build) $(test-classes))"; \
if test -n "$${files}"; then \
$(javac) -d $(test-build) -bootclasspath $(classpath-build) $${files}; \
$(javac) -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \
fi
$(javac) -source 1.2 -target 1.1 -XDjsrlimit=0 -d $(test-build) \
test/Subroutine.java
-bootclasspath $(boot-classpath) test/Subroutine.java
@touch $(@)
$(test-extra-dep): $(test-extra-sources)
@echo "compiling extra test classes"
@mkdir -p $(test-build)
files="$(shell $(MAKE) -s --no-print-directory $(test-extra-classes))"; \
files="$(shell $(MAKE) -s --no-print-directory build=$(build) $(test-extra-classes))"; \
if test -n "$${files}"; then \
$(javac) -d $(test-build) -bootclasspath $(classpath-build) $${files}; \
$(javac) -d $(test-build) -bootclasspath $(boot-classpath) $${files}; \
fi
@touch $(@)
@ -607,75 +675,91 @@ define compile-asm-object
$(as) -I$(src) $(asmflags) -c $(<) -o $(@)
endef
$(vm-cpp-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
$(vm-cpp-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
$(compile-object)
$(vm-asm-objects): $(native-build)/%-asm.o: $(src)/%.S
$(vm-asm-objects): $(build)/%-asm.o: $(src)/%.S
$(compile-asm-object)
$(bootimage-generator-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
$(bootimage-generator-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
$(compile-object)
$(heapwalk-objects): $(native-build)/%.o: $(src)/%.cpp $(vm-depends)
$(heapwalk-objects): $(build)/%.o: $(src)/%.cpp $(vm-depends)
$(compile-object)
$(driver-object): $(driver-source)
$(compile-object)
$(driver-dynamic-object): $(driver-source)
$(build)/main-dynamic.o: $(driver-source)
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(cflags) -DBOOT_LIBRARY=\"$(so-prefix)$(name)$(so-suffix)\" \
$(cxx) $(cflags) -DBOOT_LIBRARY=\"$(so-prefix)jvm$(so-suffix)\" \
-c $(<) $(call output,$(@))
$(boot-object): $(boot-source)
$(compile-object)
$(build)/classpath.jar: $(classpath-dep)
(wd=$$(pwd) && \
cd $(classpath-build) && \
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
$(boot-javahome-object): $(src)/boot-javahome.cpp
$(compile-object)
$(native-build)/binaryToObject-main.o: $(src)/binaryToObject/main.cpp
$(build)/binaryToObject-main.o: $(src)/binaryToObject/main.cpp
$(build-cxx) -c $(^) -o $(@)
$(native-build)/binaryToObject-elf64.o: $(src)/binaryToObject/elf.cpp
$(build-cxx) -DBITS_PER_WORD=64 -c $(^) -o $(@)
$(build)/binaryToObject-elf64.o: $(src)/binaryToObject/elf.cpp
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=64 -c $(^) -o $(@)
$(native-build)/binaryToObject-elf32.o: $(src)/binaryToObject/elf.cpp
$(build-cxx) -DBITS_PER_WORD=32 -c $(^) -o $(@)
$(build)/binaryToObject-elf32.o: $(src)/binaryToObject/elf.cpp
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=32 -c $(^) -o $(@)
$(native-build)/binaryToObject-mach-o64.o: $(src)/binaryToObject/mach-o.cpp
$(build-cxx) -DBITS_PER_WORD=64 -c $(^) -o $(@)
$(build)/binaryToObject-mach-o64.o: $(src)/binaryToObject/mach-o.cpp
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=64 -c $(^) -o $(@)
$(native-build)/binaryToObject-mach-o32.o: $(src)/binaryToObject/mach-o.cpp
$(build-cxx) -DBITS_PER_WORD=32 -c $(^) -o $(@)
$(build)/binaryToObject-mach-o32.o: $(src)/binaryToObject/mach-o.cpp
$(build-cxx) $(converter-cflags) -DBITS_PER_WORD=32 -c $(^) -o $(@)
$(native-build)/binaryToObject-pe.o: $(src)/binaryToObject/pe.cpp
$(build-cxx) -c $(^) -o $(@)
$(build)/binaryToObject-pe.o: $(src)/binaryToObject/pe.cpp
$(build-cxx) $(converter-cflags) -c $(^) -o $(@)
$(converter): $(converter-objects)
$(build-cxx) $(^) -o $(@)
$(build)/classpath.jar: $(classpath-dep) $(classpath-jar-dep)
@echo "creating $(@)"
(wd=$$(pwd) && \
cd $(classpath-build) && \
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
$(classpath-object): $(build)/classpath.jar $(converter)
@echo "creating $(@)"
$(converter) $(<) $(@) _binary_classpath_jar_start \
_binary_classpath_jar_end $(platform) $(arch)
$(generator-objects): $(native-build)/%.o: $(src)/%.cpp
$(build)/javahome.jar:
@echo "creating $(@)"
(wd=$$(pwd) && \
cd "$(build-javahome)" && \
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" $(javahome-files))
$(javahome-object): $(build)/javahome.jar $(converter)
@echo "creating $(@)"
$(converter) $(<) $(@) _binary_javahome_jar_start \
_binary_javahome_jar_end $(platform) $(arch)
$(generator-objects): $(generator-depends)
$(generator-objects): $(build)/%-build.o: $(src)/%.cpp
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(build-cxx) -DPOINTER_SIZE=$(pointer-size) -O0 -g3 $(build-cflags) \
-c $(<) -o $(@)
$(jni-objects): $(native-build)/%.o: $(classpath)/%.cpp
$(jni-objects): $(build)/%.o: $(classpath-src)/%.cpp
$(compile-object)
$(static-library): $(gnu-object-dep)
$(static-library): $(vm-objects) $(jni-objects) $(vm-heapwalk-objects)
$(static-library): $(vm-objects) $(classpath-objects) $(vm-heapwalk-objects) \
$(javahome-object) $(boot-javahome-object)
@echo "creating $(@)"
rm -rf $(@)
$(ar) cru $(@) $(^) $(call gnu-objects)
$(ar) cru $(@) $(^)
$(ranlib) $(@)
$(bootimage-bin): $(bootimage-generator)
@ -687,30 +771,24 @@ $(bootimage-object): $(bootimage-bin) $(converter)
_binary_bootimage_bin_end $(platform) $(arch) $(pointer-size) \
writable executable
$(gnu-object-dep): $(gnu-libraries)
@mkdir -p $(build)/gnu-objects
(cd $(build)/gnu-objects && \
for x in $(gnu-libraries); do ar x $${x}; done)
@touch $(@)
executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object) \
$(javahome-object) $(boot-javahome-object)
$(executable): $(gnu-object-dep)
$(executable): \
$(vm-objects) $(jni-objects) $(driver-object) $(vm-heapwalk-objects) \
$(boot-object) $(vm-classpath-object)
$(executable): $(executable-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
$(ld) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb -IMPLIB:$(@).lib \
-MANIFESTFILE:$(@).manifest
$(ld) $(lflags) $(executable-objects) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(@).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
else
$(dlltool) -z $(@).def $(^) $(call gnu-objects)
$(dlltool) -z $(@).def $(executable-objects)
$(dlltool) -d $(@).def -e $(@).exp
$(ld) $(@).exp $(^) $(call gnu-objects) $(lflags) -o $(@)
$(ld) $(@).exp $(executable-objects) $(lflags) -o $(@)
endif
else
$(ld) $(^) $(call gnu-objects) $(rdynamic) $(lflags) $(bootimage-lflags) \
-o $(@)
$(ld) $(executable-objects) $(rdynamic) $(lflags) $(bootimage-lflags) -o $(@)
endif
$(strip) $(strip-all) $(@)
@ -718,13 +796,15 @@ $(bootimage-generator):
$(MAKE) mode=$(mode) \
arch=$(build-arch) \
platform=$(bootimage-platform) \
openjdk=$(openjdk) \
openjdk-src=$(openjdk-src) \
bootimage-generator= \
build-bootimage-generator=$(bootimage-generator) \
$(bootimage-generator)
$(build-bootimage-generator): \
$(vm-objects) $(classpath-object) $(jni-objects) $(heapwalk-objects) \
$(bootimage-generator-objects)
$(vm-objects) $(classpath-object) $(classpath-objects) \
$(heapwalk-objects) $(bootimage-generator-objects)
@echo "linking $(@)"
ifeq ($(platform),windows)
ifdef msvc
@ -740,32 +820,74 @@ else
$(ld) $(^) $(rdynamic) $(lflags) -o $(@)
endif
$(dynamic-library): $(gnu-object-dep)
$(dynamic-library): \
$(vm-objects) $(dynamic-object) $(jni-objects) $(vm-heapwalk-objects) \
$(boot-object) $(vm-classpath-object) $(gnu-libraries)
$(dynamic-library): $(vm-objects) $(dynamic-object) $(classpath-objects) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-object) \
$(classpath-libraries) $(javahome-object) $(boot-javahome-object)
@echo "linking $(@)"
ifdef msvc
$(ld) $(shared) $(lflags) $(^) -out:$(@) -PDB:$(@).pdb \
-IMPLIB:$(native-build)/$(name).lib -MANIFESTFILE:$(@).manifest
-IMPLIB:$(build)/$(name).lib -MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);2"
else
$(ld) $(^) $(call gnu-objects) $(shared) $(lflags) $(bootimage-lflags) \
$(ld) $(^) $(version-script-flag) $(shared) $(lflags) $(bootimage-lflags) \
-o $(@)
endif
$(strip) $(strip-all) $(@)
$(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
$(executable-dynamic): $(driver-dynamic-objects) $(dynamic-library)
@echo "linking $(@)"
ifdef msvc
$(ld) $(lflags) -LIBPATH:$(native-build) -DEFAULTLIB:$(name) \
-PDB:$(@).pdb -IMPLIB:$(@).lib $(<) -out:$(@) -MANIFESTFILE:$(@).manifest
$(ld) $(lflags) -LIBPATH:$(build) -DEFAULTLIB:$(name) \
-PDB:$(@).pdb -IMPLIB:$(@).lib $(driver-dynamic-objects) -out:$(@) \
-MANIFESTFILE:$(@).manifest
$(mt) -manifest $(@).manifest -outputresource:"$(@);1"
else
$(ld) $(^) $(lflags) -o $(@)
$(ld) $(driver-dynamic-objects) -L$(build) -ljvm $(lflags) -o $(@)
endif
$(strip) $(strip-all) $(@)
$(generator): $(generator-objects)
@echo "linking $(@)"
$(build-ld) $(^) $(build-lflags) -o $(@)
$(openjdk-objects): $(build)/openjdk/%.o: $(openjdk-src)/%.c \
$(openjdk-headers-dep)
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
sed 's/^static jclass ia_class;//' < $(<) > $(build)/openjdk/$(notdir $(<))
$(cc) -fPIC $(openjdk-extra-cflags) $(openjdk-cflags) \
$(optimization-cflags) -w -c $(build)/openjdk/$(notdir $(<)) \
$(call output,$(@))
$(openjdk-local-objects): $(build)/openjdk/%.o: $(src)/openjdk/%.c \
$(openjdk-headers-dep)
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cc) -fPIC $(openjdk-extra-cflags) $(openjdk-cflags) \
$(optimization-cflags) -w -c $(<) $(call output,$(@))
$(openjdk-headers-dep):
@echo "generating openjdk headers"
@mkdir -p $(dir $(@))
$(javah) -d $(build)/openjdk -bootclasspath $(boot-classpath) \
$(openjdk-headers-classes)
ifeq ($(platform),windows)
sed 's/^#ifdef _WIN64/#if 1/' \
< "$(openjdk-src)/windows/native/java/net/net_util_md.h" \
> $(build)/openjdk/net_util_md.h
cp "$(openjdk-src)/windows/native/java/net/NetworkInterface.h" \
$(build)/openjdk/NetworkInterface.h
echo 'static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);' >> $(build)/openjdk/NetworkInterface.h
endif
@touch $(@)
$(openjdk-jar-dep):
@echo "extracting openjdk classes"
@mkdir -p $(dir $(@))
@mkdir -p $(classpath-build)
(cd $(classpath-build) && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/rt.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jsse.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/jce.jar")" && \
$(jar) xf "$$($(native-path) "$(openjdk)/jre/lib/resources.jar")")
@touch $(@)

309
openjdk-src.mk Normal file
View File

@ -0,0 +1,309 @@
openjdk-sources = \
$(openjdk-src)/share/native/common/check_code.c \
$(openjdk-src)/share/native/common/check_format.c \
$(openjdk-src)/share/native/common/check_version.c \
$(openjdk-src)/share/native/common/jdk_util.c \
$(openjdk-src)/share/native/common/jio.c \
$(openjdk-src)/share/native/common/jni_util.c \
$(openjdk-src)/share/native/common/verify_stub.c \
$(openjdk-src)/share/native/java/io/FileInputStream.c \
$(openjdk-src)/share/native/java/io/io_util.c \
$(openjdk-src)/share/native/java/io/ObjectInputStream.c \
$(openjdk-src)/share/native/java/io/ObjectOutputStream.c \
$(openjdk-src)/share/native/java/io/ObjectStreamClass.c \
$(openjdk-src)/share/native/java/io/RandomAccessFile.c \
$(openjdk-src)/share/native/java/lang/Class.c \
$(openjdk-src)/share/native/java/lang/ClassLoader.c \
$(openjdk-src)/share/native/java/lang/Compiler.c \
$(openjdk-src)/share/native/java/lang/Double.c \
$(openjdk-src)/share/native/java/lang/Float.c \
$(openjdk-src)/share/native/java/lang/Object.c \
$(openjdk-src)/share/native/java/lang/Package.c \
$(openjdk-src)/share/native/java/lang/ref/Finalizer.c \
$(openjdk-src)/share/native/java/lang/reflect/Array.c \
$(openjdk-src)/share/native/java/lang/reflect/Proxy.c \
$(openjdk-src)/share/native/java/lang/ResourceBundle.c \
$(openjdk-src)/share/native/java/lang/Runtime.c \
$(openjdk-src)/share/native/java/lang/SecurityManager.c \
$(openjdk-src)/share/native/java/lang/Shutdown.c \
$(openjdk-src)/share/native/java/lang/StrictMath.c \
$(openjdk-src)/share/native/java/lang/String.c \
$(openjdk-src)/share/native/java/lang/System.c \
$(openjdk-src)/share/native/java/lang/Thread.c \
$(openjdk-src)/share/native/java/lang/Throwable.c \
$(wildcard $(openjdk-src)/share/native/java/lang/fdlibm/src/*.c) \
$(openjdk-src)/share/native/java/net/DatagramPacket.c \
$(openjdk-src)/share/native/java/net/InetAddress.c \
$(openjdk-src)/share/native/java/net/Inet4Address.c \
$(openjdk-src)/share/native/java/net/Inet6Address.c \
$(openjdk-src)/share/native/java/nio/Bits.c \
$(openjdk-src)/share/native/java/security/AccessController.c \
$(openjdk-src)/share/native/java/sql/DriverManager.c \
$(openjdk-src)/share/native/java/util/concurrent/atomic/AtomicLong.c \
$(openjdk-src)/share/native/java/util/TimeZone.c \
$(openjdk-src)/share/native/java/util/zip/Adler32.c \
$(openjdk-src)/share/native/java/util/zip/CRC32.c \
$(openjdk-src)/share/native/java/util/zip/Deflater.c \
$(openjdk-src)/share/native/java/util/zip/Inflater.c \
$(openjdk-src)/share/native/java/util/zip/ZipEntry.c \
$(openjdk-src)/share/native/java/util/zip/ZipFile.c \
$(openjdk-src)/share/native/java/util/zip/zip_util.c \
$(openjdk-src)/share/native/sun/misc/GC.c \
$(openjdk-src)/share/native/sun/misc/MessageUtils.c \
$(openjdk-src)/share/native/sun/misc/NativeSignalHandler.c \
$(openjdk-src)/share/native/sun/misc/Signal.c \
$(openjdk-src)/share/native/sun/misc/Version.c \
$(openjdk-src)/share/native/sun/misc/VM.c \
$(openjdk-src)/share/native/sun/misc/VMSupport.c \
$(openjdk-src)/share/native/sun/reflect/ConstantPool.c \
$(openjdk-src)/share/native/sun/reflect/NativeAccessors.c \
$(openjdk-src)/share/native/sun/reflect/Reflection.c
openjdk-headers-classes = \
java.io.Console \
java.io.FileDescriptor \
java.io.FileInputStream \
java.io.FileOutputStream \
java.io.FileSystem \
java.io.ObjectInputStream \
java.io.ObjectOutputStream \
java.io.ObjectStreamClass \
java.io.RandomAccessFile \
java.lang.Class \
java.lang.ClassLoader \
java.lang.Compiler \
java.lang.Double \
java.lang.Float \
java.lang.Integer \
java.lang.Object \
java.lang.Package \
java.lang.Runtime \
java.lang.SecurityManager \
java.lang.Shutdown \
java.lang.StrictMath \
java.lang.String \
java.lang.System \
java.lang.Thread \
java.lang.Throwable \
java.lang.ref.Finalizer \
java.lang.reflect.Array \
java.lang.reflect.Proxy \
java.net.InetAddress \
java.net.Inet4Address \
java.net.Inet6Address \
java.net.DatagramPacket \
java.net.SocketOptions \
java.net.InetAddressImplFactory \
java.net.Inet4AddressImpl \
java.net.Inet6AddressImpl \
java.net.NetworkInterface \
java.net.PlainSocketImpl \
java.net.SocketInputStream \
java.net.SocketOutputStream \
java.nio.MappedByteBuffer \
java.security.AccessController \
java.util.ResourceBundle \
java.util.TimeZone \
java.util.concurrent.atomic.AtomicLong \
java.util.jar.JarFile \
java.util.zip.Adler32 \
java.util.zip.CRC32 \
java.util.zip.Deflater \
java.util.zip.Inflater \
java.util.zip.ZipEntry \
java.util.zip.ZipFile \
sun.misc.GC \
sun.misc.MessageUtils \
sun.misc.NativeSignalHandler \
sun.misc.Signal \
sun.misc.VM \
sun.misc.VMSupport \
sun.misc.Version \
sun.net.spi.DefaultProxySelector \
sun.nio.ch.FileKey \
sun.nio.ch.FileChannelImpl \
sun.nio.ch.FileDispatcher \
sun.nio.ch.DatagramChannelImpl \
sun.nio.ch.DatagramDispatcher \
sun.nio.ch.IOStatus \
sun.nio.ch.IOUtil \
sun.nio.ch.Net \
sun.nio.ch.ServerSocketChannelImpl \
sun.nio.ch.SocketChannelImpl \
sun.nio.ch.SocketDispatcher \
sun.nio.ch.PollArrayWrapper \
sun.nio.ch.NativeThread \
sun.reflect.ConstantPool \
sun.reflect.NativeConstructorAccessorImpl \
sun.reflect.NativeMethodAccessorImpl \
sun.reflect.Reflection \
sun.security.provider.NativeSeedGenerator
# todo: set properties according to architecture targeted and OpenJDK
# version used:
openjdk-cflags = \
"-I$(src)/openjdk" \
"-I$(build)/openjdk" \
"-I$(openjdk-src)/share/javavm/export" \
"-I$(openjdk-src)/share/native/common" \
"-I$(openjdk-src)/share/native/java/io" \
"-I$(openjdk-src)/share/native/java/lang" \
"-I$(openjdk-src)/share/native/java/lang/fdlibm/include" \
"-I$(openjdk-src)/share/native/java/net" \
"-I$(openjdk-src)/share/native/java/util/zip" \
"-I$(openjdk-src)/share/native/sun/nio/ch" \
"-I$(openjdk-src)/share/javavm/include" \
-D_LITTLE_ENDIAN \
-DARCHPROPNAME=\"x86\" \
-DRELEASE=\"1.6.0\" \
-DJDK_MAJOR_VERSION=\"1\" \
-DJDK_MINOR_VERSION=\"6\" \
-DJDK_MICRO_VERSION=\"0\" \
-DJDK_BUILD_NUMBER=\"0\" \
-D_GNU_SOURCE
ifeq ($(platform),darwin)
openjdk-cflags += \
-D_LFS_LARGEFILE=1 \
-D_ALLBSD_SOURCE
endif
ifeq ($(platform),windows)
openjdk-sources += \
$(openjdk-src)/windows/native/java/io/canonicalize_md.c \
$(openjdk-src)/windows/native/java/io/Console_md.c \
$(openjdk-src)/windows/native/java/io/FileDescriptor_md.c \
$(openjdk-src)/windows/native/java/io/FileInputStream_md.c \
$(openjdk-src)/windows/native/java/io/FileOutputStream_md.c \
$(openjdk-src)/windows/native/java/io/FileSystem_md.c \
$(openjdk-src)/windows/native/java/io/io_util_md.c \
$(openjdk-src)/windows/native/java/io/RandomAccessFile_md.c \
$(openjdk-src)/windows/native/java/io/Win32FileSystem_md.c \
$(openjdk-src)/windows/native/java/io/WinNTFileSystem_md.c \
$(openjdk-src)/windows/native/java/lang/java_props_md.c \
$(openjdk-src)/windows/native/java/lang/ProcessEnvironment_md.c \
$(openjdk-src)/windows/native/java/lang/ProcessImpl_md.c \
$(openjdk-src)/windows/native/java/net/net_util_md.c \
$(openjdk-src)/windows/native/java/net/InetAddressImplFactory.c \
$(openjdk-src)/windows/native/java/net/Inet4AddressImpl.c \
$(openjdk-src)/windows/native/java/net/Inet6AddressImpl.c \
$(openjdk-src)/windows/native/java/net/NetworkInterface.c \
$(openjdk-src)/windows/native/java/net/NetworkInterface_winXP.c \
$(openjdk-src)/windows/native/java/net/NetworkInterface_win9x.c \
$(openjdk-src)/windows/native/java/net/SocketInputStream.c \
$(openjdk-src)/windows/native/java/net/SocketOutputStream.c \
$(openjdk-src)/windows/native/java/util/WindowsPreferences.c \
$(openjdk-src)/windows/native/java/util/logging.c \
$(openjdk-src)/windows/native/java/util/TimeZone_md.c \
$(openjdk-src)/windows/native/sun/io/Win32ErrorMode.c \
$(openjdk-src)/windows/native/sun/nio/ch/DatagramChannelImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/DatagramDispatcher.c \
$(openjdk-src)/windows/native/sun/nio/ch/FileChannelImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/FileDispatcher.c \
$(openjdk-src)/windows/native/sun/nio/ch/FileKey.c \
$(openjdk-src)/windows/native/sun/nio/ch/IOUtil.c \
$(openjdk-src)/windows/native/sun/nio/ch/Net.c \
$(openjdk-src)/windows/native/sun/nio/ch/ServerSocketChannelImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/SocketChannelImpl.c \
$(openjdk-src)/windows/native/sun/nio/ch/SocketDispatcher.c \
$(openjdk-src)/windows/native/sun/nio/ch/WindowsSelectorImpl.c \
$(openjdk-src)/windows/native/sun/security/provider/WinCAPISeedGenerator.c
openjdk-headers-classes += \
java.lang.ProcessImpl \
sun.io.Win32ErrorMode \
sun.nio.ch.WindowsSelectorImpl \
openjdk-cflags += \
"-I$(openjdk-src)/windows/javavm/export" \
"-I$(openjdk-src)/windows/native/common" \
"-I$(openjdk-src)/windows/native/java/io" \
"-I$(openjdk-src)/windows/native/java/net" \
"-I$(openjdk-src)/windows/native/java/util" \
"-I$(openjdk-src)/windows/native/sun/nio/ch" \
"-I$(openjdk-src)/windows/javavm/include" \
"-I$(root)/win32/include" \
-D_JNI_IMPLEMENTATION_ \
-D_JAVASOFT_WIN32_TYPEDEF_MD_H_ \
-D_WINSOCK2API_ \
-Ds6_words=_s6_words \
-Ds6_bytes=_s6_bytes
else
openjdk-sources += \
$(openjdk-src)/solaris/native/common/jdk_util_md.c \
$(openjdk-src)/solaris/native/java/io/canonicalize_md.c \
$(openjdk-src)/solaris/native/java/io/Console_md.c \
$(openjdk-src)/solaris/native/java/io/FileDescriptor_md.c \
$(openjdk-src)/solaris/native/java/io/FileInputStream_md.c \
$(openjdk-src)/solaris/native/java/io/FileOutputStream_md.c \
$(openjdk-src)/solaris/native/java/io/FileSystem_md.c \
$(openjdk-src)/solaris/native/java/io/io_util_md.c \
$(openjdk-src)/solaris/native/java/io/RandomAccessFile_md.c \
$(openjdk-src)/solaris/native/java/io/UnixFileSystem_md.c \
$(openjdk-src)/solaris/native/java/lang/java_props_md.c \
$(openjdk-src)/solaris/native/java/lang/ProcessEnvironment_md.c \
$(openjdk-src)/solaris/native/java/lang/UNIXProcess_md.c \
$(openjdk-src)/solaris/native/java/net/net_util_md.c \
$(openjdk-src)/solaris/native/java/net/InetAddressImplFactory.c \
$(openjdk-src)/solaris/native/java/net/Inet4AddressImpl.c \
$(openjdk-src)/solaris/native/java/net/Inet6AddressImpl.c \
$(openjdk-src)/solaris/native/java/net/NetworkInterface.c \
$(openjdk-src)/solaris/native/java/net/PlainSocketImpl.c \
$(openjdk-src)/solaris/native/java/net/PlainDatagramSocketImpl.c \
$(openjdk-src)/solaris/native/java/net/SocketInputStream.c \
$(openjdk-src)/solaris/native/java/net/SocketOutputStream.c \
$(openjdk-src)/solaris/native/java/nio/MappedByteBuffer.c \
$(openjdk-src)/solaris/native/java/util/FileSystemPreferences.c \
$(openjdk-src)/solaris/native/java/util/logging.c \
$(openjdk-src)/solaris/native/java/util/TimeZone_md.c \
$(openjdk-src)/solaris/native/sun/net/dns/ResolverConfigurationImpl.c \
$(openjdk-src)/solaris/native/sun/net/spi/DefaultProxySelector.c \
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/DatagramDispatcher.c \
$(openjdk-src)/solaris/native/sun/nio/ch/FileChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/FileDispatcher.c \
$(openjdk-src)/solaris/native/sun/nio/ch/FileKey.c \
$(openjdk-src)/solaris/native/sun/nio/ch/IOUtil.c \
$(openjdk-src)/solaris/native/sun/nio/ch/Net.c \
$(openjdk-src)/solaris/native/sun/nio/ch/ServerSocketChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/SocketChannelImpl.c \
$(openjdk-src)/solaris/native/sun/nio/ch/SocketDispatcher.c \
$(openjdk-src)/solaris/native/sun/nio/ch/EPollArrayWrapper.c \
$(openjdk-src)/solaris/native/sun/nio/ch/PollArrayWrapper.c \
$(openjdk-src)/solaris/native/sun/nio/ch/InheritedChannel.c \
$(openjdk-src)/solaris/native/sun/nio/ch/NativeThread.c \
ifeq ($(platform),linux)
openjdk-sources += \
$(openjdk-src)/solaris/native/java/net/linux_close.c
endif
openjdk-headers-classes += \
java.net.PlainDatagramSocketImpl \
java.io.UnixFileSystem \
sun.nio.ch.InheritedChannel \
sun.nio.ch.EPollArrayWrapper \
openjdk-cflags += "-I$(openjdk-src)/solaris/javavm/export" \
"-I$(openjdk-src)/solaris/native/common" \
"-I$(openjdk-src)/solaris/native/java/io" \
"-I$(openjdk-src)/solaris/native/java/lang" \
"-I$(openjdk-src)/solaris/native/java/net" \
"-I$(openjdk-src)/solaris/native/java/util" \
"-I$(openjdk-src)/solaris/native/sun/nio/ch" \
"-I$(openjdk-src)/solaris/javavm/include" \
"-I$(openjdk-src)/solaris/hpi/include"
endif
openjdk-local-sources = \
$(src)/openjdk/my_net_util.c
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
openjdk-objects = \
$(call c-objects,$(openjdk-sources),$(openjdk-src),$(build)/openjdk)
openjdk-local-objects = \
$(call c-objects,$(openjdk-local-sources),$(src)/openjdk,$(build)/openjdk)
openjdk-headers-dep = $(build)/openjdk/headers.dep

288
openjdk.ld Normal file
View File

@ -0,0 +1,288 @@
#
# @(#)mapfile-vers-product 1.19 08/02/12 10:56:37
#
#
# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
# Define public interface.
SUNWprivate_1.1 {
global:
# JNI
JNI_CreateJavaVM;
JNI_GetCreatedJavaVMs;
JNI_GetDefaultJavaVMInitArgs;
# JVM
JVM_Accept;
JVM_ActiveProcessorCount;
JVM_AllocateNewArray;
JVM_AllocateNewObject;
JVM_ArrayCopy;
JVM_AssertionStatusDirectives;
JVM_Available;
JVM_Bind;
JVM_ClassDepth;
JVM_ClassLoaderDepth;
JVM_Clone;
JVM_Close;
JVM_CX8Field;
JVM_CompileClass;
JVM_CompileClasses;
JVM_CompilerCommand;
JVM_Connect;
JVM_ConstantPoolGetClassAt;
JVM_ConstantPoolGetClassAtIfLoaded;
JVM_ConstantPoolGetDoubleAt;
JVM_ConstantPoolGetFieldAt;
JVM_ConstantPoolGetFieldAtIfLoaded;
JVM_ConstantPoolGetFloatAt;
JVM_ConstantPoolGetIntAt;
JVM_ConstantPoolGetLongAt;
JVM_ConstantPoolGetMethodAt;
JVM_ConstantPoolGetMethodAtIfLoaded;
JVM_ConstantPoolGetMemberRefInfoAt;
JVM_ConstantPoolGetSize;
JVM_ConstantPoolGetStringAt;
JVM_ConstantPoolGetUTF8At;
JVM_CountStackFrames;
JVM_CurrentClassLoader;
JVM_CurrentLoadedClass;
JVM_CurrentThread;
JVM_CurrentTimeMillis;
JVM_DefineClass;
JVM_DefineClassWithSource;
JVM_DesiredAssertionStatus;
JVM_DisableCompiler;
JVM_DoPrivileged;
JVM_DTraceGetVersion;
JVM_DTraceActivate;
JVM_DTraceIsProbeEnabled;
JVM_DTraceIsSupported;
JVM_DTraceDispose;
JVM_DumpAllStacks;
JVM_DumpThreads;
JVM_EnableCompiler;
JVM_Exit;
JVM_FillInStackTrace;
JVM_FindClassFromClass;
JVM_FindClassFromClassLoader;
JVM_FindClassFromBootLoader;
JVM_FindLibraryEntry;
JVM_FindLoadedClass;
JVM_FindPrimitiveClass;
JVM_FindSignal;
JVM_FreeMemory;
JVM_GC;
JVM_GetAllThreads;
JVM_GetArrayElement;
JVM_GetArrayLength;
JVM_GetCPClassNameUTF;
JVM_GetCPFieldClassNameUTF;
JVM_GetCPFieldModifiers;
JVM_GetCPFieldNameUTF;
JVM_GetCPFieldSignatureUTF;
JVM_GetCPMethodClassNameUTF;
JVM_GetCPMethodModifiers;
JVM_GetCPMethodNameUTF;
JVM_GetCPMethodSignatureUTF;
JVM_GetCallerClass;
JVM_GetClassAccessFlags;
JVM_GetClassAnnotations;
JVM_GetClassCPEntriesCount;
JVM_GetClassCPTypes;
JVM_GetClassConstantPool;
JVM_GetClassContext;
JVM_GetClassDeclaredConstructors;
JVM_GetClassDeclaredFields;
JVM_GetClassDeclaredMethods;
JVM_GetClassFieldsCount;
JVM_GetClassInterfaces;
JVM_GetClassLoader;
JVM_GetClassMethodsCount;
JVM_GetClassModifiers;
JVM_GetClassName;
JVM_GetClassNameUTF;
JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetComponentType;
JVM_GetDeclaredClasses;
JVM_GetDeclaringClass;
JVM_GetEnclosingMethodInfo;
JVM_GetFieldAnnotations;
JVM_GetFieldIxModifiers;
JVM_GetHostName;
JVM_GetInheritedAccessControlContext;
JVM_GetInterfaceVersion;
JVM_GetLastErrorString;
JVM_GetManagement;
JVM_GetMethodAnnotations;
JVM_GetMethodDefaultAnnotationValue;
JVM_GetMethodIxArgsSize;
JVM_GetMethodIxByteCode;
JVM_GetMethodIxByteCodeLength;
JVM_GetMethodIxExceptionIndexes;
JVM_GetMethodIxExceptionTableEntry;
JVM_GetMethodIxExceptionTableLength;
JVM_GetMethodIxExceptionsCount;
JVM_GetMethodIxLocalsCount;
JVM_GetMethodIxMaxStack;
JVM_GetMethodIxModifiers;
JVM_GetMethodIxNameUTF;
JVM_GetMethodIxSignatureUTF;
JVM_GetMethodParameterAnnotations;
JVM_GetPrimitiveArrayElement;
JVM_GetProtectionDomain;
JVM_GetSockName;
JVM_GetSockOpt;
JVM_GetStackAccessControlContext;
JVM_GetStackTraceDepth;
JVM_GetStackTraceElement;
JVM_GetSystemPackage;
JVM_GetSystemPackages;
JVM_GetThreadStateNames;
JVM_GetThreadStateValues;
JVM_GetVersionInfo;
JVM_Halt;
JVM_HoldsLock;
JVM_IHashCode;
JVM_InitAgentProperties;
JVM_InitProperties;
JVM_InitializeCompiler;
JVM_InitializeSocketLibrary;
JVM_InternString;
JVM_Interrupt;
JVM_InvokeMethod;
JVM_IsArrayClass;
JVM_IsConstructorIx;
JVM_IsInterface;
JVM_IsInterrupted;
JVM_IsNaN;
JVM_IsPrimitiveClass;
JVM_IsSameClassPackage;
JVM_IsSilentCompiler;
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
JVM_LoadLibrary;
JVM_Lseek;
JVM_MaxObjectInspectionAge;
JVM_MaxMemory;
JVM_MonitorNotify;
JVM_MonitorNotifyAll;
JVM_MonitorWait;
JVM_NanoTime;
JVM_NativePath;
JVM_NewArray;
JVM_NewInstanceFromConstructor;
JVM_NewMultiArray;
JVM_OnExit;
JVM_Open;
JVM_PrintStackTrace;
JVM_RaiseSignal;
JVM_RawMonitorCreate;
JVM_RawMonitorDestroy;
JVM_RawMonitorEnter;
JVM_RawMonitorExit;
JVM_Read;
JVM_Recv;
JVM_RecvFrom;
JVM_RegisterSignal;
JVM_ReleaseUTF;
JVM_ResolveClass;
JVM_ResumeThread;
JVM_Send;
JVM_SendTo;
JVM_SetArrayElement;
JVM_SetClassSigners;
JVM_SetLength;
JVM_SetPrimitiveArrayElement;
JVM_SetProtectionDomain;
JVM_SetSockOpt;
JVM_SetThreadPriority;
JVM_Sleep;
JVM_Socket;
JVM_SocketAvailable;
JVM_SocketClose;
JVM_SocketShutdown;
JVM_StartThread;
JVM_StopThread;
JVM_SuspendThread;
JVM_SupportsCX8;
JVM_Sync;
JVM_Timeout;
JVM_TotalMemory;
JVM_TraceInstructions;
JVM_TraceMethodCalls;
JVM_UnloadLibrary;
JVM_Write;
JVM_Yield;
JVM_handle_linux_signal;
# Old reflection routines
# These do not need to be present in the product build in JDK 1.4
# but their code has not been removed yet because there will not
# be a substantial code savings until JVM_InvokeMethod and
# JVM_NewInstanceFromConstructor can also be removed; see
# reflectionCompat.hpp.
JVM_GetClassConstructor;
JVM_GetClassConstructors;
JVM_GetClassField;
JVM_GetClassFields;
JVM_GetClassMethod;
JVM_GetClassMethods;
JVM_GetField;
JVM_GetPrimitiveField;
JVM_NewInstance;
JVM_SetField;
JVM_SetPrimitiveField;
# Needed for dropping VM into JDK 1.3.x, 1.4
_JVM_native_threads;
jdk_sem_init;
jdk_sem_post;
jdk_sem_wait;
jdk_pthread_sigmask;
jdk_waitpid;
# miscellaneous functions
jio_fprintf;
jio_printf;
jio_snprintf;
jio_vfprintf;
jio_vsnprintf;
fork1;
numa_warn;
numa_error;
# Needed because there is no JVM interface for this.
sysThreadAvailableStackWithSlack;
# This is for Forte Analyzer profiling support.
AsyncGetCallTrace;
};

213
openjdk.pro Normal file
View File

@ -0,0 +1,213 @@
# proguard include file (http://proguard.sourceforge.net)
# This file is for use in combination with vm.pro when ProGuarding
# OpenJDK-based builds
# the following methods and fields are refered to by name in the VM:
-keepclassmembers class java.lang.Thread {
public void run();
}
-keep class java.lang.System {
private static void initializeSystemClass();
}
-keep class java.lang.ClassLoader {
private static java.lang.ClassLoader scl;
private static boolean sclSet;
protected ClassLoader(java.lang.ClassLoader);
}
-keep class avian.SystemClassLoader {
protected java.net.URL findResource(java.lang.String);
}
-keepnames class java.lang.ClassLoader {
public java.lang.Class loadClass(java.lang.String);
static void loadLibrary(java.lang.Class, java.lang.String, boolean);
private static java.net.URL getBootstrapResource(java.lang.String);
private static java.util.Enumeration getBootstrapResources(java.lang.String);
}
-keep class java.util.Properties {
public java.lang.Object setProperty(java.lang.String, java.lang.String);
}
-keep class avian.OpenJDK {
public static java.security.ProtectionDomain getProtectionDomain();
}
-keepclassmembers public class java.security.PrivilegedAction {
public java.lang.Object run();
}
-keepclassmembers public class * implements java.security.PrivilegedAction {
public java.lang.Object run();
}
-keepclassmembers public class java.security.PrivilegedExceptionAction {
public java.lang.Object run();
}
-keepclassmembers public class * implements java.security.PrivilegedExceptionAction {
public java.lang.Object run();
}
-keep public class java.security.PrivilegedActionException {
public PrivilegedActionException(java.lang.Exception);
}
# these class names are used to disambiguate JNI method lookups:
-keepnames public class java.net.URL
-keepnames public class java.util.Enumeration
-keepnames public class java.security.ProtectionDomain
-keepnames public class java.security.PrivilegedAction
-keepnames public class java.security.PrivilegedExceptionAction
-keepnames public class java.security.AccessControlContext
# the following methods and fields are refered to by name in the OpenJDK
# native code:
-keep class java.util.Properties {
public java.lang.Object put(java.lang.Object, java.lang.Object);
}
-keepclassmembers class * {
public boolean equals(java.lang.Object);
public void wait();
public void notify();
public void notifyAll();
public java.lang.String toString();
}
-keepclassmembers class java.lang.String {
public String(byte[]);
public String(byte[], java.lang.String);
public byte[] getBytes();
public byte[] getBytes(java.lang.String);
}
-keepclassmembers class java.lang.Boolean {
public boolean getBoolean(java.lang.String);
}
-keepclassmembers class java.util.zip.Inflater {
long strm;
boolean needDict;
boolean finished;
byte[] buf;
int off;
int len;
}
-keepclassmembers class java.io.FileDescriptor {
private int fd;
}
-keep class java.net.InetAddress {
<fields>;
}
-keep class java.net.Inet4Address {
<fields>;
}
-keep class java.net.Inet4AddressImpl
-keep class java.net.Inet6Address {
<fields>;
}
-keep class java.net.Inet6AddressImpl
-keep class java.net.InetSocketAddress {
public InetSocketAddress(java.net.InetAddress, int);
}
-keep class java.net.ServerSocket
-keepclassmembers class java.net.PlainSocketImpl {
<fields>;
}
-keepclassmembers class java.io.FileInputStream {
private java.io.FileDescriptor fd;
}
-keepclassmembers class java.io.FileOutputStream {
private java.io.FileDescriptor fd;
}
# changed in native code via sun.misc.Unsafe (todo: handle other
# Atomic* classes)
-keepclassmembers class java.util.concurrent.atomic.AtomicInteger {
private int value;
}
# avoid inlining due to access check using a fixed offset into call stack:
-keep,allowshrinking,allowobfuscation class java.util.concurrent.atomic.AtomicReferenceFieldUpdater {
*** newUpdater(...);
}
# accessed reflectively via an AtomicReferenceFieldUpdater:
-keepclassmembers class java.io.BufferedInputStream {
protected byte[] buf;
}
-keep class java.lang.System {
public static java.io.InputStream in;
public static java.io.PrintStream out;
public static java.io.PrintStream err;
# avoid inlining due to access check using fixed offset into call stack:
static java.lang.Class getCallerClass();
# called from jni_util.c:
static java.lang.String getProperty(java.lang.String);
}
# refered to by name from native code:
-keepnames public class java.io.InputStream
-keepnames public class java.io.PrintStream
# avoid inlining due to access check using fixed offset into call stack:
-keep,allowshrinking,allowobfuscation class java.lang.System {
static java.lang.Class getCallerClass();
}
-keep class java.io.UnixFileSystem {
public UnixFileSystem();
}
-keep class java.io.File {
private java.lang.String path;
}
-keepclassmembers class java.lang.ClassLoader$NativeLibrary {
long handle;
private int jniVersion;
}
-keep class java.nio.charset.Charset {
# called from jni_util.c:
boolean isSupported(java.lang.String);
}
# Charsets are loaded via reflection. If you need others besides
# UTF-8, you'll need to add them (e.g. sun.nio.cs.ISO_8859_1).
-keep class sun.nio.cs.UTF_8
# loaded reflectively to handle embedded resources:
-keep class avian.resource.Handler
# refered to symbolically in MethodAccessorGenerator:
-keep class sun.reflect.MethodAccessorImpl {
<methods>;
}
-keep class sun.reflect.ConstructorAccessorImpl {
<methods>;
}
-keep class sun.reflect.SerializationConstructorAccessorImpl {
<methods>;
}
# referred to by name in LocaleData to load resources:
-keep class sun.util.resources.CalendarData
-keep class sun.util.resources.TimeZoneNames
-keep class sun.text.resources.FormatData

View File

@ -4,24 +4,24 @@ Quick Start
on Linux:
$ export JAVA_HOME=/usr/local/java # or wherever you have the JDK installed
$ make
$ build/linux-i386/avian -cp build/test Hello
$ build/linux-i386/avian -cp build/linux-i386/test Hello
on Mac OS X:
$ export JAVA_HOME=/Library/Java/Home
$ make
$ build/darwin-i386/avian -cp build/test Hello
$ build/darwin-i386/avian -cp build/darwin-i386/test Hello
on Windows (MSYS):
$ git clone git://oss.readytalk.com/win32.git ../win32
$ export JAVA_HOME="C:/Program Files/Java/jdk1.6.0_07"
$ make
$ build/windows-i386/avian -cp build/test Hello
$ build/windows-i386/avian -cp build/windows-i386/test Hello
on Windows (Cygwin):
$ git clone git://oss.readytalk.com/win32.git ../win32
$ export JAVA_HOME="/cygdrive/c/Program Files/Java/jdk1.6.0_07"
$ make
$ build/windows-i386/avian -cp build/test Hello
$ build/windows-i386/avian -cp build/windows-i386/test Hello
Adjust JAVA_HOME according to your system, but be sure to use forward
slashes in the path.
@ -51,7 +51,7 @@ Supported Platforms
Avian can currently target the following platforms:
Linux (i386 and x86_64)
Linux (i386, x86_64 and ARM)
Windows (i386 and x86_64)
Mac OS X (i386, x86_64 and 32-bit PowerPC)
@ -62,7 +62,7 @@ Building
Build requirements include:
* GNU make 3.80 or later
* GCC 3.4 or later (4.5 or later for Windows/x86_64)
* GCC 3.4 or later (4.5.1 or later for Windows/x86_64)
* JDK 1.5 or later
* MinGW 3.4 or later (only if compiling for Windows)
* zlib 1.2.3 or later
@ -73,10 +73,17 @@ been tested.
The build is directed by a single makefile and may be influenced via
certain flags described below, all of which are optional.
$ make platform={linux,windows,darwin} arch={i386,x86_64,powerpc} \
process={compile,interpret} mode={debug,debug-fast,fast,small} \
bootimage={true,false} heapdump={true,false} tails={true,false} \
continuations={true,false}
$ make \
platform={linux,windows,darwin} \
arch={i386,x86_64,powerpc,arm} \
process={compile,interpret} \
mode={debug,debug-fast,fast,small} \
bootimage={true,false} \
heapdump={true,false} \
tails={true,false} \
continuations={true,false} \
openjdk=<openjdk installation directory> \
openjdk-src=<openjdk source directory>
* platform - the target platform
default: output of $(uname -s | tr [:upper:] [:lower:]),
@ -119,6 +126,18 @@ certain flags described below, all of which are optional.
only valid for process=compile builds.
default: false
* openjdk - if set, use OpenJDK class library instead of the default
Avian class library. See "Building with the OpenJDK Class
Library" below for details.
default: not set
* openjdk-src - if this and the openjdk option above are both set,
build an embeddable VM using the OpenJDK class library. The JNI
components of the OpenJDK class library will be built from the
sources found under the specified directory. See "Building with
the OpenJDK Class Library" below for details.
default: not set
These flags determine the name of the directory used for the build.
The name always starts with ${platform}-${arch}, and each non-default
build option is appended to the name. For example, a debug build with
@ -168,7 +187,7 @@ C++ portions of the VM, while the assembly code and helper tools are
built using GCC.
The MSVC build has been tested with Visual Studio Express Edition
versions 8 and 9. Other versions may also work.
versions 8, 9, and 10. Other versions may also work.
To build with MSVC, install Cygwin as described above and set the
following environment variables:
@ -191,25 +210,57 @@ Finally, build with the msvc flag set to the MSVC tool directory:
$ make msvc="/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC"
Building with GNU Classpath
---------------------------
** Please note that this feature is still under development and is
neither complete nor well-tested. **
Building with the OpenJDK Class Library
---------------------------------------
By default, Avian uses its own lightweight class library. However,
that library only contains a relatively small subset of the classes
and methods included in the JRE. If your application requires
features beyond that subset, you may want to tell Avian to use GNU
Classpath instead. To do so, specify the directory where Classpath is
installed, e.g.:
features beyond that subset, you may want to tell Avian to use
OpenJDK's class library instead. To do so, specify the directory
where OpenJDK is installed, e.g.:
$ make clean
$ make gnu=/usr/local/classpath-0.98
$ make openjdk=/usr/lib/jvm/java-6-openjdk
This build will use the classes and native code from Classpath, except
that certain core classes are replaced with implementations from the
Avian class library for compatibility with the VM.
This will build Avian as a conventional JVM (e.g. libjvm.so) which
loads its boot class library and native libraries (e.g. libjava.so)
from /usr/lib/jvm/java-6-openjdk/jre at runtime. To run an
application in this configuration, you'll need to make sure the VM is
in your library search path. For example:
$ LD_LIBRARY_PATH=build/linux-x86_64-openjdk \
build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \
com.example.MyApplication
Alternatively, you can enable a stand-alone build using OpenJDK by
specifying the location of the OpenJDK source code, e.g.:
$ make openjdk=$(pwd)/../jdk6/build/linux-amd64/j2sdk-image \
openjdk-src=$(pwd)/../jdk6/jdk/src
You must ensure that the path specified for openjdk-src does not have
any spaces in it; make gets confused when dependency paths include
spaces, and we haven't found away around that except to avoid paths
with spaces entirely.
The result of such a build is a self-contained binary which does not
depend on external libraries, jars, or other files. In this case, the
specified paths are used only at build time; anything needed at
runtime is embedded in the binary. Thus, the process of running an
application is simplified:
$ build/linux-x86_64-openjdk-src/avian -cp /path/to/my/application \
com.example.MyApplication
Note that the resulting binary will be very large due to the size of
OpenJDK's class library. This can be mitigated using UPX, preferably
an LZMA-enabled version:
$ upx --lzma --best build/linux-x86_64-openjdk-src/avian
You can reduce the size futher for embedded builds by using ProGuard
and the supplied openjdk.pro configuration file (see "Embedding with
ProGuard and a Boot Image" below).
Installing
@ -237,7 +288,7 @@ VM object files and bootstrap classpath jar.
$ mkdir hello
$ cd hello
$ ar x ../build/${platform}-${arch}/libavian.a
$ cp ../build/classpath.jar boot.jar
$ cp ../build/${platform}-${arch}/classpath.jar boot.jar
Step 2: Build the Java code and add it to the jar.
@ -259,17 +310,21 @@ Step 3: Make an object file out of the jar.
Step 4: Write a driver which starts the VM and runs the desired main
method. Note the bootJar function, which will be called by the VM to
get a handle to the embedded jar. We tell the VM about this jar by
setting the classpath to "[bootJar]".
setting the boot classpath to "[bootJar]".
$ cat >main.cpp <<EOF
#include "stdint.h"
#include "jni.h"
#ifdef __MINGW32__
#if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport)
# define SYMBOL(x) binary_boot_jar_##x
#else
# define EXPORT __attribute__ ((visibility("default")))
#endif
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_boot_jar_##x
#else
# define SYMBOL(x) _binary_boot_jar_##x
#endif
@ -298,7 +353,7 @@ main(int ac, const char** av)
JavaVMOption options[vmArgs.nOptions];
vmArgs.options = options;
options[0].optionString = const_cast<char*>("-Djava.class.path=[bootJar]");
options[0].optionString = const_cast<char*>("-Xbootclasspath:[bootJar]");
JavaVM* vm;
void* env;
@ -391,7 +446,10 @@ For boot image builds:
space in the executable than the equivalent class files. In
practice, this can make the executable 30-50% larger. Also, AOT
compilation does not yet yield significantly faster or smaller code
than JIT compilation.
than JIT compilation. Finally, floating point code may be slower
on 32-bit x86 since the compiler cannot assume SSE2 support will be
available at runtime, and the x87 FPU is not supported except via
out-of-line helper functions.
Note you can use ProGuard without using a boot image and vice-versa,
as desired.
@ -411,7 +469,7 @@ Step 2: Create a stage1 directory and extract the contents of the
class library jar into it.
$ mkdir stage1
$ (cd stage1 && jar xf ../../build/classpath.jar)
$ (cd stage1 && jar xf ../../build/linux-i386-bootimage/classpath.jar)
Step 3: Build the Java code and add it to stage1.
@ -435,7 +493,7 @@ EOF
Step 5: Run ProGuard with stage1 as input and stage2 as output.
$ java -jar ../../proguard4.4/lib/proguard.jar \
$ java -jar ../../proguard4.6/lib/proguard.jar \
-injars stage1 -outjars stage2 @../vm.pro @hello.pro
(note: pass -dontusemixedcaseclassnames to ProGuard when building on
@ -447,10 +505,10 @@ Step 6: Build the boot image.
Step 7: Make an object file out of the boot image.
$ ../build/${platform}-${arch}/binaryToObject \
$ ../build/linux-i386-bootimage/binaryToObject \
bootimage.bin bootimage-bin.o \
_binary_bootimage_bin_start _binary_bootimage_bin_end \
${platform} ${arch} 8 writable executable
linux i386 8 writable executable
Step 8: Write a driver which starts the VM and runs the desired main
method. Note the bootimageBin function, which will be called by the
@ -466,11 +524,15 @@ containing them. See the previous example for instructions.
#include "stdint.h"
#include "jni.h"
#ifdef __MINGW32__
#if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport)
# define BOOTIMAGE_BIN(x) binary_bootimage_bin_##x
#else
# define EXPORT __attribute__ ((visibility("default")))
#endif
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define BOOTIMAGE_BIN(x) binary_bootimage_bin_##x
#else
# define BOOTIMAGE_BIN(x) _binary_bootimage_bin_##x
#endif
@ -545,3 +607,12 @@ executable, and optionally strip its symbols.
$ g++ -rdynamic *.o -ldl -lpthread -lz -o hello
$ strip --strip-all hello
Trademarks
----------
Oracle and Java are registered trademarks of Oracle and/or its
affiliates. Other names may be trademarks of their respective owners.
The Avian project is not affiliated with Oracle.

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -22,7 +22,7 @@
#include "common.h"
extern "C" void NO_RETURN
vmJump(void* address, void* base, void* stack, void* thread,
vmJump(void* address, void* frame, void* stack, void* thread,
uintptr_t returnLow, uintptr_t returnHigh);
namespace vm {

View File

@ -1,5 +1,5 @@
/* arm.S: JNI gluecode for ARM/Linux
Copyright (c) 2008-2009, Avian Contributors
Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -50,7 +50,31 @@ vmNativeCall:
.globl vmJump
vmJump:
mov lr, r0
ldr r0, [sp]
ldr r1, [sp, #4]
mov sp, r2
mov r4, r3
ldmia sp, {r0,r1}
mov pc, lr
mov r8, r3
bx lr
#define CHECKPOINT_THREAD 4
#define CHECKPOINT_STACK 24
.globl vmRun
vmRun:
// r0: function
// r1: arguments
// r2: checkpoint
stmfd sp!, {r4-r11, lr}
str sp, [r2, #CHECKPOINT_STACK]
mov r12, r0
ldr r0, [r2, #CHECKPOINT_THREAD]
blx r12
.globl vmRun_returnAddress
vmRun_returnAddress:
ldmfd sp!, {r4-r11, lr}
bx lr

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -14,9 +14,12 @@
#include "types.h"
#include "common.h"
#define VA_LIST(x) (&(x))
#define IP_REGISTER(context) (context->uc_mcontext.arm_pc)
#define STACK_REGISTER(context) (context->uc_mcontext.arm_sp)
#define THREAD_REGISTER(context) (context->uc_mcontext.arm_ip)
#define LINK_REGISTER(context) (context->uc_mcontext.arm_lr)
extern "C" uint64_t
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
@ -27,7 +30,7 @@ namespace vm {
inline void
trap()
{
asm("nop");
asm("bkpt");
}
inline void
@ -55,9 +58,11 @@ loadMemoryBarrier()
}
inline void
syncInstructionCache(const void* start UNUSED, unsigned size UNUSED)
syncInstructionCache(const void* start, unsigned size)
{
asm("nop");
__clear_cache
(const_cast<void*>(start),
const_cast<uint8_t*>(static_cast<const uint8_t*>(start) + size));
}
typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
@ -101,6 +106,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
memcpy(gprTable + gprIndex, arguments + ai, 8);
gprIndex += 8 / BytesPerWord;
} else { // pass argument on stack
gprIndex = GprCount;
if (stackIndex & 1) { // 8-byte alignment
memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck
++stackIndex;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -22,6 +22,12 @@ const bool TailCalls = true;
const bool TailCalls = false;
#endif
#ifdef AVIAN_USE_FRAME_POINTER
const bool UseFramePointer = true;
#else
const bool UseFramePointer = false;
#endif
enum Operation {
Return,
LoadBarrier,
@ -323,6 +329,7 @@ class Assembler {
virtual unsigned frameFootprint(unsigned footprint) = 0;
virtual unsigned argumentFootprint(unsigned footprint) = 0;
virtual bool argumentAlignment() = 0;
virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0;
@ -337,13 +344,16 @@ class Assembler {
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
virtual void nextFrame(void* start, unsigned size, unsigned footprint,
void* link, void* stackLimit,
unsigned targetParameterFootprint, void** ip,
void** stack) = 0;
virtual void* frameIp(void* stack) = 0;
virtual unsigned frameHeaderSize() = 0;
virtual unsigned frameReturnAddressSize() = 0;
virtual unsigned frameFooterSize() = 0;
virtual int returnAddressOffset() = 0;
virtual int framePointerOffset() = 0;
virtual void nextFrame(void** stack, void** base) = 0;
virtual void plan
(UnaryOperation op,
@ -385,17 +395,21 @@ class Assembler {
virtual Architecture* arch() = 0;
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) = 0;
virtual void checkStackOverflow(uintptr_t handler,
unsigned stackLimitOffsetFromThread) = 0;
virtual void saveFrame(unsigned stackOffset) = 0;
virtual void pushFrame(unsigned argumentCount, ...) = 0;
virtual void allocateFrame(unsigned footprint) = 0;
virtual void adjustFrame(unsigned footprint) = 0;
virtual void popFrame() = 0;
virtual void adjustFrame(unsigned difference) = 0;
virtual void popFrame(unsigned footprint) = 0;
virtual void popFrameForTailCall(unsigned footprint, int offset,
int returnAddressSurrogate,
int framePointerSurrogate) = 0;
virtual void popFrameAndPopArgumentsAndReturn(unsigned argumentFootprint)
virtual void popFrameAndPopArgumentsAndReturn(unsigned frameFootprint,
unsigned argumentFootprint)
= 0;
virtual void popFrameAndUpdateStackAndReturn(unsigned stackOffsetFromThread)
virtual void popFrameAndUpdateStackAndReturn(unsigned frameFootprint,
unsigned stackOffsetFromThread)
= 0;
virtual void apply(Operation op) = 0;
@ -414,13 +428,15 @@ class Assembler {
virtual void writeTo(uint8_t* dst) = 0;
virtual Promise* offset() = 0;
virtual Promise* offset(bool forTrace = false) = 0;
virtual Block* endBlock(bool startNew) = 0;
virtual void endEvent() = 0;
virtual unsigned length() = 0;
virtual unsigned scratchSize() = 0;
virtual unsigned footerSize() = 0;
virtual void dispose() = 0;
};

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2009, Avian Contributors
/* Copyright (c) 2009-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -232,7 +232,7 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
fileHeader.e_entry = 0;
fileHeader.e_phoff = 0;
fileHeader.e_shoff = sizeof(FileHeader);
fileHeader.e_flags = 0;
fileHeader.e_flags = (machine == EM_ARM ? 0x04000000 : 0);
fileHeader.e_ehsize = sizeof(FileHeader);
fileHeader.e_phentsize = 0;
fileHeader.e_phnum = 0;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -12,6 +12,32 @@
#include "stdio.h"
#include "string.h"
#define V1(v) v
#ifdef OPPOSITE_ENDIAN
# define V2(v) \
((((v) >> 8) & 0xFF) | \
(((v) << 8)))
# define V4(v) \
((((v) >> 24) & 0x000000FF) | \
(((v) >> 8) & 0x0000FF00) | \
(((v) << 8) & 0x00FF0000) | \
(((v) << 24)))
# define V8(v) \
(((static_cast<uint64_t>(v) >> 56) & UINT64_C(0x00000000000000FF)) | \
((static_cast<uint64_t>(v) >> 40) & UINT64_C(0x000000000000FF00)) | \
((static_cast<uint64_t>(v) >> 24) & UINT64_C(0x0000000000FF0000)) | \
((static_cast<uint64_t>(v) >> 8) & UINT64_C(0x00000000FF000000)) | \
((static_cast<uint64_t>(v) << 8) & UINT64_C(0x000000FF00000000)) | \
((static_cast<uint64_t>(v) << 24) & UINT64_C(0x0000FF0000000000)) | \
((static_cast<uint64_t>(v) << 40) & UINT64_C(0x00FF000000000000)) | \
((static_cast<uint64_t>(v) << 56)))
#else
# define V2(v) v
# define V4(v) v
# define V8(v) v
#endif
#define MH_MAGIC_64 0xfeedfacf
#define MH_MAGIC 0xfeedface
@ -37,6 +63,7 @@
#define CPU_SUBTYPE_POWERPC_ALL 0
#if (BITS_PER_WORD == 64)
# define VW(v) V8(v)
# define Magic MH_MAGIC_64
# define Segment LC_SEGMENT_64
# define FileHeader mach_header_64
@ -44,6 +71,7 @@
# define Section section_64
# define NList struct nlist_64
#elif (BITS_PER_WORD == 32)
# define VW(v) V4(v)
# define Magic MH_MAGIC
# define Segment LC_SEGMENT
# define FileHeader mach_header
@ -191,32 +219,32 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
unsigned endNameLength = strlen(endName) + 1;
FileHeader header = {
Magic, // magic
cpuType,
cpuSubType,
MH_OBJECT, // filetype,
2, // ncmds
sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command), // sizeofcmds
0 // flags
V4(Magic), // magic
V4(cpuType),
V4(cpuSubType),
V4(MH_OBJECT), // filetype,
V4(2), // ncmds
V4(sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command)), // sizeofcmds
V4(0) // flags
};
SegmentCommand segment = {
Segment, // cmd
sizeof(SegmentCommand) + sizeof(Section), // cmdsize
V4(Segment), // cmd
V4(sizeof(SegmentCommand) + sizeof(Section)), // cmdsize
"", // segname
0, // vmaddr
pad(size), // vmsize
sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command), // fileoff
pad(size), // filesize
7, // maxprot
7, // initprot
1, // nsects
0 // flags
VW(0), // vmaddr
VW(pad(size)), // vmsize
VW(sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command)), // fileoff
VW(pad(size)), // filesize
V4(7), // maxprot
V4(7), // initprot
V4(1), // nsects
V4(0) // flags
};
strncpy(segment.segname, segmentName, sizeof(segment.segname));
@ -224,55 +252,55 @@ writeObject(const uint8_t* data, unsigned size, FILE* out,
Section sect = {
"", // sectname
"", // segname
0, // addr
pad(size), // size
sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command), // offset
log(alignment), // align
0, // reloff
0, // nreloc
S_REGULAR, // flags
0, // reserved1
0, // reserved2
VW(0), // addr
VW(pad(size)), // size
V4(sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command)), // offset
V4(log(alignment)), // align
V4(0), // reloff
V4(0), // nreloc
V4(S_REGULAR), // flags
V4(0), // reserved1
V4(0), // reserved2
};
strncpy(sect.segname, segmentName, sizeof(sect.segname));
strncpy(sect.sectname, sectionName, sizeof(sect.sectname));
symtab_command symbolTable = {
LC_SYMTAB, // cmd
sizeof(symtab_command), // cmdsize
sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command)
+ pad(size), // symoff
2, // nsyms
sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command)
+ pad(size)
+ (sizeof(NList) * 2), // stroff
1 + startNameLength + endNameLength, // strsize
V4(LC_SYMTAB), // cmd
V4(sizeof(symtab_command)), // cmdsize
V4(sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command)
+ pad(size)), // symoff
V4(2), // nsyms
V4(sizeof(FileHeader)
+ sizeof(SegmentCommand)
+ sizeof(Section)
+ sizeof(symtab_command)
+ pad(size)
+ (sizeof(NList) * 2)), // stroff
V4(1 + startNameLength + endNameLength), // strsize
};
NList symbolList[] = {
{
1, // n_un
N_SECT | N_EXT, // n_type
1, // n_sect
0, // n_desc
0 // n_value
V4(1), // n_un
V1(N_SECT | N_EXT), // n_type
V1(1), // n_sect
V2(0), // n_desc
VW(0) // n_value
},
{
1 + startNameLength, // n_un
N_SECT | N_EXT, // n_type
1, // n_sect
0, // n_desc
size // n_value
V4(1 + startNameLength), // n_un
V1(N_SECT | N_EXT), // n_type
V1(1), // n_sect
V2(0), // n_desc
VW(size) // n_value
}
};

45
src/boot-javahome.cpp Normal file
View File

@ -0,0 +1,45 @@
/* Copyright (c) 2010, 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. */
#ifdef _MSC_VER
typedef unsigned char uint8_t;
#else
# include "stdint.h"
#endif
#ifdef BOOT_JAVAHOME
#if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport)
# define SYMBOL(x) binary_javahome_jar_##x
#else
# define EXPORT __attribute__ ((visibility("default")))
# define SYMBOL(x) _binary_javahome_jar_##x
#endif
extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
EXPORT const uint8_t*
javahomeJar(unsigned* size)
{
*size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start);
}
}
#undef SYMBOL
#endif//BOOT_JAVAHOME

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -32,7 +32,7 @@ extern "C" void __cxa_pure_virtual(void) { abort(); }
#ifdef BOOT_IMAGE
#if (defined __MINGW32__) || (defined _MSC_VER)
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_bootimage_bin_##x
#else
# define SYMBOL(x) _binary_bootimage_bin_##x
@ -52,11 +52,13 @@ extern "C" {
}
#undef SYMBOL
#endif//BOOT_IMAGE
#ifdef BOOT_CLASSPATH
#if (defined __MINGW32__) || (defined _MSC_VER)
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_classpath_jar_##x
#else
# define SYMBOL(x) _binary_classpath_jar_##x
@ -76,4 +78,6 @@ extern "C" {
}
#undef SYMBOL
#endif//BOOT_CLASSPATH

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -23,6 +23,38 @@ using namespace vm;
namespace {
const unsigned HeapCapacity = 768 * 1024 * 1024;
// Notes on immutable references in the heap image:
//
// One of the advantages of a bootimage-based build is that reduces
// the overhead of major GCs at runtime since we can avoid scanning
// the pre-built heap image entirely. However, this only works if we
// can ensure that no part of the heap image (with exceptions noted
// below) ever points to runtime-allocated objects. Therefore (most)
// references in the heap image are considered immutable, and any
// attempt to update them at runtime will cause the process to abort.
//
// However, some references in the heap image really must be updated
// at runtime: e.g. the static field table for each class. Therefore,
// we allocate these as "fixed" objects, subject to mark-and-sweep
// collection, instead of as "copyable" objects subject to copying
// collection. This strategy avoids the necessity of maintaining
// "dirty reference" bitsets at runtime for the entire heap image;
// each fixed object has its own bitset specific to that object.
//
// In addition to the "fixed" object solution, there are other
// strategies available to avoid attempts to update immutable
// references at runtime:
//
// * Table-based: use a lazily-updated array or vector to associate
// runtime data with heap image objects (see
// e.g. getClassRuntimeData in machine.cpp).
//
// * Update references at build time: for example, we set the names
// of primitive classes before generating the heap image so that we
// need not populate them lazily at runtime.
bool
endsWith(const char* suffix, const char* s, unsigned length)
{
@ -44,7 +76,11 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
DelayedPromise* addresses = 0;
for (Finder::Iterator it(t->m->finder); it.hasMore();) {
for (Finder::Iterator it
(static_cast<Finder*>
(systemClassLoaderFinder(t, root(t, Machine::BootLoader))));
it.hasMore();)
{
unsigned nameSize = 0;
const char* name = it.next(&nameSize);
@ -53,30 +89,59 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
{
// fprintf(stderr, "%.*s\n", nameSize - 6, name);
object c = resolveSystemClass
(t, makeByteArray(t, "%.*s", nameSize - 6, name));
if (t->exception) return 0;
(t, root(t, Machine::BootLoader),
makeByteArray(t, "%.*s", nameSize - 6, name), true);
PROTECT(t, c);
if (classMethodTable(t, c)) {
for (unsigned i = 0; i < arrayLength(t, classMethodTable(t, c)); ++i) {
object method = arrayBody(t, classMethodTable(t, c), i);
if ((methodCode(t, method) or (methodFlags(t, method) & ACC_NATIVE))
and ((methodName == 0
if (((methodName == 0
or ::strcmp
(reinterpret_cast<char*>
(&byteArrayBody
(t, vm::methodName(t, method), 0)), methodName) == 0)
and (methodSpec == 0
or ::strcmp
(reinterpret_cast<char*>
(&byteArrayBody
(t, vm::methodName(t, method), 0)), methodName) == 0)
and (methodSpec == 0
or ::strcmp
(reinterpret_cast<char*>
(&byteArrayBody
(t, vm::methodSpec(t, method), 0)), methodSpec)
== 0)))
(t, vm::methodSpec(t, method), 0)), methodSpec)
== 0)))
{
t->m->processor->compileMethod
(t, zone, &constants, &calls, &addresses, method);
if (methodCode(t, method)
or (methodFlags(t, method) & ACC_NATIVE))
{
PROTECT(t, method);
t->m->processor->compileMethod
(t, zone, &constants, &calls, &addresses, method);
}
object addendum = methodAddendum(t, method);
if (addendum and methodAddendumExceptionTable(t, addendum)) {
PROTECT(t, addendum);
// resolve exception types now to avoid trying to update
// immutable references at runtime
for (unsigned i = 0; i < shortArrayLength
(t, methodAddendumExceptionTable(t, addendum)); ++i)
{
uint16_t index = shortArrayBody
(t, methodAddendumExceptionTable(t, addendum), i) - 1;
object o = singletonObject
(t, addendumPool(t, addendum), index);
if (objectClass(t, o) == type(t, Machine::ReferenceType)) {
o = resolveClass
(t, root(t, Machine::BootLoader), referenceName(t, o));
set(t, addendumPool(t, addendum),
SingletonBody + (index * BytesPerWord), o);
}
}
}
}
}
}
@ -89,7 +154,7 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
if (methodFlags(t, method) & ACC_NATIVE) {
address = reinterpret_cast<uintptr_t>(code + image->thunks.native.start);
} else {
address = methodCompiled(t, method);
address = codeCompiled(t, methodCode(t, method));
}
static_cast<ListenPromise*>(pointerValue(t, tripleSecond(t, calls)))
@ -101,7 +166,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code,
assert(t, value >= code);
void* location;
bool flat = addresses->listener->resolve(0, &location);
bool flat = addresses->listener->resolve
(reinterpret_cast<int64_t>(code), &location);
uintptr_t offset = value - code;
if (flat) {
offset |= BootFlatConstant;
@ -131,14 +197,17 @@ visitRoots(Thread* t, BootImage* image, HeapWalker* w, object constants)
{
Machine* m = t->m;
for (HashMapIterator it(t, m->classMap); it.hasMore();) {
for (HashMapIterator it(t, classLoaderMap(t, root(t, Machine::BootLoader)));
it.hasMore();)
{
w->visitRoot(tripleSecond(t, it.next()));
}
image->loader = w->visitRoot(m->loader);
image->bootLoader = w->visitRoot(root(t, Machine::BootLoader));
image->appLoader = w->visitRoot(root(t, Machine::AppLoader));
image->types = w->visitRoot(m->types);
m->processor->visitRoots(w);
m->processor->visitRoots(t, w);
for (; constants; constants = tripleThird(t, constants)) {
w->visitRoot(tripleFirst(t, constants));
@ -177,9 +246,17 @@ makeHeapImage(Thread* t, BootImage* image, uintptr_t* heap, uintptr_t* map,
unsigned size = objectSize(t, p);
unsigned number;
if (currentObject
and (currentOffset * BytesPerWord) == ClassStaticTable)
if ((currentObject
and (currentOffset * BytesPerWord) == ClassStaticTable)
or instanceOf(t, type(t, Machine::SystemClassLoaderType), p))
{
// Static tables and system classloaders must be allocated
// as fixed objects in the heap image so that they can be
// marked as dirty and visited during GC. Otherwise,
// attempts to update references in these objects to point
// to runtime-allocated memory would fail because we don't
// scan non-fixed objects in the heap image during GC.
FixedAllocator allocator
(t->m->system, reinterpret_cast<uint8_t*>(heap + position),
(capacity - position) * BytesPerWord);
@ -279,9 +356,9 @@ offset(object a, uintptr_t* b)
}
void
writeBootImage(Thread* t, FILE* out, BootImage* image, uint8_t* code,
unsigned codeCapacity, const char* className,
const char* methodName, const char* methodSpec)
writeBootImage2(Thread* t, FILE* out, BootImage* image, uint8_t* code,
unsigned codeCapacity, const char* className,
const char* methodName, const char* methodSpec)
{
Zone zone(t->m->system, t->m->heap, 64 * 1024);
@ -292,44 +369,119 @@ writeBootImage(Thread* t, FILE* out, BootImage* image, uint8_t* code,
object constants = makeCodeImage
(t, &zone, image, code, codeMap, className, methodName, methodSpec);
if (t->exception) return;
PROTECT(t, constants);
const unsigned HeapCapacity = 32 * 1024 * 1024;
// this map will not be used when the bootimage is loaded, so
// there's no need to preserve it:
setRoot(t, Machine::ByteArrayMap, makeWeakHashMap(t, 0, 0));
// name all primitive classes so we don't try to update immutable
// references at runtime:
{ object name = makeByteArray(t, "void");
set(t, type(t, Machine::JvoidType), ClassName, name);
name = makeByteArray(t, "boolean");
set(t, type(t, Machine::JbooleanType), ClassName, name);
name = makeByteArray(t, "byte");
set(t, type(t, Machine::JbyteType), ClassName, name);
name = makeByteArray(t, "short");
set(t, type(t, Machine::JshortType), ClassName, name);
name = makeByteArray(t, "char");
set(t, type(t, Machine::JcharType), ClassName, name);
name = makeByteArray(t, "int");
set(t, type(t, Machine::JintType), ClassName, name);
name = makeByteArray(t, "float");
set(t, type(t, Machine::JfloatType), ClassName, name);
name = makeByteArray(t, "long");
set(t, type(t, Machine::JlongType), ClassName, name);
name = makeByteArray(t, "double");
set(t, type(t, Machine::JdoubleType), ClassName, name);
}
// resolve primitive array classes in case they are needed at
// runtime:
{ object name = makeByteArray(t, "[B");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
name = makeByteArray(t, "[Z");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
name = makeByteArray(t, "[S");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
name = makeByteArray(t, "[C");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
name = makeByteArray(t, "[I");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
name = makeByteArray(t, "[J");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
name = makeByteArray(t, "[F");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
name = makeByteArray(t, "[D");
resolveSystemClass(t, root(t, Machine::BootLoader), name, true);
}
collect(t, Heap::MajorCollection);
uintptr_t* heap = static_cast<uintptr_t*>
(t->m->heap->allocate(HeapCapacity));
uintptr_t* heapMap = static_cast<uintptr_t*>
(t->m->heap->allocate(heapMapSize(HeapCapacity)));
memset(heapMap, 0, heapMapSize(HeapCapacity));
// this map will not be used when the bootimage is loaded, so
// there's no need to preserve it:
t->m->byteArrayMap = makeWeakHashMap(t, 0, 0);
collect(t, Heap::MajorCollection);
HeapWalker* heapWalker = makeHeapImage
(t, image, heap, heapMap, HeapCapacity, constants);
updateConstants(t, constants, code, codeMap, heapWalker->map());
image->classCount = hashMapSize(t, t->m->classMap);
unsigned* classTable = static_cast<unsigned*>
(t->m->heap->allocate(image->classCount * sizeof(unsigned)));
image->bootClassCount = hashMapSize
(t, classLoaderMap(t, root(t, Machine::BootLoader)));
unsigned* bootClassTable = static_cast<unsigned*>
(t->m->heap->allocate(image->bootClassCount * sizeof(unsigned)));
{ unsigned i = 0;
for (HashMapIterator it(t, t->m->classMap); it.hasMore();) {
classTable[i++] = heapWalker->map()->find(tripleSecond(t, it.next()));
for (HashMapIterator it
(t, classLoaderMap(t, root(t, Machine::BootLoader)));
it.hasMore();)
{
bootClassTable[i++] = heapWalker->map()->find
(tripleSecond(t, it.next()));
}
}
image->stringCount = hashMapSize(t, t->m->stringMap);
image->appClassCount = hashMapSize
(t, classLoaderMap(t, root(t, Machine::AppLoader)));
unsigned* appClassTable = static_cast<unsigned*>
(t->m->heap->allocate(image->appClassCount * sizeof(unsigned)));
{ unsigned i = 0;
for (HashMapIterator it
(t, classLoaderMap(t, root(t, Machine::AppLoader)));
it.hasMore();)
{
appClassTable[i++] = heapWalker->map()->find(tripleSecond(t, it.next()));
}
}
image->stringCount = hashMapSize(t, root(t, Machine::StringMap));
unsigned* stringTable = static_cast<unsigned*>
(t->m->heap->allocate(image->stringCount * sizeof(unsigned)));
{ unsigned i = 0;
for (HashMapIterator it(t, t->m->stringMap); it.hasMore();) {
for (HashMapIterator it(t, root(t, Machine::StringMap)); it.hasMore();) {
stringTable[i++] = heapWalker->map()->find
(jreferenceTarget(t, tripleFirst(t, it.next())));
}
@ -344,17 +496,19 @@ writeBootImage(Thread* t, FILE* out, BootImage* image, uint8_t* code,
fprintf(stderr, "class count %d string count %d call count %d\n"
"heap size %d code size %d\n",
image->classCount, image->stringCount, image->callCount,
image->bootClassCount, image->stringCount, image->callCount,
image->heapSize, image->codeSize);
if (true) {
fwrite(image, sizeof(BootImage), 1, out);
fwrite(classTable, image->classCount * sizeof(unsigned), 1, out);
fwrite(bootClassTable, image->bootClassCount * sizeof(unsigned), 1, out);
fwrite(appClassTable, image->appClassCount * sizeof(unsigned), 1, out);
fwrite(stringTable, image->stringCount * sizeof(unsigned), 1, out);
fwrite(callTable, image->callCount * sizeof(unsigned) * 2, 1, out);
unsigned offset = (image->classCount * sizeof(unsigned))
unsigned offset = (image->bootClassCount * sizeof(unsigned))
+ (image->appClassCount * sizeof(unsigned))
+ (image->stringCount * sizeof(unsigned))
+ (image->callCount * sizeof(unsigned) * 2);
@ -372,6 +526,23 @@ writeBootImage(Thread* t, FILE* out, BootImage* image, uint8_t* code,
}
}
uint64_t
writeBootImage(Thread* t, uintptr_t* arguments)
{
FILE* out = reinterpret_cast<FILE*>(arguments[0]);
BootImage* image = reinterpret_cast<BootImage*>(arguments[1]);
uint8_t* code = reinterpret_cast<uint8_t*>(arguments[2]);
unsigned codeCapacity = arguments[3];
const char* className = reinterpret_cast<const char*>(arguments[4]);
const char* methodName = reinterpret_cast<const char*>(arguments[5]);
const char* methodSpec = reinterpret_cast<const char*>(arguments[6]);
writeBootImage2
(t, out, image, code, codeCapacity, className, methodName, methodSpec);
return 1;
}
} // namespace
int
@ -384,16 +555,18 @@ main(int ac, const char** av)
}
System* s = makeSystem(0);
Heap* h = makeHeap(s, 128 * 1024 * 1024);
Finder* f = makeFinder(s, av[1], 0);
Heap* h = makeHeap(s, HeapCapacity * 2);
Classpath* c = makeClasspath(s, h, AVIAN_JAVA_HOME, AVIAN_EMBED_PREFIX);
Finder* f = makeFinder(s, h, av[1], 0);
Processor* p = makeProcessor(s, h, false);
BootImage image;
const unsigned CodeCapacity = 16 * 1024 * 1024;
const unsigned CodeCapacity = 128 * 1024 * 1024;
uint8_t* code = static_cast<uint8_t*>(h->allocate(CodeCapacity));
p->initialize(&image, code, CodeCapacity);
Machine* m = new (h->allocate(sizeof(Machine))) Machine(s, h, f, p, 0, 0);
Machine* m = new (h->allocate(sizeof(Machine))) Machine
(s, h, f, 0, p, c, 0, 0);
Thread* t = p->makeThread(m, 0, 0);
enter(t, Thread::ActiveState);
@ -405,15 +578,22 @@ main(int ac, const char** av)
return -1;
}
writeBootImage
(t, output, &image, code, CodeCapacity,
(ac > 3 ? av[3] : 0), (ac > 4 ? av[4] : 0), (ac > 5 ? av[5] : 0));
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(output),
reinterpret_cast<uintptr_t>(&image),
reinterpret_cast<uintptr_t>(code),
CodeCapacity,
reinterpret_cast<uintptr_t>(ac > 3 ? av[3] : 0),
reinterpret_cast<uintptr_t>(ac > 4 ? av[4] : 0),
reinterpret_cast<uintptr_t>(ac > 5 ? av[5] : 0) };
run(t, writeBootImage, arguments);
fclose(output);
if (t->exception) {
printTrace(t, t->exception);
return -1;
} else {
return 0;
}
return 0;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -45,6 +45,7 @@ class BootImage {
Thunk defaultVirtual;
Thunk native;
Thunk aioob;
Thunk stackOverflow;
Thunk table;
};
@ -55,11 +56,13 @@ class BootImage {
unsigned heapSize;
unsigned codeSize;
unsigned classCount;
unsigned bootClassCount;
unsigned appClassCount;
unsigned stringCount;
unsigned callCount;
unsigned loader;
unsigned bootLoader;
unsigned appLoader;
unsigned types;
unsigned methodTree;
unsigned methodTreeSentinal;
@ -73,6 +76,7 @@ class BootImage {
unsigned compileVirtualMethodCall;
unsigned invokeNativeCall;
unsigned throwArrayIndexOutOfBoundsCall;
unsigned throwStackOverflowCall;
#define THUNK(s) unsigned s##Call;
#include "thunks.cpp"

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2009, Avian Contributors
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -18,10 +18,11 @@ using namespace vm;
namespace {
int64_t
search(Thread* t, object name, object (*op)(Thread*, object),
bool replaceDots)
search(Thread* t, object loader, object name,
object (*op)(Thread*, object, object), bool replaceDots)
{
if (LIKELY(name)) {
PROTECT(t, loader);
PROTECT(t, name);
object n = makeByteArray(t, stringLength(t, name) + 1);
@ -32,683 +33,69 @@ search(Thread* t, object name, object (*op)(Thread*, object),
replace('.', '/', s);
}
object r = op(t, n);
if (t->exception) {
return 0;
}
return reinterpret_cast<int64_t>(r);
return reinterpret_cast<int64_t>(op(t, loader, n));
} else {
t->exception = makeNullPointerException(t);
return 0;
throwNew(t, Machine::NullPointerExceptionType);
}
}
void
enumerateThreads(Thread* t, Thread* x, object array, unsigned* index,
unsigned limit)
object
resolveSystemClassThrow(Thread* t, object loader, object spec)
{
if (*index < limit) {
set(t, array, ArrayBody + (*index * BytesPerWord), x->javaThread);
++ (*index);
if (x->peer) enumerateThreads(t, x->peer, array, index, limit);
if (x->child) enumerateThreads(t, x->child, array, index, limit);
}
}
bool
compatibleArrayTypes(Thread* t, object a, object b)
{
return classArrayElementSize(t, a)
and classArrayElementSize(t, b)
and (a == b
or (not ((classVmFlags(t, a) & PrimitiveFlag)
or (classVmFlags(t, b) & PrimitiveFlag))));
}
void
runOnLoadIfFound(Thread* t, System::Library* library)
{
void* p = library->resolve("JNI_OnLoad");
if (p) {
jint (JNICALL * JNI_OnLoad)(Machine*, void*);
memcpy(&JNI_OnLoad, &p, sizeof(void*));
JNI_OnLoad(t->m, 0);
}
return resolveSystemClass(t, loader, spec, true);
}
} // namespace
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_toString
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
unsigned hash = objectHash(t, this_);
object s = makeString
(t, "%s@0x%x",
&byteArrayBody(t, className(t, objectClass(t, this_)), 0),
hash);
return reinterpret_cast<int64_t>(s);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_getClass
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
return reinterpret_cast<int64_t>(objectClass(t, this_));
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Object_wait
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
int64_t milliseconds; memcpy(&milliseconds, arguments + 1, 8);
vm::wait(t, this_, milliseconds);
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Object_notify
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
notify(t, this_);
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Object_notifyAll
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
notifyAll(t, this_);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_hashCode
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
return objectHash(t, this_);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_clone
(Thread* t, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[0]);
PROTECT(t, o);
object class_ = objectClass(t, o);
unsigned size = baseSize(t, o, class_) * BytesPerWord;
object clone;
if (classArrayElementSize(t, class_)) {
clone = static_cast<object>(allocate(t, size, classObjectMask(t, class_)));
memcpy(clone, o, size);
// clear any object header flags:
setObjectClass(t, o, objectClass(t, o));
} else {
clone = make(t, class_);
memcpy(reinterpret_cast<void**>(clone) + 1,
reinterpret_cast<void**>(o) + 1,
size - BytesPerWord);
}
return reinterpret_cast<int64_t>(clone);
}
extern "C" JNIEXPORT void JNICALL
Avian_avian_SystemClassLoader_acquireClassLock
(Thread* t, object, uintptr_t*)
{
acquire(t, t->m->classLock);
}
extern "C" JNIEXPORT void JNICALL
Avian_avian_SystemClassLoader_releaseClassLock
(Thread* t, object, uintptr_t*)
{
release(t, t->m->classLock);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_defineClass
Avian_avian_SystemClassLoader_findLoadedVMClass
(Thread* t, object, uintptr_t* arguments)
{
object loader = reinterpret_cast<object>(arguments[0]);
PROTECT(t, loader);
object b = reinterpret_cast<object>(arguments[1]);
int offset = arguments[2];
int length = arguments[3];
uint8_t* buffer = static_cast<uint8_t*>
(t->m->heap->allocate(length));
memcpy(buffer, &byteArrayBody(t, b, offset), length);
object c = parseClass(t, loader, buffer, length);
t->m->heap->free(buffer, length);
if (c) {
PROTECT(t, c);
if (getClassLoaderMap(t, loader) == 0) {
object map = makeHashMap(t, 0, 0);
set(t, loader, ClassLoaderMap, map);
}
hashMapInsert(t, getClassLoaderMap(t, loader), className(t, c), c,
byteArrayHash);
}
return reinterpret_cast<int64_t>(c);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_reallyFindLoadedClass
(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[1]);
return search(t, name, findLoadedSystemClass, true);
return search(t, loader, name, findLoadedClass, true);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findClass
(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[1]);
return search(t, name, resolveSystemClass, true);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_resolveClass
Avian_avian_SystemClassLoader_findVMClass
(Thread* t, object, uintptr_t* arguments)
{
object loader = reinterpret_cast<object>(arguments[0]);
object spec = reinterpret_cast<object>(arguments[1]);
object name = reinterpret_cast<object>(arguments[1]);
return reinterpret_cast<int64_t>(resolveClass(t, loader, spec));
return search(t, loader, name, resolveSystemClassThrow, true);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_resourceExists
(Thread* t, object, uintptr_t* arguments)
{
object loader = reinterpret_cast<object>(arguments[0]);
object name = reinterpret_cast<object>(arguments[1]);
if (LIKELY(name)) {
RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);
THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
return t->m->finder->exists(RUNTIME_ARRAY_BODY(n));
unsigned length;
bool r = static_cast<Finder*>(systemClassLoaderFinder(t, loader))->stat
(RUNTIME_ARRAY_BODY(n), &length) == System::TypeFile;
// fprintf(stderr, "resource %s exists? %d\n", n, r);
return r;
} else {
t->exception = makeNullPointerException(t);
return 0;
throwNew(t, Machine::NullPointerExceptionType);
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_io_ObjectInputStream_makeInstance
Avian_avian_SystemClassLoader_getClass
(Thread* t, object, uintptr_t* arguments)
{
object c = reinterpret_cast<object>(arguments[0]);
return reinterpret_cast<int64_t>(make(t, c));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_primitiveClass
(Thread* t, object, uintptr_t* arguments)
{
char name = arguments[0];
switch (name) {
case 'B':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JbyteType));
case 'C':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JcharType));
case 'D':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JdoubleType));
case 'F':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JfloatType));
case 'I':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JintType));
case 'J':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JlongType));
case 'S':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JshortType));
case 'V':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JvoidType));
case 'Z':
return reinterpret_cast<int64_t>
(arrayBody(t, t->m->types, Machine::JbooleanType));
default:
t->exception = makeIllegalArgumentException(t);
return 0;
}
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Class_initialize
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
initClass(t, this_);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Class_isAssignableFrom
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
object that = reinterpret_cast<object>(arguments[1]);
if (LIKELY(that)) {
return vm::isAssignableFrom(t, this_, that);
} else {
t->exception = makeNullPointerException(t);
return 0;
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Field_getPrimitive
(Thread* t, object, uintptr_t* arguments)
{
object instance = reinterpret_cast<object>(arguments[0]);
int code = arguments[1];
int offset = arguments[2];
switch (code) {
case ByteField:
return cast<int8_t>(instance, offset);
case BooleanField:
return cast<uint8_t>(instance, offset);
case CharField:
return cast<uint16_t>(instance, offset);
case ShortField:
return cast<int16_t>(instance, offset);
case IntField:
return cast<int32_t>(instance, offset);
case LongField:
return cast<int64_t>(instance, offset);
case FloatField:
return cast<uint32_t>(instance, offset);
case DoubleField:
return cast<uint64_t>(instance, offset);
default:
abort(t);
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Field_getObject
(Thread*, object, uintptr_t* arguments)
{
object instance = reinterpret_cast<object>(arguments[0]);
int offset = arguments[1];
return reinterpret_cast<int64_t>(cast<object>(instance, offset));
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_reflect_Field_setPrimitive
(Thread* t, object, uintptr_t* arguments)
{
object instance = reinterpret_cast<object>(arguments[0]);
int code = arguments[1];
int offset = arguments[2];
int64_t value; memcpy(&value, arguments + 3, 8);
switch (code) {
case ByteField:
cast<int8_t>(instance, offset) = static_cast<int8_t>(value);
break;
case BooleanField:
cast<uint8_t>(instance, offset) = static_cast<uint8_t>(value);
break;
case CharField:
cast<uint16_t>(instance, offset) = static_cast<uint16_t>(value);
break;
case ShortField:
cast<int16_t>(instance, offset) = static_cast<int16_t>(value);
break;
case IntField:
cast<int32_t>(instance, offset) = static_cast<int32_t>(value);
break;
case LongField:
cast<int64_t>(instance, offset) = static_cast<int64_t>(value);
break;
case FloatField:
cast<uint32_t>(instance, offset) = static_cast<uint32_t>(value);
break;
case DoubleField:
cast<uint64_t>(instance, offset) = static_cast<uint64_t>(value);
break;
default:
abort(t);
}
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_reflect_Field_setObject
(Thread* t, object, uintptr_t* arguments)
{
object instance = reinterpret_cast<object>(arguments[0]);
int offset = arguments[1];
object value = reinterpret_cast<object>(arguments[2]);
set(t, instance, offset, value);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Constructor_make
(Thread* t, object, uintptr_t* arguments)
{
object c = reinterpret_cast<object>(arguments[0]);
return reinterpret_cast<int64_t>(make(t, c));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_getCaller
(Thread* t, object, uintptr_t*)
{
class Visitor: public Processor::StackVisitor {
public:
Visitor(Thread* t): t(t), method(0), count(0) { }
virtual bool visit(Processor::StackWalker* walker) {
if (count == 2) {
method = walker->method();
return false;
} else {
++ count;
return true;
}
}
Thread* t;
object method;
unsigned count;
} v(t);
t->m->processor->walkStack(t, &v);
return reinterpret_cast<int64_t>(v.method);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Method_invoke
(Thread* t, object, uintptr_t* arguments)
{
object method = reinterpret_cast<object>(arguments[0]);
object instance = reinterpret_cast<object>(arguments[1]);
object args = reinterpret_cast<object>(arguments[2]);
object v = t->m->processor->invokeArray(t, method, instance, args);
if (t->exception) {
t->exception = makeInvocationTargetException(t, t->exception);
}
return reinterpret_cast<int64_t>(v);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Array_getLength
(Thread* t, object, uintptr_t* arguments)
{
object array = reinterpret_cast<object>(arguments[0]);
if (LIKELY(array)) {
unsigned elementSize = classArrayElementSize(t, objectClass(t, array));
if (LIKELY(elementSize)) {
return cast<uintptr_t>(array, BytesPerWord);
} else {
t->exception = makeIllegalArgumentException(t);
}
} else {
t->exception = makeNullPointerException(t);
}
return 0;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_reflect_Array_makeObjectArray
(Thread* t, object, uintptr_t* arguments)
{
object elementType = reinterpret_cast<object>(arguments[0]);
int length = arguments[1];
return reinterpret_cast<int64_t>
(makeObjectArray(t, classLoader(t, elementType), elementType, length));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Float_floatToRawIntBits
(Thread*, object, uintptr_t* arguments)
{
return static_cast<int32_t>(*arguments);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Float_intBitsToFloat
(Thread*, object, uintptr_t* arguments)
{
return static_cast<int32_t>(*arguments);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Double_doubleToRawLongBits
(Thread*, object, uintptr_t* arguments)
{
int64_t v; memcpy(&v, arguments, 8);
return v;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Double_longBitsToDouble
(Thread*, object, uintptr_t* arguments)
{
int64_t v; memcpy(&v, arguments, 8);
return v;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_String_intern
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
return reinterpret_cast<int64_t>(intern(t, this_));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_getVMProperty
(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[0]);
object found = reinterpret_cast<object>(arguments[1]);
PROTECT(t, found);
unsigned length = stringLength(t, name);
RUNTIME_ARRAY(char, n, length + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
int64_t r = 0;
if (::strcmp(RUNTIME_ARRAY_BODY(n), "java.lang.classpath") == 0) {
r = reinterpret_cast<int64_t>(makeString(t, "%s", t->m->finder->path()));
} else if (::strcmp(RUNTIME_ARRAY_BODY(n), "avian.version") == 0) {
r = reinterpret_cast<int64_t>(makeString(t, AVIAN_VERSION));
} else if (::strcmp(RUNTIME_ARRAY_BODY(n), "file.encoding") == 0) {
r = reinterpret_cast<int64_t>(makeString(t, "ASCII"));
} else {
const char* v = findProperty(t, RUNTIME_ARRAY_BODY(n));
if (v) {
r = reinterpret_cast<int64_t>(makeString(t, v));
}
}
if (r) {
booleanArrayBody(t, found, 0) = true;
}
return r;
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_System_arraycopy
(Thread* t, object, uintptr_t* arguments)
{
object src = reinterpret_cast<object>(arguments[0]);
int32_t srcOffset = arguments[1];
object dst = reinterpret_cast<object>(arguments[2]);
int32_t dstOffset = arguments[3];
int32_t length = arguments[4];
if (LIKELY(src and dst)) {
if (LIKELY(compatibleArrayTypes
(t, objectClass(t, src), objectClass(t, dst))))
{
unsigned elementSize = classArrayElementSize(t, objectClass(t, src));
if (LIKELY(elementSize)) {
intptr_t sl = cast<uintptr_t>(src, BytesPerWord);
intptr_t dl = cast<uintptr_t>(dst, BytesPerWord);
if (LIKELY(length > 0)) {
if (LIKELY(srcOffset >= 0 and srcOffset + length <= sl and
dstOffset >= 0 and dstOffset + length <= dl))
{
uint8_t* sbody = &cast<uint8_t>(src, ArrayBody);
uint8_t* dbody = &cast<uint8_t>(dst, ArrayBody);
if (src == dst) {
memmove(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
} else {
memcpy(dbody + (dstOffset * elementSize),
sbody + (srcOffset * elementSize),
length * elementSize);
}
if (classObjectMask(t, objectClass(t, dst))) {
mark(t, dst, ArrayBody + (dstOffset * BytesPerWord), length);
}
return;
} else {
t->exception = makeIndexOutOfBoundsException(t);
return;
}
} else {
return;
}
}
}
} else {
t->exception = makeNullPointerException(t);
return;
}
t->exception = makeArrayStoreException(t);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_System_identityHashCode
(Thread* t, object, uintptr_t* arguments)
{
object o = reinterpret_cast<object>(arguments[0]);
if (LIKELY(o)) {
return objectHash(t, o);
} else {
t->exception = makeNullPointerException(t);
return 0;
}
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_load
(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[0]);
bool mapName = arguments[1];
unsigned length = stringLength(t, name);
RUNTIME_ARRAY(char, n, length + 1);
stringChars(t, name, RUNTIME_ARRAY_BODY(n));
ACQUIRE(t, t->m->classLock);
const char* builtins = findProperty(t, "avian.builtins");
if (mapName and builtins) {
const char* s = builtins;
while (*s) {
if (::strncmp(s, RUNTIME_ARRAY_BODY(n), length) == 0
and (s[length] == ',' or s[length] == 0))
{
// library is built in to this executable
if (not t->m->triedBuiltinOnLoad) {
t->m->triedBuiltinOnLoad = true;
runOnLoadIfFound(t, t->m->libraries);
}
return;
} else {
while (*s and *s != ',') ++ s;
if (*s) ++ s;
}
}
}
System::Library* last = t->m->libraries;
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
if (lib->name()
and ::strcmp(lib->name(), RUNTIME_ARRAY_BODY(n)) == 0
and lib->mapName() == mapName)
{
// already loaded
return;
}
last = lib;
}
System::Library* lib;
if (LIKELY(t->m->system->success
(t->m->system->load(&lib, RUNTIME_ARRAY_BODY(n), mapName))))
{
last->setNext(lib);
runOnLoadIfFound(t, lib);
} else {
object message = makeString
(t, "library not found: %s", RUNTIME_ARRAY_BODY(n));
t->exception = makeUnsatisfiedLinkError(t, message);
}
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_gc
(Thread* t, object, uintptr_t*)
{
collect(t, Heap::MajorCollection);
(getJClass(t, reinterpret_cast<object>(arguments[0])));
}
#ifdef AVIAN_HEAPDUMP
@ -720,17 +107,16 @@ Avian_avian_Machine_dumpHeap
object outputFile = reinterpret_cast<object>(*arguments);
unsigned length = stringLength(t, outputFile);
char n[length + 1];
stringChars(t, outputFile, n);
FILE* out = vm::fopen(n, "wb");
THREAD_RUNTIME_ARRAY(t, char, n, length + 1);
stringChars(t, outputFile, RUNTIME_ARRAY_BODY(n));
FILE* out = vm::fopen(RUNTIME_ARRAY_BODY(n), "wb");
if (out) {
{ ENTER(t, Thread::ExclusiveState);
dumpHeap(t, out);
}
fclose(out);
} else {
object message = makeString(t, "file not found: %s", n);
t->exception = makeRuntimeException(t, message);
throwNew(t, Machine::RuntimeExceptionType, "file not found: %s", n);
}
}
@ -745,193 +131,6 @@ Avian_java_lang_Runtime_exit
t->m->system->exit(arguments[1]);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Runtime_freeMemory
(Thread*, object, uintptr_t*)
{
// todo
return 0;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Runtime_totalMemory
(Thread*, object, uintptr_t*)
{
// todo
return 0;
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Runtime_addShutdownHook
(Thread* t, object, uintptr_t* arguments)
{
object hook = reinterpret_cast<object>(arguments[1]);
PROTECT(t, hook);
ACQUIRE(t, t->m->shutdownLock);
t->m->shutdownHooks = makePair(t, hook, t->m->shutdownHooks);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Throwable_trace
(Thread* t, object, uintptr_t* arguments)
{
int32_t skipCount = arguments[0];
class Visitor: public Processor::StackVisitor {
public:
Visitor(Thread* t, int skipCount):
t(t), trace(0), skipCount(skipCount)
{ }
virtual bool visit(Processor::StackWalker* walker) {
if (skipCount == 0) {
object method = walker->method();
if (isAssignableFrom
(t, arrayBody(t, t->m->types, Machine::ThrowableType),
methodClass(t, method))
and vm::strcmp(reinterpret_cast<const int8_t*>("<init>"),
&byteArrayBody(t, methodName(t, method), 0))
== 0)
{
return true;
} else {
trace = makeTrace(t, walker);
return false;
}
} else {
-- skipCount;
return true;
}
}
Thread* t;
object trace;
unsigned skipCount;
} v(t, skipCount);
t->m->processor->walkStack(t, &v);
if (v.trace == 0) v.trace = makeArray(t, 0);
return reinterpret_cast<int64_t>(v.trace);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Throwable_resolveTrace
(Thread* t, object, uintptr_t* arguments)
{
object trace = reinterpret_cast<object>(*arguments);
PROTECT(t, trace);
unsigned length = arrayLength(t, trace);
object elementType = arrayBody
(t, t->m->types, Machine::StackTraceElementType);
object array = makeObjectArray
(t, classLoader(t, elementType), elementType, length);
PROTECT(t, array);
object e = 0;
PROTECT(t, e);
object class_ = 0;
PROTECT(t, class_);
object method = 0;
PROTECT(t, method);
for (unsigned i = 0; i < length; ++i) {
e = arrayBody(t, trace, i);
class_ = className(t, methodClass(t, traceElementMethod(t, e)));
class_ = makeString(t, class_, 0, byteArrayLength(t, class_) - 1, 0);
method = methodName(t, traceElementMethod(t, e));
method = makeString(t, method, 0, byteArrayLength(t, method) - 1, 0);
unsigned line = t->m->processor->lineNumber
(t, traceElementMethod(t, e), traceElementIp(t, e));
object file = classSourceFile(t, methodClass(t, traceElementMethod(t, e)));
file = file ? makeString(t, file, 0, byteArrayLength(t, file) - 1, 0) : 0;
object ste = makeStackTraceElement(t, class_, method, file, line);
set(t, array, ArrayBody + (i * BytesPerWord), ste);
}
return reinterpret_cast<int64_t>(array);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Thread_currentThread
(Thread* t, object, uintptr_t*)
{
return reinterpret_cast<int64_t>(t->javaThread);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Thread_doStart
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<int64_t>
(startThread(t, reinterpret_cast<object>(*arguments)));
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Thread_interrupt
(Thread* t, object, uintptr_t* arguments)
{
int64_t peer; memcpy(&peer, arguments, 8);
interrupt(t, reinterpret_cast<Thread*>(peer));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Thread_getStackTrace
(Thread* t, object, uintptr_t* arguments)
{
int64_t peer; memcpy(&peer, arguments, 8);
if (reinterpret_cast<Thread*>(peer) == t) {
return reinterpret_cast<int64_t>(makeTrace(t));
} else {
return reinterpret_cast<int64_t>
(t->m->processor->getStackTrace(t, reinterpret_cast<Thread*>(peer)));
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Thread_activeCount
(Thread* t, object, uintptr_t*)
{
return t->m->liveCount;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Thread_enumerate
(Thread* t, object, uintptr_t* arguments)
{
object array = reinterpret_cast<object>(*arguments);
ACQUIRE_RAW(t, t->m->stateLock);
unsigned count = min(t->m->liveCount, objectArrayLength(t, array));
unsigned index = 0;
enumerateThreads(t, t->m->rootThread, array, &index, count);
return count;
}
extern "C" JNIEXPORT void JNICALL
Avian_java_lang_Thread_setDaemon
(Thread* t, object, uintptr_t* arguments)
{
object thread = reinterpret_cast<object>(arguments[0]);
bool daemon = arguments[1] != 0;
setDaemon(t, thread, daemon);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength
(Thread* t, object, uintptr_t* arguments)
@ -939,10 +138,14 @@ Avian_avian_resource_Handler_00024ResourceInputStream_getContentLength
object path = reinterpret_cast<object>(*arguments);
if (LIKELY(path)) {
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
THREAD_RUNTIME_ARRAY(t, char, p, stringLength(t, path) + 1);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
System::Region* r = t->m->finder->find(RUNTIME_ARRAY_BODY(p));
System::Region* r = t->m->bootFinder->find(RUNTIME_ARRAY_BODY(p));
if (r == 0) {
r = t->m->appFinder->find(RUNTIME_ARRAY_BODY(p));
}
if (r) {
jint rSize = r->length();
r->dispose();
@ -959,17 +162,31 @@ Avian_avian_resource_Handler_00024ResourceInputStream_open
object path = reinterpret_cast<object>(*arguments);
if (LIKELY(path)) {
RUNTIME_ARRAY(char, p, stringLength(t, path) + 1);
THREAD_RUNTIME_ARRAY(t, char, p, stringLength(t, path) + 1);
stringChars(t, path, RUNTIME_ARRAY_BODY(p));
return reinterpret_cast<int64_t>
(t->m->finder->find(RUNTIME_ARRAY_BODY(p)));
System::Region* r = t->m->bootFinder->find(RUNTIME_ARRAY_BODY(p));
if (r == 0) {
r = t->m->appFinder->find(RUNTIME_ARRAY_BODY(p));
}
return reinterpret_cast<int64_t>(r);
} else {
t->exception = makeNullPointerException(t);
return 0;
throwNew(t, Machine::NullPointerExceptionType);
}
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_resource_Handler_00024ResourceInputStream_available
(Thread*, object, uintptr_t* arguments)
{
int64_t peer; memcpy(&peer, arguments, 8);
int32_t position = arguments[2];
System::Region* region = reinterpret_cast<System::Region*>(peer);
return static_cast<jint>(region->length()) - position;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_resource_Handler_00024ResourceInputStream_read__JI
(Thread*, object, uintptr_t* arguments)

Some files were not shown because too many files have changed in this diff Show More