Пример #1
0
    internal static IEnumerable <CodeInstruction> ReplaceColors(
        IEnumerable <CodeInstruction> instructions,
        IEnumerable <KeyValuePair <Color, MethodInfo> > replacements
        )
    {
        var replDict = replacements is null ? null : replacements is IDictionary <Color, MethodInfo> dict ? dict : replacements.ToDictionary(x => x.Key, x => x.Value);

        var instrs = instructions.ToArray();

        for (int i = 0; i < instrs.Length; i++)
        {
            CodeInstruction in0 = instrs[i];
            if (i + 3 < instrs.Length && replDict is not null)
            {
                CodeInstruction in1 = instrs[i + 1];
                CodeInstruction in2 = instrs[i + 2];
                CodeInstruction in3 = instrs[i + 3];

                if (in3.opcode == OpCodes.Newobj && in3.operand is ConstructorInfo ctor && ctor.DeclaringType == typeof(Color))
                {
                    int?val0 = in0.AsInt();
                    int?val1 = in1.AsInt();
                    int?val2 = in2.AsInt();

                    if (val0.HasValue && val1.HasValue && val2.HasValue)
                    {
                        Color c = new(val0.Value, val1.Value, val2.Value);
                        if (replDict.TryGetValue(c, out var repl))
                        {
                            yield return(new CodeInstruction(
                                             opcode: OpCodes.Call,
                                             operand: repl
                                             ));

                            i += 3;
                            continue;
                        }
                    }
                }
            }

            yield return(in0);
        }
    }