1 package org.simantics.scl.compiler.internal.codegen.references;
3 import java.util.ArrayList;
6 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
7 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
8 import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;
9 import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
10 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
11 import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
12 import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;
13 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
14 import org.simantics.scl.compiler.types.TVar;
15 import org.simantics.scl.compiler.types.Type;
16 import org.simantics.scl.compiler.types.Types;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
20 public final class ValRef implements IVal {
21 private static final Logger LOGGER = LoggerFactory.getLogger(ValRef.class);
22 public static final ValRef[] EMPTY_ARRAY = new ValRef[0];
25 ValRef prev; // FreeVars with the same binding form a linked list
31 * Just for deserialization
33 public ValRef(Type[] parameters) {
34 this.parameters = parameters;
37 ValRef(Val binding, Type[] parameters) {
38 //System.out.println("+ " + bindin g);
39 this.parameters = parameters;
43 public void setBinding(Val binding) {
44 this.binding = binding;
46 ValRef head = binding.occurrence;
47 binding.occurrence = this;
54 int removeModiId = -1;
55 public void remove() {
56 //System.out.println("- " + binding);
59 binding.occurrence = next;
60 } catch(NullPointerException e) {
61 LOGGER.error("removeModiId = " + removeModiId);
62 LOGGER.error("current ModiId = " + SSASimplificationContext.modiId, e);
63 throw new InternalCompilerError("The ValRef has already been removed.");
69 if(SCLCompilerConfiguration.DEBUG) {
74 removeModiId = SSASimplificationContext.modiId;
77 public Val getBinding() {
81 public ValRef getNext() {
85 public static Val[] getBindings(ValRef[] refs) {
86 Val[] result = new Val[refs.length];
87 for(int i=0;i<refs.length;++i)
88 result[i] = refs[i].getBinding();
93 public ValRef createOccurrence() {
94 return binding.createOccurrence(parameters);
98 public ValRef createOccurrence(Type... otherParameters) {
99 return binding.createOccurrence(Types.concat(parameters, otherParameters));
103 public IVal createSpecialization(Type... otherParameters) {
104 return new ValSpecialization(binding, Types.concat(parameters, otherParameters));
107 public void setParent(ValRefBinder parent) {
108 this.parent = parent;
112 public Type getType() {
113 if(parameters.length == 0)
114 return binding.getType();
116 return Types.instantiate(binding.getType(), parameters);
119 public static ValRef[] createOccurrences(IVal[] vals) {
120 ValRef[] result = new ValRef[vals.length];
121 for(int i=0;i<vals.length;++i)
122 result[i] = vals[i].createOccurrence();
126 public static <T extends IVal> ValRef[] createOccurrences(List<T> vals) {
127 ValRef[] result = new ValRef[vals.size()];
128 for(int i=0;i<vals.size();++i)
129 result[i] = vals.get(i).createOccurrence();
133 public Type[] getTypeParameters() {
137 public Type getTypeParameter(int i) {
138 return parameters[i];
141 public static ValRef[] concat(ValRef[] refs1, ValRef[] refs2) {
142 ValRef[] result = new ValRef[refs1.length + refs2.length];
143 for(int i=0;i<refs1.length;++i)
144 result[i] = refs1[i];
145 for(int i=0;i<refs2.length;++i)
146 result[refs1.length + i] = refs2[i];
151 public void push(MethodBuilder mb) {
155 public ValRefBinder getParent() {
159 public SSAFunction getParentFunction() {
160 return parent.getParentFunction();
163 public void replace(TVar[] vars, Type[] replacements) {
164 for(int i=0;i<parameters.length;++i) {
165 Type oldType = parameters[i];
166 Type newType = parameters[i].replace(vars, replacements);
167 if(oldType != newType) {
168 Type[] newParameters = new Type[parameters.length];
170 newParameters[j] = parameters[j];
171 newParameters[i] = newType;
172 for(int j=i+1;j<parameters.length;++j)
173 newParameters[j] = parameters[j].replace(vars, replacements);
174 this.parameters = newParameters;
181 public void setTypeParameters(Type[] parameters) {
182 this.parameters = parameters;
185 public static ValRef[] copy(ValRef[] refs) {
186 ValRef[] result = new ValRef[refs.length];
187 for(int i=0;i<refs.length;++i)
188 result[i] = refs[i].copy();
192 public ValRef copy() {
193 return binding.createOccurrence(parameters);
196 public void collectFreeVariables(SSAFunction function,
197 ArrayList<ValRef> vars) {
198 if(binding instanceof BoundVar) {
199 BoundVar var = (BoundVar)binding;
200 if(var.getFunctionParent() != function)
205 public void replaceBy(Val binding) {
211 public Type apply(MethodBuilder mb, Type[] typeParameters,
213 return binding.apply(mb, Types.concat(this.parameters, typeParameters), parameters);
217 * Replaces this reference with an application
219 public void replaceByApply(Val function, Val ... parameters) {
220 getParent().replaceByApply(this, function, this.parameters, parameters);
224 public Object realizeValue(TransientClassBuilder classLoader) {
225 return binding.realizeValue(classLoader);
229 public void setLabel(String label) {
232 public void updateParentEffect() {
233 if(parent instanceof LetApply) {
234 LetApply apply = (LetApply)parent;
235 if(apply.getFunction() == this)
236 apply.updateEffect();