TypeInformation ParseTypeFields(Mono.Cecil.TypeDefinition type, bool onlyFieldWithGhostField = true)
        {
            var root = new TypeInformation(type);

            if (!type.HasFields)
            {
                return(root);
            }

            foreach (var field in type.Fields)
            {
                if (!field.IsPublic || field.IsStatic)
                {
                    continue;
                }

                if (!onlyFieldWithGhostField || CecilExtensions.HasGhostFieldAttribute(type, field))
                {
                    if (!CecilExtensions.HasGhostFieldAttribute(type, field) || CecilExtensions.GetGhostFieldAttribute(type, field).SendData)
                    {
                        root.Add(ParseTypeField(type, field, TypeAttribute.Empty()));
                    }
                }
            }
            return(root);
        }
示例#2
0
 public static void PrintInfo(this Mono.Cecil.TypeDefinition type)
 {
     System.Console.WriteLine($"Printing info about ({type.Name})");
     if (type.IsBlittable())
     {
         System.Console.WriteLine("Blittable");
     }
     if (type.IsPublic)
     {
         System.Console.WriteLine("Public");
     }
     if (type.IsEnum)
     {
         System.Console.WriteLine("Enum");
     }
     if (type.IsStruct())
     {
         System.Console.WriteLine("Struct");
     }
     if (type.IsPrimitive)
     {
         System.Console.WriteLine("Primitive");
     }
     if (type.IsValueType)
     {
         System.Console.WriteLine("ValueType");
     }
     if (type.IsClass)
     {
         System.Console.WriteLine("Class");
     }
 }
示例#3
0
        public static System.Reflection.MethodBase ConvertToSystemReflectionMethodInfo(Mono.Cecil.MethodDefinition md)
        {
            System.Reflection.MethodInfo result = null;
            String md_name = Campy.Utils.Utility.NormalizeMonoCecilName(md.FullName);

            // Get owning type.
            Mono.Cecil.TypeDefinition td = md.DeclaringType;
            Type t = ConvertToSystemReflectionType(td);

            foreach (System.Reflection.MethodInfo mi in t.GetMethods(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.CreateInstance | System.Reflection.BindingFlags.Default))
            {
                String full_name = string.Format("{0} {1}.{2}({3})", mi.ReturnType.FullName, Campy.Utils.Utility.RemoveGenericParameters(mi.ReflectedType), mi.Name, string.Join(",", mi.GetParameters().Select(o => string.Format("{0}", o.ParameterType)).ToArray()));
                full_name = Campy.Utils.Utility.NormalizeSystemReflectionName(full_name);
                if (md_name.Contains(full_name))
                {
                    return(mi);
                }
            }
            foreach (System.Reflection.ConstructorInfo mi in t.GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.CreateInstance | System.Reflection.BindingFlags.Default))
            {
                String full_name = string.Format("{0}.{1}({2})", Campy.Utils.Utility.RemoveGenericParameters(mi.ReflectedType), mi.Name, string.Join(",", mi.GetParameters().Select(o => string.Format("{0}", o.ParameterType)).ToArray()));
                full_name = Campy.Utils.Utility.NormalizeSystemReflectionName(full_name);
                if (md_name.Contains(full_name))
                {
                    return(mi);
                }
            }
            Debug.Assert(result != null);
            return(result);
        }
        static internal TypeInformation ParseTypeFields(Mono.Cecil.TypeDefinition type, bool onlyFieldWithGhostField = true)
        {
            bool isBuffer      = CecilExtensions.IsBufferElementData(type);
            bool isCommandData = CecilExtensions.IsICommandData(type);
            var  root          = new TypeInformation(type);

            if (isBuffer)
            {
                root.AttributeMask &= ~(TypeAttribute.AttributeFlags.InterpolatedAndExtrapolated);
            }

            if (!type.HasFields)
            {
                return(root);
            }
            foreach (var field in type.Fields)
            {
                if (!field.IsPublic || field.IsStatic)
                {
                    continue;
                }

                var ghostField = CecilExtensions.GetGhostFieldAttribute(type, field);
                if (!onlyFieldWithGhostField && isCommandData &&
                    field.HasAttributeOnMemberOImplementedInterfaces <DontSerializeForCommand>())
                {
                    continue;
                }
                if (!onlyFieldWithGhostField || (ghostField != null && ghostField.SendData))
                {
                    root.Add(ParseTypeField(field, field.FieldType, ghostField, TypeAttribute.Empty(), root.AttributeMask));
                }
            }
            foreach (var prop in type.Properties)
            {
                if (prop.GetMethod == null || !prop.GetMethod.IsPublic || prop.GetMethod.IsStatic)
                {
                    continue;
                }
                if (prop.SetMethod == null || !prop.SetMethod.IsPublic || prop.SetMethod.IsStatic)
                {
                    continue;
                }

                var ghostField = CecilExtensions.GetGhostFieldAttribute(type, prop);
                if (!onlyFieldWithGhostField && isCommandData &&
                    prop.HasAttributeOnMemberOImplementedInterfaces <DontSerializeForCommand>())
                {
                    continue;
                }

                if (!onlyFieldWithGhostField || (ghostField != null && ghostField.SendData))
                {
                    root.Add(ParseTypeField(prop, prop.PropertyType, ghostField, TypeAttribute.Empty(), root.AttributeMask));
                }
            }


            return(root);
        }
示例#5
0
        static private void showString(Mono.Cecil.TypeDefinition type,
                                       Mono.Cecil.AssemblyDefinition assembly,
                                       string prefix = "")
        {
            nestSearch(type, assembly, ref prefix, showString);

            type.Methods.ToList().ForEach((method) =>
            {
                var lineCount = 0;
                if (method.HasBody)
                {
                    method.Body.Instructions.ToList().ForEach(inst =>
                    {
                        if (inst.OpCode == Mono.Cecil.Cil.OpCodes.Ldstr)
                        {
                            if (lineCount == 0)
                            {
                                Console.WriteLine(string.Format("{0}.{1}:", prefix, method.Name));
                            }
                            Console.WriteLine(string.Format("{0}:{1}", lineCount, inst.Operand.ToString()));
                            lineCount++;
                        }
                    });
                }

                if (lineCount != 0)
                {
                    Console.WriteLine();
                }
            });
        }
 public ILType(ILModule module, Mono.Cecil.TypeDefinition type)
 {
     this.type = type;
     foreach (Mono.Cecil.FieldDefinition f in type.Fields)
     {
         this.fields.Add(f.Name, new ILField(this, f));
     }
     foreach (Mono.Cecil.MethodDefinition m in type.Methods)
     {
         if (m.IsStatic == false)
         {
             var method = new ILMethod(this, null);
             method.fail         = "只能导出static 函数";
             methods[m.FullName] = method;
         }
         else
         {
             var method = new ILMethod(this, m);
             if (methods.ContainsKey(m.FullName))
             {
                 throw new Exception("already have a func named:" + type.FullName + "::" + m.Name);
             }
             methods[m.FullName] = method;
         }
     }
 }
        public ILType(ILModule module, Mono.Cecil.TypeDefinition type, ILogger logger)
        {
            if (type.HasCustomAttributes && type.IsClass)
            {
                attributes.AddRange(type.CustomAttributes);
            }

            foreach (Mono.Cecil.FieldDefinition f in type.Fields)
            {
                this.fields.Add(f.Name, new ILField(this, f));
            }
            foreach (Mono.Cecil.MethodDefinition m in type.Methods)
            {
                if (m.IsStatic == false)
                {
                    var method = new ILMethod(this, null, logger);
                    method.fail         = "只能导出static 函数";
                    methods[m.FullName] = method;
                }
                else
                {
                    var method = new ILMethod(this, m, logger);
                    if (methods.ContainsKey(m.FullName))
                    {
                        throw new Exception("already have a func named:" + type.FullName + "::" + m.Name);
                    }
                    methods[m.FullName] = method;
                }
            }
        }
