/* * Copyright (C) 2010-2016 JPEXS, All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. */ package com.jpexs.decompiler.flash.abc.avm2.fastavm2; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import java.util.HashSet; import java.util.List; import java.util.Set; /** * * @author JPEXS */ public class AVM2InstructionItem { public AVM2Instruction ins; public AVM2InstructionItem prev; public AVM2InstructionItem next; private AVM2InstructionItem jumpTarget; public Set<AVM2InstructionItem> jumpsHere; public Set<AVM2InstructionItem> lastInsOf; private List<AVM2InstructionItem> containerLastInstructions; // 1 means reachable, 2 means reachable and processed int reachable; public boolean excluded; public AVM2InstructionItem(AVM2Instruction ins) { this.ins = ins; } public boolean isJumpTarget() { return jumpsHere != null && !jumpsHere.isEmpty(); } public int jumpsHereSize() { return jumpsHere == null ? 0 : jumpsHere.size(); } public boolean isContainerLastInstruction() { return lastInsOf != null && !lastInsOf.isEmpty(); } public void removeJumpTarget() { if (jumpTarget == null) { return; } if (jumpTarget.jumpsHere != null) { jumpTarget.jumpsHere.remove(this); } jumpTarget = null; } public AVM2InstructionItem getJumpTarget() { return jumpTarget; } public AVM2Instruction getJumpTargetInstruction() { return jumpTarget == null ? null : jumpTarget.ins; } public void setJumpTarget(AVM2InstructionItem item) { removeJumpTarget(); if (item == null) { return; } if (item.jumpsHere == null) { item.jumpsHere = new HashSet<>(); } item.jumpsHere.add(this); jumpTarget = item; } public List<AVM2InstructionItem> getContainerLastInstructions() { return containerLastInstructions; } public void removeContainerLastInstructions() { if (containerLastInstructions == null) { return; } for (AVM2InstructionItem lastIns : containerLastInstructions) { if (lastIns.lastInsOf != null) { lastIns.lastInsOf.remove(this); } } containerLastInstructions = null; } public void replaceContainerLastInstruction(AVM2InstructionItem oldItem, AVM2InstructionItem newItem) { if (containerLastInstructions == null) { return; } for (int i = 0; i < containerLastInstructions.size(); i++) { if (containerLastInstructions.get(i) == oldItem) { containerLastInstructions.set(i, newItem); if (oldItem.lastInsOf != null) { oldItem.lastInsOf.remove(this); } newItem.ensureLastInstructionOf().add(this); } } } public void setContainerLastInstructions(List<AVM2InstructionItem> lastInstructions) { removeContainerLastInstructions(); for (AVM2InstructionItem lastIns : lastInstructions) { lastIns.ensureLastInstructionOf().add(this); } containerLastInstructions = lastInstructions; } private Set<AVM2InstructionItem> ensureLastInstructionOf() { if (lastInsOf == null) { lastInsOf = new HashSet<>(); } return lastInsOf; } public boolean isExcluded() { return excluded; } }