]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/ValRef.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / references / ValRef.java
1 package org.simantics.scl.compiler.internal.codegen.references;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.List;\r
5 \r
6 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
7 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
8 import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;\r
9 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
10 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
11 import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
12 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;\r
13 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
14 import org.simantics.scl.compiler.types.TVar;\r
15 import org.simantics.scl.compiler.types.Type;\r
16 import org.simantics.scl.compiler.types.Types;\r
17 \r
18 public final class ValRef implements IVal {\r
19     public static final ValRef[] EMPTY_ARRAY = new ValRef[0];\r
20 \r
21     Val binding;\r
22     ValRef prev; // FreeVars with the same binding form a linked list\r
23     ValRef next;     \r
24     ValRefBinder parent;\r
25     Type[] parameters;\r
26     \r
27     /**\r
28      * Just for deserialization\r
29      */\r
30     public ValRef(Type[] parameters) {\r
31         this.parameters = parameters;\r
32     }\r
33     \r
34     ValRef(Val binding, Type[] parameters) {\r
35         //System.out.println("+ " + bindin g);\r
36         this.parameters = parameters;        \r
37         setBinding(binding);\r
38     }    \r
39     \r
40     public void setBinding(Val binding) {\r
41         this.binding = binding;\r
42         \r
43         ValRef head = binding.occurrence;\r
44         binding.occurrence = this;\r
45         this.next = head;\r
46         this.prev = null;\r
47         if(head != null)\r
48             head.prev = this;\r
49     }\r
50     \r
51     int removeModiId = -1;\r
52     public void remove() {\r
53         //System.out.println("- " + binding);\r
54         if(prev == null)\r
55             try {\r
56                 binding.occurrence = next;\r
57             } catch(NullPointerException e) {\r
58                 System.err.println("removeModiId = " + removeModiId);\r
59                 System.err.println("current ModiId = " + SSASimplificationContext.modiId);\r
60                 throw new InternalCompilerError("The ValRef has already been removed.");\r
61             }\r
62         else\r
63             prev.next = next;\r
64         if(next != null)\r
65             next.prev = prev;\r
66         if(SCLCompilerConfiguration.DEBUG) {\r
67             next = null;\r
68             prev = null;\r
69             binding = null;\r
70         }\r
71         removeModiId = SSASimplificationContext.modiId;\r
72     }\r
73     \r
74     public Val getBinding() {\r
75         return binding;\r
76     }\r
77     \r
78     public ValRef getNext() {\r
79         return next;\r
80     }\r
81     \r
82     public static Val[] getBindings(ValRef[] refs) {\r
83         Val[] result = new Val[refs.length];\r
84         for(int i=0;i<refs.length;++i)\r
85             result[i] = refs[i].getBinding();\r
86         return result;\r
87     }\r
88 \r
89     @Override\r
90     public ValRef createOccurrence() {\r
91         return binding.createOccurrence(parameters);\r
92     }\r
93 \r
94     @Override\r
95     public ValRef createOccurrence(Type... otherParameters) {\r
96         return binding.createOccurrence(Types.concat(parameters, otherParameters));\r
97     }\r
98     \r
99     @Override\r
100     public IVal createSpecialization(Type... otherParameters) {\r
101         return new ValSpecialization(binding, Types.concat(parameters, otherParameters));\r
102     }\r
103 \r
104     public void setParent(ValRefBinder parent) {\r
105         this.parent = parent;\r
106     }\r
107     \r
108     @Override\r
109     public Type getType() {\r
110         if(parameters.length == 0)\r
111             return binding.getType();\r
112         else\r
113             return Types.instantiate(binding.getType(), parameters); \r
114     }\r
115     \r
116     public static ValRef[] createOccurrences(IVal[] vals) {\r
117         ValRef[] result = new ValRef[vals.length];\r
118         for(int i=0;i<vals.length;++i)\r
119             result[i] = vals[i].createOccurrence();\r
120         return result;\r
121     }\r
122     \r
123     public static <T extends IVal> ValRef[] createOccurrences(List<T> vals) {\r
124         ValRef[] result = new ValRef[vals.size()];\r
125         for(int i=0;i<vals.size();++i)\r
126             result[i] = vals.get(i).createOccurrence();\r
127         return result;\r
128     }\r
129     \r
130     public Type[] getTypeParameters() {\r
131         return parameters;\r
132     }\r
133     \r
134     public Type getTypeParameter(int i) {\r
135         return parameters[i];\r
136     }\r
137 \r
138     public static ValRef[] concat(ValRef[] refs1, ValRef[] refs2) {\r
139         ValRef[] result = new ValRef[refs1.length + refs2.length];\r
140         for(int i=0;i<refs1.length;++i)\r
141             result[i] = refs1[i];\r
142         for(int i=0;i<refs2.length;++i)\r
143             result[refs1.length + i] = refs2[i];\r
144         return result;\r
145     }\r
146     \r
147     @Override\r
148     public void push(MethodBuilder mb) {\r
149         binding.push(mb);\r
150     }\r
151     \r
152     public ValRefBinder getParent() {\r
153         return parent;\r
154     }\r
155     \r
156     public SSAFunction getParentFunction() {\r
157         return parent.getParentFunction();\r
158     }\r
159     \r
160     public void replace(TVar[] vars, Type[] replacements) {\r
161         for(int i=0;i<parameters.length;++i) {\r
162             Type oldType = parameters[i];\r
163             Type newType = parameters[i].replace(vars, replacements);\r
164             if(oldType != newType) {\r
165                 Type[] newParameters = new Type[parameters.length];\r
166                 for(int j=0;j<i;++j)\r
167                     newParameters[j] = parameters[j];\r
168                 newParameters[i] = newType;\r
169                 for(int j=i+1;j<parameters.length;++j)\r
170                     newParameters[j] = parameters[j].replace(vars, replacements);\r
171                 this.parameters = newParameters;\r
172                 return;\r
173             }\r
174             \r
175         }\r
176     }\r
177 \r
178     public void setTypeParameters(Type[] parameters) {\r
179         this.parameters = parameters;\r
180     }\r
181     \r
182     public static ValRef[] copy(ValRef[] refs) {\r
183         ValRef[] result = new ValRef[refs.length];\r
184         for(int i=0;i<refs.length;++i)\r
185             result[i] = refs[i].copy();\r
186         return result;\r
187     }\r
188 \r
189     public ValRef copy() {\r
190         return binding.createOccurrence(parameters);\r
191     }\r
192 \r
193     public void collectFreeVariables(SSAFunction function,\r
194             ArrayList<ValRef> vars) {\r
195         if(binding instanceof BoundVar) {\r
196             BoundVar var = (BoundVar)binding;\r
197             if(var.getFunctionParent() != function)\r
198                 vars.add(this);\r
199         }\r
200     }\r
201 \r
202     public void replaceBy(Val binding) {\r
203         remove();\r
204         setBinding(binding);\r
205     }\r
206     \r
207     @Override\r
208     public Type apply(MethodBuilder mb, Type[] typeParameters,\r
209             Val... parameters) {\r
210         return binding.apply(mb, Types.concat(this.parameters, typeParameters), parameters);\r
211     }\r
212 \r
213     /**\r
214      * Replaces this reference with an application\r
215      */\r
216     public void replaceByApply(Val function, Val ... parameters) {\r
217         getParent().replaceByApply(this, function, this.parameters, parameters);\r
218     }\r
219     \r
220     @Override\r
221     public Object realizeValue(TransientClassBuilder classLoader) {\r
222         return binding.realizeValue(classLoader); \r
223     }\r
224 \r
225     @Override\r
226     public void setLabel(String label) {\r
227     }\r
228 \r
229     public void updateParentEffect() {\r
230         if(parent instanceof LetApply) {\r
231             LetApply apply = (LetApply)parent;\r
232             if(apply.getFunction() == this)\r
233                 apply.updateEffect();\r
234         }\r
235     }\r
236 }\r