mirror of
https://github.com/corda/corda.git
synced 2025-01-31 16:35:43 +00:00
commit
c5d7e5b8c5
@ -27,4 +27,6 @@ public class ClassAddendum extends Addendum {
|
||||
public Pair enclosingMethod;
|
||||
|
||||
public VMMethod[] bootstrapMethodTable;
|
||||
|
||||
public VMMethod[] bootstrapLambdaTable;
|
||||
}
|
||||
|
@ -1,3 +1,13 @@
|
||||
/* Copyright (c) 2008-2016, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
public class CallSite {
|
||||
|
@ -1,3 +1,13 @@
|
||||
/* Copyright (c) 2008-2016, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
public class LambdaConversionException extends java.lang.Exception {
|
||||
|
@ -1,3 +1,13 @@
|
||||
/* Copyright (c) 2008-2016, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
import static avian.Stream.write1;
|
||||
@ -306,4 +316,14 @@ public class LambdaMetafactory {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public static CallSite altMetafactory(MethodHandles.Lookup caller,
|
||||
String invokedName,
|
||||
MethodType invokedType,
|
||||
Object... args)
|
||||
throws LambdaConversionException
|
||||
{
|
||||
// todo: handle flags
|
||||
return metafactory(caller, invokedName, invokedType, (MethodType) args[0], (MethodHandle) args[1], (MethodType) args[2]);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,13 @@
|
||||
/* Copyright (c) 2008-2016, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
import avian.Classes;
|
||||
|
@ -1,3 +1,13 @@
|
||||
/* Copyright (c) 2008-2016, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
public class MethodHandles {
|
||||
|
@ -1,3 +1,13 @@
|
||||
/* Copyright (c) 2008-2016, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
import static avian.Assembler.*;
|
||||
@ -242,8 +252,8 @@ public final class MethodType implements java.io.Serializable {
|
||||
ObjectType(aload, areturn, 1),
|
||||
IntegerType(iload, ireturn, 1),
|
||||
FloatType(fload, freturn, 1),
|
||||
LongType(lload, lreturn, 1),
|
||||
DoubleType(dload, dreturn, 1),
|
||||
LongType(lload, lreturn, 2),
|
||||
DoubleType(dload, dreturn, 2),
|
||||
VoidType(-1, Assembler.return_, -1);
|
||||
|
||||
public final int load;
|
||||
|
48
classpath/java/lang/invoke/SerializedLambda.java
Normal file
48
classpath/java/lang/invoke/SerializedLambda.java
Normal file
@ -0,0 +1,48 @@
|
||||
/* Copyright (c) 2008-2016, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
public class SerializedLambda implements java.io.Serializable {
|
||||
public int getImplMethodKind() {
|
||||
// todo
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getImplClass() {
|
||||
// todo
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getImplMethodName() {
|
||||
// todo
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getImplMethodSignature() {
|
||||
// todo
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getFunctionalInterfaceClass() {
|
||||
// todo
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getFunctionalInterfaceMethodName() {
|
||||
// todo
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getFunctionalInterfaceMethodSignature() {
|
||||
// todo
|
||||
return null;
|
||||
}
|
||||
}
|
@ -523,6 +523,9 @@ class MyClasspath : public Classpath {
|
||||
GcJobject* blockerLock = makeJobject(t);
|
||||
thread->setBlockerLock(t, blockerLock);
|
||||
|
||||
#if HAVE_ThreadName_Ljava_lang_String_
|
||||
GcString* name = vm::makeString(t, "Thread-%p", thread);
|
||||
#else
|
||||
const unsigned BufferSize = 256;
|
||||
char buffer[BufferSize];
|
||||
unsigned length = vm::snprintf(buffer, BufferSize, "Thread-%p", thread);
|
||||
@ -530,6 +533,7 @@ class MyClasspath : public Classpath {
|
||||
for (unsigned i = 0; i < length; ++i) {
|
||||
name->body()[i] = buffer[i];
|
||||
}
|
||||
#endif
|
||||
thread->setName(t, name);
|
||||
|
||||
return thread;
|
||||
|
@ -4040,15 +4040,26 @@ bool isLambda(Thread* t,
|
||||
return vm::strcmp(reinterpret_cast<const int8_t*>(
|
||||
"java/lang/invoke/LambdaMetafactory"),
|
||||
bootstrap->class_()->name()->body().begin()) == 0
|
||||
and vm::strcmp(reinterpret_cast<const int8_t*>("metafactory"),
|
||||
and ((vm::strcmp(reinterpret_cast<const int8_t*>("metafactory"),
|
||||
bootstrap->name()->body().begin()) == 0
|
||||
and vm::strcmp(
|
||||
reinterpret_cast<const int8_t*>(
|
||||
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/"
|
||||
"String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/"
|
||||
"MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/"
|
||||
"String;Ljava/lang/invoke/MethodType;Ljava/lang/"
|
||||
"invoke/"
|
||||
"MethodType;Ljava/lang/invoke/MethodHandle;Ljava/"
|
||||
"lang/"
|
||||
"invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
|
||||
bootstrap->spec()->body().begin()) == 0;
|
||||
bootstrap->spec()->body().begin()) == 0)
|
||||
or (vm::strcmp(reinterpret_cast<const int8_t*>("altMetafactory"),
|
||||
bootstrap->name()->body().begin()) == 0
|
||||
and vm::strcmp(
|
||||
reinterpret_cast<const int8_t*>(
|
||||
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/"
|
||||
"lang/"
|
||||
"String;Ljava/lang/invoke/MethodType;[Ljava/lang/"
|
||||
"Object;)Ljava/lang/invoke/CallSite;"),
|
||||
bootstrap->spec()->body().begin()) == 0));
|
||||
}
|
||||
|
||||
void compile(MyThread* t,
|
||||
@ -5133,6 +5144,16 @@ loop:
|
||||
GcClass* c = context->method->class_();
|
||||
PROTECT(t, c);
|
||||
|
||||
GcMethod* target
|
||||
= c->addendum()->bootstrapLambdaTable()
|
||||
? cast<GcMethod>(
|
||||
t,
|
||||
cast<GcArray>(t, c->addendum()->bootstrapLambdaTable())
|
||||
->body()[invocation->bootstrap()])
|
||||
: nullptr;
|
||||
PROTECT(t, target);
|
||||
|
||||
if (target == nullptr) {
|
||||
GcCharArray* bootstrapArray = cast<GcCharArray>(
|
||||
t,
|
||||
cast<GcArray>(t, c->addendum()->bootstrapMethodTable())
|
||||
@ -5141,7 +5162,8 @@ loop:
|
||||
|
||||
if (isLambda(t, c->loader(), bootstrapArray, invocation)) {
|
||||
if (bc->hostVM == 0) {
|
||||
throwNew(t,
|
||||
throwNew(
|
||||
t,
|
||||
GcVirtualMachineError::Type,
|
||||
"lambda expression encountered, but host VM is not "
|
||||
"available; use -hostvm option to bootimage-generator to "
|
||||
@ -5149,16 +5171,18 @@ loop:
|
||||
}
|
||||
|
||||
JNIEnv* e;
|
||||
if (bc->hostVM->vtable->AttachCurrentThread(bc->hostVM, &e, 0) == 0) {
|
||||
if (bc->hostVM->vtable->AttachCurrentThread(bc->hostVM, &e, 0)
|
||||
== 0) {
|
||||
e->vtable->PushLocalFrame(e, 256);
|
||||
|
||||
jclass lmfClass
|
||||
= e->vtable->FindClass(e, "java/lang/invoke/LambdaMetafactory");
|
||||
jclass lmfClass = e->vtable->FindClass(
|
||||
e, "java/lang/invoke/LambdaMetafactory");
|
||||
jmethodID makeLambda = e->vtable->GetStaticMethodID(
|
||||
e,
|
||||
lmfClass,
|
||||
"makeLambda",
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/"
|
||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
|
||||
"String;Ljava/"
|
||||
"lang/String;Ljava/lang/String;Ljava/lang/String;I)[B");
|
||||
|
||||
GcReference* reference = cast<GcReference>(
|
||||
@ -5232,14 +5256,24 @@ loop:
|
||||
invocation->template_()->spec()->body().begin(),
|
||||
invocation->template_()->spec()->length());
|
||||
|
||||
GcMethod* target = resolveMethod(
|
||||
target = resolveMethod(
|
||||
t, lambdaClass, "make", RUNTIME_ARRAY_BODY(spec));
|
||||
|
||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||
compileDirectInvoke(t, frame, target, tailCall);
|
||||
GcArray* table
|
||||
= cast<GcArray>(t, c->addendum()->bootstrapLambdaTable());
|
||||
if (table == nullptr) {
|
||||
table = makeArray(
|
||||
t,
|
||||
cast<GcArray>(t, c->addendum()->bootstrapMethodTable())
|
||||
->length());
|
||||
c->addendum()->setBootstrapLambdaTable(t, table);
|
||||
}
|
||||
|
||||
table->setBodyElement(t, invocation->bootstrap(), target);
|
||||
} else {
|
||||
throwNew(
|
||||
t, GcVirtualMachineError::Type, "unable to attach to host VM");
|
||||
throwNew(t,
|
||||
GcVirtualMachineError::Type,
|
||||
"unable to attach to host VM");
|
||||
}
|
||||
} else {
|
||||
throwNew(t,
|
||||
@ -5247,6 +5281,10 @@ loop:
|
||||
"invokedynamic not supported for AOT-compiled code except "
|
||||
"in the case of lambda expressions");
|
||||
}
|
||||
}
|
||||
|
||||
bool tailCall = isTailCall(t, code, ip, context->method, target);
|
||||
compileDirectInvoke(t, frame, target, tailCall);
|
||||
} else {
|
||||
unsigned index = addDynamic(t, invocation);
|
||||
|
||||
|
@ -1220,7 +1220,7 @@ GcClassAddendum* getClassAddendum(Thread* t, GcClass* class_, GcSingleton* pool)
|
||||
if (addendum == 0) {
|
||||
PROTECT(t, class_);
|
||||
|
||||
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0, -1, 0, 0, 0);
|
||||
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0, -1, 0, 0, 0, 0);
|
||||
setField(t, class_, ClassAddendum, addendum);
|
||||
}
|
||||
return addendum;
|
||||
@ -6055,8 +6055,6 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
||||
GcNoSuchMethodError::Type));
|
||||
PROTECT(t, bootstrap);
|
||||
|
||||
assertT(t, bootstrap->parameterCount() == 2 + bootstrapArray->length());
|
||||
|
||||
GcLookup* lookup
|
||||
= makeLookup(t, c, ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC);
|
||||
PROTECT(t, lookup);
|
||||
@ -6078,14 +6076,47 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
||||
array->setBodyElement(t, argument++, name);
|
||||
array->setBodyElement(t, argument++, type);
|
||||
|
||||
MethodSpecIterator it(
|
||||
t, reinterpret_cast<const char*>(bootstrap->spec()->body().begin()));
|
||||
const char* spec;
|
||||
GcArray* argArray = array;
|
||||
PROTECT(t, argArray);
|
||||
|
||||
if (::strcmp(reinterpret_cast<char*>(bootstrap->spec()->body().begin()),
|
||||
"(Ljava/lang/invoke/MethodHandles$Lookup;"
|
||||
"Ljava/lang/String;"
|
||||
"Ljava/lang/invoke/MethodType;"
|
||||
"[Ljava/lang/Object;)"
|
||||
"Ljava/lang/invoke/CallSite;") == 0) {
|
||||
// LambdaMetaFactory.altMetafactory
|
||||
array = makeArray(t, bootstrapArray->length() - 1);
|
||||
spec = "(Ljava/lang/invoke/MethodHandles$Lookup;"
|
||||
"Ljava/lang/String;"
|
||||
"Ljava/lang/invoke/MethodType;"
|
||||
"Ljava/lang/invoke/MethodType;"
|
||||
"Ljava/lang/invoke/MethodHandle;"
|
||||
"Ljava/lang/invoke/MethodType;"
|
||||
"I"
|
||||
"I"
|
||||
"[Ljava/lang/Class;"
|
||||
"I"
|
||||
"[Ljava/lang/invoke/MethodType;"
|
||||
")Ljava/lang/invoke/CallSite;";
|
||||
} else if (bootstrap->parameterCount() == 2 + bootstrapArray->length()) {
|
||||
spec = reinterpret_cast<char*>(bootstrap->spec()->body().begin());
|
||||
} else {
|
||||
abort(t);
|
||||
}
|
||||
|
||||
MethodSpecIterator it(t, spec);
|
||||
|
||||
for (unsigned i = 0; i < argument; ++i)
|
||||
it.next();
|
||||
|
||||
if (argArray != array) {
|
||||
argument = 0;
|
||||
}
|
||||
|
||||
unsigned i = 0;
|
||||
while (it.hasNext()) {
|
||||
while (i + 1 < bootstrapArray->length() && it.hasNext()) {
|
||||
const char* p = it.next();
|
||||
switch (*p) {
|
||||
case 'L': {
|
||||
@ -6162,8 +6193,12 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
||||
? 0
|
||||
: makeMethodHandle(t, REF_invokeSpecial, c->loader(), bootstrap, 0);
|
||||
|
||||
if (argArray != array) {
|
||||
argArray->setBodyElement(t, 3, array);
|
||||
}
|
||||
|
||||
return cast<GcCallSite>(
|
||||
t, t->m->processor->invokeArray(t, bootstrap, handle, array));
|
||||
t, t->m->processor->invokeArray(t, bootstrap, handle, argArray));
|
||||
}
|
||||
|
||||
void noop()
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "avian/constants.h"
|
||||
#include "avian/finder.h"
|
||||
@ -908,8 +909,6 @@ std::string cppFieldType(Module& module, Field* f)
|
||||
|
||||
void writeAccessor(Output* out, Class* cl, Field* f)
|
||||
{
|
||||
std::string typeName = f->typeName;
|
||||
|
||||
out->write("const unsigned ");
|
||||
out->write(capitalize(cl->name));
|
||||
out->write(capitalize(f->name));
|
||||
@ -920,8 +919,23 @@ void writeAccessor(Output* out, Class* cl, Field* f)
|
||||
out->write("#define HAVE_");
|
||||
out->write(capitalize(cl->name));
|
||||
out->write(capitalize(f->name));
|
||||
out->write(" 1\n");
|
||||
|
||||
if (! f->javaSpec.empty()) {
|
||||
std::string s = f->javaSpec;
|
||||
std::replace(s.begin(), s.end(), '/', '_');
|
||||
std::replace(s.begin(), s.end(), '$', '_');
|
||||
std::replace(s.begin(), s.end(), ';', '_');
|
||||
std::replace(s.begin(), s.end(), '[', '_');
|
||||
|
||||
out->write("#define HAVE_");
|
||||
out->write(capitalize(cl->name));
|
||||
out->write(capitalize(f->name));
|
||||
out->write("_");
|
||||
out->write(s);
|
||||
out->write(" 1\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
void writeAccessors(Output* out, Module& module)
|
||||
{
|
||||
|
@ -9,6 +9,24 @@ public class InvokeDynamic {
|
||||
int operate(int a, int b);
|
||||
}
|
||||
|
||||
private interface Operation2 {
|
||||
long operate(long a, int b);
|
||||
}
|
||||
|
||||
private static class Pair<A, B> {
|
||||
public final A first;
|
||||
public final B second;
|
||||
|
||||
public Pair(A first, B second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
}
|
||||
|
||||
private interface Supplier<T> extends java.io.Serializable {
|
||||
T get();
|
||||
}
|
||||
|
||||
private static void expect(boolean v) {
|
||||
if (! v) throw new RuntimeException();
|
||||
}
|
||||
@ -24,8 +42,19 @@ public class InvokeDynamic {
|
||||
}
|
||||
|
||||
private void test() {
|
||||
int c = 2;
|
||||
{ int c = 2;
|
||||
Operation op = (a, b) -> ((a + b) * c) - foo;
|
||||
expect(op.operate(2, 3) == ((2 + 3) * 2) - foo);
|
||||
}
|
||||
|
||||
{ int c = 2;
|
||||
Operation2 op = (a, b) -> ((a + b) * c) - foo;
|
||||
expect(op.operate(2, 3) == ((2 + 3) * 2) - foo);
|
||||
}
|
||||
|
||||
{ Supplier<Pair<Long, Double>> s = () -> new Pair<Long, Double>(42L, 77.1D);
|
||||
expect(s.get().first == 42L);
|
||||
expect(s.get().second == 77.1D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user