1 package org.simantics.scl.compiler.internal.codegen.references;
\r
3 import java.util.ArrayList;
\r
4 import java.util.List;
\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
18 public final class ValRef implements IVal {
\r
19 public static final ValRef[] EMPTY_ARRAY = new ValRef[0];
\r
22 ValRef prev; // FreeVars with the same binding form a linked list
\r
24 ValRefBinder parent;
\r
28 * Just for deserialization
\r
30 public ValRef(Type[] parameters) {
\r
31 this.parameters = parameters;
\r
34 ValRef(Val binding, Type[] parameters) {
\r
35 //System.out.println("+ " + bindin g);
\r
36 this.parameters = parameters;
\r
37 setBinding(binding);
\r
40 public void setBinding(Val binding) {
\r
41 this.binding = binding;
\r
43 ValRef head = binding.occurrence;
\r
44 binding.occurrence = this;
\r
51 int removeModiId = -1;
\r
52 public void remove() {
\r
53 //System.out.println("- " + binding);
\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
66 if(SCLCompilerConfiguration.DEBUG) {
\r
71 removeModiId = SSASimplificationContext.modiId;
\r
74 public Val getBinding() {
\r
78 public ValRef getNext() {
\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
90 public ValRef createOccurrence() {
\r
91 return binding.createOccurrence(parameters);
\r
95 public ValRef createOccurrence(Type... otherParameters) {
\r
96 return binding.createOccurrence(Types.concat(parameters, otherParameters));
\r
100 public IVal createSpecialization(Type... otherParameters) {
\r
101 return new ValSpecialization(binding, Types.concat(parameters, otherParameters));
\r
104 public void setParent(ValRefBinder parent) {
\r
105 this.parent = parent;
\r
109 public Type getType() {
\r
110 if(parameters.length == 0)
\r
111 return binding.getType();
\r
113 return Types.instantiate(binding.getType(), parameters);
\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
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
130 public Type[] getTypeParameters() {
\r
134 public Type getTypeParameter(int i) {
\r
135 return parameters[i];
\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
148 public void push(MethodBuilder mb) {
\r
152 public ValRefBinder getParent() {
\r
156 public SSAFunction getParentFunction() {
\r
157 return parent.getParentFunction();
\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
178 public void setTypeParameters(Type[] parameters) {
\r
179 this.parameters = parameters;
\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
189 public ValRef copy() {
\r
190 return binding.createOccurrence(parameters);
\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
202 public void replaceBy(Val binding) {
\r
204 setBinding(binding);
\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
214 * Replaces this reference with an application
\r
216 public void replaceByApply(Val function, Val ... parameters) {
\r
217 getParent().replaceByApply(this, function, this.parameters, parameters);
\r
221 public Object realizeValue(TransientClassBuilder classLoader) {
\r
222 return binding.realizeValue(classLoader);
\r
226 public void setLabel(String label) {
\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