use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project intellij-community by JetBrains.
the class OriginsAnalysis method resultOrigins.
/**
*
* @param frames fixpoint of frames
* @param instructions method instructions
* @param graph method control flow graph
* @return array, array[i] == true means that the result of a method execution may originate at an i-th instruction
* @throws AnalyzerException
*/
@NotNull
public static boolean[] resultOrigins(Frame<Value>[] frames, InsnList instructions, ControlFlowGraph graph) throws AnalyzerException {
TIntArrayList[] backTransitions = new TIntArrayList[instructions.size()];
for (int i = 0; i < backTransitions.length; i++) {
backTransitions[i] = new TIntArrayList();
}
LinkedList<InsnLocation> queue = new LinkedList<>();
HashSet<InsnLocation> queued = new HashSet<>();
for (int from = 0; from < instructions.size(); from++) {
for (int to : graph.transitions[from]) {
TIntArrayList froms = backTransitions[to];
froms.add(from);
int opcode = instructions.get(to).getOpcode();
if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.ARETURN) {
InsnLocation sourceLoc = new InsnLocation(false, from, frames[to].getStackSize() - 1);
if (queued.add(sourceLoc)) {
queue.push(sourceLoc);
}
}
}
}
boolean[] result = new boolean[instructions.size()];
while (!queue.isEmpty()) {
InsnLocation resultLocation = queue.pop();
int insnIndex = resultLocation.insnIndex;
AbstractInsnNode insn = instructions.get(insnIndex);
int opcode = insn.getOpcode();
Location preLocation = previousLocation(frames[insnIndex], resultLocation, insn);
if (preLocation == null) {
if (opcode != Opcodes.INVOKEINTERFACE && opcode != Opcodes.GETFIELD && !(opcode >= Opcodes.IALOAD && opcode <= Opcodes.SALOAD)) {
result[insnIndex] = true;
}
} else {
TIntArrayList froms = backTransitions[insnIndex];
for (int i = 0; i < froms.size(); i++) {
InsnLocation preILoc = new InsnLocation(preLocation.local, froms.getQuick(i), preLocation.slot);
if (queued.add(preILoc)) {
queue.push(preILoc);
}
}
}
}
return result;
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class InlineCodegen method removeStaticInitializationTrigger.
private static void removeStaticInitializationTrigger(@NotNull MethodNode methodNode) {
InsnList insnList = methodNode.instructions;
AbstractInsnNode insn = insnList.getFirst();
while (insn != null) {
if (MultifileClassPartCodegen.isStaticInitTrigger(insn)) {
AbstractInsnNode clinitTriggerCall = insn;
insn = insn.getNext();
insnList.remove(clinitTriggerCall);
} else {
insn = insn.getNext();
}
}
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class InlineCodegen method generateAndInsertFinallyBlocks.
private void generateAndInsertFinallyBlocks(@NotNull MethodNode intoNode, @NotNull List<MethodInliner.PointForExternalFinallyBlocks> insertPoints, int offsetForFinallyLocalVar) {
if (!codegen.hasFinallyBlocks())
return;
Map<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks> extensionPoints = new HashMap<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks>();
for (MethodInliner.PointForExternalFinallyBlocks insertPoint : insertPoints) {
extensionPoints.put(insertPoint.beforeIns, insertPoint);
}
DefaultProcessor processor = new DefaultProcessor(intoNode, offsetForFinallyLocalVar);
int curFinallyDepth = 0;
AbstractInsnNode curInstr = intoNode.instructions.getFirst();
while (curInstr != null) {
processor.processInstruction(curInstr, true);
if (InlineCodegenUtil.isFinallyStart(curInstr)) {
//TODO depth index calc could be more precise
curFinallyDepth = getConstant(curInstr.getPrevious());
}
MethodInliner.PointForExternalFinallyBlocks extension = extensionPoints.get(curInstr);
if (extension != null) {
Label start = new Label();
MethodNode finallyNode = InlineCodegenUtil.createEmptyMethodNode();
finallyNode.visitLabel(start);
ExpressionCodegen finallyCodegen = new ExpressionCodegen(finallyNode, codegen.getFrameMap(), codegen.getReturnType(), codegen.getContext(), codegen.getState(), codegen.getParentCodegen());
finallyCodegen.addBlockStackElementsForNonLocalReturns(codegen.getBlockStackElements(), curFinallyDepth);
FrameMap frameMap = finallyCodegen.getFrameMap();
FrameMap.Mark mark = frameMap.mark();
int marker = -1;
Set<LocalVarNodeWrapper> intervals = processor.getLocalVarsMetaInfo().getCurrentIntervals();
for (LocalVarNodeWrapper interval : intervals) {
marker = Math.max(interval.getNode().index + 1, marker);
}
while (frameMap.getCurrentSize() < Math.max(processor.getNextFreeLocalIndex(), offsetForFinallyLocalVar + marker)) {
frameMap.enterTemp(Type.INT_TYPE);
}
finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, extension.finallyIntervalEnd.getLabel());
//Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, curInstr);
SimpleInterval splitBy = new SimpleInterval((LabelNode) start.info, extension.finallyIntervalEnd);
processor.getTryBlocksMetaInfo().splitCurrentIntervals(splitBy, true);
//processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy);
mark.dropTo();
}
curInstr = curInstr.getNext();
}
processor.substituteTryBlockNodes(intoNode);
//processor.substituteLocalVarTable(intoNode);
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class TrustAllX509TrustManagerDetector method checkClass.
// ---- Implements ClassScanner ----
// Only used for libraries where we have to analyze bytecode
@Override
@SuppressWarnings("rawtypes")
public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) {
if (!context.isFromClassLibrary()) {
// Non-library code checked at the AST level
return;
}
if (!classNode.interfaces.contains("javax/net/ssl/X509TrustManager")) {
return;
}
List methodList = classNode.methods;
for (Object m : methodList) {
MethodNode method = (MethodNode) m;
if ("checkServerTrusted".equals(method.name) || "checkClientTrusted".equals(method.name)) {
InsnList nodes = method.instructions;
// Stays true if method doesn't perform any "real"
boolean emptyMethod = true;
// operations
for (int i = 0, n = nodes.size(); i < n; i++) {
// Future work: Improve this check to be less sensitive to irrelevant
// instructions/statements/invocations (e.g. System.out.println) by
// looking for calls that could lead to a CertificateException being
// thrown, e.g. throw statement within the method itself or invocation
// of another method that may throw a CertificateException, and only
// reporting an issue if none of these calls are found. ControlFlowGraph
// may be useful here.
AbstractInsnNode instruction = nodes.get(i);
int type = instruction.getType();
if (type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE && !(type == AbstractInsnNode.INSN && instruction.getOpcode() == Opcodes.RETURN)) {
emptyMethod = false;
break;
}
}
if (emptyMethod) {
Location location = context.getLocation(method, classNode);
context.report(ISSUE, location, getErrorMessage(method.name));
}
}
}
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class ControlFlowGraph method toDot.
/**
* Generates dot output of the graph. This can be used with
* graphwiz to visualize the graph. For example, if you
* save the output as graph1.gv you can run
* <pre>
* $ dot -Tps graph1.gv -o graph1.ps
* </pre>
* to generate a postscript file, which you can then view
* with "gv graph1.ps".
*
* (There are also some online web sites where you can
* paste in dot graphs and see the visualization right
* there in the browser.)
*
* @return a dot description of this control flow graph,
* useful for debugging
*/
@SuppressWarnings("unused")
public String toDot(@Nullable Set<Node> highlight) {
StringBuilder sb = new StringBuilder();
sb.append("digraph G {\n");
AbstractInsnNode instruction = mMethod.instructions.getFirst();
// Special start node
sb.append(" start -> ").append(getId(mNodeMap.get(instruction))).append(";\n");
sb.append(" start [shape=plaintext];\n");
while (instruction != null) {
Node node = mNodeMap.get(instruction);
if (node != null) {
if (node.successors != null) {
for (Node to : node.successors) {
sb.append(" ").append(getId(node)).append(" -> ").append(getId(to));
if (node.instruction instanceof JumpInsnNode) {
sb.append(" [label=\"");
if (((JumpInsnNode) node.instruction).label == to.instruction) {
sb.append("yes");
} else {
sb.append("no");
}
sb.append("\"]");
}
sb.append(";\n");
}
}
if (node.exceptions != null) {
for (Node to : node.exceptions) {
sb.append(getId(node)).append(" -> ").append(getId(to));
sb.append(" [label=\"exception\"];\n");
}
}
}
instruction = instruction.getNext();
}
// Labels
sb.append("\n");
for (Node node : mNodeMap.values()) {
instruction = node.instruction;
sb.append(" ").append(getId(node)).append(" ");
sb.append("[label=\"").append(dotDescribe(node)).append("\"");
if (highlight != null && highlight.contains(node)) {
sb.append(",shape=box,style=filled");
} else if (instruction instanceof LineNumberNode || instruction instanceof LabelNode || instruction instanceof FrameNode) {
sb.append(",shape=oval,style=dotted");
} else {
sb.append(",shape=box");
}
sb.append("];\n");
}
sb.append("}");
return sb.toString();
}
Aggregations