dexInstruction= processInvokeInstruction(cstInsn, referencedTypes);
}
else
{
dexInstruction= new Element(sanitizeInstructionName(cstInsn.getOpcode().getName()), NS_DEX);
Constant constant= cstInsn.getConstant();
// TODO hack
String type= constant.typeName();
String name= "kind";
if (!type.equals("field") && !type.equals("known-null") && !type.equals("type") && !type.equals("string"))
{
name= "type";
}
dexInstruction.setAttribute(name, constant.typeName());
if (constant instanceof CstMemberRef)
{
CstMemberRef memberRef= (CstMemberRef) constant;
String definingClassType= memberRef.getDefiningClass().getClassType().toHuman();
dexInstruction.setAttribute("class-type", definingClassType);
addReference(referencedTypes, definingClassType, ReferenceKind.USAGE);
CstNat nameAndType= memberRef.getNat();
String memberType= nameAndType.getFieldType().getType().toHuman();
dexInstruction.setAttribute("member-type", memberType);
addReference(referencedTypes, memberType, ReferenceKind.USAGE);
String memberName= nameAndType.getName().toHuman();
dexInstruction.setAttribute("member-name", memberName);
// if this is a member access to a red class, we need to
// eliminate it.
if (isRedType(definingClassType))
{
// Just accessing the memberType does not require to
// initialize its class.
// Therefore we can relax the rule of issuing a red
// class exception.
dexInstruction= createAssertElement(definingClassType + "," + memberType, memberName);
}
else if (isRedType(memberType))
{
// If the member-type is a red class replace it with a
// generic RedTypeMarker
dexInstruction.setAttribute("member-type", "org.xmlvm.runtime.RedTypeMarker");
}
}
else if (constant instanceof CstString)
{
CstString cstString= (CstString) constant;
String value= cstString.getString().getString();
encodeString(dexInstruction, value);
}
else
{
// These are CstInsn instructions that we need to remove, if
// their constant is a red type.
List<String> instructionsToCheck= Arrays.asList(new String[] { "new-instance", "instance-of", "check-cast", "const-class", "new-array" });
if (instructionsToCheck.contains(opname) && isRedType(constant.toHuman()))
{
dexInstruction= createAssertElement(constant.toHuman(), opname);
}
else
{
dexInstruction.setAttribute("value", constant.toHuman());
}
}
if (cstInsn.getOpcode().getName().startsWith("filled-new-array"))
{
addRegistersAsChildren(cstInsn.getRegisters(), dexInstruction);
}
else
{
addRegistersAsAttributes(cstInsn.getRegisters(), dexInstruction);
}
}
}
else if (instruction instanceof TargetInsn)
{
TargetInsn targetInsn= (TargetInsn) instruction;
String instructionName= targetInsn.getOpcode().getName();
dexInstruction= new Element(sanitizeInstructionName(instructionName), NS_DEX);
addRegistersAsAttributes(targetInsn.getRegisters(), dexInstruction);
if (instructionName.equals("packed-switch") || instructionName.equals("sparse-switch"))
{
SwitchData switchData= switchDataBlocks.get(targetInsn.getTargetAddress());
if (switchData == null)
{
Log.error(TAG, "DEXmlvmOutputProcess: Couldn't find SwitchData block.");
System.exit(-1);
}
IntList cases= switchData.getCases();
CodeAddress[] caseTargets= switchData.getTargets();
// Sanity check.
if (cases.size() != caseTargets.length)
{
Log.error(TAG, "DEXmlvmOutputProcess: SwitchData size mismatch: cases vs targets.");
System.exit(-1);
}
for (int i= 0; i < cases.size(); ++i)
{
Element caseElement= new Element("case", NS_DEX);
caseElement.setAttribute("key", String.valueOf(cases.get(i)));
caseElement.setAttribute("label", String.valueOf(caseTargets[i].getAddress()));
dexInstruction.addContent(caseElement);
}
}
else if (instructionName.equals("fill-array-data"))
{
ArrayList<Constant> data= arrayData.get(targetInsn.getTargetAddress()).getValues();
for (Constant c : data)
{
Element constant= new Element("constant", NS_DEX);
constant.setAttribute("value", c.toHuman());
dexInstruction.addContent(constant);
}
}
else
{