1 package org.simantics.scl.compiler.constants;
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;
22 import gnu.trove.map.hash.THashMap;
25 * Constant is a subclass of Val that does not need to be
26 * copied when a function is copied.
28 * @author Hannu Niemistö
30 public abstract class Constant extends Val {
32 public static boolean TRACE_REALIZATION = false;
36 public Constant(Type type) {
41 public Type getType() {
45 public int getArity() {
50 public void push(MethodBuilder mb) {
51 throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support push.");
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
62 * @param failure, label where to jump if deconstruct fails.
63 * May be null, if deconstructing cannot fail.
65 public void deconstruct(MethodBuilder mb, IVal parameter, Cont success, Label failure) {
66 throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support deconstruct.");
70 * Returns -1, if the constant does not support deconstructing. Otherwise
71 * gives the tag of the constructor.
73 public int constructorTag() {
77 public void inline(SSASimplificationContext context, LetApply apply) {
81 public Val copy(THashMap<TVar, TVar> tvarMap) {
86 public int getEffectiveArity() {
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)
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);
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");
109 classFile.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "VALUE", TypeDesc.OBJECT);
111 MethodBuilder mb = classFile.addInitializer();
114 mb.storeStaticField(classFile.getClassName(), "VALUE", TypeDesc.OBJECT);
118 moduleBuilder.addClass(classFile);
120 MutableClassLoader classLoader = builder.classLoader;
121 classLoader.addClasses(moduleBuilder.getClasses());
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());
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);