package org.simantics.scl.compiler.internal.codegen.ssa.exits; import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.internal.codegen.continuations.Cont; import org.simantics.scl.compiler.internal.codegen.continuations.ContRef; import org.simantics.scl.compiler.internal.codegen.references.Val; import org.simantics.scl.compiler.internal.codegen.references.ValRef; import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock; import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit; import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder; import org.simantics.scl.compiler.internal.codegen.utils.CopyContext; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext; import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext; import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; public class Jump extends SSAExit implements ValRefBinder { private ContRef target; private ValRef[] parameters; public Jump(ContRef target, ValRef ... parameters) { setTarget(target); setParameters(parameters); } public ContRef getTarget() { return target; } public void setTarget(ContRef target) { this.target = target; target.setParent(this); } public ValRef[] getParameters() { return parameters; } public void setParameters(ValRef[] parameters) { this.parameters = parameters; for(ValRef parameter : parameters) parameter.setParent(this); } @Override public void generateCode(MethodBuilder mb) { mb.jump(target, ValRef.getBindings(parameters)); } @Override public void toString(PrintingContext context) { context.append(target); for(ValRef parameter : parameters) { context.append(' '); context.append(parameter); } context.append('\n'); for(SSABlock block : getSuccessors()) context.addBlock(block); } @Override public void validate(SSAValidationContext context) { context.validate(target); if(target.getParent() != this) throw new InternalCompilerError(); for(ValRef parameter : parameters) { context.validate(parameter); if(parameter.getParent() != this) throw new InternalCompilerError(); } Cont cont = target.getBinding(); context.assertEquals(cont.getArity(), parameters.length); //for(int i=0;i vars) { for(ValRef parameter : parameters) parameter.collectFreeVariables(function, vars); } @Override public Cont addParametersInFrontOf(ContRef contRef, Val[] newParameters, Val[] oldParameters, Cont proxy) { ValRef[] occurences = ValRef.createOccurrences(newParameters); for(ValRef ref : occurences) ref.setParent(this); this.parameters = ValRef.concat(occurences, this.parameters); return proxy; } public void setParameter(int position, ValRef parameter) { parameters[position] = parameter; parameter.setParent(this); } public ValRef getParameter(int position) { return parameters[position]; } @Override public boolean isJump(Cont cont, Val parameter) { return target.getBinding() == cont && parameters.length == 1 && parameters[0].getBinding() == parameter; } @Override public SSABlock[] getSuccessors() { Cont cont = target.getBinding(); if(cont instanceof SSABlock) return new SSABlock[] {(SSABlock)cont}; else return SSABlock.EMPTY_ARRAY; } @Override public void forValRefs(ValRefVisitor visitor) { for(ValRef parameter : parameters) visitor.visit(parameter); } }