use of jadx.api.plugins.input.data.ICallSite in project jadx by skylot.
the class InvokeDecoder method decode.
@Override
public void decode(CodeDecodeState state) {
DataReader reader = state.reader();
int mthIdx = reader.readS2();
if (payloadSize == 4) {
reader.skip(2);
}
JavaInsnData insn = state.insn();
insn.setIndex(mthIdx);
boolean instanceCall;
IMethodProto mthProto;
if (apiOpcode == Opcode.INVOKE_CUSTOM) {
ICallSite callSite = insn.getIndexAsCallSite();
insn.setPayload(callSite);
mthProto = (IMethodProto) callSite.getValues().get(2).getValue();
// 'this' arg already included in proto args
instanceCall = false;
} else {
IMethodRef mthRef = insn.getIndexAsMethod();
mthRef.load();
insn.setPayload(mthRef);
mthProto = mthRef;
instanceCall = apiOpcode != Opcode.INVOKE_STATIC;
}
int argsCount = mthProto.getArgTypes().size();
if (instanceCall) {
argsCount++;
}
// allocate twice of the size for worst case
insn.setRegsCount(argsCount * 2);
int[] regs = insn.getRegsArray();
// calculate actual count of registers
// set '1' in regs to be filled with stack values later, '0' for skip
int regsCount = 0;
if (instanceCall) {
regs[regsCount++] = 1;
}
for (String type : mthProto.getArgTypes()) {
int size = getRegsCountForType(type);
regs[regsCount++] = 1;
if (size == 2) {
regs[regsCount++] = 0;
}
}
insn.setRegsCount(regsCount);
for (int i = regsCount - 1; i >= 0; i--) {
if (regs[i] == 1) {
state.pop(i);
}
}
String returnType = mthProto.getReturnType();
if (!returnType.equals("V")) {
insn.setResultReg(state.push(returnType));
} else {
insn.setResultReg(-1);
}
}
use of jadx.api.plugins.input.data.ICallSite in project jadx by skylot.
the class UsageInfoVisitor method processInsn.
private static void processInsn(RootNode root, MethodNode mth, InsnData insnData, UsageInfo usageInfo) {
if (insnData.getOpcode() == Opcode.UNKNOWN) {
return;
}
switch(insnData.getIndexType()) {
case TYPE_REF:
insnData.decode();
ArgType usedType = ArgType.parse(insnData.getIndexAsType());
usageInfo.clsUse(mth, usedType);
break;
case FIELD_REF:
insnData.decode();
FieldNode fieldNode = root.resolveField(FieldInfo.fromRef(root, insnData.getIndexAsField()));
if (fieldNode != null) {
usageInfo.fieldUse(mth, fieldNode);
}
break;
case METHOD_REF:
{
insnData.decode();
IMethodRef mthRef;
ICustomPayload payload = insnData.getPayload();
if (payload != null) {
mthRef = ((IMethodRef) payload);
} else {
mthRef = insnData.getIndexAsMethod();
}
MethodNode methodNode = root.resolveMethod(MethodInfo.fromRef(root, mthRef));
if (methodNode != null) {
usageInfo.methodUse(mth, methodNode);
}
break;
}
case CALL_SITE:
{
insnData.decode();
ICallSite callSite = InsnDataUtils.getCallSite(insnData);
IMethodHandle methodHandle = InsnDataUtils.getMethodHandleAt(callSite, 4);
if (methodHandle != null) {
IMethodRef mthRef = methodHandle.getMethodRef();
MethodNode mthNode = root.resolveMethod(MethodInfo.fromRef(root, mthRef));
if (mthNode != null) {
usageInfo.methodUse(mth, mthNode);
}
}
break;
}
}
}
use of jadx.api.plugins.input.data.ICallSite in project jadx by skylot.
the class InvokeCustomBuilder method build.
public static InsnNode build(MethodNode mth, InsnData insn, boolean isRange) {
try {
ICallSite callSite = InsnDataUtils.getCallSite(insn);
if (callSite == null) {
throw new JadxRuntimeException("Failed to get call site for insn: " + insn);
}
callSite.load();
List<EncodedValue> values = callSite.getValues();
if (CustomLambdaCall.isLambdaInvoke(values)) {
return CustomLambdaCall.buildLambdaMethodCall(mth, insn, isRange, values);
}
if (CustomStringConcat.isStringConcat(values)) {
return CustomStringConcat.buildStringConcat(insn, isRange, values);
}
// TODO: output raw dynamic call
throw new JadxRuntimeException("Failed to process invoke-custom instruction: " + callSite);
} catch (Exception e) {
throw new JadxRuntimeException("'invoke-custom' instruction processing error: " + e.getMessage(), e);
}
}
Aggregations