Merge branch 'master' into wip

Conflicts:
	makefile
	src/codegen/arm/assembler.cpp
	src/codegen/powerpc/assembler.cpp
	src/codegen/x86/assembler.cpp
This commit is contained in:
Joshua Warner 2013-02-27 19:27:07 -07:00
commit 9327043bc5
124 changed files with 3345 additions and 1122 deletions

View File

@ -95,7 +95,8 @@ certain flags described below, all of which are optional.
continuations={true,false} \
use-clang={true,false} \
openjdk=<openjdk installation directory> \
openjdk-src=<openjdk source directory>
openjdk-src=<openjdk source directory> \
android=<android source directory>
* `platform` - the target platform
* _default:_ output of $(uname -s | tr [:upper:] [:lower:]),
@ -156,8 +157,8 @@ Note that this does not currently affect cross compiles, only
native builds.
* _default:_ false
* `openjdk` - if set, use OpenJDK class library instead of the default
Avian class library. See "Building with the OpenJDK Class
* `openjdk` - if set, use the OpenJDK class library instead of the
default Avian class library. See "Building with the OpenJDK Class
Library" below for details.
* _default:_ not set
@ -168,6 +169,11 @@ sources found under the specified directory. See "Building with
the OpenJDK Class Library" below for details.
* _default:_ not set
* `android` - if set, use the Android class library instead of the
default Avian class library. See "Building with the Android 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
@ -235,6 +241,7 @@ 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 the OpenJDK Class Library
---------------------------------------
@ -306,7 +313,7 @@ _Stand-alone build:_
$ apt-get install openjdk-7-jdk
$ apt-get source openjdk-7-jdk
$ apt-get build-dep openjdk-7-jdk
(cd openjdk-7-7~b147-2.0 && dpkg-buildpackage)
$ (cd openjdk-7-7~b147-2.0 && dpkg-buildpackage)
$ make openjdk=/usr/lib/jvm/java-7-openjdk \
openjdk-src=$(pwd)/openjdk-7-7~b147-2.0/build/openjdk/jdk/src \
test
@ -324,7 +331,7 @@ _Stand-alone build:_
openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test
####Windows (Cygwin):
_Prerequisite:_ Build OpenJDK 7 according to [this site](http://weblogs.java.net/blog/simonis/archive/2011/10/28/yaojowbi-yet-another-openjdk-windows-build-instruction).
_Prerequisite:_ Build OpenJDK 7 according to [this site](http://weblogs.java.net/blog/simonis/archive/2011/10/28/yaojowbi-yet-another-openjdk-windows-build-instruction). Alternatively, use https://github.com/alexkasko/openjdk-unofficial-builds.
_Conventional build:_
@ -339,6 +346,51 @@ Currently, only OpenJDK 7 is supported. Later versions might work,
but have not yet been tested.
Building with the Android Class Library
---------------------------------------
As an alternative to both the Avian and OpenJDK class libaries, you
can also build with the Android Class Library on some platforms
(currently just Linux, but possibly others in the future). To build
this way, do the following, starting from the Avian directory:
$ cd ..
$ mkdir android
$ git clone https://android.googlesource.com/platform/bionic
$ git clone https://android.googlesource.com/platform/system/core
$ git clone https://android.googlesource.com/platform/external/expat
$ git clone https://android.googlesource.com/platform/external/fdlibm
$ git clone https://android.googlesource.com/platform/external/icu4c
$ git clone https://android.googlesource.com/platform/libnativehelper
$ git clone https://android.googlesource.com/platform/external/openssl
$ git clone https://android.googlesource.com/platform/external/zlib
$ git clone git://git.openssl.org/openssl.git openssl-upstream
$ git clone https://github.com/dicej/android-libcore64 libcore
$ (cd expat && CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --enable-static \
&& make)
$ (cd fdlibm && CFLAGS=-fPIC bash configure && make)
$ (cd icu4c && CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --enable-static \
&& make)
$ (cd openssl-upstream && git checkout OpenSSL_1_0_1e \
&& (for x in ../openssl/patches/*.patch; do patch -p1 < $x; done) \
&& CC="gcc -fPIC" ./config && make)
$ cd ../avian
$ make android=$(pwd)/../android test
Note that we use https://github.com/dicej/android-libcore64 above
instead of the upstream
https://android.googlesource.com/platform/libcore repository. This is
temporary until upstream has been patched with 64-bit support.
Also note that we use the upstream OpenSSL repository and apply the
Android patches to it. This is because it is not clear how to build
the Android fork of OpenSSL directly without checking out and building
the entire platform. As of this writing, the patches apply cleanly
against OpenSSL 1.0.1e, so that's the tag we check out, but this may
change in the future when the Android fork rebases against a new
OpenSSL version.
Installing
----------

75
android.pro Normal file
View File

@ -0,0 +1,75 @@
# these are referenced in JniConstants.cpp:
-keep class java.text.Bidi$Run
-keep class java.math.BigDecimal
-keep class java.lang.Boolean
-keep class java.lang.Byte
-keep class java.nio.charset.CharsetICU {
CharsetICU(java.lang.String, java.lang.String, java.lang.String[]);
}
-keep class java.lang.reflect.Constructor
-keep class java.util.zip.Deflater
-keep class java.lang.Double
-keep class libcore.io.ErrnoException
-keep class java.lang.reflect.Field
-keep class libcore.icu.NativeDecimalFormat$FieldPositionIterator {
void setData(int[]);
}
-keep class java.io.FileDescriptor
-keep class libcore.io.GaiException
-keep class java.net.Inet6Address
-keep class java.net.InetAddress
-keep class java.net.InetSocketAddress
-keep class java.util.zip.Inflater
-keep class java.lang.Integer
-keep class libcore.icu.LocaleData
-keep class java.lang.Long
-keep class java.lang.reflect.Method
-keep class libcore.util.MutableInt
-keep class libcore.util.MutableLong
-keep class java.text.ParsePosition
-keep class java.util.regex.PatternSyntaxException
-keep class java.lang.RealToString
-keep class java.net.Socket
-keep class java.net.SocketImpl
-keep class java.lang.String
-keep class libcore.io.StructAddrinfo
-keep class libcore.io.StructFlock
-keep class libcore.io.StructGroupReq
-keep class libcore.io.StructLinger
-keep class libcore.io.StructPasswd
-keep class libcore.io.StructPollfd
-keep class libcore.io.StructStat {
StructStat(long, long, int, long, int, int, long, long, long, long, long, long, long);
}
-keep class libcore.io.StructStatFs
-keep class libcore.io.StructTimeval
-keep class libcore.io.StructUtsname {
StructUtsname(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
}
# referenced from libcore native code
-keep class libcore.icu.LocaleData {
<fields>;
}
# called from the VM
-keep class java.lang.Thread {
Thread(java.lang.ThreadGroup, java.lang.String, int, boolean);
}
-keep class avian.Classes {
java.lang.Class forName(java.lang.String, boolean, java.lang.ClassLoader);
int findField(avian.VMClass, java.lang.String);
int findMethod(avian.VMClass, java.lang.String, java.lang.Class[]);
java.lang.annotation.Annotation getAnnotation(java.lang.ClassLoader, java.lang.Object[]);
}
-keep class java.lang.VMThread {
VMThread(java.lang.Thread);
}
# loaded reflectively to handle embedded resources:
-keep class avian.avianvmresource.Handler

View File

@ -16,6 +16,8 @@ import static avian.Stream.read2;
import java.lang.reflect.Modifier;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.lang.annotation.Annotation;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -262,6 +264,159 @@ public class Classes {
link(c, c.loader);
}
public static Class forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
{
if (loader == null) {
loader = Class.class.getClassLoader();
}
Class c = loader.loadClass(name);
VMClass vmc = SystemClassLoader.vmClass(c);
Classes.link(vmc, loader);
if (initialize) {
Classes.initialize(vmc);
}
return c;
}
public static Class forCanonicalName(String name) {
return forCanonicalName(null, name);
}
public static Class forCanonicalName(ClassLoader loader, String name) {
try {
if (name.startsWith("[")) {
return forName(name, true, loader);
} else if (name.startsWith("L")) {
return forName(name.substring(1, name.length() - 1), true, loader);
} else {
if (name.length() == 1) {
return SystemClassLoader.getClass
(Classes.primitiveClass(name.charAt(0)));
} else {
throw new ClassNotFoundException(name);
}
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private static int next(char c, String s, int start) {
for (int i = start; i < s.length(); ++i) {
if (s.charAt(i) == c) return i;
}
throw new RuntimeException();
}
public static Class[] getParameterTypes(VMMethod vmMethod) {
int count = vmMethod.parameterCount;
Class[] types = new Class[count];
int index = 0;
String spec = new String
(vmMethod.spec, 1, vmMethod.spec.length - 2);
try {
for (int i = 0; i < spec.length(); ++i) {
char c = spec.charAt(i);
if (c == ')') {
break;
} else if (c == 'L') {
int start = i + 1;
i = next(';', spec, start);
String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName(name, true, vmMethod.class_.loader);
} else if (c == '[') {
int start = i;
while (spec.charAt(i) == '[') ++i;
if (spec.charAt(i) == 'L') {
i = next(';', spec, i + 1);
String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName
(name, true, vmMethod.class_.loader);
} else {
String name = spec.substring(start, i + 1);
types[index++] = forCanonicalName(vmMethod.class_.loader, name);
}
} else {
String name = spec.substring(i, i + 1);
types[index++] = forCanonicalName(vmMethod.class_.loader, name);
}
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return types;
}
public static int findField(VMClass vmClass, String name) {
if (vmClass.fieldTable != null) {
Classes.link(vmClass);
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (toString(vmClass.fieldTable[i].name).equals(name)) {
return i;
}
}
}
return -1;
}
public static String toString(byte[] array) {
return new String(array, 0, array.length - 1);
}
public static boolean match(Class[] a, Class[] b) {
if (a.length == b.length) {
for (int i = 0; i < a.length; ++i) {
if (! a[i].isAssignableFrom(b[i])) {
return false;
}
}
return true;
} else {
return false;
}
}
public static int 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 < vmClass.methodTable.length; ++i) {
if (toString(vmClass.methodTable[i].name).equals(name)
&& match(parameterTypes,
getParameterTypes(vmClass.methodTable[i])))
{
return i;
}
}
}
return -1;
}
public static Annotation getAnnotation(ClassLoader loader, Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
(loader, new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a));
}
return (Annotation) a[0];
}
public static native Method makeMethod(Class c, int slot);
private static native void acquireClassLock();
private static native void releaseClassLock();

View File

@ -28,6 +28,8 @@ public class SystemClassLoader extends ClassLoader {
public static native Class getClass(VMClass vmClass);
public static native VMClass vmClass(Class jClass);
private native VMClass findLoadedVMClass(String name);
protected Class reallyFindLoadedClass(String name){
@ -35,6 +37,30 @@ public class SystemClassLoader extends ClassLoader {
return c == null ? null : getClass(c);
}
protected Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class c = findLoadedClass(name);
if (c == null) {
ClassLoader parent = getParent();
if (parent != null) {
try {
c = parent.loadClass(name);
} catch (ClassNotFoundException ok) { }
}
if (c == null) {
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
private native String resourceURLPrefix(String name);
protected URL findResource(String name) {

View File

@ -10,7 +10,7 @@
#include "stdlib.h"
#include "string.h"
#include "zlib-custom.h"
#include "avian/zlib-custom.h"
#include "jni.h"
#include "jni-util.h"

View File

@ -11,7 +11,7 @@
package java.lang;
public final class Boolean implements Comparable<Boolean> {
public static final Class TYPE = Class.forCanonicalName("Z");
public static final Class TYPE = avian.Classes.forCanonicalName("Z");
public static final Boolean FALSE = new Boolean(false);
public static final Boolean TRUE = new Boolean(true);

View File

@ -11,7 +11,7 @@
package java.lang;
public final class Byte extends Number implements Comparable<Byte> {
public static final Class TYPE = Class.forCanonicalName("B");
public static final Class TYPE = avian.Classes.forCanonicalName("B");
private final byte value;

View File

@ -14,7 +14,7 @@ public final class Character implements Comparable<Character> {
public static final int MIN_RADIX = 2;
public static final int MAX_RADIX = 36;
public static final Class TYPE = Class.forCanonicalName("C");
public static final Class TYPE = avian.Classes.forCanonicalName("C");
private final char value;

View File

@ -145,38 +145,7 @@ public final class Class <T> implements Type, AnnotatedElement {
ClassLoader loader)
throws ClassNotFoundException
{
if (loader == null) {
loader = Class.class.vmClass.loader;
}
Class c = loader.loadClass(name);
Classes.link(c.vmClass, loader);
if (initialize) {
Classes.initialize(c.vmClass);
}
return c;
}
public static Class forCanonicalName(String name) {
return forCanonicalName(null, name);
}
public static Class forCanonicalName(ClassLoader loader, String name) {
try {
if (name.startsWith("[")) {
return forName(name, true, loader);
} else if (name.startsWith("L")) {
return forName(name.substring(1, name.length() - 1), true, loader);
} else {
if (name.length() == 1) {
return SystemClassLoader.getClass
(Classes.primitiveClass(name.charAt(0)));
} else {
throw new ClassNotFoundException(name);
}
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return Classes.forName(name, initialize, loader);
}
public Class getComponentType() {
@ -211,84 +180,36 @@ public final class Class <T> implements Type, AnnotatedElement {
return Classes.isAssignableFrom(vmClass, c.vmClass);
}
private static Field findField(VMClass vmClass, String name) {
if (vmClass.fieldTable != null) {
Classes.link(vmClass);
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (Field.getName(vmClass.fieldTable[i]).equals(name)) {
return new Field(vmClass.fieldTable[i]);
}
}
}
return null;
}
public Field getDeclaredField(String name) throws NoSuchFieldException {
Field f = findField(vmClass, name);
if (f == null) {
int index = Classes.findField(vmClass, name);
if (index < 0) {
throw new NoSuchFieldException(name);
} else {
return f;
return new Field(vmClass.fieldTable[index]);
}
}
public Field getField(String name) throws NoSuchFieldException {
for (VMClass c = vmClass; c != null; c = c.super_) {
Field f = findField(c, name);
if (f != null) {
return f;
int index = Classes.findField(c, name);
if (index >= 0) {
return new Field(vmClass.fieldTable[index]);
}
}
throw new NoSuchFieldException(name);
}
private static boolean match(Class[] a, Class[] b) {
if (a.length == b.length) {
for (int i = 0; i < a.length; ++i) {
if (! a[i].isAssignableFrom(b[i])) {
return false;
}
}
return true;
} else {
return false;
}
}
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 < vmClass.methodTable.length; ++i) {
if (Method.getName(vmClass.methodTable[i]).equals(name)
&& match(parameterTypes,
Method.getParameterTypes(vmClass.methodTable[i])))
{
return new Method(vmClass.methodTable[i]);
}
}
}
return null;
}
public Method getDeclaredMethod(String name, Class ... parameterTypes)
throws NoSuchMethodException
{
if (name.startsWith("<")) {
throw new NoSuchMethodException(name);
}
Method m = findMethod(vmClass, name, parameterTypes);
if (m == null) {
int index = Classes.findMethod(vmClass, name, parameterTypes);
if (index < 0) {
throw new NoSuchMethodException(name);
} else {
return m;
return new Method(vmClass.methodTable[index]);
}
}
@ -299,9 +220,9 @@ public final class Class <T> implements Type, AnnotatedElement {
throw new NoSuchMethodException(name);
}
for (VMClass c = vmClass; c != null; c = c.super_) {
Method m = findMethod(c, name, parameterTypes);
if (m != null) {
return m;
int index = Classes.findMethod(c, name, parameterTypes);
if (index >= 0) {
return new Method(vmClass.methodTable[index]);
}
}
throw new NoSuchMethodException(name);
@ -310,11 +231,11 @@ public final class Class <T> implements Type, AnnotatedElement {
public Constructor getConstructor(Class ... parameterTypes)
throws NoSuchMethodException
{
Method m = findMethod(vmClass, "<init>", parameterTypes);
if (m == null) {
int index = Classes.findMethod(vmClass, "<init>", parameterTypes);
if (index < 0) {
throw new NoSuchMethodException();
} else {
return new Constructor(m);
return new Constructor(new Method(vmClass.methodTable[index]));
}
}
@ -325,7 +246,7 @@ public final class Class <T> implements Type, AnnotatedElement {
Constructor[] constructors = getDeclaredConstructors();
for (int i = 0; i < constructors.length; ++i) {
if (match(parameterTypes, constructors[i].getParameterTypes())) {
if (Classes.match(parameterTypes, constructors[i].getParameterTypes())) {
c = constructors[i];
}
}

View File

@ -11,7 +11,7 @@
package java.lang;
public final class Double extends Number {
public static final Class TYPE = Class.forCanonicalName("D");
public static final Class TYPE = avian.Classes.forCanonicalName("D");
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
public static final double POSITIVE_INFINITY = 1.0 / 0.0;

View File

@ -11,7 +11,7 @@
package java.lang;
public final class Float extends Number {
public static final Class TYPE = Class.forCanonicalName("F");
public static final Class TYPE = avian.Classes.forCanonicalName("F");
private static final int EXP_BIT_MASK = 0x7F800000;
private static final int SIGNIF_BIT_MASK = 0x007FFFFF;

View File

@ -11,7 +11,7 @@
package java.lang;
public final class Integer extends Number implements Comparable<Integer> {
public static final Class TYPE = Class.forCanonicalName("I");
public static final Class TYPE = avian.Classes.forCanonicalName("I");
public static final int MIN_VALUE = 0x80000000;
public static final int MAX_VALUE = 0x7FFFFFFF;

View File

@ -14,7 +14,7 @@ public final class Long extends Number implements Comparable<Long> {
public static final long MIN_VALUE = -9223372036854775808l;
public static final long MAX_VALUE = 9223372036854775807l;
public static final Class TYPE = Class.forCanonicalName("J");
public static final Class TYPE = avian.Classes.forCanonicalName("J");
private final long value;

View File

@ -11,7 +11,7 @@
package java.lang;
public final class Short extends Number implements Comparable<Short> {
public static final Class TYPE = Class.forCanonicalName("S");
public static final Class TYPE = avian.Classes.forCanonicalName("S");
public static final short MAX_VALUE = 32767;
private final short value;

View File

@ -127,6 +127,11 @@ public final class String
} else {
c = Utf8.decode((byte[])data, offset, length);
if(c instanceof char[]) length = ((char[])c).length;
if (c == null) {
throw new RuntimeException
("unable to parse \"" + new String(data, offset, length, false)
+ "\"");
}
}
this.data = c;

View File

@ -11,7 +11,7 @@
package java.lang;
public final class Void {
public static final Class TYPE = Class.forCanonicalName("V");
public static final Class TYPE = avian.Classes.forCanonicalName("V");
private Void() { }
}

View File

@ -61,7 +61,7 @@ public class Field<T> extends AccessibleObject {
}
public Class getType() {
return Class.forCanonicalName
return Classes.forCanonicalName
(vmField.class_.loader,
new String(vmField.spec, 0, vmField.spec.length - 1, false));
}

View File

@ -13,6 +13,7 @@ package java.lang.reflect;
import avian.VMMethod;
import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader;
import avian.Classes;
import java.lang.annotation.Annotation;
@ -58,61 +59,8 @@ public class Method<T> extends AccessibleObject implements Member {
return new String(vmMethod.spec, 0, vmMethod.spec.length - 1, false);
}
private static int next(char c, String s, int start) {
for (int i = start; i < s.length(); ++i) {
if (s.charAt(i) == c) return i;
}
throw new RuntimeException();
}
public Class[] getParameterTypes() {
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
(vmMethod.spec, 1, vmMethod.spec.length - 1, false);
try {
for (int i = 0; i < spec.length(); ++i) {
char c = spec.charAt(i);
if (c == ')') {
break;
} else if (c == 'L') {
int start = i + 1;
i = next(';', spec, start);
String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName(name, true, vmMethod.class_.loader);
} else if (c == '[') {
int start = i;
while (spec.charAt(i) == '[') ++i;
if (spec.charAt(i) == 'L') {
i = next(';', spec, i + 1);
String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName
(name, true, vmMethod.class_.loader);
} else {
String name = spec.substring(start, i + 1);
types[index++] = Class.forCanonicalName
(vmMethod.class_.loader, name);
}
} else {
String name = spec.substring(i, i + 1);
types[index++] = Class.forCanonicalName
(vmMethod.class_.loader, name);
}
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return types;
return Classes.getParameterTypes(vmMethod);
}
public Object invoke(Object instance, Object ... arguments)
@ -151,7 +99,7 @@ public class Method<T> extends AccessibleObject implements Member {
public Class getReturnType() {
for (int i = 0; i < vmMethod.spec.length - 1; ++i) {
if (vmMethod.spec[i] == ')') {
return Class.forCanonicalName
return Classes.forCanonicalName
(vmMethod.class_.loader,
new String
(vmMethod.spec, i + 1, vmMethod.spec.length - i - 2, false));
@ -160,22 +108,13 @@ public class Method<T> extends AccessibleObject implements Member {
throw new RuntimeException();
}
private Annotation getAnnotation(Object[] a) {
if (a[0] == null) {
a[0] = Proxy.newProxyInstance
(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 (vmMethod.hasAnnotations()) {
Object[] table = (Object[]) vmMethod.addendum.annotationTable;
for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i];
if (a[1] == class_) {
return (T) getAnnotation(a);
return (T) Classes.getAnnotation(vmMethod.class_.loader, a);
}
}
}
@ -187,7 +126,8 @@ public class Method<T> extends AccessibleObject implements Member {
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]);
array[i] = Classes.getAnnotation
(vmMethod.class_.loader, (Object[]) table[i]);
}
return array;
} else {

View File

@ -16,6 +16,9 @@ import static avian.Stream.write4;
import static avian.Stream.set4;
import static avian.Assembler.*;
import avian.SystemClassLoader;
import avian.Classes;
import avian.ConstantPool;
import avian.ConstantPool.PoolEntry;
@ -87,26 +90,15 @@ public class Proxy {
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, ConstantPool.addClass(pool, className) + 1);
write1(out, getfield);
write2(out, ConstantPool.addFieldRef
(pool, "java/lang/Class",
"vmClass", "Lavian/VMClass;") + 1);
write1(out, getfield);
write2(out, ConstantPool.addFieldRef
(pool, "avian/VMClass",
"methodTable", "[Lavian/VMMethod;") + 1);
write1(out, ldc_w);
write2(out, ConstantPool.addInteger(pool, index) + 1);
write1(out, aaload);
write1(out, invokespecial);
write1(out, invokestatic);
write2(out, ConstantPool.addMethodRef
(pool, "java/lang/reflect/Method",
"<init>", "(Lavian/VMMethod;)V") + 1);
(pool, "avian/Classes",
"makeMethod", "(Ljava/lang/Class;I)Ljava/lang/reflect/Method;")
+ 1);
write1(out, ldc_w);
write2(out, ConstantPool.addInteger(pool, parameterCount) + 1);
@ -363,10 +355,11 @@ public class Proxy {
Map<String,avian.VMMethod> virtualMap = new HashMap();
for (Class c: interfaces) {
avian.VMMethod[] ivtable = c.vmClass.virtualTable;
avian.VMMethod[] ivtable = SystemClassLoader.vmClass(c).virtualTable;
if (ivtable != null) {
for (avian.VMMethod m: ivtable) {
virtualMap.put(Method.getName(m) + Method.getSpec(m), m);
virtualMap.put
(Classes.toString(m.name) + Classes.toString(m.spec), m);
}
}
}
@ -376,15 +369,15 @@ public class Proxy {
for (avian.VMMethod m: virtualMap.values()) {
methodTable[i] = new MethodData
(0,
ConstantPool.addUtf8(pool, Method.getName(m)),
ConstantPool.addUtf8(pool, Method.getSpec(m)),
ConstantPool.addUtf8(pool, Classes.toString(m.name)),
ConstantPool.addUtf8(pool, Classes.toString(m.spec)),
makeInvokeCode(pool, name, m.spec, m.parameterCount,
m.parameterFootprint, i));
++ i;
}
methodTable[i++] = new MethodData
(0,
(Modifier.PUBLIC,
ConstantPool.addUtf8(pool, "<init>"),
ConstantPool.addUtf8
(pool, "(Ljava/lang/reflect/InvocationHandler;)V"),

View File

@ -1,5 +1,7 @@
package sun.misc;
import java.lang.reflect.Field;
public final class Unsafe {
private void Unsafe() { }
@ -50,10 +52,15 @@ public final class Unsafe {
public native int arrayBaseOffset(Class arrayClass);
public native long objectFieldOffset(Field field);
public native void copyMemory(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long count);
public native boolean compareAndSwapInt(Object o, long offset, int old,
int new_);
public void copyMemory(long src, long dst, long count) {
copyMemory(null, src, null, dst, count);
}

View File

@ -15,7 +15,7 @@
#include <avian/util/string.h>
#include "environment.h"
#include "avian/environment.h"
namespace avian {

View File

@ -11,7 +11,7 @@
#ifndef STREAM_H
#define STREAM_H
#include "common.h"
#include "avian/common.h"
namespace vm {

View File

@ -12,7 +12,7 @@
#define AVIAN_CODEGEN_ASSEMBLER_H
#include <avian/vm/system/system.h>
#include "zone.h"
#include "avian/zone.h"
#include <avian/vm/codegen/lir.h>
#include <avian/vm/codegen/promise.h>

View File

@ -12,7 +12,7 @@
#define AVIAN_CODEGEN_COMPILER_H
#include <avian/vm/system/system.h>
#include "zone.h"
#include "avian/zone.h"
#include "assembler.h"
namespace avian {

View File

@ -11,7 +11,7 @@
#ifndef AVIAN_CODEGEN_PROMISE_H
#define AVIAN_CODEGEN_PROMISE_H
#include "allocator.h"
#include "avian/allocator.h"
namespace avian {
namespace codegen {

View File

@ -11,7 +11,7 @@
#ifndef AVIAN_CODEGEN_REGISTERS_H
#define AVIAN_CODEGEN_REGISTERS_H
#include "common.h"
#include "avian/common.h"
namespace avian {
namespace codegen {

View File

@ -12,7 +12,7 @@
#define HEAP_H
#include <avian/vm/system/system.h>
#include "allocator.h"
#include "avian/allocator.h"
namespace vm {

View File

@ -11,8 +11,8 @@
#ifndef SYSTEM_H
#define SYSTEM_H
#include "common.h"
#include "allocator.h"
#include "avian/common.h"
#include "avian/allocator.h"
#include <avian/util/abort.h>
namespace vm {

119
makefile
View File

@ -148,6 +148,59 @@ ifneq ($(openjdk),)
build-javahome = $(openjdk)/jre
endif
ifneq ($(android),)
options := $(options)-android
classpath-jar-dep = $(build)/android.dep
luni-native = $(android)/libcore/luni/src/main/native
classpath-cflags = -DBOOT_JAVAHOME
android-cflags := -I$(luni-native) \
-I$(android)/libnativehelper/include/nativehelper \
-I$(android)/core/include \
-I$(android)/zlib \
-I$(android)/icu4c/i18n \
-I$(android)/icu4c/common \
-I$(android)/expat \
-I$(android)/openssl/include \
-I$(android)/libcore/include \
-I$(build)/android-src/external/fdlibm \
-I$(build)/android-src \
-fno-exceptions \
-DHAVE_SYS_UIO_H \
-D_FILE_OFFSET_BITS=64 \
-g3 \
-Werror \
-fPIC \
-fvisibility=hidden
classpath-lflags := \
$(android)/icu4c/lib/libicui18n.a \
$(android)/icu4c/lib/libicuuc.a \
$(android)/icu4c/lib/libicudata.a \
$(android)/fdlibm/libfdm.a \
$(android)/expat/.libs/libexpat.a \
$(android)/openssl-upstream/libssl.a \
$(android)/openssl-upstream/libcrypto.a \
-lstdc++
luni-cpps := $(shell find $(luni-native) -name '*.cpp')
classpath-objects = \
$(call cpp-objects,$(luni-cpps),$(luni-native),$(build))
luni-java = $(android)/libcore/luni/src/main/java
luni-javas := $(shell find $(luni-java) -name '*.java')
dalvik-java = $(android)/libcore/dalvik/src/main/java
dalvik-javas := $(shell find $(dalvik-java) -name '*.java')
xml-java = $(android)/libcore/xml/src/main/java
xml-javas := $(shell find $(xml-java) -name '*.java')
android-classes = \
$(call java-classes,$(luni-javas),$(luni-java),$(build)/android) \
$(call java-classes,$(dalvik-javas),$(dalvik-java),$(build)/android) \
$(call java-classes,$(xml-javas),$(xml-java),$(build)/android)
classpath = android
javahome-files = tzdata
javahome-object = $(build)/javahome-jar.o
boot-javahome-object = $(build)/boot-javahome.o
build-javahome = $(android)/bionic/libc/zoneinfo
endif
ifeq ($(classpath),avian)
jni-sources := $(shell find $(classpath-src) -name '*.cpp')
jni-objects = $(call cpp-objects,$(jni-sources),$(classpath-src),$(build))
@ -214,7 +267,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
target-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
common-cflags = $(warnings) -fno-rtti -fno-exceptions -I$(classpath-src) \
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) -Iinclude $(classpath-cflags) \
"-I$(JAVA_HOME)/include" -I$(src) -I$(build) -Iinclude $(classpath-cflags) \
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
-DAVIAN_INFO="\"$(info)\"" \
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
@ -244,7 +297,7 @@ common-lflags = -lm -lz $(classpath-lflags)
build-lflags = -lz -lpthread -ldl
lflags = $(common-lflags) -lpthread -ldl
lflags = $(common-lflags) $(classpath-lflags) -lpthread -ldl
soname-flag = -Wl,-soname -Wl,$(so-prefix)jvm$(so-suffix)
version-script-flag = -Wl,--version-script=openjdk.ld
@ -514,7 +567,8 @@ ifeq ($(platform),darwin)
ifeq ($(arch),arm)
ios-version := \
$(shell if test -d $(sdk-dir)/iPhoneOS6.0.sdk; then echo 6.0; \
$(shell if test -d $(sdk-dir)/iPhoneOS6.1.sdk; then echo 6.1; \
elif test -d $(sdk-dir)/iPhoneOS6.0.sdk; then echo 6.0; \
elif test -d $(sdk-dir)/iPhoneOS5.1.sdk; then echo 5.1; \
elif test -d $(sdk-dir)/iPhoneOS5.0.sdk; then echo 5.0; \
elif test -d $(sdk-dir)/iPhoneOS4.3.sdk; then echo 4.3; \
@ -940,9 +994,6 @@ generated-code = \
$(build)/type-maps.cpp
vm-depends := $(generated-code) \
$(wildcard $(src)/*.h) \
$(wildcard $(src)/codegen/*.h) \
$(wildcard $(src)/codegen/compiler/*.h) \
$(shell find src include -name '*.h' -or -name '*.inc.cpp')
vm-sources = \
@ -1171,6 +1222,7 @@ ifneq ($(classpath),avian)
# them to synthesize a class:
classpath-sources := \
$(classpath-src)/avian/Addendum.java \
$(classpath-src)/avian/AnnotationInvocationHandler.java \
$(classpath-src)/avian/Assembler.java \
$(classpath-src)/avian/Callback.java \
$(classpath-src)/avian/CallbackReceiver.java \
@ -1193,6 +1245,15 @@ ifneq ($(classpath),avian)
ifneq ($(openjdk),)
classpath-sources := $(classpath-sources) \
$(classpath-src)/avian/OpenJDK.java
else
classpath-sources := $(classpath-sources) \
$(classpath-src)/sun/reflect/ConstantPool.java \
$(classpath-src)/java/lang/ReflectiveOperationException.java \
$(classpath-src)/java/net/ProtocolFamily.java \
$(classpath-src)/java/net/StandardProtocolFamily.java \
$(classpath-src)/sun/misc/Cleaner.java \
$(classpath-src)/sun/misc/Unsafe.java \
$(classpath-src)/java/lang/reflect/Proxy.java
endif
else
classpath-sources := $(shell find $(classpath-src) -name '*.java')
@ -1354,7 +1415,7 @@ endif
$(build)/run-tests.sh: $(test-classes) makefile
echo 'cd $$(dirname $$0)' > $(@)
echo "sh ./test.sh 2>/dev/null \\" >> $(@)
echo "$(shell echo $(library-path) | sed 's|$(build)|\.|g') ./$(name)-unittest${exe-suffix} ./$(name)${exe-suffix} $(mode) \"-Djava.library.path=$$(pwd) -cp test\" \\" >> $(@)
echo "$(shell echo $(library-path) | sed 's|$(build)|\.|g') ./$(name)-unittest${exe-suffix} ./$(notdir $(test-executable)) $(mode) \"-Djava.library.path=. -cp test\" \\" >> $(@)
echo "$(call class-names,$(test-build),$(filter-out $(test-support-classes), $(test-classes))) \\" >> $(@)
echo "$(continuation-tests) $(tail-tests)" >> $(@)
@ -1370,14 +1431,45 @@ $(generated-code): %.cpp: $(src)/types.def $(generator) $(classpath-dep)
$(classpath-build)/%.class: $(classpath-src)/%.java
@echo $(<)
$(classpath-dep): $(classpath-sources)
$(classpath-dep): $(classpath-sources) $(classpath-jar-dep)
@echo "compiling classpath classes"
@mkdir -p $(classpath-build)
$(javac) -d $(classpath-build) -bootclasspath $(boot-classpath) \
$(shell $(MAKE) -s --no-print-directory build=$(build) \
$(classpath-classes))
classes="$(shell $(MAKE) -s --no-print-directory build=$(build) \
$(classpath-classes))"; if [ -n "$${classes}" ]; then \
$(javac) -d $(classpath-build) -bootclasspath $(boot-classpath) \
$${classes}; fi
@touch $(@)
$(build)/android-src/%.cpp: $(luni-native)/%.cpp
if [ "$(luni-native)/libcore_icu_ICU.cpp" = "$(<)" ]; then \
sed 's/register_libcore_icu_ICU/hide_register_libcore_icu_ICU/' \
< $(<) > $(@).tmp && cat $(@).tmp $(src)/android/icu.cpp > $(@); else \
cp $(<) $(@); fi
$(build)/%.o: $(build)/android-src/%.cpp $(build)/android.dep
@echo "compiling $(@)"
@mkdir -p $(dir $(@))
$(cxx) $(android-cflags) -c $$($(windows-path) $(<)) $(call output,$(@))
$(build)/android.dep: $(luni-javas) $(dalvik-javas) $(xml-javas)
@echo "compiling luni classes"
@mkdir -p $(classpath-build)
@mkdir -p $(build)/android
@mkdir -p $(build)/android-src/external/fdlibm
@mkdir -p $(build)/android-src/libexpat
cp $(android)/fdlibm/fdlibm.h $(build)/android-src/external/fdlibm/
cp $(android)/expat/lib/expat.h $(build)/android-src/libexpat/
cp -a $(luni-java)/* $(dalvik-java)/* $(xml-java)/* $(build)/android-src/
sed -i 's/return ordinal - o.ordinal;/return ordinal - o.ordinal();/' \
$(build)/android-src/java/lang/Enum.java
find $(build)/android-src -name '*.java' > $(build)/android.txt
$(javac) -Xmaxerrs 1000 -d $(build)/android -sourcepath $(luni-java) \
@$(build)/android.txt
rm $(build)/android/sun/misc/Unsafe* \
$(build)/android/java/lang/reflect/Proxy*
cp -r $(build)/android/* $(classpath-build)
@touch $(@)
$(test-build)/%.class: $(test)/%.java
@echo $(<)
@ -1596,7 +1688,7 @@ else
endif
$(bootimage-object) $(codeimage-object): $(bootimage-generator) \
$(openjdk-jar-dep)
$(classpath-jar-dep)
@echo "generating bootimage and codeimage binaries from $(classpath-build) using $(<)"
$(<) -cp $(classpath-build) -bootimage $(bootimage-object) -codeimage $(codeimage-object) \
-bootimage-symbols $(bootimage-symbols) \
@ -1606,7 +1698,8 @@ executable-objects = $(vm-objects) $(classpath-objects) $(driver-object) \
$(vm-heapwalk-objects) $(boot-object) $(vm-classpath-objects) \
$(javahome-object) $(boot-javahome-object) $(lzma-decode-objects)
unittest-executable-objects = $(unittest-objects) $(vm-objects) $(build)/util/arg-parser.o
unittest-executable-objects = $(unittest-objects) $(vm-objects) \
$(classpath-objects) $(build)/util/arg-parser.o
ifeq ($(process),interpret)
unittest-executable-objects += $(all-codegen-target-objects)

View File

@ -332,7 +332,8 @@ else
$(src)/openjdk/my_java_props_macosx.c
else
openjdk-sources += \
$(openjdk-src)/solaris/native/java/lang/java_props_macosx.c
$(openjdk-src)/solaris/native/java/lang/java_props_macosx.c \
$(openjdk-src)/macosx/native/sun/nio/ch/KQueueArrayWrapper.c
endif
openjdk-cflags += \

View File

@ -136,6 +136,7 @@
public InetSocketAddress(java.net.InetAddress, int);
}
-keep class java.net.ServerSocket
-keep class java.net.SocketTimeoutException
-keepclassmembers class java.net.PlainSocketImpl {
<fields>;

12
src/android/icu.cpp Normal file
View File

@ -0,0 +1,12 @@
void
register_libcore_icu_ICU(JNIEnv* e)
{
UErrorCode status = U_ZERO_ERROR;
udata_setFileAccess(UDATA_NO_FILES, &status);
if (status != U_ZERO_ERROR) abort();
u_init(&status);
if (status != U_ZERO_ERROR) abort();
jniRegisterNativeMethods(e, "libcore/icu/ICU", gMethods, NELEM(gMethods));
}

View File

@ -9,7 +9,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "types.h"
#include "avian/types.h"
.text

View File

@ -12,7 +12,7 @@
#define VECTOR_H
#include <avian/vm/system/system.h>
#include "target.h"
#include "avian/target.h"
#include <avian/util/math.h>

View File

@ -11,7 +11,7 @@
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include "common.h"
#include "avian/common.h"
namespace vm {

View File

@ -19,7 +19,7 @@
# undef interface
#endif
#include "common.h"
#include "avian/common.h"
extern "C" void NO_RETURN
vmJump(void* address, void* frame, void* stack, void* thread,

View File

@ -11,8 +11,8 @@
#ifndef ARM_H
#define ARM_H
#include "types.h"
#include "common.h"
#include "avian/types.h"
#include "avian/common.h"
#include <avian/util/runtime-array.h>
#ifdef __APPLE__

View File

@ -11,10 +11,10 @@
#ifndef BOOTIMAGE_H
#define BOOTIMAGE_H
#include "common.h"
#include "avian/common.h"
#include "java-common.h"
#include "target.h"
#include "machine.h"
#include "avian/target.h"
#include "avian/machine.h"
#include <avian/util/math.h>

View File

@ -0,0 +1,660 @@
/* Copyright (c) 2010-2012, 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. */
#ifndef CLASSPATH_COMMON_H
#define CLASSPATH_COMMON_H
#include <avian/util/string.h>
#include <avian/util/runtime-array.h>
using namespace avian::util;
namespace vm {
object
getTrace(Thread* t, unsigned skipCount)
{
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, type(t, 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 = makeObjectArray(t, 0);
return v.trace;
}
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
arrayCopy(Thread* t, object src, int32_t srcOffset, object dst,
int32_t dstOffset, int32_t length)
{
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 = fieldAtOffset<uintptr_t>(src, BytesPerWord);
intptr_t dl = fieldAtOffset<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 = &fieldAtOffset<uint8_t>(src, ArrayBody);
uint8_t* dbody = &fieldAtOffset<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 {
throwNew(t, Machine::IndexOutOfBoundsExceptionType);
}
} else {
return;
}
}
}
} else {
throwNew(t, Machine::NullPointerExceptionType);
return;
}
throwNew(t, Machine::ArrayStoreExceptionType);
}
void
runOnLoadIfFound(Thread* t, System::Library* library)
{
void* p = library->resolve("JNI_OnLoad");
#ifdef PLATFORM_WINDOWS
if (p == 0) {
p = library->resolve("_JNI_OnLoad@8");
if (p == 0) {
p = library->resolve("JNI_OnLoad@8");
}
}
#endif
if (p) {
jint (JNICALL * JNI_OnLoad)(Machine*, void*);
memcpy(&JNI_OnLoad, &p, sizeof(void*));
JNI_OnLoad(t->m, 0);
}
}
System::Library*
loadLibrary(Thread* t, const char* name)
{
ACQUIRE(t, t->m->classLock);
System::Library* last = t->m->libraries;
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
if (lib->name() and ::strcmp(lib->name(), name) == 0) {
// already loaded
return lib;
}
last = lib;
}
System::Library* lib;
if (t->m->system->success(t->m->system->load(&lib, name))) {
last->setNext(lib);
return lib;
} else {
return 0;
}
}
System::Library*
loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
bool runOnLoad, bool throw_ = true)
{
ACQUIRE(t, t->m->classLock);
char* mappedName;
unsigned nameLength = strlen(name);
if (mapName) {
const char* builtins = findProperty(t, "avian.builtins");
if (builtins) {
const char* s = builtins;
while (*s) {
if (::strncmp(s, name, nameLength) == 0
and (s[nameLength] == ',' or s[nameLength] == 0))
{
// library is built in to this executable
if (runOnLoad and not t->m->triedBuiltinOnLoad) {
t->m->triedBuiltinOnLoad = true;
// todo: release the classLock before calling this to
// avoid the possibility of deadlock:
runOnLoadIfFound(t, t->m->libraries);
}
return t->m->libraries;
} else {
while (*s and *s != ',') ++ s;
if (*s) ++ s;
}
}
}
const char* prefix = t->m->system->libraryPrefix();
const char* suffix = t->m->system->librarySuffix();
unsigned mappedNameLength = nameLength + strlen(prefix) + strlen(suffix);
mappedName = static_cast<char*>
(t->m->heap->allocate(mappedNameLength + 1));
snprintf(mappedName, mappedNameLength + 1, "%s%s%s", prefix, name, suffix);
name = mappedName;
nameLength = mappedNameLength;
} else {
mappedName = 0;
}
THREAD_RESOURCE2
(t, char*, mappedName, unsigned, nameLength, if (mappedName) {
t->m->heap->free(mappedName, nameLength + 1);
});
System::Library* lib = 0;
for (Tokenizer tokenizer(path, t->m->system->pathSeparator());
tokenizer.hasMore();)
{
String token(tokenizer.next());
unsigned fullNameLength = token.length + 1 + nameLength;
THREAD_RUNTIME_ARRAY(t, char, fullName, fullNameLength + 1);
snprintf(RUNTIME_ARRAY_BODY(fullName), fullNameLength + 1,
"%.*s/%s", token.length, token.text, name);
lib = loadLibrary(t, RUNTIME_ARRAY_BODY(fullName));
if (lib) break;
}
if (lib == 0) {
lib = loadLibrary(t, name);
}
if (lib) {
if (runOnLoad) {
runOnLoadIfFound(t, lib);
}
} else if (throw_) {
throwNew(t, Machine::UnsatisfiedLinkErrorType, "library not found: %s",
name);
}
return lib;
}
object
clone(Thread* t, object o)
{
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 clone;
}
object
makeStackTraceElement(Thread* t, object e)
{
PROTECT(t, e);
object class_ = className(t, methodClass(t, traceElementMethod(t, e)));
PROTECT(t, class_);
THREAD_RUNTIME_ARRAY(t, char, s, byteArrayLength(t, class_));
replace('/', '.', RUNTIME_ARRAY_BODY(s),
reinterpret_cast<char*>(&byteArrayBody(t, class_, 0)));
class_ = makeString(t, "%s", RUNTIME_ARRAY_BODY(s));
object method = methodName(t, traceElementMethod(t, e));
PROTECT(t, method);
method = t->m->classpath->makeString
(t, method, 0, byteArrayLength(t, method) - 1);
unsigned line = t->m->processor->lineNumber
(t, traceElementMethod(t, e), traceElementIp(t, e));
object file = classSourceFile(t, methodClass(t, traceElementMethod(t, e)));
file = file ? t->m->classpath->makeString
(t, file, 0, byteArrayLength(t, file) - 1) : 0;
return makeStackTraceElement(t, class_, method, file, line);
}
object
translateInvokeResult(Thread* t, unsigned returnCode, object o)
{
switch (returnCode) {
case ByteField:
return makeByte(t, intValue(t, o));
case BooleanField:
return makeBoolean(t, intValue(t, o) != 0);
case CharField:
return makeChar(t, intValue(t, o));
case ShortField:
return makeShort(t, intValue(t, o));
case FloatField:
return makeFloat(t, intValue(t, o));
case IntField:
case LongField:
case ObjectField:
case VoidField:
return o;
case DoubleField:
return makeDouble(t, longValue(t, o));
default:
abort(t);
}
}
object
resolveClassBySpec(Thread* t, object loader, const char* spec,
unsigned specLength)
{
switch (*spec) {
case 'L': {
THREAD_RUNTIME_ARRAY(t, char, s, specLength - 1);
memcpy(RUNTIME_ARRAY_BODY(s), spec + 1, specLength - 2);
RUNTIME_ARRAY_BODY(s)[specLength - 2] = 0;
return resolveClass(t, loader, RUNTIME_ARRAY_BODY(s));
}
case '[': {
THREAD_RUNTIME_ARRAY(t, char, s, specLength + 1);
memcpy(RUNTIME_ARRAY_BODY(s), spec, specLength);
RUNTIME_ARRAY_BODY(s)[specLength] = 0;
return resolveClass(t, loader, RUNTIME_ARRAY_BODY(s));
}
default:
return primitiveClass(t, *spec);
}
}
object
resolveJType(Thread* t, object loader, const char* spec, unsigned specLength)
{
return getJClass(t, resolveClassBySpec(t, loader, spec, specLength));
}
object
resolveParameterTypes(Thread* t, object loader, object spec,
unsigned* parameterCount, unsigned* returnTypeSpec)
{
PROTECT(t, loader);
PROTECT(t, spec);
object list = 0;
PROTECT(t, list);
unsigned offset = 1;
unsigned count = 0;
while (byteArrayBody(t, spec, offset) != ')') {
switch (byteArrayBody(t, spec, offset)) {
case 'L': {
unsigned start = offset;
++ offset;
while (byteArrayBody(t, spec, offset) != ';') ++ offset;
++ offset;
object type = resolveClassBySpec
(t, loader, reinterpret_cast<char*>(&byteArrayBody(t, spec, start)),
offset - start);
list = makePair(t, type, list);
++ count;
} break;
case '[': {
unsigned start = offset;
while (byteArrayBody(t, spec, offset) == '[') ++ offset;
switch (byteArrayBody(t, spec, offset)) {
case 'L':
++ offset;
while (byteArrayBody(t, spec, offset) != ';') ++ offset;
++ offset;
break;
default:
++ offset;
break;
}
object type = resolveClassBySpec
(t, loader, reinterpret_cast<char*>(&byteArrayBody(t, spec, start)),
offset - start);
list = makePair(t, type, list);
++ count;
} break;
default:
list = makePair
(t, primitiveClass(t, byteArrayBody(t, spec, offset)), list);
++ offset;
++ count;
break;
}
}
*parameterCount = count;
*returnTypeSpec = offset + 1;
return list;
}
object
resolveParameterJTypes(Thread* t, object loader, object spec,
unsigned* parameterCount, unsigned* returnTypeSpec)
{
object list = resolveParameterTypes
(t, loader, spec, parameterCount, returnTypeSpec);
PROTECT(t, list);
object array = makeObjectArray
(t, type(t, Machine::JclassType), *parameterCount);
PROTECT(t, array);
for (int i = *parameterCount - 1; i >= 0; --i) {
object c = getJClass(t, pairFirst(t, list));
set(t, array, ArrayBody + (i * BytesPerWord), c);
list = pairSecond(t, list);
}
return array;
}
object
resolveExceptionJTypes(Thread* t, object loader, object addendum)
{
if (addendum == 0 or methodAddendumExceptionTable(t, addendum) == 0) {
return makeObjectArray(t, type(t, Machine::JclassType), 0);
}
PROTECT(t, loader);
PROTECT(t, addendum);
object array = makeObjectArray
(t, type(t, Machine::JclassType),
shortArrayLength(t, methodAddendumExceptionTable(t, addendum)));
PROTECT(t, array);
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, loader, referenceName(t, o));
set(t, addendumPool(t, addendum), SingletonBody + (index * BytesPerWord),
o);
}
o = getJClass(t, o);
set(t, array, ArrayBody + (i * BytesPerWord), o);
}
return array;
}
object
invoke(Thread* t, object method, object instance, object args)
{
PROTECT(t, method);
PROTECT(t, instance);
PROTECT(t, args);
if (methodFlags(t, method) & ACC_STATIC) {
instance = 0;
}
if ((args == 0 ? 0 : objectArrayLength(t, args))
!= methodParameterCount(t, method))
{
throwNew(t, Machine::IllegalArgumentExceptionType);
}
if (methodParameterCount(t, method)) {
PROTECT(t, method);
unsigned specLength = byteArrayLength(t, methodSpec(t, method));
THREAD_RUNTIME_ARRAY(t, char, spec, specLength);
memcpy(RUNTIME_ARRAY_BODY(spec),
&byteArrayBody(t, methodSpec(t, method), 0), specLength);
unsigned i = 0;
for (MethodSpecIterator it(t, RUNTIME_ARRAY_BODY(spec)); it.hasNext();) {
object type;
bool objectType = false;
const char* p = it.next();
switch (*p) {
case 'Z': type = vm::type(t, Machine::BooleanType); break;
case 'B': type = vm::type(t, Machine::ByteType); break;
case 'S': type = vm::type(t, Machine::ShortType); break;
case 'C': type = vm::type(t, Machine::CharType); break;
case 'I': type = vm::type(t, Machine::IntType); break;
case 'F': type = vm::type(t, Machine::FloatType); break;
case 'J': type = vm::type(t, Machine::LongType); break;
case 'D': type = vm::type(t, Machine::DoubleType); break;
case 'L': ++ p;
case '[': {
objectType = true;
unsigned nameLength = it.s - p;
THREAD_RUNTIME_ARRAY(t, char, name, nameLength);
memcpy(RUNTIME_ARRAY_BODY(name), p, nameLength - 1);
RUNTIME_ARRAY_BODY(name)[nameLength - 1] = 0;
type = resolveClass
(t, classLoader(t, methodClass(t, method)),
RUNTIME_ARRAY_BODY(name));
} break;
default:
abort();
}
object arg = objectArrayBody(t, args, i++);
if ((arg == 0 and (not objectType))
or (arg and (not instanceOf(t, type, arg))))
{
// fprintf(stderr, "%s is not a %s\n", arg ? &byteArrayBody(t, className(t, objectClass(t, arg)), 0) : reinterpret_cast<const int8_t*>("<null>"), &byteArrayBody(t, className(t, type), 0));
throwNew(t, Machine::IllegalArgumentExceptionType);
}
}
}
unsigned returnCode = methodReturnCode(t, method);
THREAD_RESOURCE0(t, {
if (t->exception) {
object exception = t->exception;
t->exception = makeThrowable
(t, Machine::InvocationTargetExceptionType, 0, 0, exception);
}
});
object result;
if (args) {
result = t->m->processor->invokeArray(t, method, instance, args);
} else {
result = t->m->processor->invoke(t, method, instance);
}
return translateInvokeResult(t, returnCode, result);
}
// only safe to call during bootstrap when there's only one thread
// running:
void
intercept(Thread* t, object c, const char* name, const char* spec,
void* function)
{
object m = findMethodOrNull(t, c, name, spec);
if (m) {
PROTECT(t, m);
object clone = methodClone(t, m);
// make clone private to prevent vtable updates at compilation
// time. Otherwise, our interception might be bypassed by calls
// through the vtable.
methodFlags(t, clone) |= ACC_PRIVATE;
methodFlags(t, m) |= ACC_NATIVE;
object native = makeNativeIntercept(t, function, true, clone);
PROTECT(t, native);
object runtimeData = getMethodRuntimeData(t, m);
set(t, runtimeData, MethodRuntimeDataNative, native);
} else {
// If we can't find the method, just ignore it, since ProGuard may
// have stripped it out as unused. Otherwise, the code below can
// be uncommented for debugging purposes.
// fprintf(stderr, "unable to find %s%s in %s\n",
// name, spec, &byteArrayBody(t, className(t, c), 0));
// abort(t);
}
}
Finder*
getFinder(Thread* t, const char* name, unsigned nameLength)
{
ACQUIRE(t, t->m->referenceLock);
for (object p = root(t, Machine::VirtualFileFinders);
p; p = finderNext(t, p))
{
if (byteArrayLength(t, finderName(t, p)) == nameLength
and strncmp(reinterpret_cast<const char*>
(&byteArrayBody(t, finderName(t, p), 0)),
name, nameLength))
{
return static_cast<Finder*>(finderFinder(t, p));
}
}
object n = makeByteArray(t, nameLength + 1);
memcpy(&byteArrayBody(t, n, 0), name, nameLength);
void* p = t->m->libraries->resolve
(reinterpret_cast<const char*>(&byteArrayBody(t, n, 0)));
if (p) {
uint8_t* (*function)(unsigned*);
memcpy(&function, &p, BytesPerWord);
unsigned size;
uint8_t* data = function(&size);
if (data) {
Finder* f = makeFinder(t->m->system, t->m->heap, data, size);
object finder = makeFinder
(t, f, n, root(t, Machine::VirtualFileFinders));
setRoot(t, Machine::VirtualFileFinders, finder);
return f;
}
}
return 0;
}
} // namespace vm
#endif//CLASSPATH_COMMON_H

