Resolve inline methods lazily, to prevent issues when types for unused inline methods aren't present in the odex file

git-svn-id: https://smali.googlecode.com/svn/trunk@527 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-12-25 23:05:57 +00:00
parent f7c84c8c41
commit 64c389570e
2 changed files with 41 additions and 27 deletions

View File

@ -246,10 +246,10 @@ public class DeodexUtil {
throw new RuntimeException("Could not find the inline method with index " + inlineMethodIndex); throw new RuntimeException("Could not find the inline method with index " + inlineMethodIndex);
} }
assert inlineMethod != null; assert inlineMethod != null;
assert inlineMethod.methodIdItem != null; assert inlineMethod.getMethodIdItem() != null;
Opcode opcode = null; Opcode opcode = null;
switch (inlineMethod.methodType) { switch (inlineMethod.getMethodType()) {
case Direct: case Direct:
opcode = Opcode.INVOKE_DIRECT; opcode = Opcode.INVOKE_DIRECT;
break; break;
@ -262,14 +262,14 @@ public class DeodexUtil {
} }
i.fixedInstruction = new Instruction35msf(opcode, (Instruction35ms)i.instruction, i.fixedInstruction = new Instruction35msf(opcode, (Instruction35ms)i.instruction,
inlineMethod.methodIdItem); inlineMethod.getMethodIdItem());
insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize(i.offset*2)/2); insn nextInstruction = i.getInstructionAtOffset(i.offset + i.instruction.getSize(i.offset*2)/2);
assert nextInstruction != null; assert nextInstruction != null;
if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) { if (nextInstruction.instruction.opcode == Opcode.MOVE_RESULT_OBJECT) {
nextInstruction.registerReferenceType = nextInstruction.registerReferenceType =
inlineMethod.methodIdItem.getPrototype().getReturnType().getTypeDescriptor(); inlineMethod.getMethodIdItem().getPrototype().getReturnType().getTypeDescriptor();
} }
return true; return true;

View File

@ -90,24 +90,7 @@ public class Deodexerant {
} }
String methodDescriptor = parts[1]; String methodDescriptor = parts[1];
inlineMethods[i] = new InlineMethod(methodDescriptor, type);
Matcher m = fullMethodPattern.matcher(methodDescriptor);
if (!m.matches()) {
throw new RuntimeException("Invalid method descriptor: " + methodDescriptor);
}
String classType = m.group(1);
String methodName = m.group(2);
String methodParams = m.group(3);
String methodRet = m.group(4);
MethodIdItem method = parseAndResolveMethod(classType, methodName, methodParams, methodRet);
if (method == null) {
inlineMethods[i] = null;
continue;
}
inlineMethods[i] = new InlineMethod(method, type);
} }
} }
@ -416,13 +399,44 @@ public class Deodexerant {
Static Static
} }
public static class InlineMethod { public class InlineMethod {
public final MethodIdItem methodIdItem; public final String inlineMethodDescriptor;
public final InlineMethodType methodType; private final InlineMethodType methodType;
public InlineMethod(MethodIdItem methodIdItem, InlineMethodType methodType) { private MethodIdItem methodIdItem = null;
this.methodIdItem = methodIdItem;
public InlineMethod(String inlineMethodDescriptor, InlineMethodType methodType) {
this.inlineMethodDescriptor = inlineMethodDescriptor;
this.methodType = methodType; this.methodType = methodType;
} }
public MethodIdItem getMethodIdItem() {
if (methodIdItem == null) {
loadMethod();
}
return methodIdItem;
}
public InlineMethodType getMethodType() {
return methodType;
}
private void loadMethod() {
Matcher m = fullMethodPattern.matcher(inlineMethodDescriptor);
if (!m.matches()) {
throw new RuntimeException("Invalid method descriptor: " + inlineMethodDescriptor);
}
String classType = m.group(1);
String methodName = m.group(2);
String methodParams = m.group(3);
String methodRet = m.group(4);
MethodIdItem method = parseAndResolveMethod(classType, methodName, methodParams, methodRet);
if (method == null) {
throw new RuntimeException("Could not resolve method " + inlineMethodDescriptor);
}
this.methodIdItem = method;
}
} }
private TypeIdItem getType(String typeDescriptor) { private TypeIdItem getType(String typeDescriptor) {