1 package org.simantics.scl.compiler.internal.codegen.ssa.exits;
\r
3 import java.util.ArrayList;
\r
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
\r
6 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
\r
7 import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
\r
8 import org.simantics.scl.compiler.internal.codegen.references.Val;
\r
9 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
\r
10 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
\r
11 import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit;
\r
12 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
\r
13 import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;
\r
14 import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
\r
15 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
\r
16 import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
\r
17 import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
\r
18 import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
\r
19 import org.simantics.scl.compiler.types.TVar;
\r
20 import org.simantics.scl.compiler.types.Type;
\r
22 public class Jump extends SSAExit implements ValRefBinder {
\r
23 private ContRef target;
\r
24 private ValRef[] parameters;
\r
26 public Jump(ContRef target, ValRef ... parameters) {
\r
28 setParameters(parameters);
\r
31 public ContRef getTarget() {
\r
35 public void setTarget(ContRef target) {
\r
36 this.target = target;
\r
37 target.setParent(this);
\r
40 public ValRef[] getParameters() {
\r
44 public void setParameters(ValRef[] parameters) {
\r
45 this.parameters = parameters;
\r
46 for(ValRef parameter : parameters)
\r
47 parameter.setParent(this);
\r
51 public void generateCode(MethodBuilder mb) {
\r
52 mb.jump(target, ValRef.getBindings(parameters));
\r
56 public void toString(PrintingContext context) {
\r
57 context.append(target);
\r
58 for(ValRef parameter : parameters) {
\r
59 context.append(' ');
\r
60 context.append(parameter);
\r
62 context.append('\n');
\r
63 for(SSABlock block : getSuccessors())
\r
64 context.addBlock(block);
\r
69 public void validate(SSAValidationContext context) {
\r
70 context.validate(target);
\r
71 if(target.getParent() != this)
\r
72 throw new InternalCompilerError();
\r
73 for(ValRef parameter : parameters) {
\r
74 context.validate(parameter);
\r
75 if(parameter.getParent() != this)
\r
76 throw new InternalCompilerError();
\r
79 Cont cont = target.getBinding();
\r
80 context.assertEquals(cont.getArity(), parameters.length);
\r
81 //for(int i=0;i<parameters.length;++i)
\r
82 // context.assertSubsumes(parameters[i].getType(), cont.getParameterType(i));
\r
86 public void destroy() {
\r
88 for(ValRef parameter : parameters)
\r
93 public SSAExit copy(CopyContext context) {
\r
94 return new Jump(context.copy(target), context.copy(parameters));
\r
98 public void replace(TVar[] vars, Type[] replacements) {
\r
99 for(ValRef parameter : parameters)
\r
100 parameter.replace(vars, replacements);
\r
104 public void collectFreeVariables(SSAFunction function,
\r
105 ArrayList<ValRef> vars) {
\r
106 for(ValRef parameter : parameters)
\r
107 parameter.collectFreeVariables(function, vars);
\r
111 public Cont addParametersInFrontOf(ContRef contRef, Val[] newParameters, Val[] oldParameters, Cont proxy) {
\r
112 ValRef[] occurences = ValRef.createOccurrences(newParameters);
\r
113 for(ValRef ref : occurences)
\r
114 ref.setParent(this);
\r
115 this.parameters = ValRef.concat(occurences, this.parameters);
\r
119 public void setParameter(int position, ValRef parameter) {
\r
120 parameters[position] = parameter;
\r
121 parameter.setParent(this);
\r
124 public ValRef getParameter(int position) {
\r
125 return parameters[position];
\r
129 public boolean isJump(Cont cont, Val parameter) {
\r
130 return target.getBinding() == cont &&
\r
131 parameters.length == 1 &&
\r
132 parameters[0].getBinding() == parameter;
\r
136 public SSABlock[] getSuccessors() {
\r
137 Cont cont = target.getBinding();
\r
138 if(cont instanceof SSABlock)
\r
139 return new SSABlock[] {(SSABlock)cont};
\r
141 return SSABlock.EMPTY_ARRAY;
\r
145 public void forValRefs(ValRefVisitor visitor) {
\r
146 for(ValRef parameter : parameters)
\r
147 visitor.visit(parameter);
\r