All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.dex2jar.ir.ts.EndRemover Maven / Gradle / Ivy

package com.googlecode.dex2jar.ir.ts;

import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.LabelAndLocalMapper;
import com.googlecode.dex2jar.ir.Trap;
import com.googlecode.dex2jar.ir.expr.Local;
import com.googlecode.dex2jar.ir.stmt.GotoStmt;
import com.googlecode.dex2jar.ir.stmt.LabelStmt;
import com.googlecode.dex2jar.ir.stmt.Stmt;
import com.googlecode.dex2jar.ir.stmt.Stmt.ST;
import com.googlecode.dex2jar.ir.stmt.StmtList;
import com.googlecode.dex2jar.ir.stmt.Stmts;
import java.util.ArrayList;

/**
 * Try to clean following between a {@link Trap}
 * 
    *
  1. Move {@link Stmt}s outside a {@link Trap} if {@link Stmt}s are not throw
  2. *
  3. Remove {@link Trap} if all {@link Stmt}s are not throw
  4. *
  5. ...;GOTO L2; ... ; L2: ; return; => ...;return ; ... ; L2: ; return;
  6. *
* * @author bob */ public class EndRemover implements Transformer { private static final LabelAndLocalMapper KEEP_LOCAL = new LabelAndLocalMapper() { @Override public Local map(Local local) { return local; } }; @Override public void transform(IrMethod irMethod) { for (Trap trap : new ArrayList<>(irMethod.traps)) { // copy the list and we can remove one from original list LabelStmt start = null; boolean removeTrap = true; Stmt p = trap.start.getNext(); while (p != null && p != trap.end) { boolean notThrow = Cfg.notThrow(p); if (!notThrow) { start = null; p = p.getNext(); removeTrap = false; continue; } switch (p.st) { case LABEL: if (start != null) { move4Label(irMethod.stmts, start, p.getPre(), (LabelStmt) p); } start = (LabelStmt) p; p = p.getNext(); break; case GOTO: case RETURN: case RETURN_VOID: if (start != null) { Stmt tmp = p.getNext(); move4End(irMethod.stmts, start, p); start = null; p = tmp; } else { p = p.getNext(); } break; default: p = p.getNext(); } } if (removeTrap) { irMethod.traps.remove(trap); } } StmtList stmts = irMethod.stmts; for (Stmt p = stmts.getFirst(); p != null; p = p.getNext()) { if (p.st == ST.GOTO) { LabelStmt target = ((GotoStmt) p).target; Stmt next = target.getNext(); if (next != null && (next.st == ST.RETURN || next.st == ST.RETURN_VOID)) { Stmt nnext = next.clone(KEEP_LOCAL); stmts.insertAfter(p, nnext); stmts.remove(p); p = nnext; } } } } private void move4Label(StmtList stmts, LabelStmt start, Stmt end, LabelStmt label) { move4End(stmts, start, end); stmts.insertAfter(end, Stmts.nGoto(label)); } private void move4End(StmtList stmts, LabelStmt start, Stmt end) { Stmt g1 = Stmts.nGoto(start); stmts.insertBefore(start, g1); Stmt last = stmts.getLast(); while (last.st == ST.GOTO && ((GotoStmt) last).target == start) { stmts.remove(last); last = stmts.getLast(); } stmts.move(start, end, last); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy