Search in sources :

Example 1 with ALoad

use of net.runelite.asm.attributes.code.instructions.ALoad in project runelite by runelite.

the class ClientErrorTransformer method transform.

private void transform(Method m) {
    if (!m.isStatic() || m.getDescriptor().size() != 2 || !m.getDescriptor().getTypeOfArg(0).equals(Type.STRING) || !m.getDescriptor().getTypeOfArg(1).equals(Type.THROWABLE))
        return;
    Code code = m.getCode();
    Instructions ins = code.getInstructions();
    /*
			Makes it so the old code in this method is logically dead,
			letting the mapper map it but making it so it's never executed.
		 */
    // load throwable
    Instruction aload0 = new ALoad(ins, 1);
    IfNull ifNull = new IfNull(ins, InstructionType.IFNULL);
    ifNull.setTo(ins.createLabelFor(ins.getInstructions().get(0)));
    // load throwable
    Instruction aload1 = new ALoad(ins, 1);
    InvokeVirtual printStackTrace = new InvokeVirtual(ins, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class("java/lang/Throwable"), "printStackTrace", new Signature("()V")));
    Instruction ret = new VReturn(ins);
    ins.addInstruction(0, aload0);
    ins.addInstruction(1, ifNull);
    ins.addInstruction(2, aload1);
    ins.addInstruction(3, printStackTrace);
    ins.addInstruction(4, ret);
    done = true;
}
Also used : Instructions(net.runelite.asm.attributes.code.Instructions) Instruction(net.runelite.asm.attributes.code.Instruction) Code(net.runelite.asm.attributes.Code) VReturn(net.runelite.asm.attributes.code.instructions.VReturn) IfNull(net.runelite.asm.attributes.code.instructions.IfNull) InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad)

Example 2 with ALoad

use of net.runelite.asm.attributes.code.instructions.ALoad in project runelite by runelite.

the class RuneliteBufferTransformer method injectLengthHeader.

/**
 * inject the length header after the packet opcode
 *
 * @param group
 */
private void injectLengthHeader(ClassGroup group) {
    RWOpcodeFinder rw = new RWOpcodeFinder(group);
    rw.find();
    Method writeOpcode = rw.getWriteOpcode();
    Code code = writeOpcode.getCode();
    Instructions instructions = code.getInstructions();
    List<Instruction> ins = instructions.getInstructions();
    Instruction start = ins.get(0);
    Instruction end = ins.stream().filter(i -> i.getType() == RETURN).findFirst().get();
    Label labelForStart = instructions.createLabelFor(start);
    Label labelForEnd = instructions.createLabelFor(end);
    final net.runelite.asm.pool.Field runelitePacketField = new net.runelite.asm.pool.Field(new net.runelite.asm.pool.Class(findClient(group).getName()), RUNELITE_PACKET, Type.BOOLEAN);
    int idx = ins.indexOf(labelForStart);
    instructions.addInstruction(idx++, new GetStatic(instructions, runelitePacketField));
    instructions.addInstruction(idx++, new IfEq(instructions, labelForStart));
    net.runelite.asm.pool.Method method = new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(writeOpcode.getClassFile().getName()), RUNELITE_FINISH_PACKET, new Signature("()V"));
    instructions.addInstruction(idx++, new ALoad(instructions, 0));
    instructions.addInstruction(idx++, new InvokeVirtual(instructions, method));
    idx = ins.indexOf(labelForEnd);
    instructions.addInstruction(idx++, new GetStatic(instructions, runelitePacketField));
    instructions.addInstruction(idx++, new IfEq(instructions, labelForEnd));
    method = new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(writeOpcode.getClassFile().getName()), RUNELITE_INIT_PACKET, new Signature("()V"));
    instructions.addInstruction(idx++, new ALoad(instructions, 0));
    instructions.addInstruction(idx++, new InvokeVirtual(instructions, method));
    logger.info("Injected finish/init packet calls into {}", writeOpcode);
}
Also used : RWOpcodeFinder(net.runelite.deob.c2s.RWOpcodeFinder) Label(net.runelite.asm.attributes.code.Label) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) IfEq(net.runelite.asm.attributes.code.instructions.IfEq) Instruction(net.runelite.asm.attributes.code.Instruction) Code(net.runelite.asm.attributes.Code) Field(net.runelite.asm.Field) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad)

Example 3 with ALoad

use of net.runelite.asm.attributes.code.instructions.ALoad in project runelite by runelite.

the class InjectHookMethod method injectHookMethod.

