Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.rsxml.handler.analysis;
- import com.rsxml.*;
- import com.rsxml.util.*;
- import org.apache.commons.collections4.*;
- import org.apache.commons.collections4.multimap.*;
- import org.apache.commons.lang3.*;
- import org.objectweb.asm.tree.*;
- import org.objectweb.asm.tree.analysis.*;
- import java.io.*;
- import java.util.*;
- import java.util.concurrent.atomic.*;
- /**
- * @author Caleb Whiting
- * <p>
- * Represents a branch of a stack tree.
- */
- public class StackBranch {
- /**
- * The user-defined ID of this branch.
- */
- private String id;
- /**
- * The properties of the instruction this represents.
- */
- private final Map<String, Object> properties = new LinkedHashMap<>();
- /**
- * The branches of this branch.
- */
- private final List<StackBranch> branches = new LinkedList<>();
- /**
- * Gets the properties of the instruction this represents.
- *
- * @return {@link StackBranch#properties}.
- */
- public Map<String, Object> getProperties() {
- return properties;
- }
- /**
- * Gets the branches of this branch.
- *
- * @return {@link StackBranch#branches}.
- */
- public List<StackBranch> getBranches() {
- return branches;
- }
- /**
- * Gets the user-defined ID of this branch.
- *
- * @return {@link StackBranch#id}.
- */
- public String getId() {
- return id;
- }
- /**
- * Sets the user-defined ID of this branch.
- *
- * @param id The user-defined ID of this branch.
- */
- public void setId(String id) {
- this.id = id;
- }
- /**
- * Search the given instructions for this stack branch, and it's branches.
- *
- * @param ctx The context in which this is being handled.
- * @param instructions The instructions of the method to search.
- * @param frames The frames of the method to search.
- * @param index The start index of the instructions to search.
- * @param result The map in which to store the results of this search.
- * @param minIndex The minimum index of the stack tree that this is a branch of
- * @return true if this search was successful; otherwise false.
- */
- public boolean accept(Context ctx, AbstractInsnNode[] instructions, Frame<SourceValue>[] frames,
- int index, MultiValuedMap<String, AbstractInsnNode> result, AtomicInteger minIndex) {
- AbstractInsnNode instruction = instructions[index];
- Frame<SourceValue> frame = frames[index];
- /* Check properties */
- for (Map.Entry<String, Object> entry : getProperties().entrySet()) {
- Object o = instruction.getProperty(entry.getKey(), ctx);
- if (o == null) {
- return false;
- }
- if (o.toString().equals(entry.getValue().toString())) {
- continue;
- }
- return false;
- }
- MultiValuedMap<String, AbstractInsnNode> subResult = new HashSetValuedHashMap<>();
- if (getBranches().size() > 0) {
- if (frame == null) {
- return false;
- }
- /* Check stack */
- AbstractInsnNode[] stack = frame.compute(instructions, frames);
- if (getBranches().size() > stack.length) {
- return false;
- }
- for (int branchIndex = 0; branchIndex < getBranches().size(); branchIndex++) {
- AbstractInsnNode value = stack[stack.length - getBranches().size() + branchIndex];
- if (value == null || !getBranches().get(branchIndex).accept(ctx, instructions, frames, value.getIndex(), subResult, minIndex)) {
- return false;
- }
- }
- }
- result.putAll(subResult);
- /* Register instruction */
- if (getId() != null && getId().length() > 0) {
- result.put(getId(), instruction);
- }
- minIndex.set(Integer.min(minIndex.get(), instruction.getIndex()));
- return true;
- }
- public void print(PrintStream out, int depth) {
- String prefix = StringUtils.repeat("\t", depth);
- out.println(prefix + this);
- if (getBranches().size() > 0) {
- out.println(prefix + "{");
- for (StackBranch branch : getBranches()) {
- branch.print(out, depth + 1);
- }
- out.println(prefix + "}");
- }
- }
- @Override
- public String toString() {
- Map<String, Object> properties = new LinkedHashMap<>(this.properties);
- if (properties.containsKey("opcode")) {
- properties.put("opcode", InsnUtils.getOpcodeName((Integer) properties.get("opcode")));
- }
- if (properties.containsKey("type")) {
- properties.put("type", InsnUtils.getTypeName((Integer) properties.get("type")));
- }
- return String.format("StackBranch[properties=%s, id='%s']", properties, id);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement