public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (
                    !lines[i].Optimized &&
                    lines[i].Operation is OpLdConst &&
                    lines[i + 1].OpCode == ILOpCode.Ceq && string.IsNullOrEmpty(lines[i + 1].Label))
                {
                    int         value        = (int)lines[i].RawParameter;
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpArithmetic2("compareEqual_const"),
                    };
                    newOperation.RawParameter = lines[i].RawParameter;
                    newOperation.StackContent = lines[i + 1].StackContent;
                    lines.Insert(i + 2, newOperation);
                    lines[i].Optimized     = true;
                    lines[i + 1].Optimized = true;
                }
            }
        }
Пример #2
0
        // IL_0000: ldarg.0
        // IL_0001: ldarg.1
        // IL_0002: stfld uint32 PlatformEnemy::'<MaxX>k__BackingField'
        public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (lines[i].Operation is OpLdarg &&
                    lines[i + 1].Operation is OpLdarg &&
                    lines[i + 2].Operation is OpStfld)
                {
                    bool        is16Bit      = lines[i + 2].Operation.Is16Bit(context, lines[i + 2]);
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpSetfld(lines[i].RawParameter.ToString(), lines[i + 1].RawParameter.ToString(), lines[i + 2].RawParameter.ToString(), is16Bit),
                    };
                    newOperation.RawParameter = newOperation.Operation.ConvertParameter(context, null);
                    newOperation.StackContent = lines[i + 2].StackContent;
                    lines.Insert(i + 3, newOperation);
                    lines[i].Optimized     = true;
                    lines[i + 1].Optimized = true;
                    lines[i + 2].Optimized = true;
                }
            }
        }
Пример #3
0
        // IL_00a8: ldarg.0
        // // this.data_++;
        // IL_00a9: ldarg.0
        // IL_00aa: ldfld int32 Player::data_
        // IL_00af: ldc.i4.1
        // IL_00b0: add
        // // (no C# code)
        // IL_00b1: stfld int32 Player::data_
        public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (lines[i].Operation is OpLdarg &&
                    lines[i + 1].Operation is OpLdarg &&
                    lines[i + 2].Operation is OpLdfld &&
                    lines[i + 3].OpCode == ILOpCode.Ldc_i4_1 &&
                    lines[i + 4].OpCode == ILOpCode.Add &&
                    lines[i + 5].Operation is OpStfld)
                {
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpIncfld(lines[i].RawParameter.ToString(), lines[i + 2].RawParameter.ToString()),
                    };
                    newOperation.RawParameter = newOperation.Operation.ConvertParameter(context, null);
                    newOperation.StackContent = lines[i + 5].StackContent;
                    lines.Insert(i + 6, newOperation);
                    lines[i].Optimized     = true;
                    lines[i + 1].Optimized = true;
                    lines[i + 2].Optimized = true;
                    lines[i + 3].Optimized = true;
                    lines[i + 4].Optimized = true;
                    lines[i + 5].Optimized = true;
                }
            }
        }
Пример #4
0
        public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (lines[i].Operation is OpLdConst &&
                    lines[i + 1].Operation is OpStloc && string.IsNullOrEmpty(lines[i + 1].Label))
                {
                    int         variable     = ((OpStloc)lines[i + 1].Operation).VarIndex;
                    int         value        = (int)lines[i].RawParameter;
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpInitVar(variable, value),
                    };
                    newOperation.RawParameter = newOperation.Operation.ConvertParameter(context, null);
                    newOperation.StackContent = lines[i + 1].StackContent;
                    lines.Insert(i + 2, newOperation);
                    lines[i].Optimized     = true;
                    lines[i + 1].Optimized = true;
                }
            }
        }
Пример #5
0
        public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (
                    !lines[i].Optimized &&
                    lines[i].Operation is OpLdConst &&
                    lines[i + 1].Operation is OpShortJump && lines[i + 1].OpCode != ILOpCode.Br_s && string.IsNullOrEmpty(lines[i + 1].Label))
                {
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpBranchConst(lines[i + 1].Operation.Command + "_const"),
                    };
                    newOperation.RawParameter = lines[i].RawParameter + ", " + lines[i + 1].RawParameter;
                    newOperation.StackContent = lines[i + 1].StackContent;
                    lines.Insert(i + 2, newOperation);
                    lines[i].Optimized     = true;
                    lines[i + 1].Optimized = true;
                }
            }
        }
