com.googlecode.dex2jar.ir.ts.DeadCodeTransformer Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2009-2012 Panxiaobo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.dex2jar.ir.ts;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.Trap;
import com.googlecode.dex2jar.ir.expr.Local;
import com.googlecode.dex2jar.ir.expr.PhiExpr;
import com.googlecode.dex2jar.ir.expr.Value;
import com.googlecode.dex2jar.ir.stmt.AssignStmt;
import com.googlecode.dex2jar.ir.stmt.LabelStmt;
import com.googlecode.dex2jar.ir.stmt.Stmt;
import java.util.*;
public class DeadCodeTransformer implements Transformer {
@Override
public void transform(IrMethod method) {
Cfg.createCFG(method);
Cfg.dfsVisit(method, null);
if (method.traps != null) {
for (Iterator it = method.traps.iterator(); it.hasNext();) {
Trap t = it.next();
boolean allNotThrow = true;
for (Stmt p = t.start; p != t.end; p = p.getNext()) {
if (p.visited && Cfg.isThrow(p)) {
allNotThrow = false;
break;
}
}
if (allNotThrow) {
it.remove();
continue;
}
boolean allNotVisited = true;
boolean allVisited = true;
for (LabelStmt labelStmt : t.handlers) {
if (labelStmt.visited) {
allNotVisited = false;
} else {
allVisited = false;
}
}
if (allNotVisited) {
it.remove();
} else {
// keep start and end
t.start.visited = true;
t.end.visited = true;
if (!allVisited) { // part visited
List types = new ArrayList<>(t.handlers.length);
List labelStmts = new ArrayList<>(t.handlers.length);
for (int i = 0; i < t.handlers.length; i++) {
labelStmts.add(t.handlers[i]);
types.add(t.types[i]);
}
t.handlers = labelStmts.toArray(new LabelStmt[labelStmts.size()]);
t.types = types.toArray(new String[types.size()]);
}
}
}
}
Set definedLocals = new HashSet<>();
for (Iterator it = method.stmts.iterator(); it.hasNext();) {
Stmt p = it.next();
if (!p.visited) {
it.remove();
continue;
}
if (p.st == Stmt.ST.ASSIGN || p.st == Stmt.ST.IDENTITY) {
if (p.getOp1().vt == Value.VT.LOCAL) {
definedLocals.add((Local) p.getOp1());
}
}
}
if (method.phiLabels != null) {
for (Iterator it = method.phiLabels.iterator(); it.hasNext();) {
LabelStmt labelStmt = it.next();
if (!labelStmt.visited) {
it.remove();
continue;
}
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
definedLocals.add((Local) phi.getOp1());
}
}
}
}
method.locals.clear();
method.locals.addAll(definedLocals);
Set tmp = new HashSet<>();
if (method.phiLabels != null) {
for (Iterator it = method.phiLabels.iterator(); it.hasNext();) {
LabelStmt labelStmt = it.next();
if (labelStmt.phis != null) {
for (AssignStmt phi : labelStmt.phis) {
PhiExpr phiExpr = (PhiExpr) phi.getOp2();
boolean needRebuild = false;
for (Value v : phiExpr.getOps()) {
if (!definedLocals.contains(v)) {
needRebuild = true;
break;
}
}
if (needRebuild) {
for (Value v : phiExpr.getOps()) {
if (definedLocals.contains(v)) {
tmp.add(v);
}
}
phiExpr.setOps(tmp.toArray(new Value[tmp.size()]));
tmp.clear();
}
}
}
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy