DefineGlobalMethod() public method

public DefineGlobalMethod ( string name, System attributes, System returnType, System parameterTypes ) : System.Reflection.Emit.MethodBuilder
name string
attributes System
returnType System
parameterTypes System
return System.Reflection.Emit.MethodBuilder
Esempio n. 1
0
        /// <summary>
        /// Compiles the signature for the procedure but not the body.
        /// This needs to be done first so that other methods can 
        /// call this method, this way we don't have problems with;
        /// dependencies between methods.
        /// </summary>
        public MethodBuilder CompileSignature(ModuleBuilder module)
        {
            Type[] argTypes = new Type[ArgumentCount];

            for (int i = 0; i < argTypes.Length; i++) {
                argTypes[i] = typeof(int);
            }

            if (HasResultArgument) {
                argTypes[argTypes.Length - 1] = typeof(int).MakeByRefType();
            }

            MethodBuilder method = module.DefineGlobalMethod(_name, MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Public, typeof(void), argTypes);
            int pos = 1;
            foreach (Variable arg in ValueArguments) {
                SymbolTable.DefineArgument(arg.Name);
                method.DefineParameter(pos, ParameterAttributes.In, arg.Name);
                pos++;
            }

            if (HasResultArgument) {
                SymbolTable.DefineArgument(ResultArgument.Name);
                method.DefineParameter(pos, ParameterAttributes.Out, ResultArgument.Name);
            }
            SymbolTable.Clear();
            return method;
        }
        private void GenerateAssemblyLookup(ModuleBuilder module)
        {
            if (_embeddedAssemblies.Count == 0) {
                return;
            }
            foreach (Assembly ass in _embeddedAssemblies) {
                string shortname = ass.FullName.Substring(0, ass.FullName.IndexOf(","));
                string tempfile = Path.GetTempFileName();
                File.Copy(new Uri(ass.EscapedCodeBase).LocalPath, tempfile, true);
                MemoryStream ms = new MemoryStream(File.ReadAllBytes(tempfile));
                ms.Seek(0, SeekOrigin.Begin);
                module.DefineManifestResource(shortname, ms, ResourceAttributes.Public);
                File.Delete(tempfile);
            }

            MethodBuilder resolveAssemblyMethod = module.DefineGlobalMethod("ResolveAssembly", MethodAttributes.Public | MethodAttributes.Static, typeof(Assembly), new Type[] { typeof(object), typeof(System.ResolveEventArgs) });
            ILGenerator ilResolve = resolveAssemblyMethod.GetILGenerator();
            CompileContext resolvecontext = new CompileContext();
            resolvecontext.PushIL(ilResolve);
            LocalBuilder localStream = ilResolve.DeclareLocal(typeof(Stream));
            LocalBuilder localBuf = ilResolve.DeclareLocal(typeof(byte[]));
            LocalBuilder localName = ilResolve.DeclareLocal(typeof(string));

            ilResolve.Emit(OpCodes.Ldarg_1);
            ilResolve.Emit(OpCodes.Call, typeof(ResolveEventArgs).GetMethod("get_Name"));
            ilResolve.Emit(OpCodes.Stloc, localName);

            ilResolve.Emit(OpCodes.Ldloc, localName);
            ilResolve.Emit(OpCodes.Ldc_I4_0);
            ilResolve.Emit(OpCodes.Ldloc, localName);
            ilResolve.Emit(OpCodes.Ldstr, ",");
            ilResolve.Emit(OpCodes.Call, typeof(string).GetMethod("IndexOf", new Type[] { typeof(string) }));
            ilResolve.Emit(OpCodes.Call, typeof(string).GetMethod("Substring", new Type[] { typeof(int), typeof(int) }));
            ilResolve.Emit(OpCodes.Stloc, localName);

            Assign(localStream, Call(Call(typeof(Assembly), "GetExecutingAssembly", false), "GetManifestResourceStream", false, localName), resolvecontext);

            Label notNull = ilResolve.DefineLabel();
            ilResolve.Emit(OpCodes.Ldloc, localStream);
            ilResolve.Emit(OpCodes.Brtrue, notNull);
            {
                //Not found, just return null
                ilResolve.Emit(OpCodes.Ldnull);
                ilResolve.Emit(OpCodes.Ret);
            }
            ilResolve.MarkLabel(notNull);
            Call(localStream, "get_Length", false).Compile(resolvecontext);
            ilResolve.Emit(OpCodes.Conv_Ovf_I);
            ilResolve.Emit(OpCodes.Newarr, typeof(System.Byte));
            ilResolve.Emit(OpCodes.Stloc, localBuf);

            ilResolve.Emit(OpCodes.Ldloc, localStream);
            ilResolve.Emit(OpCodes.Ldloc, localBuf);
            ilResolve.Emit(OpCodes.Ldc_I4_0);
            ilResolve.Emit(OpCodes.Ldloc, localBuf);
            ilResolve.Emit(OpCodes.Ldlen);
            ilResolve.Emit(OpCodes.Conv_I4);
            ilResolve.Emit(OpCodes.Callvirt, typeof(Stream).GetMethod("Read", new Type[] { typeof(byte[]), typeof(int), typeof(int) }));
            ilResolve.Emit(OpCodes.Pop);

            //Notify that we loaded this embedded...
            ilResolve.Emit(OpCodes.Ldarg_1);
            ilResolve.Emit(OpCodes.Call, typeof(ResolveEventArgs).GetMethod("get_Name"));
            ilResolve.Emit(OpCodes.Ldstr, " was not found externally, loading embedded version...");
            ilResolve.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            ilResolve.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) }));

            Call(typeof(Assembly), "Load", false, localBuf).Compile(resolvecontext);
            ilResolve.Emit(OpCodes.Ret);
            resolvecontext.PopIL();

            MethodBuilder moduleInitializer = module.DefineGlobalMethod(".cctor", MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName, null, new Type[] { });
            ILGenerator ilStartup = moduleInitializer.GetILGenerator();
            ilStartup.Emit(OpCodes.Call, typeof(System.AppDomain).GetMethod("get_CurrentDomain"));
            ilStartup.Emit(OpCodes.Ldnull);
            ilStartup.Emit(OpCodes.Ldftn, resolveAssemblyMethod);
            ilStartup.Emit(OpCodes.Newobj, MethodResolver.GetConstructor(typeof(System.ResolveEventHandler)));
            ilStartup.Emit(OpCodes.Callvirt, MethodResolver.GetMethod(typeof(System.AppDomain), "add_AssemblyResolve"));
            ilStartup.Emit(OpCodes.Ret);
        }
Esempio n. 3
0
        void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
        {
            this.peKind  = portableExecutableKind;
            this.machine = imageFileMachine;

            if ((peKind & PortableExecutableKinds.PE32Plus) != 0 || (peKind & PortableExecutableKinds.Unmanaged32Bit) != 0)
            {
                throw new NotImplementedException(peKind.ToString());
            }
            if (machine == ImageFileMachine.IA64 || machine == ImageFileMachine.AMD64)
            {
                throw new NotImplementedException(machine.ToString());
            }

            if (resource_writers != null)
            {
                foreach (IResourceWriter writer in resource_writers)
                {
                    writer.Generate();
                    writer.Close();
                }
            }

            // Create a main module if not already created
            ModuleBuilder mainModule = null;

            if (modules != null)
            {
                foreach (ModuleBuilder module in modules)
                {
                    if (module.FullyQualifiedName == assemblyFileName)
                    {
                        mainModule = module;
                    }
                }
            }
            if (mainModule == null)
            {
                mainModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName);
            }

            if (!is_module_only)
            {
                mainModule.IsMain = true;
            }

            /*
             * Create a new entry point if the one specified
             * by the user is in another module.
             */
            if ((entry_point != null) && entry_point.DeclaringType.Module != mainModule)
            {
                Type[] paramTypes;
                if (entry_point.GetParametersCount() == 1)
                {
                    paramTypes = new Type [] { typeof(string) }
                }
                ;
                else
                {
                    paramTypes = Type.EmptyTypes;
                }

                MethodBuilder mb    = mainModule.DefineGlobalMethod("__EntryPoint$", MethodAttributes.Static | MethodAttributes.PrivateScope, entry_point.ReturnType, paramTypes);
                ILGenerator   ilgen = mb.GetILGenerator();
                if (paramTypes.Length == 1)
                {
                    ilgen.Emit(OpCodes.Ldarg_0);
                }
                ilgen.Emit(OpCodes.Tailcall);
                ilgen.Emit(OpCodes.Call, entry_point);
                ilgen.Emit(OpCodes.Ret);

                entry_point = mb;
            }

            if (version_res != null)
            {
                DefineVersionInfoResourceImpl(assemblyFileName);
            }

            if (sn != null)
            {
                // runtime needs to value to embed it into the assembly
                public_key = sn.PublicKey;
            }

            foreach (ModuleBuilder module in modules)
            {
                if (module != mainModule)
                {
                    module.Save();
                }
            }

            // Write out the main module at the end, because it needs to
            // contain the hash of the other modules
            mainModule.Save();

            if ((sn != null) && (sn.CanSign))
            {
                sn.Sign(System.IO.Path.Combine(this.AssemblyDir, assemblyFileName));
            }

            created = true;
        }
