use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.
the class ConstantPoolParser method parse0.
/**
* Parses the constant for the given index if it hasn't already been
* parsed, also storing it in the constant pool. This will also
* have the side effect of parsing any entries the indicated one
* depends on.
*
* @param idx which constant
* @return {@code non-null;} the parsed constant
*/
private Constant parse0(int idx, BitSet wasUtf8) {
Constant cst = pool.getOrNull(idx);
if (cst != null) {
return cst;
}
int at = offsets[idx];
try {
int tag = bytes.getUnsignedByte(at);
switch(tag) {
case CONSTANT_Utf8:
{
cst = parseUtf8(at);
wasUtf8.set(idx);
break;
}
case CONSTANT_Integer:
{
int value = bytes.getInt(at + 1);
cst = CstInteger.make(value);
break;
}
case CONSTANT_Float:
{
int bits = bytes.getInt(at + 1);
cst = CstFloat.make(bits);
break;
}
case CONSTANT_Long:
{
long value = bytes.getLong(at + 1);
cst = CstLong.make(value);
break;
}
case CONSTANT_Double:
{
long bits = bytes.getLong(at + 1);
cst = CstDouble.make(bits);
break;
}
case CONSTANT_Class:
{
int nameIndex = bytes.getUnsignedShort(at + 1);
CstString name = (CstString) parse0(nameIndex, wasUtf8);
cst = new CstType(Type.internClassName(name.getString()));
break;
}
case CONSTANT_String:
{
int stringIndex = bytes.getUnsignedShort(at + 1);
cst = parse0(stringIndex, wasUtf8);
break;
}
case CONSTANT_Fieldref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstFieldRef(type, nat);
break;
}
case CONSTANT_Methodref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstMethodRef(type, nat);
break;
}
case CONSTANT_InterfaceMethodref:
{
int classIndex = bytes.getUnsignedShort(at + 1);
CstType type = (CstType) parse0(classIndex, wasUtf8);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = new CstInterfaceMethodRef(type, nat);
break;
}
case CONSTANT_NameAndType:
{
int nameIndex = bytes.getUnsignedShort(at + 1);
CstString name = (CstString) parse0(nameIndex, wasUtf8);
int descriptorIndex = bytes.getUnsignedShort(at + 3);
CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);
cst = new CstNat(name, descriptor);
break;
}
case CONSTANT_MethodHandle:
{
int kind = bytes.getUnsignedByte(at + 1);
int constantIndex = bytes.getUnsignedShort(at + 2);
Constant ref;
switch(kind) {
case CstMethodHandle.KIND_GETFIELD:
case CstMethodHandle.KIND_GETSTATIC:
case CstMethodHandle.KIND_PUTFIELD:
case CstMethodHandle.KIND_PUTSTATIC:
CstFieldRef field = (CstFieldRef) parse0(constantIndex, wasUtf8);
ref = field;
break;
case CstMethodHandle.KIND_INVOKEVIRTUAL:
case CstMethodHandle.KIND_NEWINVOKESPECIAL:
CstMethodRef method = (CstMethodRef) parse0(constantIndex, wasUtf8);
ref = method;
break;
case CstMethodHandle.KIND_INVOKESTATIC:
case CstMethodHandle.KIND_INVOKESPECIAL:
ref = parse0(constantIndex, wasUtf8);
if (!(ref instanceof CstMethodRef || ref instanceof CstInterfaceMethodRef)) {
throw new ParseException("Unsupported ref constant type for MethodHandle " + ref.getClass());
}
break;
case CstMethodHandle.KIND_INVOKEINTERFACE:
CstInterfaceMethodRef interfaceMethod = (CstInterfaceMethodRef) parse0(constantIndex, wasUtf8);
ref = interfaceMethod;
break;
default:
throw new ParseException("Unsupported MethodHandle kind: " + kind);
}
cst = CstMethodHandle.make(kind, ref);
break;
}
case CONSTANT_MethodType:
{
int descriptorIndex = bytes.getUnsignedShort(at + 1);
CstString descriptor = (CstString) parse0(descriptorIndex, wasUtf8);
cst = CstMethodType.make(descriptor);
break;
}
case CONSTANT_InvokeDynamic:
{
int bootstrapMethodIndex = bytes.getUnsignedShort(at + 1);
int natIndex = bytes.getUnsignedShort(at + 3);
CstNat nat = (CstNat) parse0(natIndex, wasUtf8);
cst = CstInvokeDynamic.make(bootstrapMethodIndex, nat);
break;
}
default:
{
throw new ParseException("unknown tag byte: " + Hex.u1(tag));
}
}
} catch (ParseException ex) {
ex.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
throw ex;
} catch (RuntimeException ex) {
ParseException pe = new ParseException(ex);
pe.addContext("...while parsing cst " + Hex.u2(idx) + " at offset " + Hex.u4(at));
throw pe;
}
pool.set(idx, cst);
return cst;
}
use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.
the class StdAttributeFactory method annotationDefault.
/**
* Parses an {@code AnnotationDefault} attribute.
*/
private Attribute annotationDefault(DirectClassFile cf, int offset, int length, ParseObserver observer) {
if (length < 2) {
throwSeverelyTruncated();
}
AnnotationParser ap = new AnnotationParser(cf, offset, length, observer);
Constant cst = ap.parseValueAttribute();
return new AttAnnotationDefault(cst, length);
}
use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.
the class CfTranslator method updateDexStatistics.
/**
* Helper that updates the dex statistics.
*/
private static void updateDexStatistics(DxContext context, CfOptions cfOptions, DexOptions dexOptions, RopMethod optRmeth, RopMethod nonOptRmeth, LocalVariableInfo locals, int paramSize, int originalByteCount) {
/*
* Run rop->dex again on optimized vs. non-optimized method to
* collect statistics. We have to totally convert both ways,
* since converting the "real" method getting added to the
* file would corrupt it (by messing with its constant pool
* indices).
*/
DalvCode optCode = RopTranslator.translate(optRmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
DalvCode nonOptCode = RopTranslator.translate(nonOptRmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
/*
* Fake out the indices, so code.getInsns() can work well enough
* for the current purpose.
*/
DalvCode.AssignIndicesCallback callback = new DalvCode.AssignIndicesCallback() {
public int getIndex(Constant cst) {
// Everything is at index 0!
return 0;
}
};
optCode.assignIndices(callback);
nonOptCode.assignIndices(callback);
context.codeStatistics.updateDexStatistics(nonOptCode, optCode);
context.codeStatistics.updateOriginalByteCount(originalByteCount);
}
use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.
the class SCCP method simulateMath.
/**
* Simulates math insns, if possible.
*
* @param insn non-null insn to simulate
* @param resultType basic type of the result
* @return constant result or null if not simulatable.
*/
private Constant simulateMath(SsaInsn insn, int resultType) {
Insn ropInsn = insn.getOriginalRopInsn();
int opcode = insn.getOpcode().getOpcode();
RegisterSpecList sources = insn.getSources();
int regA = sources.get(0).getReg();
Constant cA;
Constant cB;
if (latticeValues[regA] != CONSTANT) {
cA = null;
} else {
cA = latticeConstants[regA];
}
if (sources.size() == 1) {
CstInsn cstInsn = (CstInsn) ropInsn;
cB = cstInsn.getConstant();
} else {
/* sources.size() == 2 */
int regB = sources.get(1).getReg();
if (latticeValues[regB] != CONSTANT) {
cB = null;
} else {
cB = latticeConstants[regB];
}
}
if (cA == null || cB == null) {
// TODO handle a constant of 0 with MUL or AND
return null;
}
switch(resultType) {
case Type.BT_INT:
int vR;
boolean skip = false;
int vA = ((CstInteger) cA).getValue();
int vB = ((CstInteger) cB).getValue();
switch(opcode) {
case RegOps.ADD:
vR = vA + vB;
break;
case RegOps.SUB:
// 1 source for reverse sub, 2 sources for regular sub
if (sources.size() == 1) {
vR = vB - vA;
} else {
vR = vA - vB;
}
break;
case RegOps.MUL:
vR = vA * vB;
break;
case RegOps.DIV:
if (vB == 0) {
skip = true;
// just to hide a warning
vR = 0;
} else {
vR = vA / vB;
}
break;
case RegOps.AND:
vR = vA & vB;
break;
case RegOps.OR:
vR = vA | vB;
break;
case RegOps.XOR:
vR = vA ^ vB;
break;
case RegOps.SHL:
vR = vA << vB;
break;
case RegOps.SHR:
vR = vA >> vB;
break;
case RegOps.USHR:
vR = vA >>> vB;
break;
case RegOps.REM:
if (vB == 0) {
skip = true;
// just to hide a warning
vR = 0;
} else {
vR = vA % vB;
}
break;
default:
throw new RuntimeException("Unexpected op");
}
return skip ? null : CstInteger.make(vR);
default:
// not yet supported
return null;
}
}
use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.
the class OutputFinisher method assignIndices.
/**
* Helper for {@link #assignIndices} which does assignment for one
* instruction.
*
* @param insn {@code non-null;} the instruction
* @param callback {@code non-null;} the callback
*/
private static void assignIndices(MultiCstInsn insn, DalvCode.AssignIndicesCallback callback) {
for (int i = 0; i < insn.getNumberOfConstants(); ++i) {
Constant cst = insn.getConstant(i);
int index = callback.getIndex(cst);
insn.setIndex(i, index);
if (cst instanceof CstMemberRef) {
CstMemberRef member = (CstMemberRef) cst;
CstType definer = member.getDefiningClass();
index = callback.getIndex(definer);
insn.setClassIndex(index);
}
}
}
Aggregations