Skip to content

Commit 4e1691c

Browse files
committed
added another reason for introducing intermediate registers and casts
1 parent 5218e5e commit 4e1691c

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

src/soot/toDex/ExprVisitor.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -297,18 +297,25 @@ private void buildCalculatingBinaryInsn(final String binaryOperation,
297297
// on non-primitive values
298298
if (!(secondOperand.getType() instanceof PrimType))
299299
throw new RuntimeException("Invalid value type for primitibe operation");
300-
301-
// If the second register is not of the precise target type, we need to
302-
// cast. This can happen, because we cannot load BYTE values. We instead
303-
// load INT constants and then need to typecast.
300+
301+
// For some data types, there are no calculating opcodes in Dalvik. In
302+
// this case, we need to use a bigger opcode and cast the result back.
303+
PrimitiveType destRegType = PrimitiveType.getByName(destinationReg.getType().toString());
304304
Register secondOpReg = regAlloc.asImmediate(secondOperand, constantV);
305305
Register orgDestReg = destinationReg;
306-
PrimitiveType destRegType = PrimitiveType.getByName(destinationReg.getType().toString());
307-
if (isBiggerThan(PrimitiveType.getByName(secondOpReg.getType().toString()), destRegType)) {
308-
destinationReg = regAlloc.asTmpReg(secondOpReg.getType());
306+
if (isSmallerThan(destRegType, PrimitiveType.INT)) {
307+
destinationReg = regAlloc.asTmpReg(IntType.v());
309308
}
310-
else if (isBiggerThan(PrimitiveType.getByName(firstOpReg.getType().toString()), destRegType)) {
311-
destinationReg = regAlloc.asTmpReg(firstOpReg.getType());
309+
else {
310+
// If the second register is not of the precise target type, we need to
311+
// cast. This can happen, because we cannot load BYTE values. We instead
312+
// load INT constants and then need to typecast.
313+
if (isBiggerThan(PrimitiveType.getByName(secondOpReg.getType().toString()), destRegType)) {
314+
destinationReg = regAlloc.asTmpReg(secondOpReg.getType());
315+
}
316+
else if (isBiggerThan(PrimitiveType.getByName(firstOpReg.getType().toString()), destRegType)) {
317+
destinationReg = regAlloc.asTmpReg(firstOpReg.getType());
318+
}
312319
}
313320

314321
// use special "/2addr"-opcodes if destination equals first op
@@ -698,6 +705,10 @@ private boolean isBiggerThan(PrimitiveType type, PrimitiveType relativeTo) {
698705
return type.compareTo(relativeTo) > 0;
699706
}
700707

708+
private boolean isSmallerThan(PrimitiveType type, PrimitiveType relativeTo) {
709+
return type.compareTo(relativeTo) < 0;
710+
}
711+
701712
private Opcode getCastOpc(PrimitiveType sourceType, PrimitiveType castType) {
702713
Opcode opc = Opcode.valueOf(sourceType.getName().toUpperCase() + "_TO_"
703714
+ castType.getName().toUpperCase());

0 commit comments

Comments
 (0)