Esempio n. 4
0
        private MethodBuilder BuildFunctionStub(Function function, ModuleBuilder builder)
        {
            if (function == null || builder == null)
                throw new ArgumentNullException();
            //
            // Создаем функцию
            //

            // Имя (уникальное)
            string functionName = function.Name;
            while (m_Functions.Find(functionName, SymbolType.Function) != null)
                functionName += "#";

            // Возвращаемый тип
            System.Type returnType = function.Type.ToSystemType();

            // Параметры
            System.Type[] parameters = null;
            if (function.Parameters != null)
            {
                parameters = new System.Type[function.Parameters.Count];

                for (int x = 0; x < function.Parameters.Count; x++)
                {
                    parameters[x] = function.Parameters[x].Type.ToSystemType();
                }
            }

            // Создаем метод (глобально)
            MethodBuilder method = builder.DefineGlobalMethod(functionName, MethodAttributes.Public | MethodAttributes.Static, returnType, parameters);

            if (function.Parameters != null)
            {
                for (int x = 0; x < function.Parameters.Count; x++)
                {
                    ParameterBuilder p = null;
                    p = method.DefineParameter(x + 1, ParameterAttributes.None, function.Parameters[x].Name);
                    function.Body.SymbolTable.Add(p.Name, SymbolType.Variable, function.Parameters[x], p);
                }
            }

            function.Builder = method;
            m_Functions.Add(functionName, SymbolType.Function, function, method);
            return method;
        }
Esempio n. 5
0
        /// <summary>
        /// Emits metadata declaration for this function given a ModuleBuilder object
        /// </summary>
        /// <param name="mb">ModuleBuilder object</param>
        public void EmitDeclaration(ModuleBuilder mb)
        {
            // Define global public static method
            this.mb = mb.DefineGlobalMethod(name, MethodAttributes.Public | MethodAttributes.Static, Type.GetType("System.Void"), null);

            // Setup arguments
            Type[] types = new Type[localScope.arguments.Count];

            for (int i = 0; i < localScope.arguments.Count; i++)
            {
                types[i] = localScope.arguments[i].type.ToCLRType();
            }

            // Set method arguments
            this.mb.SetParameters(types);

            // Set return type
            this.mb.SetReturnType(returnType.ToCLRType());
        }