private void injectHookMethod(Annotation hook, Method deobMethod, Method vanillaMethod) throws InjectionException {
    String hookName = hook.getElement().getString();
    Instructions instructions = vanillaMethod.getCode().getInstructions();
    Signature.Builder builder = new Signature.Builder().setReturnType(// Hooks always return void
    Type.VOID);
    for (Type type : deobMethod.getDescriptor().getArguments()) {
        builder.addArgument(inject.deobfuscatedTypeToApiType(type));
    }
    assert deobMethod.isStatic() == vanillaMethod.isStatic();
    if (!deobMethod.isStatic()) {
        // Add variable to signature
        builder.addArgument(0, inject.deobfuscatedTypeToApiType(new Type(deobMethod.getClassFile().getName())));
    }
    Signature signature = builder.build();
    List<Integer> insertIndexes = findHookLocations(hook, vanillaMethod);
    insertIndexes.sort((a, b) -> Integer.compare(b, a));
    for (int insertPos : insertIndexes) {
        if (!deobMethod.isStatic()) {
            instructions.addInstruction(insertPos++, new ALoad(instructions, 0));
        }
        // current variable index
        int index = deobMethod.isStatic() ? 0 : 1;
        for (int i = index; i < signature.size(); ++i) {
            Type type = signature.getTypeOfArg(i);
            Instruction load = inject.createLoadForTypeIndex(instructions, type, index);
            instructions.addInstruction(insertPos++, load);
            index += type.getSize();
        }
        // Invoke callback
        InvokeStatic invoke = new InvokeStatic(instructions, new net.runelite.asm.pool.Method(new net.runelite.asm.pool.Class(HOOKS), hookName, signature));
        instructions.addInstruction(insertPos++, invoke);
    }
    logger.info("Injected method hook {} in {} with {} args: {}", hookName, vanillaMethod, signature.size(), signature.getArguments());
}
Also used : Instructions(net.runelite.asm.attributes.code.Instructions) ReturnInstruction(net.runelite.asm.attributes.code.instruction.types.ReturnInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) InstructionType(net.runelite.asm.attributes.code.InstructionType) Type(net.runelite.asm.Type) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Example 4 with ALoad

use of net.runelite.asm.attributes.code.instructions.ALoad in project runelite by runelite.

the class MixinInjector method injectMethods.

private void injectMethods(ClassFile mixinCf, ClassFile cf, Map<net.runelite.asm.pool.Field, Field> shadowFields) throws InjectionException {
    // Keeps mappings between methods annotated with @Copy -> the copied method within the vanilla pack
    Map<net.runelite.asm.pool.Method, CopiedMethod> copiedMethods = new HashMap<>();
    // Handle the copy mixins first, so all other mixins know of the copies
    for (Method method : mixinCf.getMethods()) {
        Annotation copyAnnotation = method.getAnnotations().find(COPY);
        if (copyAnnotation == null) {
            continue;
        }
        String deobMethodName = (String) copyAnnotation.getElement().getValue();
        ClassFile deobCf = inject.toDeobClass(cf);
        Method deobMethod = findDeobMethod(deobCf, deobMethodName, method.getDescriptor());
        if (deobMethod == null) {
            throw new InjectionException("Failed to find the deob method " + deobMethodName + " for mixin " + mixinCf);
        }
        if (method.isStatic() != deobMethod.isStatic()) {
            throw new InjectionException("Mixin method " + method + " should be " + (deobMethod.isStatic() ? "static" : "non-static"));
        }
        // Find the vanilla class where the method to copy is in
        String obClassName = DeobAnnotations.getObfuscatedName(deobMethod.getClassFile().getAnnotations());
        ClassFile obCf = inject.getVanilla().findClass(obClassName);
        assert obCf != null : "unable to find vanilla class from obfuscated name " + obClassName;
        String obMethodName = DeobAnnotations.getObfuscatedName(deobMethod.getAnnotations());
        Signature obMethodSignature = DeobAnnotations.getObfuscatedSignature(deobMethod);
        if (obMethodName == null) {
            obMethodName = deobMethod.getName();
        }
        if (obMethodSignature == null) {
            obMethodSignature = deobMethod.getDescriptor();
        }
        Method obMethod = obCf.findMethod(obMethodName, obMethodSignature);
        if (obMethod == null) {
            throw new InjectionException("Failed to find the ob method " + obMethodName + " for mixin " + mixinCf);
        }
        if (method.getDescriptor().size() > obMethod.getDescriptor().size()) {
            throw new InjectionException("Mixin methods cannot have more parameters than their corresponding ob method");
        }
        Method copy = new Method(cf, "copy$" + deobMethodName, obMethodSignature);
        moveCode(copy, obMethod.getCode());
        copy.setAccessFlags(obMethod.getAccessFlags());
        copy.setPublic();
        copy.getExceptions().getExceptions().addAll(obMethod.getExceptions().getExceptions());
        copy.getAnnotations().getAnnotations().addAll(obMethod.getAnnotations().getAnnotations());
        cf.addMethod(copy);
        /*
				If the desc for the mixin method and the desc for the ob method
				are the same in length, assume that the mixin method is taking
				care of the garbage parameter itself.
			 */
        boolean hasGarbageValue = method.getDescriptor().size() != obMethod.getDescriptor().size() && deobMethod.getDescriptor().size() < obMethodSignature.size();
        copiedMethods.put(method.getPoolMethod(), new CopiedMethod(copy, hasGarbageValue));
        logger.debug("Injected copy of {} to {}", obMethod, copy);
    }
    // Handle the rest of the mixin types
    for (Method method : mixinCf.getMethods()) {
        boolean isClinit = "<clinit>".equals(method.getName());
        boolean isInit = "<init>".equals(method.getName());
        boolean hasInject = method.getAnnotations().find(INJECT) != null;
        // You can't annotate clinit, so its always injected
        if ((hasInject && isInit) || isClinit) {
            if (!"()V".equals(method.getDescriptor().toString())) {
                throw new InjectionException("Injected constructors cannot have arguments");
            }
            Method[] originalMethods = cf.getMethods().stream().filter(n -> n.getName().equals(method.getName())).toArray(Method[]::new);
            // If there isn't a <clinit> already just inject ours, otherwise rename it
            // This is always true for <init>
            String name = method.getName();
            if (originalMethods.length > 0) {
                name = "rl$$" + (isInit ? "init" : "clinit");
            }
            String numberlessName = name;
            for (int i = 1; cf.findMethod(name, method.getDescriptor()) != null; i++) {
                name = numberlessName + i;
            }
            Method copy = new Method(cf, name, method.getDescriptor());
            moveCode(copy, method.getCode());
            copy.setAccessFlags(method.getAccessFlags());
            copy.setPrivate();
            assert method.getExceptions().getExceptions().isEmpty();
            // Remove the call to the superclass's ctor
            if (isInit) {
                Instructions instructions = copy.getCode().getInstructions();
                ListIterator<Instruction> listIter = instructions.getInstructions().listIterator();
                for (; listIter.hasNext(); ) {
                    Instruction instr = listIter.next();
                    if (instr instanceof InvokeSpecial) {
                        InvokeSpecial invoke = (InvokeSpecial) instr;
                        assert invoke.getMethod().getName().equals("<init>");
                        listIter.remove();
                        int pops = invoke.getMethod().getType().getArguments().size() + 1;
                        for (int i = 0; i < pops; i++) {
                            listIter.add(new Pop(instructions));
                        }
                        break;
                    }
                }
            }
            setOwnersToTargetClass(mixinCf, cf, copy, shadowFields, copiedMethods);
            cf.addMethod(copy);
            // Call our method at the return point of the matching method(s)
            for (Method om : originalMethods) {
                Instructions instructions = om.getCode().getInstructions();
                ListIterator<Instruction> listIter = instructions.getInstructions().listIterator();
                for (; listIter.hasNext(); ) {
                    Instruction instr = listIter.next();
                    if (instr instanceof ReturnInstruction) {
                        listIter.previous();
                        if (isInit) {
                            listIter.add(new ALoad(instructions, 0));
                            listIter.add(new InvokeSpecial(instructions, copy.getPoolMethod()));
                        } else if (isClinit) {
                            listIter.add(new InvokeStatic(instructions, copy.getPoolMethod()));
                        }
                        listIter.next();
                    }
                }
            }
            logger.debug("Injected mixin method {} to {}", copy, cf);
        } else if (hasInject) {
            // Make sure the method doesn't invoke copied methods
            for (Instruction i : method.getCode().getInstructions().getInstructions()) {
                if (i instanceof InvokeInstruction) {
                    InvokeInstruction ii = (InvokeInstruction) i;
                    if (copiedMethods.containsKey(ii.getMethod())) {
                        throw new InjectionException("Injected methods cannot invoke copied methods");
                    }
                }
            }
            Method copy = new Method(cf, method.getName(), method.getDescriptor());
            moveCode(copy, method.getCode());
            copy.setAccessFlags(method.getAccessFlags());
            copy.setPublic();
            assert method.getExceptions().getExceptions().isEmpty();
            setOwnersToTargetClass(mixinCf, cf, copy, shadowFields, copiedMethods);
            cf.addMethod(copy);
            logger.debug("Injected mixin method {} to {}", copy, cf);
        } else if (method.getAnnotations().find(REPLACE) != null) {
            Annotation replaceAnnotation = method.getAnnotations().find(REPLACE);
            String deobMethodName = (String) replaceAnnotation.getElement().getValue();
            ClassFile deobCf = inject.toDeobClass(cf);
            Method deobMethod = findDeobMethod(deobCf, deobMethodName, method.getDescriptor());
            if (deobMethod == null) {
                throw new InjectionException("Failed to find the deob method " + deobMethodName + " for mixin " + mixinCf);
            }
            if (method.isStatic() != deobMethod.isStatic()) {
                throw new InjectionException("Mixin method " + method + " should be " + (deobMethod.isStatic() ? "static" : "non-static"));
            }
            String obMethodName = DeobAnnotations.getObfuscatedName(deobMethod.getAnnotations());
            Signature obMethodSignature = DeobAnnotations.getObfuscatedSignature(deobMethod);
            // Deob signature is the same as ob signature
            if (obMethodName == null) {
                obMethodName = deobMethod.getName();
            }
            if (obMethodSignature == null) {
                obMethodSignature = deobMethod.getDescriptor();
            }
            // Find the vanilla class where the method to copy is in
            String obClassName = DeobAnnotations.getObfuscatedName(deobMethod.getClassFile().getAnnotations());
            ClassFile obCf = inject.getVanilla().findClass(obClassName);
            Method obMethod = obCf.findMethod(obMethodName, obMethodSignature);
            assert obMethod != null : "obfuscated method " + obMethodName + obMethodSignature + " does not exist";
            if (method.getDescriptor().size() > obMethod.getDescriptor().size()) {
                throw new InjectionException("Mixin methods cannot have more parameters than their corresponding ob method");
            }
            Type returnType = method.getDescriptor().getReturnValue();
            Type deobReturnType = inject.apiTypeToDeobfuscatedType(returnType);
            if (!returnType.equals(deobReturnType)) {
                ClassFile deobReturnTypeClassFile = inject.getDeobfuscated().findClass(deobReturnType.getInternalName());
                if (deobReturnTypeClassFile != null) {
                    ClassFile obReturnTypeClass = inject.toObClass(deobReturnTypeClassFile);
                    Instructions instructions = method.getCode().getInstructions();
                    ListIterator<Instruction> listIter = instructions.getInstructions().listIterator();
                    for (; listIter.hasNext(); ) {
                        Instruction instr = listIter.next();
                        if (instr instanceof ReturnInstruction) {
                            listIter.previous();
                            CheckCast checkCast = new CheckCast(instructions);
                            checkCast.setType(new Type(obReturnTypeClass.getName()));
                            listIter.add(checkCast);
                            listIter.next();
                        }
                    }
                }
            }
            moveCode(obMethod, method.getCode());
            boolean hasGarbageValue = method.getDescriptor().size() != obMethod.getDescriptor().size() && deobMethod.getDescriptor().size() < obMethodSignature.size();
            if (hasGarbageValue) {
                int garbageIndex = obMethod.isStatic() ? obMethod.getDescriptor().size() - 1 : obMethod.getDescriptor().size();
                /*
						If the mixin method doesn't have the garbage parameter,
						the compiler will have produced code that uses the garbage
						parameter's local variable index for other things,
						so we'll have to add 1 to all loads/stores to indices
						that are >= garbageIndex.
					 */
                shiftLocalIndices(obMethod.getCode().getInstructions(), garbageIndex);
            }
            setOwnersToTargetClass(mixinCf, cf, obMethod, shadowFields, copiedMethods);
            logger.debug("Replaced method {} with mixin method {}", obMethod, method);
        }
    }
}
Also used : FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) ListIterator(java.util.ListIterator) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) GetField(net.runelite.asm.attributes.code.instructions.GetField) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Code(net.runelite.asm.attributes.Code) ALoad(net.runelite.asm.attributes.code.instructions.ALoad) ArrayList(java.util.ArrayList) Method(net.runelite.asm.Method) ILoad(net.runelite.asm.attributes.code.instructions.ILoad) Map(java.util.Map) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) ClassPath(com.google.common.reflect.ClassPath) Pop(net.runelite.asm.attributes.code.instructions.Pop) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) InvokeDynamic(net.runelite.asm.attributes.code.instructions.InvokeDynamic) DeobAnnotations(net.runelite.deob.DeobAnnotations) Logger(org.slf4j.Logger) ClassFileVisitor(net.runelite.asm.visitors.ClassFileVisitor) Field(net.runelite.asm.Field) ReturnInstruction(net.runelite.asm.attributes.code.instruction.types.ReturnInstruction) IOException(java.io.IOException) ClassInfo(com.google.common.reflect.ClassPath.ClassInfo) Type(net.runelite.asm.Type) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic) PutField(net.runelite.asm.attributes.code.instructions.PutField) Mixin(net.runelite.api.mixins.Mixin) List(java.util.List) ClassFile(net.runelite.asm.ClassFile) Annotation(net.runelite.asm.attributes.annotation.Annotation) ClassReader(org.objectweb.asm.ClassReader) Instructions(net.runelite.asm.attributes.code.Instructions) CheckCast(net.runelite.asm.attributes.code.instructions.CheckCast) InvokeSpecial(net.runelite.asm.attributes.code.instructions.InvokeSpecial) Signature(net.runelite.asm.signature.Signature) Instruction(net.runelite.asm.attributes.code.Instruction) InputStream(java.io.InputStream) HashMap(java.util.HashMap) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) ReturnInstruction(net.runelite.asm.attributes.code.instruction.types.ReturnInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) ReturnInstruction(net.runelite.asm.attributes.code.instruction.types.ReturnInstruction) ClassFile(net.runelite.asm.ClassFile) InvokeSpecial(net.runelite.asm.attributes.code.instructions.InvokeSpecial) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) CheckCast(net.runelite.asm.attributes.code.instructions.CheckCast) Annotation(net.runelite.asm.attributes.annotation.Annotation) Pop(net.runelite.asm.attributes.code.instructions.Pop) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) Type(net.runelite.asm.Type) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Example 5 with ALoad

use of net.runelite.asm.attributes.code.instructions.ALoad in project runelite by runelite.

the class InjectInvoker method injectInvoker.

private void injectInvoker(ClassFile clazz, java.lang.reflect.Method method, Method deobfuscatedMethod, Method invokeMethod, String garbage) {
    if (clazz.findMethod(method.getName(), deobfuscatedMethod.getDescriptor()) != null) {
        logger.warn("Not injecting method {} because it already exists!", method);
        // this can happen from exporting a field and method with the same name
        return;
    }
    assert invokeMethod.isStatic() == deobfuscatedMethod.isStatic();
    assert invokeMethod.isStatic() || invokeMethod.getClassFile() == clazz;
    Type lastGarbageArgumentType = null;
    if (deobfuscatedMethod.getDescriptor().getArguments().size() != invokeMethod.getDescriptor().getArguments().size()) {
        // allow for obfuscated method to have a single bogus signature at the end
        assert deobfuscatedMethod.getDescriptor().size() + 1 == invokeMethod.getDescriptor().size();
        List<Type> arguments = invokeMethod.getDescriptor().getArguments();
        lastGarbageArgumentType = arguments.get(arguments.size() - 1);
    }
    // Injected method signature is always the same as the API
    Signature apiSignature = inject.javaMethodToSignature(method);
    Method invokerMethodSignature = new Method(clazz, method.getName(), apiSignature);
    invokerMethodSignature.setAccessFlags(ACC_PUBLIC);
    // create code attribute
    Code code = new Code(invokerMethodSignature);
    invokerMethodSignature.setCode(code);
    Instructions instructions = code.getInstructions();
    List<Instruction> ins = instructions.getInstructions();
    // this + arguments
    code.setMaxStack(1 + invokeMethod.getDescriptor().size());
    // load function arguments onto the stack.
    int index = 0;
    if (!invokeMethod.isStatic()) {
        // this
        ins.add(new ALoad(instructions, index++));
    } else {
        // this method is always non static
        ++index;
    }
    for (int i = 0; i < deobfuscatedMethod.getDescriptor().size(); ++i) {
        Type type = deobfuscatedMethod.getDescriptor().getTypeOfArg(i);
        Instruction loadInstruction = inject.createLoadForTypeIndex(instructions, type, index);
        ins.add(loadInstruction);
        Signature invokeDesc = invokeMethod.getDescriptor();
        Type obType = invokeDesc.getTypeOfArg(i);
        if (!type.equals(obType)) {
            CheckCast checkCast = new CheckCast(instructions);
            checkCast.setType(obType);
            ins.add(checkCast);
        }
        if (loadInstruction instanceof DLoad || loadInstruction instanceof LLoad) {
            index += 2;
        } else {
            index += 1;
        }
    }
    if (lastGarbageArgumentType != null) {
        // if garbage is null here it might just be an unused parameter, not part of the obfuscation
        if (garbage == null) {
            garbage = "0";
        }
        switch(lastGarbageArgumentType.toString()) {
            case "Z":
            case "B":
            case "C":
                ins.add(new BiPush(instructions, Byte.parseByte(garbage)));
                break;
            case "S":
                ins.add(new SiPush(instructions, Short.parseShort(garbage)));
                break;
            case "I":
                ins.add(new LDC(instructions, Integer.parseInt(garbage)));
                break;
            case "D":
                ins.add(new LDC(instructions, Double.parseDouble(garbage)));
                break;
            case "F":
                ins.add(new LDC(instructions, Float.parseFloat(garbage)));
                break;
            case "J":
                ins.add(new LDC(instructions, Long.parseLong(garbage)));
                break;
            default:
                throw new RuntimeException("Unknown type");
        }
    }
    if (invokeMethod.isStatic()) {
        ins.add(new InvokeStatic(instructions, invokeMethod.getPoolMethod()));
    } else {
        ins.add(new InvokeVirtual(instructions, invokeMethod.getPoolMethod()));
    }
    Type returnValue = invokeMethod.getDescriptor().getReturnValue();
    InstructionType returnType;
    if (returnValue.isPrimitive() && returnValue.getDimensions() == 0) {
        switch(returnValue.toString()) {
            case "Z":
            case "I":
                returnType = InstructionType.IRETURN;
                break;
            case "J":
                returnType = InstructionType.LRETURN;
                break;
            case "F":
                returnType = InstructionType.FRETURN;
                break;
            case "D":
                returnType = InstructionType.DRETURN;
                break;
            case "V":
                returnType = InstructionType.RETURN;
                break;
            default:
                assert false;
                return;
        }
    } else {
        returnType = InstructionType.ARETURN;
    }
    ins.add(new Return(instructions, returnType));
    clazz.addMethod(invokerMethodSignature);
}
Also used : SiPush(net.runelite.asm.attributes.code.instructions.SiPush) LLoad(net.runelite.asm.attributes.code.instructions.LLoad) Return(net.runelite.asm.attributes.code.instructions.Return) InstructionType(net.runelite.asm.attributes.code.InstructionType) DLoad(net.runelite.asm.attributes.code.instructions.DLoad) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) Method(net.runelite.asm.Method) CheckCast(net.runelite.asm.attributes.code.instructions.CheckCast) Instruction(net.runelite.asm.attributes.code.Instruction) BiPush(net.runelite.asm.attributes.code.instructions.BiPush) Code(net.runelite.asm.attributes.Code) InstructionType(net.runelite.asm.attributes.code.InstructionType) Type(net.runelite.asm.Type) InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Signature(net.runelite.asm.signature.Signature) ALoad(net.runelite.asm.attributes.code.instructions.ALoad) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Aggregations

