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
017 package org.jetbrains.jet.lang.cfg.pseudocode;
018
019 import com.google.common.collect.Lists;
020 import com.google.common.collect.Maps;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.jet.lang.cfg.Label;
023
024 import java.util.*;
025
026 public 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 }