001/* 002 * Copyright 2010-2013 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.jetbrains.jet.lang.cfg.pseudocode; 018 019import com.google.common.collect.Lists; 020import com.google.common.collect.Maps; 021import org.jetbrains.annotations.NotNull; 022import org.jetbrains.jet.lang.cfg.Label; 023 024import java.util.*; 025 026public class NondeterministicJumpInstruction extends InstructionImpl{ 027 private Instruction next; 028 private final List<Label> targetLabels; 029 private final Map<Label, Instruction> resolvedTargets; 030 031 public NondeterministicJumpInstruction(List<Label> targetLabels) { 032 this.targetLabels = Lists.newArrayList(targetLabels); 033 resolvedTargets = Maps.newLinkedHashMap(); 034 } 035 036 public NondeterministicJumpInstruction(Label targetLabel) { 037 this(Lists.newArrayList(targetLabel)); 038 } 039 040 public List<Label> getTargetLabels() { 041 return targetLabels; 042 } 043 044 public Map<Label, Instruction> getResolvedTargets() { 045 return resolvedTargets; 046 } 047 048 public void setResolvedTarget(Label label, Instruction resolvedTarget) { 049 Instruction target = outgoingEdgeTo(resolvedTarget); 050 resolvedTargets.put(label, target); 051 } 052 053 public Instruction getNext() { 054 return next; 055 } 056 public void setNext(Instruction next) { 057 this.next = outgoingEdgeTo(next); 058 } 059 060 @Override 061 public void accept(InstructionVisitor visitor) { 062 visitor.visitNondeterministicJump(this); 063 } 064 065 @NotNull 066 @Override 067 public Collection<Instruction> getNextInstructions() { 068 List<Instruction> targetInstructions = Lists.newArrayList(getResolvedTargets().values()); 069 targetInstructions.add(getNext()); 070 return targetInstructions; 071 } 072 073 @Override 074 public String toString() { 075 StringBuilder sb = new StringBuilder(); 076 sb.append("jmp?("); 077 for (Iterator<Label> iterator = targetLabels.iterator(); iterator.hasNext(); ) { 078 Label targetLabel = iterator.next(); 079 sb.append(targetLabel.getName()); 080 if (iterator.hasNext()) { 081 sb.append(", "); 082 } 083 } 084 sb.append(")"); 085 return sb.toString(); 086 } 087 088 @Override 089 protected Instruction createCopy() { 090 return createCopy(getTargetLabels()); 091 } 092 093 @NotNull 094 public final Instruction copy(@NotNull List<Label> newTargetLabels) { 095 return updateCopyInfo(createCopy(newTargetLabels)); 096 } 097 098 private Instruction createCopy(@NotNull List<Label> newTargetLabels) { 099 return new NondeterministicJumpInstruction(newTargetLabels); 100 } 101}