Instruction (net.runelite.asm.attributes.code.Instruction)9 Instructions (net.runelite.asm.attributes.code.Instructions)9 ALoad (net.runelite.asm.attributes.code.instructions.ALoad)9 Signature (net.runelite.asm.signature.Signature)8 Method (net.runelite.asm.Method)7 Type (net.runelite.asm.Type)6 Code (net.runelite.asm.attributes.Code)6 Field (net.runelite.asm.Field)4 InstructionType (net.runelite.asm.attributes.code.InstructionType)4 InvokeStatic (net.runelite.asm.attributes.code.instructions.InvokeStatic)4 LDC (net.runelite.asm.attributes.code.instructions.LDC)4 CheckCast (net.runelite.asm.attributes.code.instructions.CheckCast)3 GetField (net.runelite.asm.attributes.code.instructions.GetField)3 ILoad (net.runelite.asm.attributes.code.instructions.ILoad)3 IMul (net.runelite.asm.attributes.code.instructions.IMul)3 InvokeVirtual (net.runelite.asm.attributes.code.instructions.InvokeVirtual)3 PutStatic (net.runelite.asm.attributes.code.instructions.PutStatic)3 ArrayList (java.util.ArrayList)2 ListIterator (java.util.ListIterator)2 ClassFile (net.runelite.asm.ClassFile)2