View File

@ -20,7 +20,7 @@
#include "stddef.h"
#include "string.h"
#include "stdio.h"
#include "types.h"
#include "avian/types.h"
#include "math.h"
#ifdef _MSC_VER

View File

@ -11,9 +11,9 @@
#ifndef FINDER_H
#define FINDER_H
#include "common.h"
#include "avian/common.h"
#include <avian/vm/system/system.h>
#include "allocator.h"
#include "avian/allocator.h"
namespace vm {

View File

@ -11,7 +11,7 @@
#ifndef HEAPWALK_H
#define HEAPWALK_H
#include "common.h"
#include "avian/common.h"
#include "java-common.h"
namespace vm {

View File

@ -11,7 +11,7 @@
#ifndef JNIENV_H
#define JNIENV_H
#include "machine.h"
#include "avian/machine.h"
#define BOOTSTRAP_PROPERTY "avian.bootstrap"
#define CRASHDIR_PROPERTY "avian.crash.dir"

View File

@ -11,10 +11,10 @@
#ifndef LZMA_UTIL_H
#define LZMA_UTIL_H
#include "lzma.h"
#include "avian/lzma.h"
#include "C/Types.h"
#include <avian/vm/system/system.h>
#include "allocator.h"
#include "avian/allocator.h"
namespace vm {

View File

@ -12,7 +12,7 @@
#define LZMA_H
#include <avian/vm/system/system.h>
#include "allocator.h"
#include "avian/allocator.h"
namespace vm {

View File

@ -11,14 +11,14 @@
#ifndef MACHINE_H
#define MACHINE_H
#include "common.h"
#include "avian/common.h"
#include "java-common.h"
#include <avian/vm/system/system.h>
#include <avian/vm/heap/heap.h>
#include "finder.h"
#include "processor.h"
#include "constants.h"
#include "arch.h"
#include "avian/finder.h"
#include "avian/processor.h"
#include "avian/constants.h"
#include "avian/arch.h"
using namespace avian::util;
@ -1230,10 +1230,11 @@ class Machine {
OutOfMemoryError,
Shutdown,
VirtualFileFinders,
VirtualFiles
VirtualFiles,
ArrayInterfaceTable
};
static const unsigned RootCount = VirtualFiles + 1;
static const unsigned RootCount = ArrayInterfaceTable + 1;
Machine(System* system, Heap* heap, Finder* bootFinder, Finder* appFinder,
Processor* processor, Classpath* classpath, const char** properties,
@ -1563,6 +1564,9 @@ class Classpath {
virtual void
resolveNative(Thread* t, object method) = 0;
virtual void
preBoot(Thread* t) = 0;
virtual void
boot(Thread* t) = 0;
@ -1572,6 +1576,15 @@ class Classpath {
virtual void
updatePackageMap(Thread* t, object class_) = 0;
virtual object
makeDirectByteBuffer(Thread* t, void* p, jlong capacity) = 0;
virtual void*
getDirectBufferAddress(Thread* t, object buffer) = 0;
virtual int64_t
getDirectBufferCapacity(Thread* t, object buffer) = 0;
virtual void
dispose() = 0;
};
@ -1972,6 +1985,7 @@ addThread(Thread* t, Thread* p)
ACQUIRE_RAW(t, t->m->stateLock);
assert(t, p->state == Thread::NoState);
expect(t, t->state == Thread::ActiveState || t->state == Thread::ExclusiveState);
p->state = Thread::IdleState;
++ t->m->threadCount;

View File

@ -11,8 +11,8 @@
#ifndef POWERPC_H
#define POWERPC_H
#include "types.h"
#include "common.h"
#include "avian/types.h"
#include "avian/common.h"
#ifdef __APPLE__
# include "mach/mach_types.h"

View File

@ -11,10 +11,10 @@
#ifndef PROCESS_H
#define PROCESS_H
#include "common.h"
#include "avian/common.h"
#include <avian/vm/system/system.h>
#include "machine.h"
#include "constants.h"
#include "avian/machine.h"
#include "avian/constants.h"
namespace vm {

View File

@ -11,12 +11,12 @@
#ifndef PROCESSOR_H
#define PROCESSOR_H
#include "common.h"
#include "avian/common.h"
#include <avian/vm/system/system.h>
#include <avian/vm/heap/heap.h>
#include "bootimage.h"
#include "heapwalk.h"
#include "zone.h"
#include "avian/heapwalk.h"
#include "avian/zone.h"
namespace avian {
namespace codegen {

View File

@ -11,8 +11,8 @@
#ifndef TARGET_H
#define TARGET_H
#include "target-fields.h"
#include "common.h"
#include "avian/target-fields.h"
#include "avian/common.h"
namespace vm {
@ -23,11 +23,9 @@ targetV1(T v)
return v;
}
#ifdef TARGET_OPPOSITE_ENDIAN
template <class T>
inline T
targetV2(T v)
swapV2(T v)
{
return (((v >> 8) & 0xFF) |
((v << 8)));
@ -35,7 +33,7 @@ targetV2(T v)
template <class T>
inline T
targetV4(T v)
swapV4(T v)
{
return (((v >> 24) & 0x000000FF) |
((v >> 8) & 0x0000FF00) |
@ -45,7 +43,7 @@ targetV4(T v)
template <class T>
inline T
targetV8(T v)
swapV8(T v)
{
return (((static_cast<uint64_t>(v) >> 56) & UINT64_C(0x00000000000000FF)) |
((static_cast<uint64_t>(v) >> 40) & UINT64_C(0x000000000000FF00)) |
@ -57,6 +55,29 @@ targetV8(T v)
((static_cast<uint64_t>(v) << 56)));
}
#ifdef TARGET_OPPOSITE_ENDIAN
template <class T>
inline T
targetV2(T v)
{
return swapV2(v);
}
template <class T>
inline T
targetV4(T v)
{
return swapV4(v);
}
template <class T>
inline T
targetV8(T v)
{
return swapV8(v);
}
#else
template <class T>
inline T

View File

@ -11,8 +11,8 @@
#ifndef UTIL_H
#define UTIL_H
#include "machine.h"
#include "zone.h"
#include "avian/machine.h"
#include "avian/zone.h"
namespace vm {

View File

@ -11,8 +11,8 @@
#ifndef X86_H
#define X86_H
#include "types.h"
#include "common.h"
#include "avian/types.h"
#include "avian/common.h"
#ifdef _MSC_VER
# include "windows.h"

View File

@ -12,7 +12,7 @@
#define ZONE_H
#include <avian/vm/system/system.h>
#include "allocator.h"
#include "avian/allocator.h"
#include <avian/util/math.h>

View File

@ -8,10 +8,10 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "machine.h"
#include "constants.h"
#include "processor.h"
#include "util.h"
#include "avian/machine.h"
#include "avian/constants.h"
#include "avian/processor.h"
#include "avian/util.h"
#include <avian/util/runtime-array.h>
@ -50,6 +50,15 @@ resolveSystemClassThrow(Thread* t, object loader, object spec)
} // namespace
extern "C" JNIEXPORT void JNICALL
Avian_avian_Classes_initialize
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
initClass(t, this_);
}
extern "C" JNIEXPORT void JNICALL
Avian_avian_Classes_acquireClassLock
(Thread* t, object, uintptr_t*)
@ -75,6 +84,26 @@ Avian_avian_Classes_resolveVMClass
(resolveClass(t, loader, spec, true, Machine::ClassNotFoundExceptionType));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_defineVMClass
(Thread* t, object, uintptr_t* arguments)
{
object loader = reinterpret_cast<object>(arguments[0]);
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));
THREAD_RESOURCE2(t, uint8_t*, buffer, int, length,
t->m->heap->free(buffer, length));
memcpy(buffer, &byteArrayBody(t, b, offset), length);
return reinterpret_cast<int64_t>(defineClass(t, loader, buffer, length));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findLoadedVMClass
(Thread* t, object, uintptr_t* arguments)
@ -85,6 +114,14 @@ Avian_avian_SystemClassLoader_findLoadedVMClass
return search(t, loader, name, findLoadedClass, true);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_vmClass
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<int64_t>
(jclassVmClass(t, reinterpret_cast<object>(arguments[0])));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findVMClass
(Thread* t, object, uintptr_t* arguments)
@ -565,3 +602,23 @@ Avian_java_nio_FixedArrayByteBuffer_allocateFixed
return reinterpret_cast<intptr_t>(array);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_compareAndSwapInt
(Thread*, object, uintptr_t* arguments)
{
object target = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
uint32_t expect = arguments[4];
uint32_t update = arguments[5];
return atomicCompareAndSwap32
(&fieldAtOffset<uint32_t>(target, offset), expect, update);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_primitiveClass
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<int64_t>(primitiveClass(t, arguments[0]));
}

1672
src/classpath-android.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "machine.h"
#include "classpath-common.h"
#include "process.h"
#include "avian/machine.h"
#include "avian/classpath-common.h"
#include "avian/process.h"
#include <avian/util/runtime-array.h>
@ -109,6 +109,12 @@ class MyClasspath : public Classpath {
vm::resolveNative(t, method);
}
virtual void
preBoot(Thread*)
{
// ignore
}
virtual void
boot(Thread*)
{
@ -127,6 +133,47 @@ class MyClasspath : public Classpath {
// ignore
}
virtual object
makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
{
object c = resolveClass
(t, root(t, Machine::BootLoader), "java/nio/DirectByteBuffer");
PROTECT(t, c);
object instance = makeNew(t, c);
PROTECT(t, instance);
object constructor = resolveMethod(t, c, "<init>", "(JI)V");
t->m->processor->invoke
(t, constructor, instance, reinterpret_cast<int64_t>(p),
static_cast<int32_t>(capacity));
return instance;
}
virtual void*
getDirectBufferAddress(Thread* t, object b)
{
PROTECT(t, b);
object field = resolveField(t, objectClass(t, b), "address", "J");
return reinterpret_cast<void*>
(fieldAtOffset<int64_t>(b, fieldOffset(t, field)));
}
virtual int64_t
getDirectBufferCapacity(Thread* t, object b)
{
PROTECT(t, b);
object field = resolveField
(t, objectClass(t, b), "capacity", "I");
return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
}
virtual void
dispose()
{
@ -677,42 +724,6 @@ Avian_avian_Atomic_compareAndSwapObject
return success;
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_primitiveClass
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<int64_t>(primitiveClass(t, arguments[0]));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_defineVMClass
(Thread* t, object, uintptr_t* arguments)
{
object loader = reinterpret_cast<object>(arguments[0]);
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));
THREAD_RESOURCE2(t, uint8_t*, buffer, int, length,
t->m->heap->free(buffer, length));
memcpy(buffer, &byteArrayBody(t, b, offset), length);
return reinterpret_cast<int64_t>(defineClass(t, loader, buffer, length));
}
extern "C" JNIEXPORT void JNICALL
Avian_avian_Classes_initialize
(Thread* t, object, uintptr_t* arguments)
{
object this_ = reinterpret_cast<object>(arguments[0]);
initClass(t, this_);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_isAssignableFrom
(Thread* t, object, uintptr_t* arguments)
@ -734,3 +745,41 @@ Avian_avian_Classes_getVMClass
return reinterpret_cast<int64_t>
(objectClass(t, reinterpret_cast<object>(arguments[0])));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_Classes_makeMethod
(Thread* t, object, uintptr_t* arguments)
{
object method = arrayBody
(t, classMethodTable
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))),
arguments[1]);
PROTECT(t, method);
object c = resolveClass
(t, root(t, Machine::BootLoader), "java/lang/reflect/Method");
PROTECT(t, c);
object instance = makeNew(t, c);
PROTECT(t, instance);
object constructor = resolveMethod(t, c, "<init>", "(Lavian/VMMethod;)V");
t->m->processor->invoke(t, constructor, instance, method);
if (byteArrayBody(t, methodName(t, method), 0) == '<') {
method = instance;
c = resolveClass
(t, root(t, Machine::BootLoader), "java/lang/reflect/Constructor");
object instance = makeNew(t, c);
object constructor = resolveMethod
(t, c, "<init>", "(Ljava/lang/Method;)V");
t->m->processor->invoke(t, constructor, instance, method);
}
return reinterpret_cast<uintptr_t>(instance);
}

View File

@ -1,337 +0,0 @@
/* Copyright (c) 2010-2012, 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. */
#ifndef CLASSPATH_COMMON_H
#define CLASSPATH_COMMON_H
#include <avian/util/string.h>
#include <avian/util/runtime-array.h>
using namespace avian::util;
namespace vm {
object
getTrace(Thread* t, unsigned skipCount)
{
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, type(t, 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 = makeObjectArray(t, 0);
return v.trace;
}
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
arrayCopy(Thread* t, object src, int32_t srcOffset, object dst,
int32_t dstOffset, int32_t length)
{
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 = fieldAtOffset<uintptr_t>(src, BytesPerWord);
intptr_t dl = fieldAtOffset<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 = &fieldAtOffset<uint8_t>(src, ArrayBody);
uint8_t* dbody = &fieldAtOffset<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 {
throwNew(t, Machine::IndexOutOfBoundsExceptionType);
}
} else {
return;
}
}
}
} else {
throwNew(t, Machine::NullPointerExceptionType);
return;
}
throwNew(t, Machine::ArrayStoreExceptionType);
}
void
runOnLoadIfFound(Thread* t, System::Library* library)
{
void* p = library->resolve("JNI_OnLoad");
#ifdef PLATFORM_WINDOWS
if (p == 0) {
p = library->resolve("_JNI_OnLoad@8");
if (p == 0) {
p = library->resolve("JNI_OnLoad@8");
}
}
#endif
if (p) {
jint (JNICALL * JNI_OnLoad)(Machine*, void*);
memcpy(&JNI_OnLoad, &p, sizeof(void*));
JNI_OnLoad(t->m, 0);
}
}
System::Library*
loadLibrary(Thread* t, const char* name)
{
ACQUIRE(t, t->m->classLock);
System::Library* last = t->m->libraries;
for (System::Library* lib = t->m->libraries; lib; lib = lib->next()) {
if (lib->name() and ::strcmp(lib->name(), name) == 0) {
// already loaded
return lib;
}
last = lib;
}
System::Library* lib;
if (t->m->system->success(t->m->system->load(&lib, name))) {
last->setNext(lib);
return lib;
} else {
return 0;
}
}
System::Library*
loadLibrary(Thread* t, const char* path, const char* name, bool mapName,
bool runOnLoad)
{
ACQUIRE(t, t->m->classLock);
char* mappedName;
unsigned nameLength = strlen(name);
if (mapName) {
const char* builtins = findProperty(t, "avian.builtins");
if (builtins) {
const char* s = builtins;
while (*s) {
if (::strncmp(s, name, nameLength) == 0
and (s[nameLength] == ',' or s[nameLength] == 0))
{
// library is built in to this executable
if (runOnLoad and not t->m->triedBuiltinOnLoad) {
t->m->triedBuiltinOnLoad = true;
// todo: release the classLock before calling this to
// avoid the possibility of deadlock:
runOnLoadIfFound(t, t->m->libraries);
}
return t->m->libraries;
} else {
while (*s and *s != ',') ++ s;
if (*s) ++ s;
}
}
}
const char* prefix = t->m->system->libraryPrefix();
const char* suffix = t->m->system->librarySuffix();
unsigned mappedNameLength = nameLength + strlen(prefix) + strlen(suffix);
mappedName = static_cast<char*>
(t->m->heap->allocate(mappedNameLength + 1));
snprintf(mappedName, mappedNameLength + 1, "%s%s%s", prefix, name, suffix);
name = mappedName;
nameLength = mappedNameLength;
} else {
mappedName = 0;
}
THREAD_RESOURCE2
(t, char*, mappedName, unsigned, nameLength, if (mappedName) {
t->m->heap->free(mappedName, nameLength + 1);
});
System::Library* lib = 0;
for (Tokenizer tokenizer(path, t->m->system->pathSeparator());
tokenizer.hasMore();)
{
String token(tokenizer.next());
unsigned fullNameLength = token.length + 1 + nameLength;
THREAD_RUNTIME_ARRAY(t, char, fullName, fullNameLength + 1);
snprintf(RUNTIME_ARRAY_BODY(fullName), fullNameLength + 1,
"%.*s/%s", token.length, token.text, name);
lib = loadLibrary(t, RUNTIME_ARRAY_BODY(fullName));
if (lib) break;
}
if (lib == 0) {
lib = loadLibrary(t, name);
}
if (lib) {
if (runOnLoad) {
runOnLoadIfFound(t, lib);
}
} else {
throwNew(t, Machine::UnsatisfiedLinkErrorType, "library not found: %s",
name);
}
return lib;
}
object
clone(Thread* t, object o)
{
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 clone;
}
object
makeStackTraceElement(Thread* t, object e)
{
PROTECT(t, e);
object class_ = className(t, methodClass(t, traceElementMethod(t, e)));
PROTECT(t, class_);
THREAD_RUNTIME_ARRAY(t, char, s, byteArrayLength(t, class_));
replace('/', '.', RUNTIME_ARRAY_BODY(s),
reinterpret_cast<char*>(&byteArrayBody(t, class_, 0)));
class_ = makeString(t, "%s", RUNTIME_ARRAY_BODY(s));
object method = methodName(t, traceElementMethod(t, e));
PROTECT(t, method);
method = t->m->classpath->makeString
(t, method, 0, byteArrayLength(t, method) - 1);
unsigned line = t->m->processor->lineNumber
(t, traceElementMethod(t, e), traceElementIp(t, e));
object file = classSourceFile(t, methodClass(t, traceElementMethod(t, e)));
file = file ? t->m->classpath->makeString
(t, file, 0, byteArrayLength(t, file) - 1) : 0;
return makeStackTraceElement(t, class_, method, file, line);
}
object
translateInvokeResult(Thread* t, unsigned returnCode, object o)
{
switch (returnCode) {
case ByteField:
return makeByte(t, intValue(t, o));
case BooleanField:
return makeBoolean(t, intValue(t, o) != 0);
case CharField:
return makeChar(t, intValue(t, o));
case ShortField:
return makeShort(t, intValue(t, o));
case FloatField:
return makeFloat(t, intValue(t, o));
case IntField:
case LongField:
case ObjectField:
case VoidField:
return o;
case DoubleField:
return makeDouble(t, longValue(t, o));
default:
abort(t);
}
}
} // namespace vm
#endif//CLASSPATH_COMMON_H

View File

@ -8,10 +8,10 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "machine.h"
#include "classpath-common.h"
#include "util.h"
#include "process.h"
#include "avian/machine.h"
#include "avian/classpath-common.h"
#include "avian/util.h"
#include "avian/process.h"
#ifdef PLATFORM_WINDOWS
@ -339,7 +339,7 @@ makeClassNameString(Thread* t, object name)
replace('/', '.', RUNTIME_ARRAY_BODY(s),
reinterpret_cast<char*>(&byteArrayBody(t, name, 0)));
return makeString(t, "%s", s);
return makeString(t, "%s", RUNTIME_ARRAY_BODY(s));
}
object
@ -639,6 +639,12 @@ class MyClasspath : public Classpath {
vm::resolveNative(t, method);
}
virtual void
preBoot(Thread*)
{
// ignore
}
virtual void
boot(Thread* t)
{
@ -653,7 +659,7 @@ class MyClasspath : public Classpath {
expect(t, loadLibrary(t, libraryPath, "verify", true, true));
expect(t, loadLibrary(t, libraryPath, "java", true, true));
# ifndef PLATFORM_WINDOWS
loadLibrary(t, libraryPath, "mawt", true, true);
loadLibrary(t, libraryPath, "mawt", true, true, false);
# endif
#endif // not AVIAN_OPENJDK_SRC
@ -755,7 +761,8 @@ class MyClasspath : public Classpath {
length);
RUNTIME_ARRAY_BODY(packageName)[length] = 0;
object key = vm::makeByteArray(t, "%s", packageName);
object key = vm::makeByteArray
(t, "%s", RUNTIME_ARRAY_BODY(packageName));
PROTECT(t, key);
hashMapRemove
@ -775,7 +782,7 @@ class MyClasspath : public Classpath {
&byteArrayBody(t, source, PrefixLength),
sourceNameLength);
source = vm::makeByteArray(t, "%s", sourceName);
source = vm::makeByteArray(t, "%s", RUNTIME_ARRAY_BODY(sourceName));
} else {
source = vm::makeByteArray(t, "avian-dummy-package-source");
}
@ -786,6 +793,47 @@ class MyClasspath : public Classpath {
}
}
virtual object
makeDirectByteBuffer(Thread* t, void* p, jlong capacity)
{
object c = resolveClass
(t, root(t, Machine::BootLoader), "java/nio/DirectByteBuffer");
PROTECT(t, c);
object instance = makeNew(t, c);
PROTECT(t, instance);
object constructor = resolveMethod(t, c, "<init>", "(JI)V");
t->m->processor->invoke
(t, constructor, instance, reinterpret_cast<int64_t>(p),
static_cast<int32_t>(capacity));
return instance;
}
virtual void*
getDirectBufferAddress(Thread* t, object b)
{
PROTECT(t, b);
object field = resolveField(t, objectClass(t, b), "address", "J");
return reinterpret_cast<void*>
(fieldAtOffset<int64_t>(b, fieldOffset(t, field)));
}
virtual int64_t
getDirectBufferCapacity(Thread* t, object b)
{
PROTECT(t, b);
object field = resolveField
(t, objectClass(t, b), "capacity", "I");
return fieldAtOffset<int32_t>(b, fieldOffset(t, field));
}
virtual void
dispose()
{
@ -838,49 +886,6 @@ struct jvm_version_info {
unsigned: 32;
};
Finder*
getFinder(Thread* t, const char* name, unsigned nameLength)
{
ACQUIRE(t, t->m->referenceLock);
for (object p = root(t, Machine::VirtualFileFinders);
p; p = finderNext(t, p))
{
if (byteArrayLength(t, finderName(t, p)) == nameLength
and strncmp(reinterpret_cast<const char*>
(&byteArrayBody(t, finderName(t, p), 0)),
name, nameLength))
{
return static_cast<Finder*>(finderFinder(t, p));
}
}
object n = makeByteArray(t, nameLength + 1);
memcpy(&byteArrayBody(t, n, 0), name, nameLength);
void* p = t->m->libraries->resolve
(reinterpret_cast<const char*>(&byteArrayBody(t, n, 0)));
if (p) {
uint8_t* (*function)(unsigned*);
memcpy(&function, &p, BytesPerWord);
unsigned size;
uint8_t* data = function(&size);
if (data) {
Finder* f = makeFinder(t->m->system, t->m->heap, data, size);
object finder = makeFinder
(t, f, n, root(t, Machine::VirtualFileFinders));
setRoot(t, Machine::VirtualFileFinders, finder);
return f;
}
}
return 0;
}
bool
pathEqual(const char* a, const char* b, unsigned length)
{
@ -1528,7 +1533,8 @@ getZipFileEntry(Thread* t, object method, uintptr_t* arguments)
RUNTIME_ARRAY_BODY(p)[byteArrayLength(t, path) + 1] = 0;
}
return reinterpret_cast<int64_t>(find(file, p, byteArrayLength(t, path)));
return reinterpret_cast<int64_t>
(find(file, RUNTIME_ARRAY_BODY(p), byteArrayLength(t, path)));
} else {
int64_t entry = longValue
(t, t->m->processor->invoke
@ -1871,7 +1877,7 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
#ifdef AVIAN_OPENJDK_SRC
if (not absolute) {
if (strcmp(n, "net") == 0) {
if (strcmp(RUNTIME_ARRAY_BODY(n), "net") == 0) {
bool ran;
{ ACQUIRE(t, t->m->classLock);
@ -1888,7 +1894,7 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
}
return;
} else if (strcmp(n, "management") == 0) {
} else if (strcmp(RUNTIME_ARRAY_BODY(n), "management") == 0) {
bool ran;
{ ACQUIRE(t, t->m->classLock);
@ -1905,8 +1911,8 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
}
return;
} else if (strcmp(n, "zip") == 0
or strcmp(n, "nio") == 0)
} else if (strcmp(RUNTIME_ARRAY_BODY(n), "zip") == 0
or strcmp(RUNTIME_ARRAY_BODY(n), "nio") == 0)
{
return;
}
@ -1918,44 +1924,6 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
RUNTIME_ARRAY_BODY(n), not absolute, true);
}
// only safe to call during bootstrap when there's only one thread
// running:
void
intercept(Thread* t, object c, const char* name, const char* spec,
void* function)
{
object m = findMethodOrNull(t, c, name, spec);
if (m) {
PROTECT(t, m);
object clone = methodClone(t, m);
// make clone private to prevent vtable updates at compilation
// time. Otherwise, our interception might be bypassed by calls
// through the vtable.
methodFlags(t, clone) |= ACC_PRIVATE;
methodFlags(t, m) |= ACC_NATIVE;
object native = makeNativeIntercept(t, function, true, clone);
PROTECT(t, native);
object runtimeData = getMethodRuntimeData(t, m);
set(t, runtimeData, MethodRuntimeDataNative, native);
} else {
// If we can't find the method, just ignore it, since ProGuard may
// have stripped it out as unused. Otherwise, the code below can
// be uncommented for debugging purposes.
// fprintf(stderr, "unable to find %s%s in %s\n",
// name, spec, &byteArrayBody(t, className(t, c), 0));
// abort(t);
}
}
void
interceptFileOperations(Thread* t)
{
@ -2185,162 +2153,6 @@ countConstructors(Thread* t, object c, bool publicOnly)
return count;
}
object
resolveClassBySpec(Thread* t, object loader, const char* spec,
unsigned specLength)
{
switch (*spec) {
case 'L': {
THREAD_RUNTIME_ARRAY(t, char, s, specLength - 1);
memcpy(RUNTIME_ARRAY_BODY(s), spec + 1, specLength - 2);
RUNTIME_ARRAY_BODY(s)[specLength - 2] = 0;
return resolveClass(t, loader, s);
}
case '[': {
THREAD_RUNTIME_ARRAY(t, char, s, specLength + 1);
memcpy(RUNTIME_ARRAY_BODY(s), spec, specLength);
RUNTIME_ARRAY_BODY(s)[specLength] = 0;
return resolveClass(t, loader, s);
}
default:
return primitiveClass(t, *spec);
}
}
object
resolveJType(Thread* t, object loader, const char* spec, unsigned specLength)
{
return getJClass(t, resolveClassBySpec(t, loader, spec, specLength));
}
object
resolveParameterTypes(Thread* t, object loader, object spec,
unsigned* parameterCount, unsigned* returnTypeSpec)
{
PROTECT(t, loader);
PROTECT(t, spec);
object list = 0;
PROTECT(t, list);
unsigned offset = 1;
unsigned count = 0;
while (byteArrayBody(t, spec, offset) != ')') {
switch (byteArrayBody(t, spec, offset)) {
case 'L': {
unsigned start = offset;
++ offset;
while (byteArrayBody(t, spec, offset) != ';') ++ offset;
++ offset;
object type = resolveClassBySpec
(t, loader, reinterpret_cast<char*>(&byteArrayBody(t, spec, start)),
offset - start);
list = makePair(t, type, list);
++ count;
} break;
case '[': {
unsigned start = offset;
while (byteArrayBody(t, spec, offset) == '[') ++ offset;
switch (byteArrayBody(t, spec, offset)) {
case 'L':
++ offset;
while (byteArrayBody(t, spec, offset) != ';') ++ offset;
++ offset;
break;
default:
++ offset;
break;
}
object type = resolveClassBySpec
(t, loader, reinterpret_cast<char*>(&byteArrayBody(t, spec, start)),
offset - start);
list = makePair(t, type, list);
++ count;
} break;
default:
list = makePair
(t, primitiveClass(t, byteArrayBody(t, spec, offset)), list);
++ offset;
++ count;
break;
}
}
*parameterCount = count;
*returnTypeSpec = offset + 1;
return list;
}
object
resolveParameterJTypes(Thread* t, object loader, object spec,
unsigned* parameterCount, unsigned* returnTypeSpec)
{
object list = resolveParameterTypes
(t, loader, spec, parameterCount, returnTypeSpec);
PROTECT(t, list);
object array = makeObjectArray
(t, type(t, Machine::JclassType), *parameterCount);
PROTECT(t, array);
for (int i = *parameterCount - 1; i >= 0; --i) {
object c = getJClass(t, pairFirst(t, list));
set(t, array, ArrayBody + (i * BytesPerWord), c);
list = pairSecond(t, list);
}
return array;
}
object
resolveExceptionJTypes(Thread* t, object loader, object addendum)
{
if (addendum == 0 or methodAddendumExceptionTable(t, addendum) == 0) {
return makeObjectArray(t, type(t, Machine::JclassType), 0);
}
PROTECT(t, loader);
PROTECT(t, addendum);
object array = makeObjectArray
(t, type(t, Machine::JclassType),
shortArrayLength(t, methodAddendumExceptionTable(t, addendum)));
PROTECT(t, array);
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, loader, referenceName(t, o));
set(t, addendumPool(t, addendum), SingletonBody + (index * BytesPerWord),
o);
}
o = getJClass(t, o);
set(t, array, ArrayBody + (i * BytesPerWord), o);
}
return array;
}
object
makeJmethod(Thread* t, object vmMethod, int index)
{
@ -2354,18 +2166,18 @@ makeJmethod(Thread* t, object vmMethod, int index)
unsigned parameterCount;
unsigned returnTypeSpec;
object parameterTypes = local::resolveParameterJTypes
object parameterTypes = resolveParameterJTypes
(t, classLoader(t, methodClass(t, vmMethod)), methodSpec(t, vmMethod),
&parameterCount, &returnTypeSpec);
PROTECT(t, parameterTypes);
object returnType = local::resolveJType
object returnType = resolveJType
(t, classLoader(t, methodClass(t, vmMethod)), reinterpret_cast<char*>
(&byteArrayBody(t, methodSpec(t, vmMethod), returnTypeSpec)),
byteArrayLength(t, methodSpec(t, vmMethod)) - 1 - returnTypeSpec);
PROTECT(t, returnType);
object exceptionTypes = local::resolveExceptionJTypes
object exceptionTypes = resolveExceptionJTypes
(t, classLoader(t, methodClass(t, vmMethod)),
methodAddendum(t, vmMethod));
PROTECT(t, exceptionTypes);
@ -2430,12 +2242,12 @@ makeJconstructor(Thread* t, object vmMethod, int index)
unsigned parameterCount;
unsigned returnTypeSpec;
object parameterTypes = local::resolveParameterJTypes
object parameterTypes = resolveParameterJTypes
(t, classLoader(t, methodClass(t, vmMethod)), methodSpec(t, vmMethod),
&parameterCount, &returnTypeSpec);
PROTECT(t, parameterTypes);
object exceptionTypes = local::resolveExceptionJTypes
object exceptionTypes = resolveExceptionJTypes
(t, classLoader(t, methodClass(t, vmMethod)),
methodAddendum(t, vmMethod));
PROTECT(t, exceptionTypes);
@ -2498,7 +2310,7 @@ makeJfield(Thread* t, object vmField, int index)
(t, fieldName(t, vmField)) - 1));
PROTECT(t, name);
object type = local::resolveClassBySpec
object type = resolveClassBySpec
(t, classLoader(t, fieldClass(t, vmField)),
reinterpret_cast<char*>
(&byteArrayBody(t, fieldSpec(t, vmField), 0)),
@ -3055,19 +2867,6 @@ Avian_sun_misc_Unsafe_putOrderedObject
Avian_sun_misc_Unsafe_putObjectVolatile(t, method, arguments);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_compareAndSwapInt
(Thread*, object, uintptr_t* arguments)
{
object target = reinterpret_cast<object>(arguments[1]);
int64_t offset; memcpy(&offset, arguments + 2, 8);
uint32_t expect = arguments[4];
uint32_t update = arguments[5];
return atomicCompareAndSwap32
(&fieldAtOffset<uint32_t>(target, offset), expect, update);
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_sun_misc_Unsafe_compareAndSwapObject
(Thread* t, object, uintptr_t* arguments)
@ -3429,8 +3228,8 @@ jvmInitProperties(Thread* t, uintptr_t* arguments)
if (*p == '=') {
THREAD_RUNTIME_ARRAY(t, char, name, (p - start) + 1);
memcpy(name, start, p - start);
name[p - start] = 0;
memcpy(RUNTIME_ARRAY_BODY(name), start, p - start);
RUNTIME_ARRAY_BODY(name)[p - start] = 0;
local::setProperty
(t, method, *properties, RUNTIME_ARRAY_BODY(name), p + 1);
}
@ -4814,83 +4613,10 @@ jvmInvokeMethod(Thread* t, uintptr_t* arguments)
(t, jclassVmClass(t, jmethodClazz(t, *method))),
jmethodSlot(t, *method));
if (methodFlags(t, vmMethod) & ACC_STATIC) {
instance = 0;
}
if ((args == 0 ? 0 : objectArrayLength(t, *args))
!= methodParameterCount(t, vmMethod))
{
throwNew(t, Machine::IllegalArgumentExceptionType);
}
if (methodParameterCount(t, vmMethod)) {
PROTECT(t, vmMethod);
unsigned specLength = byteArrayLength(t, methodSpec(t, vmMethod));
THREAD_RUNTIME_ARRAY(t, char, spec, specLength);
memcpy(spec, &byteArrayBody(t, methodSpec(t, vmMethod), 0), specLength);
unsigned i = 0;
for (MethodSpecIterator it(t, spec); it.hasNext();) {
object type;
bool objectType = false;
const char* p = it.next();
switch (*p) {
case 'Z': type = vm::type(t, Machine::BooleanType); break;
case 'B': type = vm::type(t, Machine::ByteType); break;
case 'S': type = vm::type(t, Machine::ShortType); break;
case 'C': type = vm::type(t, Machine::CharType); break;
case 'I': type = vm::type(t, Machine::IntType); break;
case 'F': type = vm::type(t, Machine::FloatType); break;
case 'J': type = vm::type(t, Machine::LongType); break;
case 'D': type = vm::type(t, Machine::DoubleType); break;
case 'L': ++ p;
case '[': {
objectType = true;
unsigned nameLength = it.s - p;
THREAD_RUNTIME_ARRAY(t, char, name, nameLength);
memcpy(name, p, nameLength - 1);
name[nameLength - 1] = 0;
type = resolveClass
(t, classLoader(t, methodClass(t, vmMethod)), name);
} break;
default:
abort();
}
object arg = objectArrayBody(t, *args, i++);
if ((arg == 0 and (not objectType))
or (arg and (not instanceOf(t, type, arg))))
{
// fprintf(stderr, "%s is not a %s\n", arg ? &byteArrayBody(t, className(t, objectClass(t, arg)), 0) : reinterpret_cast<const int8_t*>("<null>"), &byteArrayBody(t, className(t, type), 0));
throwNew(t, Machine::IllegalArgumentExceptionType);
}
}
}
unsigned returnCode = methodReturnCode(t, vmMethod);
THREAD_RESOURCE0(t, {
if (t->exception) {
object exception = t->exception;
t->exception = makeThrowable
(t, Machine::InvocationTargetExceptionType, 0, 0, exception);
}
});
object result;
if (args) {
result = t->m->processor->invokeArray
(t, vmMethod, instance ? *instance : 0, *args);
} else {
result = t->m->processor->invoke(t, vmMethod, instance ? *instance : 0);
}
return reinterpret_cast<uint64_t>
(makeLocalReference(t, translateInvokeResult(t, returnCode, result)));
(makeLocalReference
(t, invoke
(t, vmMethod, instance ? *instance : 0, args ? *args : 0)));
}
extern "C" JNIEXPORT jobject JNICALL

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include <avian/util/runtime-array.h>

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include <avian/util/runtime-array.h>
#include <avian/util/math.h>

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include "codegen/compiler/context.h"
#include "codegen/compiler/frame.h"

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include "codegen/compiler/context.h"
#include "codegen/compiler/promise.h"

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include "codegen/compiler/context.h"
#include "codegen/compiler/value.h"

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include "codegen/compiler/regalloc.h"
#include "codegen/compiler/context.h"

View File

@ -11,7 +11,7 @@
#ifndef AVIAN_CODEGEN_COMPILER_REGALLOC_H
#define AVIAN_CODEGEN_COMPILER_REGALLOC_H
#include "common.h"
#include "avian/common.h"
#include <avian/vm/codegen/lir.h>
#include <avian/vm/codegen/registers.h>

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include "codegen/compiler/context.h"
#include "codegen/compiler/value.h"

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include "codegen/compiler/regalloc.h"
#include "codegen/compiler/site.h"

View File

@ -23,7 +23,7 @@
#include "registers.h"
#include "../multimethod.h"
#include "alloc-vector.h"
#include "avian/alloc-vector.h"
#include <avian/util/abort.h>
using namespace vm;

View File

@ -13,7 +13,7 @@
#include <avian/vm/codegen/lir.h>
#include <avian/vm/codegen/assembler.h>
#include "alloc-vector.h"
#include "avian/alloc-vector.h"
namespace vm {
class System;

View File

@ -11,11 +11,11 @@
#ifndef AVIAN_CODEGEN_ASSEMBLER_ARM_PROMISE_H
#define AVIAN_CODEGEN_ASSEMBLER_ARM_PROMISE_H
#include "target.h"
#include "avian/target.h"
#include <avian/vm/codegen/lir.h>
#include <avian/vm/codegen/assembler.h>
#include "alloc-vector.h"
#include "avian/alloc-vector.h"
namespace vm {
class System;

View File

@ -12,7 +12,7 @@
#include <avian/vm/codegen/architecture.h>
#include <avian/vm/codegen/registers.h>
#include "alloc-vector.h"
#include "avian/alloc-vector.h"
#include <avian/util/abort.h>
#include "encode.h"

View File

@ -10,7 +10,7 @@
#include "context.h"
#include "block.h"
#include "common.h"
#include "avian/common.h"
namespace avian {
namespace codegen {

View File

@ -10,7 +10,7 @@
#include "context.h"
#include "block.h"
#include "common.h"
#include "avian/common.h"
namespace avian {
namespace codegen {

View File

@ -12,7 +12,7 @@
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
#include <avian/vm/codegen/assembler.h>
#include "alloc-vector.h"
#include "avian/alloc-vector.h"
namespace vm {

View File

@ -10,7 +10,7 @@
#include "context.h"
#include "block.h"
#include "common.h"
#include "avian/common.h"
#include "operations.h"
#include "multimethod.h"

View File

@ -10,7 +10,7 @@
#include "context.h"
#include "block.h"
#include "common.h"
#include "avian/common.h"
#include "encode.h"
#include "operations.h"
#include "fixup.h"

View File

@ -12,12 +12,12 @@
#include <stdint.h>
#include <string.h>
#include "environment.h"
#include "target.h"
#include "alloc-vector.h"
#include "common.h"
#include "allocator.h"
#include "zone.h"
#include "avian/environment.h"
#include "avian/target.h"
#include "avian/alloc-vector.h"
#include "avian/common.h"
#include "avian/allocator.h"
#include "avian/zone.h"
#include <avian/util/runtime-array.h>
#include <avian/util/abort.h>

View File

@ -8,8 +8,8 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "allocator.h"
#include "zone.h"
#include "avian/allocator.h"
#include "avian/zone.h"
#include "context.h"
#include "block.h"

View File

@ -17,7 +17,7 @@
#include <stdint.h>
#include "alloc-vector.h"
#include "avian/alloc-vector.h"
#include <avian/vm/codegen/lir.h>
#include <avian/vm/codegen/assembler.h>

View File

@ -9,7 +9,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "avian/target.h"
#include "context.h"

View File

@ -8,8 +8,8 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "target.h"
#include "alloc-vector.h"
#include "avian/target.h"
#include "avian/alloc-vector.h"
#include <avian/util/abort.h>
#include <avian/util/math.h>

View File

@ -13,7 +13,7 @@
#include <stdint.h>
#include "common.h"
#include "avian/common.h"
#include <avian/vm/codegen/lir.h>

View File

@ -10,10 +10,10 @@
#include <string.h>
#include "allocator.h"
#include "alloc-vector.h"
#include "common.h"
#include "zone.h"
#include "avian/allocator.h"
#include "avian/alloc-vector.h"
#include "avian/common.h"
#include "avian/zone.h"
#include <avian/util/abort.h>
#include <avian/vm/system/system.h>

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "common.h"
#include "avian/common.h"
#include <avian/util/abort.h>

View File

@ -11,7 +11,7 @@
#ifndef AVIAN_CODEGEN_ASSEMBLER_X86_MULTIMETHOD_H
#define AVIAN_CODEGEN_ASSEMBLER_X86_MULTIMETHOD_H
#include "common.h"
#include "avian/common.h"
#include <avian/vm/codegen/lir.h>

View File

@ -10,10 +10,10 @@
#include <stdint.h>
#include "target.h"
#include "alloc-vector.h"
#include "allocator.h"
#include "zone.h"
#include "avian/target.h"
#include "avian/alloc-vector.h"
#include "avian/allocator.h"
#include "avian/zone.h"
#include <avian/util/abort.h>

View File

@ -11,7 +11,7 @@
#ifndef AVIAN_CODEGEN_ASSEMBLER_X86_OPERATIONS_H
#define AVIAN_CODEGEN_ASSEMBLER_X86_OPERATIONS_H
#include "common.h"
#include "avian/common.h"
#include <avian/vm/codegen/lir.h>

View File

@ -8,7 +8,7 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "alloc-vector.h"
#include "avian/alloc-vector.h"
#include "context.h"
#include "padding.h"

View File

@ -8,11 +8,11 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "common.h"
#include "avian/common.h"
#include <avian/vm/codegen/targets.h>
#include "environment.h"
#include "avian/environment.h"
namespace avian {
namespace codegen {

View File

@ -8,8 +8,8 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "types.h"
#include "target-fields.h"
#include "avian/types.h"
#include "avian/target-fields.h"
.text

View File

@ -8,8 +8,8 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "types.h"
#include "target-fields.h"
#include "avian/types.h"
#include "avian/target-fields.h"
.text

View File

@ -8,8 +8,8 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "types.h"
#include "target-fields.h"
#include "avian/types.h"
#include "avian/target-fields.h"
#define LOCAL(x) .L##x

View File

@ -8,12 +8,12 @@
There is NO WARRANTY for this software. See license.txt for
details. */
#include "machine.h"
#include "util.h"
#include "alloc-vector.h"
#include "process.h"
#include "target.h"
#include "arch.h"
#include "avian/machine.h"
#include "avian/util.h"
#include "avian/alloc-vector.h"
#include "avian/process.h"
#include "avian/target.h"
#include "avian/arch.h"
#include <avian/vm/codegen/assembler.h>
#include <avian/vm/codegen/architecture.h>

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