1 package org.simantics.scl.compiler.constants.generic;
3 import org.cojen.classfile.TypeDesc;
4 import org.objectweb.asm.Label;
5 import org.simantics.scl.compiler.constants.FunctionValue;
6 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
7 import org.simantics.scl.compiler.internal.codegen.references.IVal;
8 import org.simantics.scl.compiler.internal.codegen.references.Val;
9 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
10 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
11 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
12 import org.simantics.scl.compiler.types.TVar;
13 import org.simantics.scl.compiler.types.Type;
16 * This class represents a call to a Java method as an SCL function value.
17 * It is instantiated by the {@link org.simantics.scl.compiler.compilation.Elaboration.matchType(MethodRef, Type)} method.
19 public class CallJava extends FunctionValue {
20 StackItem[] stackItems;
24 public CallJava(TVar[] typeParameters, Type effect, Type returnType,
25 Type[] parameterTypes, StackItem[] stackItems, MethodRef methodRef,
26 OutputFilter filter) {
27 super(typeParameters, effect, returnType, parameterTypes);
28 if(stackItems == null) {
29 stackItems = new StackItem[parameterTypes.length];
30 for(int i=0;i<parameterTypes.length;++i)
31 stackItems[i] = new ParameterStackItem(i, parameterTypes[i]);
33 this.stackItems = stackItems;
34 this.methodRef = methodRef;
39 public Type applyExact(MethodBuilder mb, Val[] parameters) {
40 methodRef.invoke(mb, stackItems, parameters);
43 return getReturnType();
46 public MethodRef getMethodRef() {
51 public String toString() {
52 return methodRef.getName();
55 public final static int INCOMPARABLE = -2;
56 public final static int LESS = -1;
57 public final static int EQUAL = 0;
58 public final static int GREATER = 1;
60 public int compareTo(JavaReferenceValidator validator, CallJava other) {
61 MethodRef m1 = methodRef;
62 MethodRef m2 = other.methodRef;
63 TypeDesc[] ps1 = m1.getParameterTypes();
64 TypeDesc[] ps2 = m2.getParameterTypes();
65 if(ps1.length != ps2.length) {
66 if(ps1.length < ps2.length)
72 boolean lessOrEqual = true;
73 boolean greaterOrEqual = true;
74 for(int i=0;i<ps1.length;++i) {
75 if(ps1[i].equals(ps2[i]))
77 if(!validator.isAssignableFrom(ps1[i], ps2[i])) {
80 if(!validator.isAssignableFrom(ps2[i], ps1[i])) {
81 greaterOrEqual = false;
99 public void prepare(MethodBuilder mb) {
100 for(StackItem item : stackItems)
105 public void deconstruct(MethodBuilder mb, IVal parameter, Cont success,
107 if(parameterTypes.length != 0)
108 super.deconstruct(mb, parameter, success, failure);
110 mb.push(parameter, getType());
111 mb.invokeVirtual(TypeDesc.OBJECT, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
112 mb.ifZeroComparisonBranch(failure, "==");