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; } } }
// 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; } } }
// 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; } } }
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; } } }
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; } } }
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; } } }
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; } } } }
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; }
// #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); } } }