示例#8
0
        IMethod GetNewForArray(object token)
        {
            Mono.Cecil.ModuleDefinition module = null;
            string typename = null;

            if (token is Mono.Cecil.TypeDefinition)
            {
                Mono.Cecil.TypeDefinition _def = (token as Mono.Cecil.TypeDefinition);
                module   = _def.Module;
                typename = _def.FullName;
            }
            else if (token is Mono.Cecil.TypeReference)
            {
                Mono.Cecil.TypeReference _ref = (token as Mono.Cecil.TypeReference);
                module   = _ref.Module;
                typename = _ref.FullName;
            }
            else
            {
                throw new NotImplementedException();
            }

            ICLRType _Itype = GetType(typename, module);

            typename += "[]";
            //var _type = context.environment.GetType(typename, type.Module);
            var _type = GetType(typename, module);

            MethodParamList tlist = MethodParamList.MakeList_OneParam_Int(environment);
            var             m     = _type.GetMethod(".ctor", tlist);

            return(m);
        }
示例#9
0
        static private void debugMethod(Mono.Cecil.TypeDefinition type,
                                        Mono.Cecil.AssemblyDefinition assembly,
                                        string prefix = "")
        {
            nestSearch(type, assembly, ref prefix, debugMethod);

            type.Methods.ToList().ForEach((method) =>
            {
                var il     = method.Body.GetILProcessor();
                var module = type.Module;
                var write  = il.Create(
                    Mono.Cecil.Cil.OpCodes.Call,
                    module.Import(typeof(Console).GetMethod("WriteLine", new[] { typeof(object) })));
                var ret   = il.Create(Mono.Cecil.Cil.OpCodes.Ret);
                var leave = il.Create(Mono.Cecil.Cil.OpCodes.Leave, ret);

                il.InsertAfter(
                    method.Body.Instructions.Last(),
                    write);

                il.InsertAfter(write, leave);
                il.InsertAfter(leave, ret);

                var handler = new Mono.Cecil.Cil.ExceptionHandler(Mono.Cecil.Cil.ExceptionHandlerType.Catch)
                {
                    TryStart     = method.Body.Instructions.First(),
                    TryEnd       = write,
                    HandlerStart = write,
                    HandlerEnd   = ret,
                    CatchType    = module.Import(typeof(Exception)),
                };

                method.Body.ExceptionHandlers.Add(handler);
            });
        }
示例#10
0
 /// <summary>
 /// Aspect code to inject at the end of weaved method
 /// </summary>
 /// <param name="typeBuilder">Type Builder</param>
 /// <param name="method">Method</param>
 /// <param name="parameter">Parameter</param>
 /// <param name="il">ILGenerator</param>
 internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
 {
     il.Emit(Mono.Cecil.Cil.OpCodes.Ldsfld, field);
     il.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I4_1);
     il.Emit(Mono.Cecil.Cil.OpCodes.Sub);
     il.Emit(Mono.Cecil.Cil.OpCodes.Stsfld, field);
 }
        /// <summary>
        /// Aspect method to use for method call substition
        /// </summary>
        /// <param name="typeBuilder"></param>
        /// <param name="il"></param>
        /// <param name="method"></param>
        /// <param name="replaceMethod">Replace Method</param>
        /// <returns></returns>
        internal bool MethodCall(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.Cil.ILProcessor il, Mono.Cecil.MethodDefinition method, Mono.Cecil.MethodDefinition replaceMethod)
        {
            if (!replaceMethod.IsStatic)
            {
                return(false);
            }

            var        attrs = method.GetCustomAttributes <StaticMethodReplacerAttribute>();
            MethodInfo meth  = null;

            foreach (var attr in attrs)
            {
                var staticType = attr.staticMethodType;
                var smeth      = staticType.GetMethod(replaceMethod.Name, BindingFlags.Static | BindingFlags.Public);

                if (smeth != null)
                {
                    meth = smeth;
                }
            }

            if (meth == null)
            {
                return(false);
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Call, meth);

            return(true);
        }
示例#12
0
            public IEnumerator <Mono.Cecil.MethodDefinition> GetEnumerator()
            {
                StackQueue <Mono.Cecil.TypeDefinition> type_definitions         = new StackQueue <Mono.Cecil.TypeDefinition>();
                StackQueue <Mono.Cecil.TypeDefinition> type_definitions_closure = new StackQueue <Mono.Cecil.TypeDefinition>();

                foreach (Mono.Cecil.TypeDefinition td in _module.Types)
                {
                    type_definitions.Push(td);
                }
                while (type_definitions.Count > 0)
                {
                    Mono.Cecil.TypeDefinition td = type_definitions.Pop();
                    type_definitions_closure.Push(td);
                    foreach (Mono.Cecil.TypeDefinition ntd in td.NestedTypes)
                    {
                        type_definitions.Push(ntd);
                    }
                }
                foreach (Mono.Cecil.TypeDefinition type in type_definitions_closure)
                {
                    foreach (Mono.Cecil.MethodDefinition method in type.Methods)
                    {
                        yield return(method);
                    }
                }
            }
        public ITypeWriter PickTypeWriter(Mono.Cecil.TypeDefinition td, int indentCount, TypeCollection typeCollection, ConfigBase config)
        {
            if (td.IsEnum)
            {
                return(new EnumWriter(td, indentCount, typeCollection, config));
            }

            if (td.IsInterface)
            {
                return(new InterfaceWriter(td, indentCount, typeCollection, config));
            }

            if (td.IsClass)
            {
                if (td.BaseType.FullName == "System.MulticastDelegate" ||
                    td.BaseType.FullName == "System.Delegate")
                {
                    return(new DelegateWriter(td, indentCount, typeCollection, config));
                }

                return(new ClassWriter(td, indentCount, typeCollection, config));
            }

            throw new NotImplementedException("Could not get a type to generate for:" + td.FullName);
        }
示例#14
0
        public static Mono.Cecil.MethodDefinition ConvertToMonoCecilMethodDefinition(System.Reflection.MethodBase mi)
        {
            // Get assembly name which encloses code for kernel.
            String kernel_assembly_file_name = mi.DeclaringType.Assembly.Location;

            // Get directory containing the assembly.
            String full_path = Path.GetFullPath(kernel_assembly_file_name);

            full_path = Path.GetDirectoryName(full_path);

            String kernel_full_name = null;

            // Get full name of kernel, including normalization because they cannot be compared directly with Mono.Cecil names.
            if (mi as System.Reflection.MethodInfo != null)
            {
                System.Reflection.MethodInfo mik = mi as System.Reflection.MethodInfo;
                kernel_full_name = string.Format("{0} {1}.{2}({3})", mik.ReturnType.FullName, Campy.Utils.Utility.RemoveGenericParameters(mi.ReflectedType), mi.Name, string.Join(",", mi.GetParameters().Select(o => string.Format("{0}", o.ParameterType)).ToArray()));
            }
            else
            {
                kernel_full_name = string.Format("{0}.{1}({2})", Campy.Utils.Utility.RemoveGenericParameters(mi.ReflectedType), mi.Name, string.Join(",", mi.GetParameters().Select(o => string.Format("{0}", o.ParameterType)).ToArray()));
            }

            kernel_full_name = Campy.Utils.Utility.NormalizeSystemReflectionName(kernel_full_name);

            // Decompile entire module.
            Mono.Cecil.ModuleDefinition md = Mono.Cecil.ModuleDefinition.ReadModule(kernel_assembly_file_name);

            // Examine all types, and all methods of types in order to find the lambda in Mono.Cecil.
            List <Type> types = new List <Type>();
            StackQueue <Mono.Cecil.TypeDefinition> type_definitions         = new StackQueue <Mono.Cecil.TypeDefinition>();
            StackQueue <Mono.Cecil.TypeDefinition> type_definitions_closure = new StackQueue <Mono.Cecil.TypeDefinition>();

            foreach (Mono.Cecil.TypeDefinition td in md.Types)
            {
                type_definitions.Push(td);
            }
            while (type_definitions.Count > 0)
            {
                Mono.Cecil.TypeDefinition ty = type_definitions.Pop();
                type_definitions_closure.Push(ty);
                foreach (Mono.Cecil.TypeDefinition ntd in ty.NestedTypes)
                {
                    type_definitions.Push(ntd);
                }
            }
            foreach (Mono.Cecil.TypeDefinition td in type_definitions_closure)
            {
                foreach (Mono.Cecil.MethodDefinition md2 in td.Methods)
                {
                    String md2_name = Campy.Utils.Utility.NormalizeMonoCecilName(md2.FullName);
                    if (md2_name.Contains(kernel_full_name))
                    {
                        return(md2);
                    }
                }
            }
            return(null);
        }
示例#15
0
        internal static IEnumerable <Type> FlattenTypeHierarchy(this Type type)
        {
            yield return(type);

            foreach (var nt in type.NestedTypes.SelectMany(_ => _.FlattenTypeHierarchy()))
            {
                yield return(nt);
            }
        }
示例#16
0
        /// <summary>
        /// Aspect code to inject at the end of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            il.BeginFinallyBlock();

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, @lock);
            il.Emit(Mono.Cecil.Cil.OpCodes.Callvirt, ExitMethod);

            il.EndExceptionBlock();
        }
示例#17
0
        public void GenerateSerializer(CodeGenerator.Context context, Mono.Cecil.TypeDefinition type)
        {
            var replacements = new Dictionary <string, string>();

            if (context.FieldState.curChangeMask > 0)
            {
                replacements.Add("GHOST_CHANGE_MASK_BITS", context.FieldState.curChangeMask.ToString());
                m_TargetGenerator.GenerateFragment("GHOST_FLUSH_FINAL_COMPONENT_CHANGE_MASK", replacements);
            }

            if (type.Namespace != null && type.Namespace != "")
            {
                context.imports.Add(type.Namespace);
            }
            foreach (var ns in context.imports)
            {
                replacements["GHOST_USING"] = CodeGenNamespaceUtils.GetValidNamespaceForType(context.generatedNs, ns);
                m_TargetGenerator.GenerateFragment("GHOST_USING_STATEMENT", replacements);
            }

            context.collectionAssemblies.Add(type.Module.Assembly.Name.Name);

            replacements.Clear();
            replacements.Add("GHOST_NAME", type.FullName.Replace(".", "").Replace("/", "_"));
            replacements.Add("GHOST_NAMESPACE", context.generatedNs);
            replacements.Add("GHOST_COMPONENT_TYPE", type.FullName.Replace("/", "."));
            replacements.Add("GHOST_CHANGE_MASK_BITS", context.FieldState.numFields.ToString());
            replacements.Add("GHOST_FIELD_HASH", context.FieldState.ghostfieldHash.ToString());
            replacements.Add("GHOST_COMPONENT_EXCLUDE_FROM_COLLECTION_HASH", context.IsRuntimeAssembly ? "0" : "1");

            var ghostAttributes = CecilExtensions.GetGhostComponentAttribute(type);

            if (ghostAttributes != null && (ghostAttributes.OwnerPredictedSendType == GhostSendType.Interpolated || (ghostAttributes.PrefabType & GhostPrefabType.Client) == GhostPrefabType.InterpolatedClient))
            {
                replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Interpolated");
            }
            else if (ghostAttributes != null && (ghostAttributes.OwnerPredictedSendType == GhostSendType.Predicted || (ghostAttributes.PrefabType & GhostPrefabType.Client) == GhostPrefabType.PredictedClient))
            {
                replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Predicted");
            }
            else
            {
                replacements.Add("GHOST_SEND_MASK", "GhostComponentSerializer.SendMask.Interpolated | GhostComponentSerializer.SendMask.Predicted");
            }
            replacements.Add("GHOST_SEND_CHILD_ENTITY", (ghostAttributes != null && !ghostAttributes.SendDataForChildEntity)?"0":"1");

            if (m_TargetGenerator.Fragments["__GHOST_REPORT_PREDICTION_ERROR__"].Content.Length > 0)
            {
                m_TargetGenerator.GenerateFragment("GHOST_PREDICTION_ERROR_HEADER", replacements, m_TargetGenerator);
            }

            var serializerName = type.FullName.Replace("/", "+") + "Serializer.cs";

            m_TargetGenerator.GenerateFile("", context.outputFolder, serializerName, replacements, context.batch);

            context.generatedTypes.Add(replacements["GHOST_NAME"]);
        }
        static internal TypeInformation ParseVariantTypeFields(Mono.Cecil.TypeDefinition variantType, Mono.Cecil.TypeReference typeReference)
        {
            var type = typeReference.Resolve();

            var root = new TypeInformation(type);

            if (!variantType.HasFields)
            {
                return(root);
            }

            foreach (var field in variantType.Fields)
            {
                if (!field.IsPublic || field.IsStatic)
                {
                    continue;
                }

                if (type.Fields.FirstOrDefault(f => f.Name == field.Name) == null)
                {
                    UnityEngine.Debug.LogError($"Variant {variantType.Name}. field {field.Name} not present in original type {type.Name}");
                    continue;
                }

                //Avoid use ghost fields modifiers for the variant type. passing null prevent that
                var ghostField = CecilExtensions.GetGhostFieldAttribute(null, field);
                if (ghostField != null && ghostField.SendData)
                {
                    root.Add(ParseTypeField(field, field.FieldType, ghostField, TypeAttribute.Empty(), root.AttributeMask));
                }
            }
            foreach (var prop in type.Properties)
            {
                if (prop.GetMethod == null || !prop.GetMethod.IsPublic || prop.GetMethod.IsStatic)
                {
                    continue;
                }
                if (prop.SetMethod == null || !prop.SetMethod.IsPublic || prop.SetMethod.IsStatic)
                {
                    continue;
                }

                if (type.Properties.FirstOrDefault(f => f.Name == prop.Name) == null)
                {
                    UnityEngine.Debug.LogError($"Variant {variantType.Name}. field {prop.Name} not present in original type {type.Name}");
                    continue;
                }

                var ghostField = CecilExtensions.GetGhostFieldAttribute(type, prop);
                if (ghostField != null && ghostField.SendData)
                {
                    root.Add(ParseTypeField(prop, prop.PropertyType, ghostField, TypeAttribute.Empty(), root.AttributeMask));
                }
            }
            return(root);
        }
        /// <summary>
        /// Validate if Reader and Writer are properly applied to given type
        /// </summary>
        /// <param name="type">Type</param>
        /// <param name="methods">Type Methods</param>
        internal override void ValidateRules(Mono.Cecil.TypeDefinition type, IEnumerable <Mono.Cecil.MethodDefinition> methods)
        {
            var hasReader = methods.Any(x => x.GetCustomAttribute <ReaderAttribute>() != null);
            var hasWriter = methods.Any(x => x.GetCustomAttribute <WriterAttribute>() != null);

            if (!(hasReader && hasWriter))
            {
                throw new ThreadingValidationException(String.Format("ReaderWriterSynchronize validation: {0} must have at least one reader and writer attribute for it members", type.FullName));
            }
        }
        protected override TypeSpecificContext GetTypeContext(Mono.Cecil.TypeDefinition type, Languages.ILanguage language, System.Collections.Generic.Dictionary <string, DecompiledType> decompiledTypes)
        {
            TypeSpecificContext typeContext = base.GetTypeContext(type, language, decompiledTypes);

            if (!typeContext.IsWinRTImplementation && typeContext.CurrentType.IsNotPublic && typeContext.CurrentType.IsSealed && typeContext.CurrentType.Name.StartsWith("<CLR>"))
            {
                typeContext.IsWinRTImplementation = true;
            }

            return(typeContext);
        }
示例#21
0
        /// <summary>
        /// Compiles Brainfuck source code down to a method and sets the
        /// assembly's entry point to that method.
        /// </summary>
        /// <param name="document">
        /// A Brainfuck source code document.
        /// </param>
        public void Compile(SourceDocument document)
        {
            // Compile the Brainfuck source code to a Flame IR method body.
            var sourceBody = CompileBody(new SourceReader(document));

            // Optimize the IR method body.
            var body = sourceBody.WithImplementation(
                sourceBody.Implementation.Transform(
                    AllocaToRegister.Instance,
                    CopyPropagation.Instance,
                    new ConstantPropagation(),
                    GlobalValueNumbering.Instance,
                    CopyPropagation.Instance,
                    InstructionSimplification.Instance,
                    DeadValueElimination.Instance,
                    MemoryAccessElimination.Instance,
                    CopyPropagation.Instance,
                    new ConstantPropagation(),
                    DeadValueElimination.Instance,
                    ReassociateOperators.Instance,
                    DeadValueElimination.Instance,
                    FuseMemoryAccesses.Instance));

            if (CompilerOptions.GetValue <bool>(Options.PrintIr))
            {
                PrintIr(sourceBody, body);
            }

            // Define a class.
            var program = new Mono.Cecil.TypeDefinition(
                "Brainfuck",
                "Program",
                Mono.Cecil.TypeAttributes.Class | Mono.Cecil.TypeAttributes.Public,
                Assembly.Definition.MainModule.ImportReference(Environment.Object));

            Assembly.Definition.MainModule.Types.Add(program);

            // Add an entry point method to that class.
            var main = new Mono.Cecil.MethodDefinition(
                "Main",
                Mono.Cecil.MethodAttributes.Static | Mono.Cecil.MethodAttributes.Public,
                Assembly.Definition.MainModule.ImportReference(Environment.Void));

            program.Methods.Add(main);

            // Compile the method body down to CIL and assign it to the method.
            var emitter = new ClrMethodBodyEmitter(main, body, Environment);

            main.Body = emitter.Compile();

            // Set the entry point.
            Assembly.Definition.MainModule.EntryPoint = main;
        }
