mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
add support for openjdk=$JDK8_HOME
All tests pass for the process=compile build. Next step: process=interpret.
This commit is contained in:
parent
2465459079
commit
8a7944d25c
@ -1,6 +1,9 @@
|
|||||||
language: cpp
|
language: cpp
|
||||||
cache: apt
|
cache: apt
|
||||||
|
|
||||||
|
jdk:
|
||||||
|
- oraclejdk8
|
||||||
|
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
@ -45,6 +45,8 @@ public class Classes {
|
|||||||
|
|
||||||
public static native VMClass toVMClass(Class c);
|
public static native VMClass toVMClass(Class c);
|
||||||
|
|
||||||
|
public static native VMMethod toVMMethod(Method m);
|
||||||
|
|
||||||
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
|
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
|
||||||
throws ClassNotFoundException;
|
throws ClassNotFoundException;
|
||||||
|
|
||||||
|
@ -155,7 +155,19 @@ public class LambdaMetafactory {
|
|||||||
write1(out, p.position() + 1);
|
write1(out, p.position() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (implementation.kind) {
|
||||||
|
case MethodHandle.REF_invokeStatic:
|
||||||
write1(out, invokestatic);
|
write1(out, invokestatic);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MethodHandle.REF_invokeSpecial:
|
||||||
|
write1(out, invokespecial);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: throw new AssertionError
|
||||||
|
("todo: implement per http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.5");
|
||||||
|
}
|
||||||
|
|
||||||
write2(out, ConstantPool.addMethodRef
|
write2(out, ConstantPool.addMethodRef
|
||||||
(pool,
|
(pool,
|
||||||
Classes.makeString(implementation.method.class_.name, 0,
|
Classes.makeString(implementation.method.class_.name, 0,
|
||||||
@ -213,11 +225,9 @@ public class LambdaMetafactory {
|
|||||||
try {
|
try {
|
||||||
methodTable.add
|
methodTable.add
|
||||||
(new MethodData
|
(new MethodData
|
||||||
(Modifier.STATIC,
|
(Modifier.PUBLIC | Modifier.STATIC,
|
||||||
ConstantPool.addUtf8(pool, "make"),
|
ConstantPool.addUtf8(pool, "make"),
|
||||||
ConstantPool.addUtf8(pool, Classes.makeString
|
ConstantPool.addUtf8(pool, invokedType.toMethodDescriptorString()),
|
||||||
(invokedType.spec, 0,
|
|
||||||
invokedType.spec.length - 1)),
|
|
||||||
makeFactoryCode(pool, className, constructorSpec, invokedType)));
|
makeFactoryCode(pool, className, constructorSpec, invokedType)));
|
||||||
|
|
||||||
methodTable.add
|
methodTable.add
|
||||||
@ -231,9 +241,7 @@ public class LambdaMetafactory {
|
|||||||
(new MethodData
|
(new MethodData
|
||||||
(Modifier.PUBLIC,
|
(Modifier.PUBLIC,
|
||||||
ConstantPool.addUtf8(pool, invokedName),
|
ConstantPool.addUtf8(pool, invokedName),
|
||||||
ConstantPool.addUtf8(pool, Classes.makeString
|
ConstantPool.addUtf8(pool, methodType.toMethodDescriptorString()),
|
||||||
(methodType.spec, 0,
|
|
||||||
methodType.spec.length - 1)),
|
|
||||||
makeInvocationCode(pool, className, constructorSpec, invokedType,
|
makeInvocationCode(pool, className, constructorSpec, invokedType,
|
||||||
methodType, methodImplementation)));
|
methodType, methodImplementation)));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -262,10 +270,11 @@ public class LambdaMetafactory {
|
|||||||
try {
|
try {
|
||||||
return new CallSite
|
return new CallSite
|
||||||
(new MethodHandle
|
(new MethodHandle
|
||||||
(invokedType.loader, avian.SystemClassLoader.getClass
|
(MethodHandle.REF_invokeStatic, invokedType.loader, Classes.toVMMethod
|
||||||
|
(avian.SystemClassLoader.getClass
|
||||||
(avian.Classes.defineVMClass
|
(avian.Classes.defineVMClass
|
||||||
(invokedType.loader, classData, 0, classData.length))
|
(invokedType.loader, classData, 0, classData.length))
|
||||||
.getMethod("make", invokedType.parameterArray()).vmMethod));
|
.getMethod("make", invokedType.parameterArray()))));
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
AssertionError error = new AssertionError();
|
AssertionError error = new AssertionError();
|
||||||
error.initCause(e);
|
error.initCause(e);
|
||||||
|
@ -1,17 +1,34 @@
|
|||||||
package java.lang.invoke;
|
package java.lang.invoke;
|
||||||
|
|
||||||
|
import avian.Classes;
|
||||||
|
|
||||||
public class MethodHandle {
|
public class MethodHandle {
|
||||||
|
static final int REF_invokeStatic = 6;
|
||||||
|
static final int REF_invokeSpecial = 7;
|
||||||
|
|
||||||
|
final int kind;
|
||||||
private final ClassLoader loader;
|
private final ClassLoader loader;
|
||||||
final avian.VMMethod method;
|
final avian.VMMethod method;
|
||||||
private volatile MethodType type;
|
private volatile MethodType type;
|
||||||
|
|
||||||
MethodHandle(ClassLoader loader, avian.VMMethod method) {
|
MethodHandle(int kind, ClassLoader loader, avian.VMMethod method) {
|
||||||
|
this.kind = kind;
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new java.lang.reflect.Method(method).toString();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (method.class_ != null) {
|
||||||
|
sb.append(Classes.makeString(method.class_.name, 0,
|
||||||
|
method.class_.name.length - 1));
|
||||||
|
sb.append(".");
|
||||||
|
}
|
||||||
|
sb.append(Classes.makeString(method.name, 0,
|
||||||
|
method.name.length - 1));
|
||||||
|
sb.append(Classes.makeString(method.spec, 0,
|
||||||
|
method.spec.length - 1));
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodType type() {
|
public MethodType type() {
|
||||||
|
@ -2,12 +2,18 @@ package java.lang.invoke;
|
|||||||
|
|
||||||
import static avian.Assembler.*;
|
import static avian.Assembler.*;
|
||||||
|
|
||||||
|
import avian.Assembler;
|
||||||
import avian.Classes;
|
import avian.Classes;
|
||||||
|
import avian.VMClass;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public final class MethodType implements java.io.Serializable {
|
public final class MethodType implements java.io.Serializable {
|
||||||
|
private static final char[] Primitives = new char[] {
|
||||||
|
'V', 'Z', 'B', 'C', 'S', 'I', 'F', 'J', 'D'
|
||||||
|
};
|
||||||
|
|
||||||
final ClassLoader loader;
|
final ClassLoader loader;
|
||||||
final byte[] spec;
|
final byte[] spec;
|
||||||
private volatile List<Parameter> parameters;
|
private volatile List<Parameter> parameters;
|
||||||
@ -19,6 +25,77 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
this.spec = spec;
|
this.spec = spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toMethodDescriptorString() {
|
||||||
|
return Classes.makeString(spec, 0, spec.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String spec(Class c) {
|
||||||
|
if (c.isPrimitive()) {
|
||||||
|
VMClass vmc = Classes.toVMClass(c);
|
||||||
|
for (char p: Primitives) {
|
||||||
|
if (vmc == Classes.primitiveClass(p)) {
|
||||||
|
return String.valueOf(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AssertionError();
|
||||||
|
} else if (c.isArray()) {
|
||||||
|
return "[" + spec(c.getComponentType());
|
||||||
|
} else {
|
||||||
|
return "L" + c.getName().replace('.', '/') + ";";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodType(Class rtype,
|
||||||
|
Class ... ptypes)
|
||||||
|
{
|
||||||
|
loader = rtype.getClassLoader();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append('(');
|
||||||
|
parameters = new ArrayList(ptypes.length);
|
||||||
|
int position = 0;
|
||||||
|
for (int i = 0; i < ptypes.length; ++i) {
|
||||||
|
String spec = spec(ptypes[i]);
|
||||||
|
sb.append(spec);
|
||||||
|
|
||||||
|
Type type = type(spec);
|
||||||
|
|
||||||
|
parameters.add(new Parameter(i,
|
||||||
|
position,
|
||||||
|
spec,
|
||||||
|
ptypes[i],
|
||||||
|
type.load));
|
||||||
|
|
||||||
|
position += type.size;
|
||||||
|
}
|
||||||
|
sb.append(')');
|
||||||
|
|
||||||
|
footprint = position;
|
||||||
|
|
||||||
|
String spec = spec(rtype);
|
||||||
|
sb.append(spec);
|
||||||
|
|
||||||
|
result = new Result(spec, rtype, type(spec).return_);
|
||||||
|
|
||||||
|
this.spec = sb.toString().getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodType methodType(Class rtype,
|
||||||
|
Class ptype0,
|
||||||
|
Class ... ptypes)
|
||||||
|
{
|
||||||
|
Class[] array = new Class[ptypes.length + 1];
|
||||||
|
array[0] = ptype0;
|
||||||
|
System.arraycopy(ptypes, 0, array, 1, ptypes.length);
|
||||||
|
return methodType(rtype, array);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodType methodType(Class rtype,
|
||||||
|
Class ... ptypes)
|
||||||
|
{
|
||||||
|
return new MethodType(rtype, ptypes);
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return Classes.makeString(spec, 0, spec.length - 1);
|
return Classes.makeString(spec, 0, spec.length - 1);
|
||||||
}
|
}
|
||||||
@ -53,21 +130,14 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
int position = 0;
|
int position = 0;
|
||||||
for (i = 1; spec[i] != ')'; ++i) {
|
for (i = 1; spec[i] != ')'; ++i) {
|
||||||
|
int start = i;
|
||||||
switch (spec[i]) {
|
switch (spec[i]) {
|
||||||
case 'L': {
|
case 'L': {
|
||||||
int start = i;
|
|
||||||
++ i;
|
++ i;
|
||||||
while (spec[i] != ';') ++ i;
|
while (spec[i] != ';') ++ i;
|
||||||
|
|
||||||
list.add(new Parameter
|
|
||||||
(index,
|
|
||||||
position,
|
|
||||||
Classes.makeString(spec, start, (i - start) + 1),
|
|
||||||
aload));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case '[': {
|
case '[': {
|
||||||
int start = i;
|
|
||||||
++ i;
|
++ i;
|
||||||
while (spec[i] == '[') ++ i;
|
while (spec[i] == '[') ++ i;
|
||||||
|
|
||||||
@ -80,12 +150,6 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
list.add(new Parameter
|
|
||||||
(index,
|
|
||||||
position,
|
|
||||||
Classes.makeString(spec, start, (i - start) + 1),
|
|
||||||
aload));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'Z':
|
case 'Z':
|
||||||
@ -93,107 +157,38 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
case 'S':
|
case 'S':
|
||||||
case 'C':
|
case 'C':
|
||||||
case 'I':
|
case 'I':
|
||||||
list.add(new Parameter
|
|
||||||
(index,
|
|
||||||
position,
|
|
||||||
Classes.makeString(spec, i, 1),
|
|
||||||
iload));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F':
|
case 'F':
|
||||||
list.add(new Parameter
|
|
||||||
(index,
|
|
||||||
position,
|
|
||||||
Classes.makeString(spec, i, 1),
|
|
||||||
fload));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'J':
|
case 'J':
|
||||||
list.add(new Parameter
|
|
||||||
(index,
|
|
||||||
position,
|
|
||||||
Classes.makeString(spec, i, 1),
|
|
||||||
lload));
|
|
||||||
|
|
||||||
++ position;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
list.add(new Parameter
|
|
||||||
(index,
|
|
||||||
position,
|
|
||||||
Classes.makeString(spec, i, 1),
|
|
||||||
dload));
|
|
||||||
|
|
||||||
++ position;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: throw new AssertionError();
|
default: throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String paramSpec = Classes.makeString(spec, start, (i - start) + 1);
|
||||||
|
Type type = type(paramSpec);
|
||||||
|
|
||||||
|
list.add(new Parameter
|
||||||
|
(index,
|
||||||
|
position,
|
||||||
|
paramSpec,
|
||||||
|
Classes.forCanonicalName(loader, paramSpec),
|
||||||
|
type.load));
|
||||||
|
|
||||||
++ index;
|
++ index;
|
||||||
++ position;
|
position += type.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
footprint = position;
|
footprint = position;
|
||||||
|
|
||||||
++ i;
|
++ i;
|
||||||
|
|
||||||
switch (spec[i]) {
|
String paramSpec = Classes.makeString(spec, i, spec.length - i - 1);
|
||||||
case 'L': {
|
Type type = type(paramSpec);
|
||||||
int start = i;
|
|
||||||
++ i;
|
|
||||||
while (spec[i] != ';') ++ i;
|
|
||||||
|
|
||||||
result = new Result
|
result = new Result(paramSpec,
|
||||||
(Classes.makeString(spec, start, (i - start) + 1), areturn);
|
Classes.forCanonicalName(loader, paramSpec),
|
||||||
} break;
|
type.return_);
|
||||||
|
|
||||||
case '[': {
|
|
||||||
int start = i;
|
|
||||||
++ i;
|
|
||||||
while (spec[i] == '[') ++ i;
|
|
||||||
|
|
||||||
switch (spec[i]) {
|
|
||||||
case 'L':
|
|
||||||
++ i;
|
|
||||||
while (spec[i] != ';') ++ i;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = new Result(Classes.makeString(spec, start, (i - start) + 1),
|
|
||||||
areturn);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case 'V':
|
|
||||||
result = new Result(Classes.makeString(spec, i, 1), return_);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Z':
|
|
||||||
case 'B':
|
|
||||||
case 'S':
|
|
||||||
case 'C':
|
|
||||||
case 'I':
|
|
||||||
result = new Result(Classes.makeString(spec, i, 1), ireturn);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F':
|
|
||||||
result = new Result(Classes.makeString(spec, i, 1), freturn);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'J':
|
|
||||||
result = new Result(Classes.makeString(spec, i, 1), lreturn);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'D':
|
|
||||||
result = new Result(Classes.makeString(spec, i, 1), dreturn);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
parameters = list;
|
parameters = list;
|
||||||
}
|
}
|
||||||
@ -207,7 +202,55 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Parameter {
|
private static Type type(String spec) {
|
||||||
|
switch (spec.charAt(0)) {
|
||||||
|
case 'L':
|
||||||
|
case '[':
|
||||||
|
return Type.ObjectType;
|
||||||
|
|
||||||
|
case 'Z':
|
||||||
|
case 'B':
|
||||||
|
case 'S':
|
||||||
|
case 'C':
|
||||||
|
case 'I':
|
||||||
|
return Type.IntegerType;
|
||||||
|
|
||||||
|
case 'F':
|
||||||
|
return Type.FloatType;
|
||||||
|
|
||||||
|
case 'J':
|
||||||
|
return Type.LongType;
|
||||||
|
|
||||||
|
case 'D':
|
||||||
|
return Type.DoubleType;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
return Type.VoidType;
|
||||||
|
|
||||||
|
default: throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static enum Type {
|
||||||
|
ObjectType(aload, areturn, 1),
|
||||||
|
IntegerType(iload, ireturn, 1),
|
||||||
|
FloatType(fload, freturn, 1),
|
||||||
|
LongType(lload, lreturn, 1),
|
||||||
|
DoubleType(dload, dreturn, 1),
|
||||||
|
VoidType(-1, Assembler.return_, -1);
|
||||||
|
|
||||||
|
public final int load;
|
||||||
|
public final int return_;
|
||||||
|
public final int size;
|
||||||
|
|
||||||
|
private Type(int load, int return_, int size) {
|
||||||
|
this.load = load;
|
||||||
|
this.return_ = return_;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Parameter {
|
||||||
private final int index;
|
private final int index;
|
||||||
private final int position;
|
private final int position;
|
||||||
private final String spec;
|
private final String spec;
|
||||||
@ -217,12 +260,13 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
private Parameter(int index,
|
private Parameter(int index,
|
||||||
int position,
|
int position,
|
||||||
String spec,
|
String spec,
|
||||||
|
Class type,
|
||||||
int load)
|
int load)
|
||||||
{
|
{
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.spec = spec;
|
this.spec = spec;
|
||||||
this.type = Classes.forCanonicalName(loader, spec);
|
this.type = type;
|
||||||
this.load = load;
|
this.load = load;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,14 +287,14 @@ public final class MethodType implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Result {
|
public static class Result {
|
||||||
private final String spec;
|
private final String spec;
|
||||||
private final Class type;
|
private final Class type;
|
||||||
private final int return_;
|
private final int return_;
|
||||||
|
|
||||||
public Result(String spec, int return_) {
|
public Result(String spec, Class type, int return_) {
|
||||||
this.spec = spec;
|
this.spec = spec;
|
||||||
this.type = Classes.forCanonicalName(loader, spec);
|
this.type = type;
|
||||||
this.return_ = return_;
|
this.return_ = return_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,18 +59,6 @@ public class Method<T> extends AccessibleObject implements Member {
|
|||||||
return getSpec(vmMethod);
|
return getSpec(vmMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
if (vmMethod.class_ != null) {
|
|
||||||
sb.append(Classes.makeString(vmMethod.class_.name, 0,
|
|
||||||
vmMethod.class_.name.length - 1));
|
|
||||||
sb.append(".");
|
|
||||||
}
|
|
||||||
sb.append(getName());
|
|
||||||
sb.append(getSpec());
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getSpec(VMMethod vmMethod) {
|
public static String getSpec(VMMethod vmMethod) {
|
||||||
return Classes.makeString(vmMethod.spec, 0, vmMethod.spec.length - 1);
|
return Classes.makeString(vmMethod.spec, 0, vmMethod.spec.length - 1);
|
||||||
}
|
}
|
||||||
|
7
makefile
7
makefile
@ -1473,7 +1473,12 @@ ifneq ($(classpath),avian)
|
|||||||
$(classpath-src)/avian/VMField.java \
|
$(classpath-src)/avian/VMField.java \
|
||||||
$(classpath-src)/avian/VMMethod.java \
|
$(classpath-src)/avian/VMMethod.java \
|
||||||
$(classpath-src)/avian/avianvmresource/Handler.java \
|
$(classpath-src)/avian/avianvmresource/Handler.java \
|
||||||
$(classpath-src)/avian/file/Handler.java
|
$(classpath-src)/avian/file/Handler.java \
|
||||||
|
$(classpath-src)/java/lang/invoke/MethodHandle.java \
|
||||||
|
$(classpath-src)/java/lang/invoke/MethodHandles.java \
|
||||||
|
$(classpath-src)/java/lang/invoke/MethodType.java \
|
||||||
|
$(classpath-src)/java/lang/invoke/LambdaMetafactory.java \
|
||||||
|
$(classpath-src)/java/lang/invoke/CallSite.java
|
||||||
|
|
||||||
ifeq ($(openjdk),)
|
ifeq ($(openjdk),)
|
||||||
classpath-sources := $(classpath-sources) \
|
classpath-sources := $(classpath-sources) \
|
||||||
|
@ -263,6 +263,16 @@ const unsigned ACC_INTERFACE = 1 << 9;
|
|||||||
const unsigned ACC_ABSTRACT = 1 << 10;
|
const unsigned ACC_ABSTRACT = 1 << 10;
|
||||||
const unsigned ACC_STRICT = 1 << 11;
|
const unsigned ACC_STRICT = 1 << 11;
|
||||||
|
|
||||||
|
const unsigned REF_getField = 1;
|
||||||
|
const unsigned REF_getStatic = 2;
|
||||||
|
const unsigned REF_putField = 3;
|
||||||
|
const unsigned REF_putStatic = 4;
|
||||||
|
const unsigned REF_invokeVirtual = 5;
|
||||||
|
const unsigned REF_invokeStatic = 6;
|
||||||
|
const unsigned REF_invokeSpecial = 7;
|
||||||
|
const unsigned REF_newInvokeSpecial = 8;
|
||||||
|
const unsigned REF_invokeInterface = 9;
|
||||||
|
|
||||||
const int AVIAN_JNI_COMMIT = 1;
|
const int AVIAN_JNI_COMMIT = 1;
|
||||||
const int AVIAN_JNI_ABORT = 2;
|
const int AVIAN_JNI_ABORT = 2;
|
||||||
|
|
||||||
|
@ -113,6 +113,13 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
|||||||
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
|
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0]))->vmClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||||
|
Avian_avian_Classes_toVMMethod(Thread* t, object, uintptr_t* arguments)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<intptr_t>(t->m->classpath->getVMMethod(
|
||||||
|
t, cast<GcJmethod>(t, reinterpret_cast<object>(arguments[0]))));
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" AVIAN_EXPORT void JNICALL
|
extern "C" AVIAN_EXPORT void JNICALL
|
||||||
Avian_avian_Classes_initialize(Thread* t, object, uintptr_t* arguments)
|
Avian_avian_Classes_initialize(Thread* t, object, uintptr_t* arguments)
|
||||||
{
|
{
|
||||||
|
@ -484,6 +484,7 @@ class MyClasspath : public Classpath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
oarray = charArray;
|
oarray = charArray;
|
||||||
|
offset = 0;
|
||||||
} else {
|
} else {
|
||||||
expect(t, objectClass(t, oarray) == type(t, GcCharArray::Type));
|
expect(t, objectClass(t, oarray) == type(t, GcCharArray::Type));
|
||||||
}
|
}
|
||||||
|
@ -7351,6 +7351,12 @@ GcCallSite* resolveDynamic(MyThread* t, GcInvocation* invocation)
|
|||||||
|
|
||||||
array->setBodyElement(t, i + argument, type);
|
array->setBodyElement(t, i + argument, type);
|
||||||
} else if (strncmp(p, methodHandle, strlen(methodHandle)) == 0) {
|
} else if (strncmp(p, methodHandle, strlen(methodHandle)) == 0) {
|
||||||
|
GcReference* reference = cast<GcReference>(
|
||||||
|
t,
|
||||||
|
singletonObject(
|
||||||
|
t, invocation->pool(), bootstrapArray->body()[i + 1]));
|
||||||
|
int kind = reference->kind();
|
||||||
|
|
||||||
GcMethod* method = cast<GcMethod>(t,
|
GcMethod* method = cast<GcMethod>(t,
|
||||||
resolve(t,
|
resolve(t,
|
||||||
c->loader(),
|
c->loader(),
|
||||||
@ -7359,7 +7365,8 @@ GcCallSite* resolveDynamic(MyThread* t, GcInvocation* invocation)
|
|||||||
findMethodInClass,
|
findMethodInClass,
|
||||||
GcNoSuchMethodError::Type));
|
GcNoSuchMethodError::Type));
|
||||||
|
|
||||||
GcMethodHandle* handle = makeMethodHandle(t, c->loader(), method, 0);
|
GcMethodHandle* handle
|
||||||
|
= makeMethodHandle(t, kind, c->loader(), method, 0);
|
||||||
|
|
||||||
array->setBodyElement(t, i + argument, handle);
|
array->setBodyElement(t, i + argument, handle);
|
||||||
} else {
|
} else {
|
||||||
@ -7396,9 +7403,10 @@ GcCallSite* resolveDynamic(MyThread* t, GcInvocation* invocation)
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
GcMethodHandle* handle = (bootstrap->flags() & ACC_STATIC)
|
GcMethodHandle* handle
|
||||||
|
= (bootstrap->flags() & ACC_STATIC)
|
||||||
? 0
|
? 0
|
||||||
: makeMethodHandle(t, c->loader(), bootstrap, 0);
|
: makeMethodHandle(t, REF_invokeSpecial, c->loader(), bootstrap, 0);
|
||||||
|
|
||||||
return cast<GcCallSite>(
|
return cast<GcCallSite>(
|
||||||
t, t->m->processor->invokeArray(t, bootstrap, handle, array));
|
t, t->m->processor->invokeArray(t, bootstrap, handle, array));
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
public class InvokeDynamic {
|
public class InvokeDynamic {
|
||||||
|
private final int foo;
|
||||||
|
|
||||||
|
private InvokeDynamic(int foo) {
|
||||||
|
this.foo = foo;
|
||||||
|
}
|
||||||
|
|
||||||
private interface Operation {
|
private interface Operation {
|
||||||
int operate(int a, int b);
|
int operate(int a, int b);
|
||||||
}
|
}
|
||||||
@ -10,6 +16,14 @@ public class InvokeDynamic {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
int c = 4;
|
int c = 4;
|
||||||
Operation op = (a, b) -> a + b - c;
|
Operation op = (a, b) -> a + b - c;
|
||||||
expect(op.operate(2, 3) == 1);
|
expect(op.operate(2, 3) == (2 + 3) - 4);
|
||||||
|
|
||||||
|
new InvokeDynamic(3).test();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void test() {
|
||||||
|
int c = 2;
|
||||||
|
Operation op = (a, b) -> ((a + b) * c) - foo;
|
||||||
|
expect(op.operate(2, 3) == ((2 + 3) * 2) - foo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user