mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Add support for altMetafactory
This commit is contained in:
parent
6653118dd8
commit
40b29cdfa1
|
@ -49,9 +49,14 @@ public class JCLPlugin implements TeaVMPlugin {
|
||||||
|
|
||||||
host.add(new ClassForNameTransformer());
|
host.add(new ClassForNameTransformer());
|
||||||
host.add(new AnnotationDependencyListener());
|
host.add(new AnnotationDependencyListener());
|
||||||
|
|
||||||
|
LambdaMetafactorySubstitutor lms = new LambdaMetafactorySubstitutor();
|
||||||
host.add(new MethodReference(LambdaMetafactory.class, "metafactory", MethodHandles.Lookup.class,
|
host.add(new MethodReference(LambdaMetafactory.class, "metafactory", MethodHandles.Lookup.class,
|
||||||
String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class,
|
String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class,
|
||||||
CallSite.class), new LambdaMetafactorySubstitutor());
|
CallSite.class), lms);
|
||||||
|
host.add(new MethodReference(LambdaMetafactory.class, "altMetafactory", MethodHandles.Lookup.class,
|
||||||
|
String.class, MethodType.class, Object[].class, CallSite.class), lms);
|
||||||
|
|
||||||
host.add(new ScalaHacks());
|
host.add(new ScalaHacks());
|
||||||
|
|
||||||
host.add(new NumericClassTransformer());
|
host.add(new NumericClassTransformer());
|
||||||
|
|
|
@ -34,6 +34,9 @@ import org.teavm.model.emit.ProgramEmitter;
|
||||||
import org.teavm.model.emit.ValueEmitter;
|
import org.teavm.model.emit.ValueEmitter;
|
||||||
|
|
||||||
public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor {
|
public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor {
|
||||||
|
private static final int FLAG_SERIALIZABLE = 1;
|
||||||
|
private static final int FLAG_MARKERS = 2;
|
||||||
|
private static final int FLAG_BRIDGES = 4;
|
||||||
private int lambdaIndex;
|
private int lambdaIndex;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,6 +97,33 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
|
||||||
|
|
||||||
implementor.addMethod(worker);
|
implementor.addMethod(worker);
|
||||||
|
|
||||||
|
// Handle altMetafactory case
|
||||||
|
if (callSite.getBootstrapArguments().size() > 3) {
|
||||||
|
int flags = callSite.getBootstrapArguments().get(3).getInt();
|
||||||
|
|
||||||
|
if ((flags & FLAG_SERIALIZABLE) != 0) {
|
||||||
|
implementor.getInterfaces().add("java.io.Serializable");
|
||||||
|
}
|
||||||
|
|
||||||
|
int bootstrapArgIndex = 4;
|
||||||
|
if ((flags & FLAG_MARKERS) != 0) {
|
||||||
|
int markerCount = callSite.getBootstrapArguments().get(bootstrapArgIndex++).getInt();
|
||||||
|
for (int i = 0; i < markerCount; ++i) {
|
||||||
|
ValueType markerType = callSite.getBootstrapArguments().get(bootstrapArgIndex++).getValueType();
|
||||||
|
implementor.getInterfaces().add(((ValueType.Object) markerType).getClassName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & FLAG_BRIDGES) != 0) {
|
||||||
|
int bridgeCount = callSite.getBootstrapArguments().get(bootstrapArgIndex++).getInt();
|
||||||
|
for (int i = 0; i < bridgeCount; ++i) {
|
||||||
|
ValueType[] bridgeType = callSite.getBootstrapArguments().get(bootstrapArgIndex++).getMethodType();
|
||||||
|
createBridge(classSource, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType,
|
||||||
|
bridgeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callSite.getAgent().submitClass(implementor);
|
callSite.getAgent().submitClass(implementor);
|
||||||
return callerPe.construct(ctor.getOwnerName(), callSite.getArguments().toArray(new ValueEmitter[0]));
|
return callerPe.construct(ctor.getOwnerName(), callSite.getArguments().toArray(new ValueEmitter[0]));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.teavm.model.instructions.InstructionVisitor;
|
import org.teavm.model.instructions.InstructionVisitor;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class InvokeDynamicInstruction extends Instruction {
|
public class InvokeDynamicInstruction extends Instruction {
|
||||||
private MethodDescriptor method;
|
private MethodDescriptor method;
|
||||||
private MethodHandle bootstrapMethod;
|
private MethodHandle bootstrapMethod;
|
||||||
|
|
|
@ -15,10 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model;
|
package org.teavm.model;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public final class RuntimeConstant {
|
public final class RuntimeConstant {
|
||||||
public static final byte INT = 0;
|
public static final byte INT = 0;
|
||||||
public static final byte LONG = 1;
|
public static final byte LONG = 1;
|
||||||
|
|
46
tests/src/test/java/org/teavm/vm/LambdaTest.java
Normal file
46
tests/src/test/java/org/teavm/vm/LambdaTest.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.vm;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.teavm.junit.TeaVMTestRunner;
|
||||||
|
|
||||||
|
@RunWith(TeaVMTestRunner.class)
|
||||||
|
public class LambdaTest {
|
||||||
|
@Test
|
||||||
|
public void lambdaWithMarkers() {
|
||||||
|
Supplier<String> supplier = (Supplier<String> & A) () -> "OK";
|
||||||
|
|
||||||
|
assertEquals("OK", supplier.get());
|
||||||
|
assertTrue("Supplier is expected to implement A", supplier instanceof A);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serializableLambda() {
|
||||||
|
Supplier<String> supplier = (Supplier<String> & Serializable) () -> "OK";
|
||||||
|
|
||||||
|
assertEquals("OK", supplier.get());
|
||||||
|
assertTrue("Supplier is expected to implement Serializable", supplier instanceof Serializable);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface A {
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user