Advertisement
Guest User

Untitled

a guest
May 1st, 2016
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.20 KB | None | 0 0
  1. package com.rsxml.handler.analysis;
  2.  
  3. import com.rsxml.*;
  4. import com.rsxml.util.*;
  5. import org.apache.commons.collections4.*;
  6. import org.apache.commons.collections4.multimap.*;
  7. import org.apache.commons.lang3.*;
  8. import org.objectweb.asm.tree.*;
  9. import org.objectweb.asm.tree.analysis.*;
  10.  
  11. import java.io.*;
  12. import java.util.*;
  13. import java.util.concurrent.atomic.*;
  14.  
  15. /**
  16. * @author Caleb Whiting
  17. * <p>
  18. * Represents a branch of a stack tree.
  19. */
  20. public class StackBranch {
  21.  
  22. /**
  23. * The user-defined ID of this branch.
  24. */
  25. private String id;
  26. /**
  27. * The properties of the instruction this represents.
  28. */
  29. private final Map<String, Object> properties = new LinkedHashMap<>();
  30. /**
  31. * The branches of this branch.
  32. */
  33. private final List<StackBranch> branches = new LinkedList<>();
  34.  
  35. /**
  36. * Gets the properties of the instruction this represents.
  37. *
  38. * @return {@link StackBranch#properties}.
  39. */
  40. public Map<String, Object> getProperties() {
  41. return properties;
  42. }
  43.  
  44. /**
  45. * Gets the branches of this branch.
  46. *
  47. * @return {@link StackBranch#branches}.
  48. */
  49. public List<StackBranch> getBranches() {
  50. return branches;
  51. }
  52.  
  53. /**
  54. * Gets the user-defined ID of this branch.
  55. *
  56. * @return {@link StackBranch#id}.
  57. */
  58. public String getId() {
  59. return id;
  60. }
  61.  
  62. /**
  63. * Sets the user-defined ID of this branch.
  64. *
  65. * @param id The user-defined ID of this branch.
  66. */
  67. public void setId(String id) {
  68. this.id = id;
  69. }
  70.  
  71. /**
  72. * Search the given instructions for this stack branch, and it's branches.
  73. *
  74. * @param ctx The context in which this is being handled.
  75. * @param instructions The instructions of the method to search.
  76. * @param frames The frames of the method to search.
  77. * @param index The start index of the instructions to search.
  78. * @param result The map in which to store the results of this search.
  79. * @param minIndex The minimum index of the stack tree that this is a branch of
  80. * @return true if this search was successful; otherwise false.
  81. */
  82. public boolean accept(Context ctx, AbstractInsnNode[] instructions, Frame<SourceValue>[] frames,
  83. int index, MultiValuedMap<String, AbstractInsnNode> result, AtomicInteger minIndex) {
  84. AbstractInsnNode instruction = instructions[index];
  85. Frame<SourceValue> frame = frames[index];
  86. /* Check properties */
  87. for (Map.Entry<String, Object> entry : getProperties().entrySet()) {
  88. Object o = instruction.getProperty(entry.getKey(), ctx);
  89. if (o == null) {
  90. return false;
  91. }
  92. if (o.toString().equals(entry.getValue().toString())) {
  93. continue;
  94. }
  95. return false;
  96. }
  97. MultiValuedMap<String, AbstractInsnNode> subResult = new HashSetValuedHashMap<>();
  98. if (getBranches().size() > 0) {
  99. if (frame == null) {
  100. return false;
  101. }
  102. /* Check stack */
  103. AbstractInsnNode[] stack = frame.compute(instructions, frames);
  104. if (getBranches().size() > stack.length) {
  105. return false;
  106. }
  107. for (int branchIndex = 0; branchIndex < getBranches().size(); branchIndex++) {
  108. AbstractInsnNode value = stack[stack.length - getBranches().size() + branchIndex];
  109. if (value == null || !getBranches().get(branchIndex).accept(ctx, instructions, frames, value.getIndex(), subResult, minIndex)) {
  110. return false;
  111. }
  112. }
  113. }
  114. result.putAll(subResult);
  115. /* Register instruction */
  116. if (getId() != null && getId().length() > 0) {
  117. result.put(getId(), instruction);
  118. }
  119. minIndex.set(Integer.min(minIndex.get(), instruction.getIndex()));
  120. return true;
  121. }
  122.  
  123. public void print(PrintStream out, int depth) {
  124. String prefix = StringUtils.repeat("\t", depth);
  125. out.println(prefix + this);
  126. if (getBranches().size() > 0) {
  127. out.println(prefix + "{");
  128. for (StackBranch branch : getBranches()) {
  129. branch.print(out, depth + 1);
  130. }
  131. out.println(prefix + "}");
  132. }
  133. }
  134.  
  135. @Override
  136. public String toString() {
  137. Map<String, Object> properties = new LinkedHashMap<>(this.properties);
  138. if (properties.containsKey("opcode")) {
  139. properties.put("opcode", InsnUtils.getOpcodeName((Integer) properties.get("opcode")));
  140. }
  141. if (properties.containsKey("type")) {
  142. properties.put("type", InsnUtils.getTypeName((Integer) properties.get("type")));
  143. }
  144. return String.format("StackBranch[properties=%s, id='%s']", properties, id);
  145. }
  146.  
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement