]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/CallJava.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / generic / CallJava.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/CallJava.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/CallJava.java
new file mode 100644 (file)
index 0000000..300f118
--- /dev/null
@@ -0,0 +1,90 @@
+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