]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/Constant.java
b019c74705bc9c1a668496f49a4012cc5f444594
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / Constant.java
1 package org.simantics.scl.compiler.constants;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.objectweb.asm.Label;
5 import org.objectweb.asm.Opcodes;
6 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
7 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
8 import org.simantics.scl.compiler.internal.codegen.references.IVal;
9 import org.simantics.scl.compiler.internal.codegen.references.Val;
10 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
11 import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder;
12 import org.simantics.scl.compiler.internal.codegen.utils.JavaNamingPolicy;
13 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
14 import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;
15 import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
16 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
17 import org.simantics.scl.compiler.runtime.MutableClassLoader;
18 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
19 import org.simantics.scl.compiler.types.TVar;
20 import org.simantics.scl.compiler.types.Type;
21
22 import gnu.trove.map.hash.THashMap;
23
24 /**
25  * Constant is a subclass of Val that does not need to be
26  * copied when a function is copied.
27  * 
28  * @author Hannu Niemistö
29  */
30 public abstract class Constant extends Val {
31
32     public static boolean TRACE_REALIZATION = false;
33     
34     protected Type type;
35     
36     public Constant(Type type) {
37         this.type = type;
38     }
39     
40     @Override
41     public Type getType() {
42          return type;
43     }
44     
45     public int getArity() {
46         return 0;
47     }
48     
49     @Override
50     public void push(MethodBuilder mb) {
51         throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support push.");
52     }    
53     
54     /**
55      * Deconstructs the parameter and calls continuation with found components.
56      * If the parameter is not constructed with this constructor the execution jumps
57      * to failure. If failure is null, the deconstructor assumes that parameter can
58      * be deconstructed.
59      * @param mb
60      * @param parameter
61      * @param success
62      * @param failure, label where to jump if deconstruct fails. 
63      *        May be null, if deconstructing cannot fail.
64      */
65     public void deconstruct(MethodBuilder mb, IVal parameter, Cont success, Label failure) {
66         throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support deconstruct.");
67     }
68     
69     /**
70      * Returns -1, if the constant does not support deconstructing. Otherwise
71      * gives the tag of the constructor.
72      */
73     public int constructorTag() {
74         return -1;
75     }
76     
77     public void inline(SSASimplificationContext context, LetApply apply) {
78     }
79     
80     @Override
81     public Val copy(THashMap<TVar, TVar> tvarMap) {
82         return this;
83     }
84
85     @Override
86     public int getEffectiveArity() {     
87         return 0;
88     }
89     
90     @Override
91     public Object realizeValue(TransientClassBuilder builder) {
92         THashMap<Constant, Object> valueCache = builder.classLoader.getConstantCache();
93         if(valueCache != null) {
94             Object cachedResult = valueCache.get(this);
95             if(cachedResult != null)
96                 return cachedResult;
97         }
98         
99         String packageName = builder.classLoader.getFreshPackageName();
100         String moduleName = packageName + "/Temp";
101         JavaNamingPolicy policy = new JavaNamingPolicy(moduleName);
102         ModuleBuilder moduleBuilder = new ModuleBuilder(policy, builder.javaTypeTranslator);
103         
104         if(SCLCompilerConfiguration.TRACE_METHOD_CREATION)
105             System.out.println("Create class " + policy.getModuleClassName());
106         ClassBuilder classFile = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, policy.getModuleClassName(), "java/lang/Object");
107         classFile.setSourceFile("_SCL_RealizedValue");
108         
109         classFile.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "VALUE", TypeDesc.OBJECT);
110         
111         MethodBuilder mb = classFile.addInitializer();
112         
113         mb.pushBoxed(this);
114         mb.storeStaticField(classFile.getClassName(), "VALUE", TypeDesc.OBJECT);
115         mb.returnVoid();
116         mb.finish();
117         
118         moduleBuilder.addClass(classFile);
119         
120         MutableClassLoader classLoader = builder.classLoader;
121         classLoader.addClasses(moduleBuilder.getClasses());
122         try {
123             Object result = classLoader.loadClass(policy.getModuleClassName().replace('/', '.')).getField("VALUE").get(null);
124             if(valueCache != null) {
125                 valueCache.put(this, result);
126                 if(TRACE_REALIZATION)
127                     System.out.println("/REALIZED/ " + this + " " + getClass().getSimpleName());
128             }
129             return result;
130         } catch (IllegalAccessException e) {
131             throw new InternalCompilerError(e);
132         } catch (ClassNotFoundException e) {
133             throw new InternalCompilerError(e);
134         } catch (IllegalArgumentException e) {
135             throw new InternalCompilerError(e);
136         } catch (SecurityException e) {
137             throw new InternalCompilerError(e);
138         } catch (NoSuchFieldException e) {
139             throw new InternalCompilerError(e);
140         }
141     }
142 }