]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/CallJava.java
Prefer methods with more parameters when resolving importJava
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / generic / CallJava.java
1 package org.simantics.scl.compiler.constants.generic;
2
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;
14
15 /**
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. 
18  */
19 public class CallJava extends FunctionValue {
20     StackItem[] stackItems;
21     MethodRef methodRef;
22     OutputFilter filter;
23     
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]);
32         }
33         this.stackItems = stackItems;
34         this.methodRef = methodRef;
35         this.filter = filter;
36     }
37
38     @Override
39     public Type applyExact(MethodBuilder mb, Val[] parameters) {
40         methodRef.invoke(mb, stackItems, parameters);
41         if(filter != null)
42             filter.filter(mb);
43         return getReturnType();
44     }
45     
46     public MethodRef getMethodRef() {
47         return methodRef;
48     }
49     
50     @Override
51     public String toString() {
52         return methodRef.getName();
53     }
54
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;
59     
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)
67                 return LESS;
68             else
69                 return GREATER;
70         }
71
72         boolean lessOrEqual = true;
73         boolean greaterOrEqual = true;
74         for(int i=0;i<ps1.length;++i) {
75             if(ps1[i].equals(ps2[i]))
76                 continue;
77             if(!validator.isAssignableFrom(ps1[i], ps2[i])) {
78                 lessOrEqual = false;
79             }
80             if(!validator.isAssignableFrom(ps2[i], ps1[i])) {
81                 greaterOrEqual = false;
82             }
83         }
84         if(lessOrEqual) {
85             if(greaterOrEqual)
86                 return EQUAL;
87             else
88                 return LESS;
89         }
90         else {
91             if(greaterOrEqual)
92                 return GREATER;
93             else
94                 return INCOMPARABLE;
95         }
96     }
97     
98     @Override
99     public void prepare(MethodBuilder mb) {
100         for(StackItem item : stackItems)
101             item.prepare(mb);
102     }
103     
104     @Override
105     public void deconstruct(MethodBuilder mb, IVal parameter, Cont success,
106             Label failure) {
107         if(parameterTypes.length != 0)
108             super.deconstruct(mb, parameter, success, failure);
109         push(mb);
110         mb.push(parameter, getType());
111         mb.invokeVirtual(TypeDesc.OBJECT, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
112         mb.ifZeroComparisonBranch(failure, "==");
113         mb.jump(success);
114     }
115 }