public override object ConvertParameter(CompilerMethodContext context, ILOperation operation) { var method = context.CompilerContext.Assembly.ManifestModule.ResolveMethod((int)operation.RawParameter); var t = method.ReflectedType; var size = 0; var referenceFields = 0; foreach (var f in t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { size += f.FieldType.GetStorageBytes(); if (f.FieldType.IsReferenceCounted()) { referenceFields++; } } //var label = context.CompilerContext.Assembly.ManifestModule.ResolveMethod(operation.RawParameter).GetLabel(); var vtable = t.IsGenericType ? "0" : $"{t.Name.ToValidName()}_VTable"; // var ctor = $"{t.Name}_x_ctor"; var ctor = "0"; if (t.Assembly == typeof(Func <object>).Assembly) { ctor = $"{t.Name}_x_ctor".ToValidName(); } return($"{size}, {referenceFields}, {vtable}, {ctor}"); }
public void Execute(CompilerMethodContext context) { if (context.Method.IsAbstract) { return; } var stack = new Stack <ILOperation>(); stack.Push(context.Lines[0]); while (stack.Count > 0) { var op = stack.Pop(); if (op.StackContent != null) { continue; } if (op.PreviousInstructions.Count == 0) { op.StackContent = new List <Type>(); } else { op.StackContent = new List <Type>(op.PreviousInstructions.First(x => x.StackContent != null).StackContent); } op.Operation.SetStackContent(context, op); foreach (var instruction in op.NextInstructions) { if (instruction.StackContent == null) { stack.Push(instruction); } } } }
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 override void SetStackContent(CompilerMethodContext context, ILOperation operation) { operation.StackContent.RemoveLast(1); var field = context.CompilerContext.Assembly.ManifestModule.ResolveField((int)operation.OriginalParameter); operation.StackContent.Add(field.FieldType); }
public override string Emit(CompilerMethodContext context, ILOperation operation) { bool normalCall = false; var methodInfo = context.CompilerContext.Assembly.ManifestModule.ResolveMethod((int)operation.OriginalParameter); // for Func<> if (!methodInfo.IsVirtual || methodInfo.ReflectedType.Name.StartsWith("Func")) { normalCall = true; } if (normalCall) { return(base.Emit(context, operation)); } var index = methodInfo.ReflectedType.GetVirtualMethodIndex(methodInfo); var stackPosition = methodInfo.GetParameters().Select(x => x.ParameterType.GetStorageBytes()).Sum() + 1; if (index == -1) { throw new InvalidOperationException($"Virtual method not found: {methodInfo.Name}. Type: {methodInfo.ReflectedType.Name}"); } return($"#callVirt {index}, {stackPosition}"); }
// 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].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; } } }
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; } } }
// 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; } } }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { var last = operation.StackContent.Last(); last.CheckCompatible(context.GetLocalVariableType(VarIndex)); operation.StackContent.RemoveLast(1); }
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 override object ConvertParameter(CompilerMethodContext context, ILOperation operation) { List <string> refList = new List <string>(); bool isInstance = !context.Method.IsStatic; for (int i = 0; i < context.Method.GetParameters().Length; i++) { if (context.Method.GetParameters()[i].ParameterType.IsReferenceCounted()) { refList.Add(context.GetParameterReferencePosition(i + (isInstance ? 1 : 0)).ToString()); } } var body = context.Method.GetMethodBody(); var variables = body.LocalVariables; for (int i = 0; i < variables.Count; i++) { if (variables[i].LocalType.IsReferenceCounted()) { refList.Add(context.GetLocalVariableReferencePosition(i).ToString()); } } return($"{context.GetLocalStackSize()}, [{string.Join(',', refList)}]"); }
public override void SetNextInstructions(CompilerMethodContext context, ILOperation operation, ILOperation nextOperation) { operation.NextInstructions.Add(nextOperation); var jmpInstruction = context.Lines.FirstOrDefault(l => l.Label == _label); operation.NextInstructions.Add(jmpInstruction); }
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 override object ConvertParameter(CompilerMethodContext context, ILOperation operation) { var field = context.CompilerContext.Assembly.ManifestModule.ResolveField((int)operation.RawParameter); var pos = context.CompilerContext.GetFieldPosition(field); return($"{pos}"); }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { operation.StackContent.RemoveLast(1); var type = context.CompilerContext.Assembly.ManifestModule.ResolveType((int)operation.OriginalParameter); var dummy = Array.CreateInstance(type, 0); operation.StackContent.Add(dummy.GetType()); }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { var last = operation.StackContent.Last(); // last.CheckCompatible(typeof(long)); operation.StackContent.RemoveLast(1); operation.StackContent.Add(typeof(int)); }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { var field = context.Method.ReflectedType.Module.ResolveField((int)operation.OriginalParameter); var last = operation.StackContent.Last(); last.CheckCompatible(field.FieldType); operation.StackContent.RemoveLast(1); }
public override object ConvertParameter(CompilerMethodContext context, ILOperation operation) { if (!context.CompilerContext.StringValues.ContainsKey((int)operation.RawParameter)) { context.CompilerContext.StringValues.Add((int)operation.RawParameter, context.CompilerContext.Assembly.ManifestModule.ResolveString((int)operation.RawParameter)); } return($"string_{operation.RawParameter}"); }
public override object ConvertParameter(CompilerMethodContext context, ILOperation operation) { var field = context.Method.ReflectedType.Module.ResolveField((int)operation.RawParameter); var address = $"{field.ReflectedType.Name.ToValidName()}_field_{field.Name.ToValidName()}"; string isRef = field.FieldType.IsReferenceCounted() ? "1" : "0"; return($"{address}, {isRef}"); }
public override object ConvertParameter(CompilerMethodContext context, ILOperation operation) { var body = context.Method.GetMethodBody(); var variables = body.LocalVariables; var index = context.GetLocalVariableReferencePosition((int)operation.RawParameter); var isRef = variables[(int)operation.RawParameter].LocalType.IsReferenceCounted() ? "1" : "0"; return($"{index}, {isRef}"); }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { var method = context.CompilerContext.Assembly.ManifestModule.ResolveMethod((int)operation.OriginalParameter) as MethodBase; var parameterNum = method.GetParameters().Length; operation.StackContent.RemoveLast(parameterNum); operation.StackContent.Add(typeof(object)); }
public override object ConvertParameter(CompilerMethodContext context, ILOperation operation) { var memLabel = context.CompilerContext.GetInitValueLabel(string.Join(',', _mem)); // var ctor = $"{context.TypeContext.Type.Name}_x_ctor"; var ctor = 0; return($"{_size}, {_referenceFields}, {_vtable}, {memLabel}, {ctor}"); }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { var elemType = operation.StackContent.Last().GetElementType(); operation.RawParameter = elemType; operation.StackContent.RemoveLast(1); operation.StackContent.Add(typeof(int)); }
public override void SetNextInstructions(CompilerMethodContext context, ILOperation operation, ILOperation nextOperation) { if (_jumpType != JumpType.UnConditional) { operation.NextInstructions.Add(nextOperation); } var label = operation.RawParameter.ToString(); var jmpInstruction = context.Lines.FirstOrDefault(l => l.Label == label); operation.NextInstructions.Add(jmpInstruction); }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { if (operation.NextInstructions[0].OpCode == ILOpCode.Conv_i8 || operation.NextInstructions[0].OpCode == ILOpCode.Conv_u8) { operation.StackContent.Add(typeof(long)); } else { operation.StackContent.Add(typeof(int)); } }
public override string Emit(CompilerMethodContext context, ILOperation operation) { if (operation.PreviousInstructions.First().StackContent.Last().GetStorageBytes() == 2) { return(base.Emit(context, operation)); } else { return("; conv"); } }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { var last = operation.StackContent.Last(); if (last != typeof(int) && last != typeof(uint) && last != typeof(long) && last != typeof(ulong)) { throw new InvalidOperationException("Unsupported type in arithmetic operation."); } operation.StackContent.RemoveLast(1); operation.StackContent.Add(last); }
public void Execute(CompilerContext context) { context.Methods = new List <CompilerMethodContext>(); foreach (var @type in context.Assembly.GetTypes()) { if (@type.IsValueType) { continue; } // context.GlobalOutputFile.WriteLine($".include \".\\\\{type.Name}.asm\""); var normalizedName = type.Name.ToValidName(); var import = $"\"./{normalizedName}.asm\""; context.GlobalOutputFile.WriteLine($".include {import}"); using (var outputFile = File.CreateText(Path.Combine(context.OutputDirectory, $"{normalizedName}.asm"))) { var typeContext = new CompilerTypeContext() { CompilerContext = context, Type = @type, OutputFile = outputFile }; foreach (var pass in _typePasses) { pass.Execute(typeContext); } var methods = @type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).OfType <MethodBase>(); // var staticconstructors = @type.GetConstructors(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).OfType<MethodBase>(); // var constructors = @type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).OfType<MethodBase>(); // if (constructors.Count() > 1) // throw new Exception($"Only 1 constructor supported (at the moment). Type : {@type} "); foreach (var method in methods.Where(m => m.DeclaringType != typeof(object))) { var methodContext = new CompilerMethodContext() { CompilerContext = context, TypeContext = typeContext, Lines = new List <ILOperation>(), Method = method, }; context.Methods.Add(methodContext); foreach (var pass in _methodPasses) { pass.Execute(methodContext); } } } } }
public override void SetStackContent(CompilerMethodContext context, ILOperation operation) { switch (_jumpType) { case JumpType.Conditional: operation.StackContent.RemoveLast(1); break; case JumpType.Compare: operation.StackContent.RemoveLast(2); break; } }