Esempio n. 6
0
        private static TypeBuilder[] EmitSource(Module module, ModuleBuilder moduleB, Set replacedMethods, MetaDataMapper mapper)
        {
            ModuleEx moduleEx = new ModuleEx(module);

            ArrayList allMethods = new ArrayList();
            ArrayList allCtors = new ArrayList();
            ArrayList allTypes = new ArrayList();

            Hashtable map = mapper.MapTable;
            //FieldInfo -> FieldBuilder, MethodInfo -> MethodBuilder... mapping
            //Type -> Type mapping is performed through moduleB.GetType(), because of array & ref types

            Type[] types = module.GetTypes();
            Sort(types);

            foreach(Type type in types)
            {
                TypeBuilder typeB;
                if(type.DeclaringType != null)
                {
                    typeB = (mapper.Map(type.DeclaringType) as TypeBuilder).DefineNestedType(type.Name, type.Attributes, mapper.Map(type.BaseType), mapper.Map(GetDeclaredInterfaces(type)));
                    //Don't know how to declare nested enums :((
                    //Anyway, "nested-value-types BUG" affects them, too
                }
                else
                {
                    typeB = moduleB.DefineType(type.FullName, type.Attributes, mapper.Map(type.BaseType), mapper.Map(GetDeclaredInterfaces(type)));
                }
                allTypes.Add(typeB);
            }

            //The end of type declarations...
            foreach(Type type in types)
            {
                TypeBuilder typeB = mapper.Map(type) as TypeBuilder;
                FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                foreach(FieldInfo field in fields)
                {
                    if(field.IsLiteral)
                        continue; //Andrew: ZLP
               				    FieldAttributes attributes = AddInternalAttribute(field.Attributes);
                    FieldBuilder fieldB = typeB.DefineField(field.Name, mapper.Map(field.FieldType), attributes);
                    map[field] = fieldB;
                }

                PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                foreach(PropertyInfo property in properties)
                {
                    ParameterInfo[] parameters = property.GetIndexParameters();
                    Type[] paramTypes = new Type[parameters.Length];
                    for(int i=0; i<paramTypes.Length; i++)
                        paramTypes[i] = mapper.Map( parameters[i].ParameterType);
                    PropertyBuilder propertyB = typeB.DefineProperty(property.Name, property.Attributes, mapper.Map(property.PropertyType), paramTypes);
                    map[property] = propertyB;
                }

                EventInfo[] events = type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                foreach(EventInfo Event in events)
                {
                    EventBuilder eventB = typeB.DefineEvent(Event.Name, Event.Attributes, mapper.Map(Event.EventHandlerType));
                    map[Event] = eventB;
                }

                MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                foreach(MethodInfo method in methods)
                {
                    ParameterInfo[] parameters = method.GetParameters();
                    Type[] paramTypes = new Type[parameters.Length];
                    for(int i=0; i<paramTypes.Length; i++)
                        paramTypes[i] = mapper.Map( parameters[i].ParameterType);
                    MethodAttributes attributes = AddInternalAttribute(method.Attributes);
                    MethodBuilder methodB = typeB.DefineMethod(method.Name, attributes, method.CallingConvention, mapper.Map(method.ReturnType), paramTypes);
                    for(int i=0; i<paramTypes.Length; i++)
                        methodB.DefineParameter(i+1, parameters[i].Attributes, parameters[i].Name);
                    map[method] = methodB;
                    if(!replacedMethods.Contains(method))
                        allMethods.Add(method);
                }

                ConstructorInfo[] ctors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                foreach(ConstructorInfo ctor in ctors)
                {
                    ParameterInfo[] parameters = ctor.GetParameters();
                    Type[] paramTypes = new Type[parameters.Length];
                    for(int i=0; i<paramTypes.Length; i++)
                        paramTypes[i] = mapper.Map( parameters[i].ParameterType);
                    MethodAttributes attributes = AddInternalAttribute(ctor.Attributes);
                    ConstructorBuilder ctorB = typeB.DefineConstructor(attributes, ctor.CallingConvention, paramTypes);
                    for(int i=0; i<paramTypes.Length; i++)
                        ctorB.DefineParameter(i+1, parameters[i].Attributes, parameters[i].Name);
                    map[ctor] = ctorB;
                    if(!replacedMethods.Contains(ctor))
                        allCtors.Add(ctor);
                }
                if(type.IsValueType)
                    typeB.DefineDefaultConstructor(MethodAttributes.Public);
            }//foreach type

            MethodInfo[] globalMethods = module.GetMethods();
            foreach(MethodInfo method in globalMethods)
            {
                ParameterInfo[] parameters = method.GetParameters();
                Type[] paramTypes = new Type[parameters.Length];
                for(int i=0; i<paramTypes.Length; i++)
                    paramTypes[i] = mapper.Map( parameters[i].ParameterType);
                MethodAttributes attributes = AddInternalAttribute(method.Attributes);
                MethodBuilder methodB = moduleB.DefineGlobalMethod(method.Name, attributes, method.CallingConvention, mapper.Map(method.ReturnType), paramTypes);
                for(int i=0; i<paramTypes.Length; i++)
                    methodB.DefineParameter(i+1, parameters[i].Attributes, parameters[i].Name);
                map[method] = methodB;
                if(!replacedMethods.Contains(method))
                    allMethods.Add(method);
            }

            //The end of fields, methods, ctors declarations...

            foreach(MethodInfo method in allMethods)
            {
                ILGenerator generator = (mapper.Map(method) as MethodBuilder).GetILGenerator();
                ProcessMethod(generator, moduleEx.GetMethodEx(method), method, mapper);
            }

            foreach(ConstructorInfo ctor in allCtors)
            {
                ILGenerator generator = (mapper.Map(ctor) as ConstructorBuilder).GetILGenerator();
                ProcessMethod(generator, moduleEx.GetMethodEx(ctor), ctor, mapper);
            }

            TypeBuilder[] result = new TypeBuilder[allTypes.Count];
            allTypes.CopyTo(result);
            return(result);
        }