]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Jump.java
SCL compiler generates line numbers to bytecode
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / ssa / exits / Jump.java
1 package org.simantics.scl.compiler.internal.codegen.ssa.exits;
2
3 import java.util.ArrayList;
4
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
7 import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
8 import org.simantics.scl.compiler.internal.codegen.references.Val;
9 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
10 import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
11 import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit;
12 import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
13 import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;
14 import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
15 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
16 import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
17 import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
18 import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
19 import org.simantics.scl.compiler.types.TVar;
20 import org.simantics.scl.compiler.types.Type;
21
22 public class Jump extends SSAExit implements ValRefBinder {
23     private ContRef target;
24     private ValRef[] parameters;
25     
26     public Jump(int lineNumber, ContRef target, ValRef ... parameters) {
27         super(lineNumber);
28         setTarget(target);
29         setParameters(parameters);
30     }
31     
32     public ContRef getTarget() {
33         return target;
34     }
35     
36     public void setTarget(ContRef target) {
37         this.target = target;
38         target.setParent(this);
39     }
40     
41     public ValRef[] getParameters() {
42         return parameters;
43     }
44     
45     public void setParameters(ValRef[] parameters) {
46         this.parameters = parameters;
47         for(ValRef parameter : parameters)
48             parameter.setParent(this);
49     }
50
51     @Override
52     public void generateCode(MethodBuilder mb) {
53         mb.lineNumber(lineNumber);
54         mb.jump(target, ValRef.getBindings(parameters));
55     }
56
57     @Override
58     public void toString(PrintingContext context) {
59         context.append(target);
60         for(ValRef parameter : parameters) {
61             context.append(' ');
62             context.append(parameter);
63         }
64         context.append('\n');
65         for(SSABlock block : getSuccessors())
66             context.addBlock(block);
67         
68     }
69
70     @Override
71     public void validate(SSAValidationContext context) {
72         context.validate(target);
73         if(target.getParent() != this)
74             throw new InternalCompilerError();
75         for(ValRef parameter : parameters) {
76             context.validate(parameter);
77             if(parameter.getParent() != this)
78                 throw new InternalCompilerError();
79         }
80         
81         Cont cont = target.getBinding();
82         context.assertEquals(cont.getArity(), parameters.length);
83         //for(int i=0;i<parameters.length;++i)
84         //    context.assertSubsumes(parameters[i].getType(), cont.getParameterType(i));
85     }    
86     
87     @Override
88     public void destroy() {
89         target.remove();
90         for(ValRef parameter : parameters)
91             parameter.remove();
92     }
93
94     @Override
95     public SSAExit copy(CopyContext context) {
96         return new Jump(lineNumber, context.copy(target), context.copy(parameters));
97     }
98     
99     @Override
100     public void replace(TVar[] vars, Type[] replacements) {
101         for(ValRef parameter : parameters)
102             parameter.replace(vars, replacements);
103     }
104
105     @Override
106     public void collectFreeVariables(SSAFunction function,
107             ArrayList<ValRef> vars) {
108         for(ValRef parameter : parameters)
109             parameter.collectFreeVariables(function, vars);        
110     }
111
112     @Override
113     public Cont addParametersInFrontOf(ContRef contRef, Val[] newParameters, Val[] oldParameters, Cont proxy) {
114         ValRef[] occurences = ValRef.createOccurrences(newParameters);
115         for(ValRef ref : occurences)
116             ref.setParent(this);
117         this.parameters = ValRef.concat(occurences, this.parameters);
118         return proxy;
119     }
120
121     public void setParameter(int position, ValRef parameter) {
122         parameters[position] = parameter;
123         parameter.setParent(this);
124     }
125
126     public ValRef getParameter(int position) {
127         return parameters[position];
128     }
129     
130     @Override
131     public boolean isJump(Cont cont, Val parameter) {        
132         return target.getBinding() == cont && 
133                 parameters.length == 1 && 
134                 parameters[0].getBinding() == parameter;
135     }
136
137     @Override
138     public SSABlock[] getSuccessors() {
139         Cont cont = target.getBinding();
140         if(cont instanceof SSABlock)
141             return new SSABlock[] {(SSABlock)cont};
142         else
143             return SSABlock.EMPTY_ARRAY;
144     }
145
146     @Override
147     public void forValRefs(ValRefVisitor visitor) {
148         for(ValRef parameter : parameters)
149             visitor.visit(parameter);
150     }
151
152     @Override
153     public void cleanup() {
154         for(ValRef parameter : parameters)
155             parameter.remove();
156     }
157 }