]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/CallJava.java
(refs #7536) Implemented deconstruct in CallJava for static fields
[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             return INCOMPARABLE;
67
68         boolean lessOrEqual = true;
69         boolean greaterOrEqual = true;
70         for(int i=0;i<ps1.length;++i) {
71             if(ps1[i].equals(ps2[i]))
72                 continue;
73             if(!validator.isAssignableFrom(ps1[i], ps2[i])) {
74                 lessOrEqual = false;
75             }
76             if(!validator.isAssignableFrom(ps2[i], ps1[i])) {
77                 greaterOrEqual = false;
78             }
79         }
80         if(lessOrEqual) {
81             if(greaterOrEqual)
82                 return EQUAL;
83             else
84                 return LESS;
85         }
86         else {
87             if(greaterOrEqual)
88                 return GREATER;
89             else
90                 return INCOMPARABLE;
91         }
92     }
93     
94     @Override
95     public void prepare(MethodBuilder mb) {
96         for(StackItem item : stackItems)
97             item.prepare(mb);
98     }
99     
100     @Override
101     public void deconstruct(MethodBuilder mb, IVal parameter, Cont success,
102             Label failure) {
103         if(parameterTypes.length != 0)
104             super.deconstruct(mb, parameter, success, failure);
105         push(mb);
106         mb.push(parameter, getType());
107         mb.invokeVirtual(TypeDesc.OBJECT, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
108         mb.ifZeroComparisonBranch(failure, "==");
109         mb.jump(success);
110     }
111 }