/*
* [The "BSD licence"]
* Copyright (c) 2010 Ben Gruver (JesusFreke)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.baksmali.Adaptors;
import org.jf.baksmali.IndentingWriter;
import org.jf.baksmali.baksmali;
import org.jf.dexlib.CodeItem;
import org.jf.dexlib.Util.AccessFlags;
import java.io.IOException;
/**
* This class contains the logic used for formatting registers
*/
public class RegisterFormatter {
/**
* Write out the register range value used by Format3rc. If baksmali.noParameterRegisters is true, it will always
* output the registers in the v<n> format. But if false, then it will check if *both* registers are parameter
* registers, and if so, use the p<n> format for both. If only the last register is a parameter register, it will
* use the v<n> format for both, otherwise it would be confusing to have something like {v20 .. p1}
* @param writer the <code>IndentingWriter</code> to write to
* @param codeItem the <code>CodeItem</code> that the register is from
* @param startRegister the first register in the range
* @param lastRegister the last register in the range
*/
public static void writeRegisterRange(IndentingWriter writer, CodeItem codeItem, int startRegister,
int lastRegister) throws IOException {
assert lastRegister >= startRegister;
if (!baksmali.noParameterRegisters) {
int parameterRegisterCount = codeItem.getParent().method.getPrototype().getParameterRegisterCount()
+ (((codeItem.getParent().accessFlags & AccessFlags.STATIC.getValue())==0)?1:0);
int registerCount = codeItem.getRegisterCount();
assert startRegister <= lastRegister;
if (startRegister >= registerCount - parameterRegisterCount) {
writer.write("{p");
writer.printIntAsDec(startRegister - (registerCount - parameterRegisterCount));
writer.write(" .. p");
writer.printIntAsDec(lastRegister - (registerCount - parameterRegisterCount));
writer.write('}');
return;
}
}
writer.write("{v");
writer.printIntAsDec(startRegister);
writer.write(" .. v");
writer.printIntAsDec(lastRegister);
writer.write('}');
}
/**
* Writes a register with the appropriate format. If baksmali.noParameterRegisters is true, then it will always
* output a register in the v<n> format. If false, then it determines if the register is a parameter register,
* and if so, formats it in the p<n> format instead.
*
* @param writer the <code>IndentingWriter</code> to write to
* @param codeItem the <code>CodeItem</code> that the register is from
* @param register the register number
*/
public static void writeTo(IndentingWriter writer, CodeItem codeItem, int register) throws IOException {
if (!baksmali.noParameterRegisters) {
int parameterRegisterCount = codeItem.getParent().method.getPrototype().getParameterRegisterCount()
+ (((codeItem.getParent().accessFlags & AccessFlags.STATIC.getValue())==0)?1:0);
int registerCount = codeItem.getRegisterCount();
if (register >= registerCount - parameterRegisterCount) {
writer.write('p');
writer.printIntAsDec((register - (registerCount - parameterRegisterCount)));
return;
}
}
writer.write('v');
writer.printIntAsDec(register);
}
}