]> gerrit.simantics Code Review - simantics/platform.git/blob - constants/singletons/JustConstant.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / constants / singletons / JustConstant.java
1 package org.simantics.scl.compiler.constants.singletons;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.objectweb.asm.Label;
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.constants.FunctionValue;
7 import org.simantics.scl.compiler.constants.GetPrimitiveConstant;
8 import org.simantics.scl.compiler.constants.LocalVariableConstant;
9 import org.simantics.scl.compiler.constants.NoRepConstant;
10 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
11 import org.simantics.scl.compiler.internal.codegen.references.IVal;
12 import org.simantics.scl.compiler.internal.codegen.references.Val;
13 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
14 import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
15 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
16 import org.simantics.scl.compiler.types.TVar;
17 import org.simantics.scl.compiler.types.Type;
18 import org.simantics.scl.compiler.types.Types;
19 import org.simantics.scl.compiler.types.exceptions.MatchException;
20 import org.simantics.scl.compiler.types.kinds.Kinds;
21
22 public class JustConstant extends FunctionValue {
23     
24     private static final TVar A = Types.var(Kinds.STAR);
25     public static final JustConstant INSTANCE = new JustConstant();
26     
27     private JustConstant() {
28         super(new TVar[] {A}, Types.NO_EFFECTS, Types.apply(Types.MAYBE, A), A);
29     }
30     
31     @Override
32     public Type applyExact(MethodBuilder mb, Val[] parameters) {                
33         parameters[0].push(mb);
34         mb.box(parameters[0].getType());
35         return getReturnType();
36     }
37     
38     @Override
39     public void deconstruct(MethodBuilder mb, IVal parameter,
40             Cont success, Label failure) {
41         Type componentType;
42         try {
43             componentType = Types.matchApply(Types.MAYBE, parameter.getType());
44         } catch (MatchException e) {
45             throw new InternalCompilerError();
46         }
47         TypeDesc componentTypeDesc =
48                 mb.getJavaTypeTranslator().toTypeDesc(componentType);
49         
50         if(failure == null) {
51             IVal val = componentTypeDesc.isPrimitive() 
52                     ? new GetPrimitiveConstant(componentType, parameter, componentTypeDesc)
53                     : parameter;
54             mb.jump(success, val);
55         }
56         else {
57             Label failureLabel = mb.createLabel();
58             
59             parameter.push(mb);
60             mb.dup();
61             mb.ifNullBranch(failureLabel, true);
62             
63             if(componentTypeDesc.equals(TypeDesc.VOID)) {
64                 mb.pop();
65                 mb.jump(success, new NoRepConstant(componentType));
66             }
67             else {
68                 if(componentTypeDesc.isPrimitive())
69                     mb.convert(JavaTypeTranslator.toObjectType(componentTypeDesc), componentTypeDesc);
70                 
71                 LocalVariable lv = mb.createLocalVariable("temp", componentTypeDesc);
72                 mb.storeLocal(lv);
73                 
74                 mb.jump(success, new LocalVariableConstant(componentType, lv));
75             }
76             
77             //
78             mb.setLocation(failureLabel);
79             mb.pop();
80             mb.branch(failure);
81         }
82     }
83     public int constructorTag() {
84         return 1;
85     }
86     @Override
87     public String toString() {
88         return "Just";
89     }
90 }