
soot.toDex.ConstantVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of soot Show documentation
Show all versions of soot Show documentation
A Java Optimization Framework
package soot.toDex;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 2018 Raja Vallée-Rai and others
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.iface.reference.StringReference;
import org.jf.dexlib2.iface.reference.TypeReference;
import org.jf.dexlib2.immutable.reference.ImmutableStringReference;
import org.jf.dexlib2.immutable.reference.ImmutableTypeReference;
import soot.jimple.AbstractConstantSwitch;
import soot.jimple.ClassConstant;
import soot.jimple.DoubleConstant;
import soot.jimple.FloatConstant;
import soot.jimple.IntConstant;
import soot.jimple.LongConstant;
import soot.jimple.NullConstant;
import soot.jimple.Stmt;
import soot.jimple.StringConstant;
import soot.toDex.instructions.Insn;
import soot.toDex.instructions.Insn11n;
import soot.toDex.instructions.Insn21c;
import soot.toDex.instructions.Insn21s;
import soot.toDex.instructions.Insn31i;
import soot.toDex.instructions.Insn51l;
import soot.util.Switchable;
/**
* A visitor that builds a list of instructions from the Jimple constants it visits.
*
* Use {@link Switchable#apply(soot.util.Switch)} with this visitor to add statements. These are added to the instructions in
* the {@link StmtVisitor}.
* Do not forget to use {@link #setDestination(Register)} to set the storage location for the constant.
*
* @see StmtVisitor
*/
public class ConstantVisitor extends AbstractConstantSwitch {
private StmtVisitor stmtV;
private Register destinationReg;
private Stmt origStmt;
public ConstantVisitor(StmtVisitor stmtV) {
this.stmtV = stmtV;
}
public void setDestination(Register destinationReg) {
this.destinationReg = destinationReg;
}
public void setOrigStmt(Stmt stmt) {
this.origStmt = stmt;
}
@Override
public void defaultCase(Object o) {
// const* opcodes not used since there seems to be no point in doing so:
// CONST_HIGH16, CONST_WIDE_HIGH16
throw new Error("unknown Object (" + o.getClass() + ") as Constant: " + o);
}
@Override
public void caseStringConstant(StringConstant s) {
StringReference ref = new ImmutableStringReference(s.value);
stmtV.addInsn(new Insn21c(Opcode.CONST_STRING, destinationReg, ref), origStmt);
}
@Override
public void caseClassConstant(ClassConstant c) {
TypeReference referencedClass = new ImmutableTypeReference(c.getValue());
stmtV.addInsn(new Insn21c(Opcode.CONST_CLASS, destinationReg, referencedClass), origStmt);
}
@Override
public void caseLongConstant(LongConstant l) {
long constant = l.value;
stmtV.addInsn(buildConstWideInsn(constant), origStmt);
}
private Insn buildConstWideInsn(long literal) {
if (SootToDexUtils.fitsSigned16(literal)) {
return new Insn21s(Opcode.CONST_WIDE_16, destinationReg, (short) literal);
} else if (SootToDexUtils.fitsSigned32(literal)) {
return new Insn31i(Opcode.CONST_WIDE_32, destinationReg, (int) literal);
} else {
return new Insn51l(Opcode.CONST_WIDE, destinationReg, literal);
}
}
@Override
public void caseDoubleConstant(DoubleConstant d) {
long longBits = Double.doubleToLongBits(d.value);
stmtV.addInsn(buildConstWideInsn(longBits), origStmt);
}
@Override
public void caseFloatConstant(FloatConstant f) {
int intBits = Float.floatToIntBits(f.value);
stmtV.addInsn(buildConstInsn(intBits), origStmt);
}
private Insn buildConstInsn(int literal) {
if (SootToDexUtils.fitsSigned4(literal)) {
return new Insn11n(Opcode.CONST_4, destinationReg, (byte) literal);
} else if (SootToDexUtils.fitsSigned16(literal)) {
return new Insn21s(Opcode.CONST_16, destinationReg, (short) literal);
} else {
return new Insn31i(Opcode.CONST, destinationReg, literal);
}
}
@Override
public void caseIntConstant(IntConstant i) {
stmtV.addInsn(buildConstInsn(i.value), origStmt);
}
@Override
public void caseNullConstant(NullConstant v) {
// dex bytecode spec says: "In terms of bitwise representation, (Object)
// null == (int) 0."
stmtV.addInsn(buildConstInsn(0), origStmt);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy