]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - 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
index 300f11802ae4df144649a7d0a6f156294dc6e999..0e3ad1f52c5daa3aad92cdb733374fb2b9c8373a 100644 (file)
-package org.simantics.scl.compiler.constants.generic;\r
-\r
-import org.cojen.classfile.TypeDesc;\r
-import org.simantics.scl.compiler.constants.FunctionValue;\r
-import org.simantics.scl.compiler.internal.codegen.references.Val;\r
-import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;\r
-import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-\r
-/**\r
- * This class represents a call to a Java method as an SCL function value.\r
- * It is instantiated by the {@link org.simantics.scl.compiler.compilation.Elaboration.matchType(MethodRef, Type)} method. \r
- */\r
-public class CallJava extends FunctionValue {\r
-    StackItem[] stackItems;\r
-    MethodRef methodRef;\r
-    OutputFilter filter;\r
-    \r
-    public CallJava(TVar[] typeParameters, Type effect, Type returnType,\r
-            Type[] parameterTypes, StackItem[] stackItems, MethodRef methodRef,\r
-            OutputFilter filter) {\r
-        super(typeParameters, effect, returnType, parameterTypes);\r
-        this.stackItems = stackItems;\r
-        this.methodRef = methodRef;\r
-        this.filter = filter;\r
-    }\r
-\r
-    @Override\r
-    public Type applyExact(MethodBuilder mb, Val[] parameters) {\r
-        methodRef.invoke(mb, stackItems, parameters);\r
-        if(filter != null)\r
-            filter.filter(mb);\r
-        return getReturnType();\r
-    }\r
-    \r
-    public MethodRef getMethodRef() {\r
-        return methodRef;\r
-    }\r
-    \r
-    @Override\r
-    public String toString() {\r
-        return methodRef.getName();\r
-    }\r
-\r
-    public final static int INCOMPARABLE = -2;\r
-    public final static int LESS = -1;\r
-    public final static int EQUAL = 0;\r
-    public final static int GREATER = 1;\r
-    \r
-    public int compareTo(JavaReferenceValidator validator, CallJava other) {\r
-        MethodRef m1 = methodRef;\r
-        MethodRef m2 = other.methodRef;\r
-        TypeDesc[] ps1 = m1.getParameterTypes();\r
-        TypeDesc[] ps2 = m2.getParameterTypes();\r
-        if(ps1.length != ps2.length)\r
-            return INCOMPARABLE;\r
-\r
-        boolean lessOrEqual = true;\r
-        boolean greaterOrEqual = true;\r
-        for(int i=0;i<ps1.length;++i) {\r
-            if(ps1[i].equals(ps2[i]))\r
-                continue;\r
-            if(!validator.isAssignableFrom(ps1[i], ps2[i])) {\r
-                lessOrEqual = false;\r
-            }\r
-            if(!validator.isAssignableFrom(ps2[i], ps1[i])) {\r
-                greaterOrEqual = false;\r
-            }\r
-        }\r
-        if(lessOrEqual) {\r
-            if(greaterOrEqual)\r
-                return EQUAL;\r
-            else\r
-                return LESS;\r
-        }\r
-        else {\r
-            if(greaterOrEqual)\r
-                return GREATER;\r
-            else\r
-                return INCOMPARABLE;\r
-        }\r
-    }\r
-    \r
-    @Override\r
-    public void prepare(MethodBuilder mb) {\r
-        for(StackItem item : stackItems)\r
-            item.prepare(mb);\r
-    }\r
-}\r
+package org.simantics.scl.compiler.constants.generic;
+
+import org.cojen.classfile.TypeDesc;
+import org.objectweb.asm.Label;
+import org.simantics.scl.compiler.constants.FunctionValue;
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
+import org.simantics.scl.compiler.internal.codegen.references.IVal;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+
+/**
+ * This class represents a call to a Java method as an SCL function value.
+ * It is instantiated by the {@link org.simantics.scl.compiler.compilation.Elaboration.matchType(MethodRef, Type)} method. 
+ */
+public class CallJava extends FunctionValue {
+    StackItem[] stackItems;
+    MethodRef methodRef;
+    OutputFilter filter;
+    
+    public CallJava(TVar[] typeParameters, Type effect, Type returnType,
+            Type[] parameterTypes, StackItem[] stackItems, MethodRef methodRef,
+            OutputFilter filter) {
+        super(typeParameters, effect, returnType, parameterTypes);
+        if(stackItems == null) {
+            stackItems = new StackItem[parameterTypes.length];
+            for(int i=0;i<parameterTypes.length;++i)
+                stackItems[i] = new ParameterStackItem(i, parameterTypes[i]);
+        }
+        this.stackItems = stackItems;
+        this.methodRef = methodRef;
+        this.filter = filter;
+    }
+
+    @Override
+    public Type applyExact(MethodBuilder mb, Val[] parameters) {
+        methodRef.invoke(mb, stackItems, parameters);
+        if(filter != null)
+            filter.filter(mb);
+        return getReturnType();
+    }
+    
+    public MethodRef getMethodRef() {
+        return methodRef;
+    }
+    
+    @Override
+    public String toString() {
+        return methodRef.getName();
+    }
+
+    public final static int INCOMPARABLE = -2;
+    public final static int LESS = -1;
+    public final static int EQUAL = 0;
+    public final static int GREATER = 1;
+    
+    public int compareTo(JavaReferenceValidator validator, CallJava other) {
+        MethodRef m1 = methodRef;
+        MethodRef m2 = other.methodRef;
+        TypeDesc[] ps1 = m1.getParameterTypes();
+        TypeDesc[] ps2 = m2.getParameterTypes();
+        if(ps1.length != ps2.length)
+            return INCOMPARABLE;
+
+        boolean lessOrEqual = true;
+        boolean greaterOrEqual = true;
+        for(int i=0;i<ps1.length;++i) {
+            if(ps1[i].equals(ps2[i]))
+                continue;
+            if(!validator.isAssignableFrom(ps1[i], ps2[i])) {
+                lessOrEqual = false;
+            }
+            if(!validator.isAssignableFrom(ps2[i], ps1[i])) {
+                greaterOrEqual = false;
+            }
+        }
+        if(lessOrEqual) {
+            if(greaterOrEqual)
+                return EQUAL;
+            else
+                return LESS;
+        }
+        else {
+            if(greaterOrEqual)
+                return GREATER;
+            else
+                return INCOMPARABLE;
+        }
+    }
+    
+    @Override
+    public void prepare(MethodBuilder mb) {
+        for(StackItem item : stackItems)
+            item.prepare(mb);
+    }
+    
+    @Override
+    public void deconstruct(MethodBuilder mb, IVal parameter, Cont success,
+            Label failure) {
+        if(parameterTypes.length != 0)
+            super.deconstruct(mb, parameter, success, failure);
+        push(mb);
+        mb.push(parameter, getType());
+        mb.invokeVirtual(TypeDesc.OBJECT, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+        mb.ifZeroComparisonBranch(failure, "==");
+        mb.jump(success);
+    }
+}