示例#22
0
        /// <summary>
        /// Aspect code to inject at the end of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void EndBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var meth       = method;
            var module     = typeBuilder.Module;
            var returnType = meth.ReturnType.ReflectionType();

            if (returnType == typeof(void) || !(meth.Name.StartsWith("get_") || meth.Parameters.Count == 0))
            {
                return;
            }

            var isPrimitive = returnType.IsPrimitive();
            var isStatic    = method.IsStatic;

            if (autoField != null)
            {
                //var local = il.DeclareLocal(returnType);

                //il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, 0);
                //il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, local);

                if (!isStatic)
                {
                    il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
                }
                il.Emit(Mono.Cecil.Cil.OpCodes.Ldloc, 0);

                if (isPrimitive)
                {
                    il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, typeof(Nullable <>).MakeGenericType(returnType)
                            .GetConstructor(new Type[] { returnType }));
                }

                il.Emit(isStatic ? Mono.Cecil.Cil.OpCodes.Stsfld : Mono.Cecil.Cil.OpCodes.Stfld, autoField);
            }

            il.MarkLabel(autoLabel);

            if (autoField != null)
            {
                if (!isStatic)
                {
                    il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
                }
                il.Emit(isStatic ? Mono.Cecil.Cil.OpCodes.Ldsflda : Mono.Cecil.Cil.OpCodes.Ldflda, autoField);
                if (isPrimitive)
                {
                    returnType = typeof(Nullable <>).MakeGenericType(returnType);
                    il.Emit(Mono.Cecil.Cil.OpCodes.Call, module.Import(returnType.GetMethod("get_Value")));
                }
                il.Emit(Mono.Cecil.Cil.OpCodes.Stloc, 0);
            }
        }
示例#23
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var isSetProperty = method.Name.StartsWith("set_") && !method.IsStatic;

            if (!isSetProperty)
            {
                return;
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldarg_0);
            il.Emit(Mono.Cecil.Cil.OpCodes.Call, ThrowIfFrozenMethod);
        }
