private static IEnumerable <CodeInstruction> Transpiler(MethodBase __originalMethod,
                                                                IEnumerable <CodeInstruction> instructions)
        {
            var inst        = PatchProcessor.GetOriginalInstructions(__originalMethod);
            var modInstList = instructions.ToList();

            var insts = new Myers <CodeInstruction>(inst.ToArray(), modInstList.ToArray(), methComparer);

            insts.Compute();

            var key   = Utility.GetMethodKey(__originalMethod as MethodInfo);
            var index = MethodInfoCache.AddMethod(key, __originalMethod as MethodInfo);

            foreach (var thing in insts.changeSet)
            {
                // We only want added methods
                if (thing.change != ChangeType.Added)
                {
                    continue;
                }
                if (!InternalMethodUtility.IsFunctionCall(thing.value.opcode) ||
                    !(thing.value.operand is MethodInfo meth))
                {
                    continue;
                }

                // swap our instruction
                var replaceInstruction = MethodTransplanting.ReplaceMethodInstruction(
                    thing.value,
                    key,
                    typeof(H_HarmonyTranspilersInternalMethods),
                    index);

                // Find the place it was in our method, and replace the instruction (Optimisation Opportunity to improve this)
                for (var i = 0; i < modInstList.Count; i++)
                {
                    var instruction = modInstList[i];
                    if (!InternalMethodUtility.IsFunctionCall(instruction.opcode))
                    {
                        continue;
                    }
                    if (!(instruction.operand is MethodInfo info) || info.Name != meth.Name)
                    {
                        continue;
                    }


                    if (instruction != replaceInstruction)
                    {
                        modInstList[i] = replaceInstruction;
                    }
                    break;
                }
            }

            return(modInstList);
        }
        public static void ClearPatchCaches()
        {
            patchedAssemblies.Clear();
            patchedTypes.Clear();
            patchedMethods.Clear();

            InternalMethodUtility.ClearCaches();
            MethodTransplanting.ClearCaches();
            TranspilerMethodUtility.ClearCaches();

            MethodInfoCache.ClearCache();

#if DEBUG
            ThreadSafeLogger.Message("[Analyzer] Cleared all caches");
#endif
        }
Exemplo n.º 3
0
        // Functions primarily to check if two function call CodeInstructions are the same.
        public override bool Equals(CodeInstruction b1, CodeInstruction b2)
        {
            if (b1.opcode != b2.opcode)
            {
                return(false);
            }

            if (InternalMethodUtility.IsFunctionCall(b1.opcode))
            {
                try
                {
                    return(((MethodInfo)b1.operand).Name == ((MethodInfo)b2.operand).Name);
                }
                catch { }
            }

            return(b1.operand == b2.operand);
        }