Пример #6
0
        public void Execute(CompilerMethodContext context)
        {
            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (lines[i].Operation is OpLdstr &&
                    lines[i + 1].Operation is OpCall && lines[i + 1].RawParameter.ToString() == typeof(C64Lib.C64Address).GetMethod("FromLabel").GetLabel())
                {
                    string      label        = lines[i].RawParameter.ToString();
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpLoadPointerFromLabel(),
                    };
                    // hack
                    var p = ((string)lines[i].RawParameter).Split('_')[1];
                    newOperation.RawParameter = context.CompilerContext.StringValues[int.Parse(p)];
                    context.CompilerContext.OptimizedStringValues.Add(newOperation.RawParameter.ToString());
                    newOperation.StackContent = lines[i + 1].StackContent;
                    lines.Insert(i + 2, newOperation);
                    lines[i].Optimized     = true;
                    lines[i + 1].Optimized = true;
                }
            }
        }
Пример #7
0
        public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (lines[i].Operation is OpLdloc &&
                    lines[i + 1].OpCode == ILOpCode.Ldc_i4_1 &&
                    lines[i + 2].OpCode == ILOpCode.Add &&
                    lines[i + 3].Operation is OpStloc)
                {
                    int         variable     = ((OpStloc)lines[i + 3].Operation).VarIndex;
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpIncVar(variable),
                    };
                    newOperation.RawParameter = newOperation.Operation.ConvertParameter(context, null);
                    newOperation.StackContent = lines[i + 3].StackContent;
                    lines.Insert(i + 4, newOperation);
                    lines[i].Optimized     = true;
                    lines[i + 1].Optimized = true;
                    lines[i + 2].Optimized = true;
                    lines[i + 3].Optimized = true;
                }
            }
        }
        public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (lines[i].Operation is OpLdloc &&
                    lines[i + 1].Operation is OpLdConst &&
                    (lines[i + 2].OpCode == ILOpCode.Clt || lines[i + 2].OpCode == ILOpCode.Clt_un) &&
                    lines[i + 3].Operation is OpStloc &&
                    lines[i + 4].Operation is OpLdloc &&
                    (lines[i + 5].OpCode == ILOpCode.Brtrue || lines[i + 5].OpCode == ILOpCode.Brtrue_s))
                {
                    int         variable     = ((OpLdloc)lines[i].Operation).VarIndex;
                    int         value        = (int)lines[i + 1].RawParameter;
                    string      label        = (string)lines[i + 5].RawParameter;
                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpBranchIfVarLess(variable, value, label),
                    };
                    newOperation.RawParameter = newOperation.Operation.ConvertParameter(context, null);
                    newOperation.StackContent = lines[i + 5].StackContent;
                    lines.Insert(i + 6, newOperation);

                    for (int j = i; j < i + 6; j++)
                    {
                        lines[j].Optimized = true;
                    }
                }
            }
        }
