Esempio n. 1
0
        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);
                    }
                }
            }
        }
Esempio n. 3
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;
                }
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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}");
        }
Esempio n. 6
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;
                }
            }
        }
        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;
                }
            }
        }
Esempio n. 8
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;
                }
            }
        }
Esempio n. 9
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;
                }
            }
        }
Esempio n. 10
0
        public override void SetStackContent(CompilerMethodContext context, ILOperation operation)
        {
            var last = operation.StackContent.Last();

            last.CheckCompatible(context.GetLocalVariableType(VarIndex));
            operation.StackContent.RemoveLast(1);
        }
Esempio n. 11
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;
                }
            }
        }
Esempio n. 12
0
        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)}]");
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
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;
                }
            }
        }
Esempio n. 15
0
        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}");
        }
Esempio n. 16
0
        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());
        }
Esempio n. 17
0
        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));
        }
Esempio n. 18
0
        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);
        }
Esempio n. 19
0
 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}");
 }
Esempio n. 20
0
        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}");
        }
Esempio n. 21
0
        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}");
        }
Esempio n. 22
0
        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));
        }
Esempio n. 23
0
        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}");
        }
Esempio n. 24
0
        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));
        }
Esempio n. 25
0
        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);
        }
Esempio n. 26
0
 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));
     }
 }
Esempio n. 27
0
 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);
        }
Esempio n. 29
0
        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);
                        }
                    }
                }
            }
        }
Esempio n. 30
0
        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;
            }
        }