]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaMethod.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / JavaMethod.java
1 package org.simantics.scl.compiler.constants;
2
3 import java.util.Arrays;
4
5 import org.cojen.classfile.TypeDesc;
6 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
7 import org.simantics.scl.compiler.internal.codegen.references.Val;
8 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
9 import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder;
10 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
11 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14
15 public class JavaMethod extends FunctionValue {
16     
17     String className;
18     String methodName;
19     
20     TypeDesc returnTypeDesc;
21     TypeDesc[] parameterTypeDescs;
22     
23     boolean virtual;
24     
25     public JavaMethod(boolean virtual, String className, String methodName,
26             Type effect,
27             TypeDesc returnTypeDesc, TypeDesc[] parameterTypeDescs,
28             Type returnType, Type ... parameterTypes) {
29         super(Types.freeVarsArray(
30                 Types.functionE(parameterTypes, effect, returnType)),
31                 effect,
32                 returnType, parameterTypes);
33         if(SCLCompilerConfiguration.DEBUG) {
34             if(className == null)
35                 throw new NullPointerException();
36             if(methodName == null)
37                 throw new NullPointerException();
38             if(parameterTypeDescs != null)
39                 for(TypeDesc td : parameterTypeDescs)
40                     if(td.equals(TypeDesc.VOID))
41                         throw new InternalCompilerError();
42         }
43         ClassBuilder.checkClassName(className);
44         this.virtual = virtual;
45         this.className = className;
46         this.methodName = methodName;
47         this.returnTypeDesc = returnTypeDesc;
48         this.parameterTypeDescs = parameterTypeDescs;
49     }
50     
51     public JavaMethod(boolean virtual, String className, String methodName, Type effect,
52             Type returnType, Type ... parameterTypes) {
53         this(virtual, className, methodName, effect, null, null, returnType, parameterTypes);
54     }
55    
56     @Override
57     public Type applyExact(MethodBuilder mb, Val[] parameters) {
58         if(returnTypeDesc == null || parameterTypeDescs == null) {
59             // This method may be called from multiple threads at the same time when returnTypeDesc
60             // and parameterTypeDescs are uninitialized. Double initialization is OK in this case,
61             // but because there are two fields, we have to check that both are initialized. 
62             JavaTypeTranslator tt = mb.getJavaTypeTranslator();
63             returnTypeDesc = tt.toTypeDesc(returnType);
64             parameterTypeDescs = JavaTypeTranslator.filterVoid(
65                     tt.toTypeDescs(Arrays.copyOfRange(parameterTypes, 1, parameterTypes.length)));
66         }
67               
68         mb.push(parameters, parameterTypes);
69         if(virtual)
70             mb.invokeVirtual(className, methodName, returnTypeDesc, parameterTypeDescs);
71         else
72             mb.invokeInterface(className, methodName, returnTypeDesc, parameterTypeDescs);
73         
74         return getReturnType();
75     }
76
77     @Override
78     public String toString() {
79         return className + "." + methodName;
80     }
81
82 }