示例#24
0
 public Type_Common_CLRSharp(ICLRSharp_Environment env, Mono.Cecil.TypeDefinition type)
 {
     this.env           = env;
     this.type_CLRSharp = type;
     if (type.IsEnum)
     {
         _isenum = true;
     }
     if (type_CLRSharp.BaseType != null)
     {
         BaseType = env.GetType(type_CLRSharp.BaseType.FullName);
         if (BaseType is ICLRType_System)
         {
             if (BaseType.TypeForSystem == typeof(Enum) || BaseType.TypeForSystem == typeof(object) || BaseType.TypeForSystem == typeof(ValueType) || BaseType.TypeForSystem == typeof(System.Enum))
             {//都是这样,无所谓
                 BaseType = null;
             }
             else
             {//继承了其他系统类型
                 env.logger.Log_Error("ScriptType:" + Name + " Based On a SystemType:" + BaseType.Name);
                 HasSysBase = true;
                 throw new Exception("不得继承系统类型,脚本类型系统和脚本类型系统是隔离的");
             }
         }
         if (type_CLRSharp.HasInterfaces)
         {
             _Interfaces = new List <ICLRType>();
             foreach (var i in type_CLRSharp.Interfaces)
             {
                 var itype = env.GetType(i.FullName);
                 if (itype is ICLRType_System)
                 {
                     //继承了其他系统类型
                     if (env.GetCrossBind((itype as ICLRType_System).TypeForSystem) == null)
                     {
                         env.logger.Log_Warning("警告:没有CrossBind的情况下直接继承\nScriptType:" + Name + " Based On a SystemInterface:" + itype.Name);
                     }
                     HasSysBase = true;
                 }
                 _Interfaces.Add(itype);
             }
         }
     }
     foreach (var m in this.type_CLRSharp.Methods)
     {
         if (m.Name == ".cctor")
         {
             NeedCCtor = true;
             break;
         }
     }
 }
示例#25
0
 public Type_Common_CLRSharp(ICLRSharp_Environment env, Mono.Cecil.TypeDefinition type)
 {
     this.env           = env;
     this.type_CLRSharp = type;
     foreach (var m in this.type_CLRSharp.Methods)
     {
         if (m.Name == ".cctor")
         {
             NeedCCtor = true;
             break;
         }
     }
 }
示例#26
0
        void GenerateType(Context context, Mono.Cecil.TypeDefinition type)
        {
            var typeTree = ParseTypeFields(type);

            var generator = InternalGenerateType(context, typeTree, type.FullName);

            generator.GenerateMasks(context);

            var serializeGenerator = new TypeGenerator(context);

            generator.AppendTarget(serializeGenerator);
            serializeGenerator.GenerateSerializer(context, type);
        }
示例#27
0
        /// <summary>
        /// Aspect code to inject at the beginning of weaved method
        /// </summary>
        /// <param name="typeBuilder">Type Builder</param>
        /// <param name="method">Method</param>
        /// <param name="parameter">Parameter</param>
        /// <param name="il">ILGenerator</param>
        internal void BeginBlock(Mono.Cecil.TypeDefinition typeBuilder, Mono.Cecil.MethodDefinition method, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.Cil.ILProcessor il)
        {
            var methodName    = method.Name;
            var isSetProperty = methodName.StartsWith("set_") && !method.IsStatic;

            if (!isSetProperty)
            {
                return;
            }

            il.Emit(Mono.Cecil.Cil.OpCodes.Ldstr, methodName.Substring(4));
            il.Emit(Mono.Cecil.Cil.OpCodes.Newobj, typeof(ObjectReadOnlyException).GetConstructor(new[] { typeof(string) }));
            il.Emit(Mono.Cecil.Cil.OpCodes.Throw);
        }
示例#28
0
        public static bool CheckType(Mono.Cecil.TypeDefinition typeDef, Mono.Cecil.MethodReference methodRef)
        {
            string func;

            if (s_CheckTypeFuncs.TryGetValue(methodRef.Name, out func))
            {
                var ret = s_Calculator.Calc(func, typeDef, methodRef);
                if (null != ret)
                {
                    return((bool)Convert.ChangeType(ret, typeof(bool)));
                }
            }
            return(true);
        }
示例#29
0
 private static void OptimizeType(
     Mono.Cecil.TypeDefinition typeDefinition,
     ClrAssembly parentAssembly,
     Func <ClrMethodDefinition, MethodBody> optimizeBody)
 {
     foreach (var method in typeDefinition.Methods)
     {
         OptimizeMethod(method, parentAssembly, optimizeBody);
     }
     foreach (var type in typeDefinition.NestedTypes)
     {
         OptimizeType(type, parentAssembly, optimizeBody);
     }
 }
示例#30
0
 public bool Accept(Mono.Cecil.TypeDefinition typedef)
 {
     if (_filters.Count == 0)
     {
         return(true);
     }
     foreach (ITypeFilter filter in _filters)
     {
         if (filter.Accept(typedef))
         {
             return(true);
         }
     }
     return(false);
 }