Пример #9
0
        public void Execute(CompilerMethodContext context)
        {
            if (context.Method.IsAbstract)
            {
                return;
            }

            var body  = context.Method.GetMethodBody();
            var input = body.GetILAsByteArray();
            var lines = new List <ILOperation>();

            var index = 0;

            while (index < input.Length)
            {
                ILOpCode    opCode;
                ILOperation operation = new ILOperation();
                operation.Position = index;

                if (input[index] >= 254)
                {
                    opCode = (ILOpCode)(input[index++] * 256 + input[index++]);
                }
                else
                {
                    opCode = (ILOpCode)(input[index++]);
                }
                operation.OpCode    = opCode;
                operation.Operation = CommandMap.Get(operation.OpCode);

                if (!CommandMap.Supported(opCode))
                {
                    throw new NotSupportedException($"Command is not supported: {opCode.ToString()}");
                }

                var op        = CommandMap.Get(opCode);
                int parameter = 0;
                if (op.ParameterSize == 1)
                {
                    parameter = input[index++];
                }
                if (op.ParameterSize == 4)
                {
                    parameter = input[index++] + 256 * input[index++] + 256 * 256 * input[index++] + 256 * 256 * 256 * input[index++];
                }
                operation.RawParameter      = parameter;
                operation.OriginalParameter = parameter;
                if (op.ParameterSize == -1)
                {
                    var        parameterSize = parameter = input[index++] + 256 * input[index++] + 256 * 256 * input[index++] + 256 * 256 * 256 * input[index++];
                    List <int> parameters    = new List <int>(parameterSize);
                    for (int i = 0; i < parameterSize; i++)
                    {
                        parameters.Add(input[index++] + 256 * input[index++] + 256 * 256 * input[index++] + 256 * 256 * 256 * input[index++]);
                    }
                    operation.RawParameter      = parameters;
                    operation.OriginalParameter = parameter;
                }

                if (op.ParameterSize > -1)
                {
                    operation.RawParameter = op.ConvertParameter(context, operation);
                }
                operation.Size = index - operation.Position;

                lines.Add(operation);
            }
            context.Lines = lines;
        }
Пример #10
0
        // #newObj 3, 0 ; Newobj
        // #stack_duplicate8 ; Dup
        // #stack_push_int16 3288 ; Ldc_i4
        // ; conv ; Conv_i8
        // #stfld16 0 ; Stfld
        // #stack_duplicate8 ; Dup
        // #stack_push_int8 10 ; Ldc_i4_s
        // #stfld8 2 ; Stfld
        public void Execute(CompilerMethodContext context)
        {
            if (!context.TypeContext.CompilerContext.Optimize)
            {
                return;
            }

            var lines = context.Lines;

            for (int i = 0; i < lines.Count; i++)
            {
                if (lines[i].Operation is OpNewObj &&
                    this.GetIntParam(lines[i].RawParameter, 1) == 0 &&
                    lines[i + 1].Operation is OpDup)
                {
                    lines[i].Optimized = true;

                    var size   = this.GetIntParam(lines[i].RawParameter, 0);
                    var vtable = this.GetStringParam(lines[i].RawParameter, 2);

                    string[] mem = Enumerable.Repeat("0", size).ToArray();

                    int index = i + 1;
                    while (
                        lines[index].Operation is OpDup &&
                        (lines[index + 1].Operation is OpLdConst || lines[index + 1].Operation is OpLdstr) &&
                        (lines[index + 2].Operation is OpStfld || lines[index + 3].Operation is OpStfld))
                    {
                        // there is a conversion between ldc and setfld

                        var conv    = lines[index + 3].Operation is OpStfld;
                        var opPush  = lines[index + 1].Operation as OpLdConst;
                        var opLdstr = lines[index + 1].Operation as OpLdstr;
                        var is16    = false;

                        if (opPush != null)
                        {
                            is16 = opPush.Is16Bit(context, lines[index + 1]);
                        }
                        else if (opLdstr != null)
                        {
                            is16 = true; // ldstr;
                        }
                        else
                        {
                            throw new InvalidOperationException("Invalid operation.");
                        }
                        var value = GetStringParam(lines[index + 1].RawParameter, 0);
                        var pos   = GetIntParam(lines[index + (conv ? 3 : 2)].RawParameter, 0);
                        mem[pos] = $"<{value}";
                        if (is16)
                        {
                            mem[pos + 1] = $">{value}";
                        }
                        lines[index].Optimized     = true;
                        lines[index + 1].Optimized = true;
                        lines[index + 2].Optimized = true;
                        if (conv)
                        {
                            lines[index + 3].Optimized = true;
                        }

                        index += conv ? 4 : 3;
                    }

                    ILOperation newOperation = new ILOperation
                    {
                        Operation = new OpNewObjInit(mem, size, 0, vtable),
                    };
                    newOperation.RawParameter = newOperation.Operation.ConvertParameter(context, null);
                    newOperation.StackContent = lines[i].StackContent;
                    lines.Insert(index, newOperation);
                }
            }
        }