当前位置: 首页>>代码示例>>C#>>正文


C# ILGen.Emit方法代码示例

本文整理汇总了C#中ILGen.Emit方法的典型用法代码示例。如果您正苦于以下问题:C# ILGen.Emit方法的具体用法?C# ILGen.Emit怎么用?C# ILGen.Emit使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在ILGen的用法示例。


在下文中一共展示了ILGen.Emit方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: Compile

 public override void Compile(Executive engine, object form, ILGen il, LocalAccess locals, Stack<Type> st, object[] args)
 {
     il.Emit(OpCodes.Ldarg_1);
     il.EmitInt(locals.DefineConstant(args[0]));
     il.Emit(OpCodes.Ldelem_Ref);
     st.Push(typeof(System.Object));
 }
开发者ID:,项目名称:,代码行数:7,代码来源:

示例2: Create

        internal static Type Create(GenContext context, Type baseClass)
        {
            //ModuleBuilder mb = context.ModuleBldr;
            string name = baseClass.Name + "_impl";
            //TypeBuilder baseTB = context.ModuleBldr.DefineType(name, TypeAttributes.Class | TypeAttributes.Public, baseClass);
            TypeBuilder baseTB = context.AssemblyGen.DefinePublicType(name, baseClass, true);

            ObjExpr.MarkAsSerializable(baseTB);

            baseTB.DefineDefaultConstructor(MethodAttributes.Public);

            FieldBuilder metaField = baseTB.DefineField("_meta", typeof(IPersistentMap), FieldAttributes.Public);

            MethodBuilder metaMB = baseTB.DefineMethod("meta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IPersistentMap), Type.EmptyTypes);
            ILGen gen = new ILGen(metaMB.GetILGenerator());
            gen.EmitLoadArg(0);
            gen.EmitFieldGet(metaField);
            gen.Emit(OpCodes.Ret);

            MethodBuilder withMB = baseTB.DefineMethod("withMeta", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(IObj), new Type[] { typeof(IPersistentMap)});
            gen = new ILGen(withMB.GetILGenerator());
            gen.EmitLoadArg(0);
            gen.EmitCall(Compiler.Method_Object_MemberwiseClone);
            gen.Emit(OpCodes.Castclass, baseTB);
            gen.Emit(OpCodes.Dup);
            gen.EmitLoadArg(1);
            gen.EmitFieldSet(metaField);
            gen.Emit(OpCodes.Ret);

            for (int i = 0; i < 20; i++ )
                DefineDelegateFieldAndOverride(baseTB, i);

            return baseTB.CreateType();
        }
开发者ID:christianblunden,项目名称:clojure-clr,代码行数:34,代码来源:AFnImplGenerator.cs

示例3: FixReturn

 internal void FixReturn(ILGen cg)
 {
     cg.EmitLoadArg(_argIndex);
     cg.Emit(OpCodes.Ldloc, _refSlot);
     cg.Emit(OpCodes.Ldfld, _refSlot.LocalType.GetDeclaredField("Value"));
     cg.EmitStoreValueIndirect(_argType.GetElementType());
 }
开发者ID:TerabyteX,项目名称:main,代码行数:7,代码来源:ReturnFixer.cs

示例4: EmitArgument

        internal static ReturnFixer EmitArgument(ILGen cg, int argIndex, Type argType) {
            cg.EmitLoadArg(argIndex);

            if (!argType.IsByRef) {
                cg.EmitBoxing(argType);
                return null;
            }

            Type elementType = argType.GetElementType();
            cg.EmitLoadValueIndirect(elementType);
            Type concreteType = typeof(StrongBox<>).MakeGenericType(elementType);
            cg.EmitNew(concreteType, new Type[] { elementType });

            LocalBuilder refSlot = cg.DeclareLocal(concreteType);
            cg.Emit(OpCodes.Dup);
            cg.Emit(OpCodes.Stloc, refSlot);
            return new ReturnFixer(refSlot, argIndex, argType);
        }
开发者ID:Jaykul,项目名称:IronLangs,代码行数:18,代码来源:ReturnFixer.cs

示例5: EmitClrCallStub

        /// <summary>
        /// Generates stub to receive the CLR call and then call the dynamic language code.
        /// </summary>
        private object[] EmitClrCallStub(ILGen cg) {

            List<ReturnFixer> fixers = new List<ReturnFixer>(0);
            // Create strongly typed return type from the site.
            // This will, among other things, generate tighter code.
            Type[] siteTypes = MakeSiteSignature();

            CallSite callSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(siteTypes), InvokeBinder);
            Type siteType = callSite.GetType();

            Type convertSiteType = null;
            CallSite convertSite = null;

            if (_returnType != typeof(void)) {
                convertSite = CallSite.Create(DynamicSiteHelpers.MakeCallSiteDelegate(typeof(object), _returnType), ConvertBinder);
                convertSiteType = convertSite.GetType();
            }

            // build up constants array
            object[] constants = new object[] { TargetPlaceHolder, CallSitePlaceHolder, ConvertSitePlaceHolder };
            const int TargetIndex = 0, CallSiteIndex = 1, ConvertSiteIndex = 2;

            LocalBuilder convertSiteLocal = null;
            FieldInfo convertTarget = null;
            if (_returnType != typeof(void)) {
                // load up the conversesion logic on the stack
                convertSiteLocal = cg.DeclareLocal(convertSiteType);
                EmitConstantGet(cg, ConvertSiteIndex, convertSiteType);

                cg.Emit(OpCodes.Dup);
                cg.Emit(OpCodes.Stloc, convertSiteLocal);

                convertTarget = convertSiteType.GetField("Target");
                cg.EmitFieldGet(convertTarget);
                cg.Emit(OpCodes.Ldloc, convertSiteLocal);
            }

            // load up the invoke logic on the stack
            LocalBuilder site = cg.DeclareLocal(siteType);
            EmitConstantGet(cg, CallSiteIndex, siteType);
            cg.Emit(OpCodes.Dup);
            cg.Emit(OpCodes.Stloc, site);

            FieldInfo target = siteType.GetField("Target");
            cg.EmitFieldGet(target);
            cg.Emit(OpCodes.Ldloc, site);

            EmitConstantGet(cg, TargetIndex, typeof(object));

            for (int i = 0; i < _parameters.Length; i++) {
                if (_parameters[i].ParameterType.IsByRef) {
                    ReturnFixer rf = ReturnFixer.EmitArgument(cg, i + 1, _parameters[i].ParameterType);
                    if (rf != null) fixers.Add(rf);
                } else {
                    cg.EmitLoadArg(i + 1);
                }
            }

            // emit the invoke for the call
            cg.EmitCall(target.FieldType, "Invoke");

            // emit the invoke for the convert
            if (_returnType == typeof(void)) {
                cg.Emit(OpCodes.Pop);
            } else {
                cg.EmitCall(convertTarget.FieldType, "Invoke");
            }

            // fixup any references
            foreach (ReturnFixer rf in fixers) {
                rf.FixReturn(cg);
            }

            cg.Emit(OpCodes.Ret);
            return constants;
        }
开发者ID:octavioh,项目名称:ironruby,代码行数:79,代码来源:DelegateSignatureInfo.cs

示例6: EmitUnsupported

 private static void EmitUnsupported(ILGen gen, string name)
 {
     gen.EmitString(name);                               // gen.Emit(OpCodes.Ldstr, name);
     gen.EmitNew(CtorInfo_NotImplementedException_1);    // gen.Emit(OpCodes.Newobj, CtorInfo_NotImplementedException_1);
     gen.Emit(OpCodes.Throw);
 }
开发者ID:ragnard,项目名称:clojure-clr,代码行数:6,代码来源:GenClass.cs

示例7: EmitMain

        static void EmitMain(GenContext context, TypeBuilder proxyTB, string mainName, FieldBuilder mainFB)
        {
            MethodBuilder cb = proxyTB.DefineMethod("Main",MethodAttributes.Public| MethodAttributes.Static,CallingConventions.Standard,typeof(void),new Type[] { typeof(String[]) });
            ILGen gen = new ILGen(cb.GetILGenerator()); ;

            Label noMainLabel = gen.DefineLabel();
            Label endLabel = gen.DefineLabel();

            EmitGetVar(gen, mainFB);
            gen.Emit(OpCodes.Dup);
            gen.Emit(OpCodes.Brfalse_S, noMainLabel);
            gen.Emit(OpCodes.Castclass, typeof(IFn));
            gen.EmitLoadArg(0);                                 // gen.Emit(OpCodes.Ldarg_0);
            gen.EmitCall(Method_RT_seq);                        // gen.Emit(OpCodes.Call, Method_RT_seq);
            gen.EmitCall(Method_IFn_applyTo_Object_ISeq);       // gen.Emit(OpCodes.Call, Method_IFn_applyTo_Object_ISeq);
            gen.Emit(OpCodes.Pop);
            gen.Emit(OpCodes.Br_S, endLabel);

            // no main found
            gen.MarkLabel(noMainLabel);
            EmitUnsupported(gen, mainName);

            gen.MarkLabel(endLabel);
            gen.Emit(OpCodes.Ret);

            //context.AssyBldr.SetEntryPoint(cb);
            context.AssemblyBuilder.SetEntryPoint(cb);
        }
开发者ID:ragnard,项目名称:clojure-clr,代码行数:28,代码来源:GenClass.cs

示例8: EmitGetVar

        static void EmitGetVar(ILGen gen, FieldBuilder fb)
        {
            Label falseLabel = gen.DefineLabel();
            Label endLabel = gen.DefineLabel();

            gen.EmitFieldGet(fb);                       // gen.Emit(OpCodes.Ldsfld,fb);
            gen.Emit(OpCodes.Dup);
            gen.EmitCall(Method_Var_isBound);           // gen.Emit(OpCodes.Call, Method_Var_IsBound);
            gen.Emit(OpCodes.Brfalse_S,falseLabel);
            gen.Emit(OpCodes.Call,Method_Var_get);
            gen.Emit(OpCodes.Br_S,endLabel);
            gen.MarkLabel(falseLabel);
            gen.Emit(OpCodes.Pop);
            gen.EmitNull();                             // gen.Emit(OpCodes.Ldnull);
            gen.MarkLabel(endLabel);
        }
开发者ID:ragnard,项目名称:clojure-clr,代码行数:16,代码来源:GenClass.cs

示例9: EmitForwardingMethod

        private static void EmitForwardingMethod(TypeBuilder proxyTB, 
            bool isStatic,
            FieldBuilder regularFB,
            FieldBuilder overloadFB,
            MethodSignature sig,
            ElseGenDelegate elseGen)
        {
            MethodAttributes attributes;
            CallingConventions conventions;

            if (isStatic)
            {
                attributes = MethodAttributes.Public | MethodAttributes.Static;
                conventions = CallingConventions.Standard;
            }
            else
            {
                attributes = MethodAttributes.Public | MethodAttributes.Virtual;
                conventions = CallingConventions.HasThis;
            }

            MethodBuilder mb = proxyTB.DefineMethod(sig.Name, attributes, conventions, sig.ReturnType, sig.ParamTypes);
            ILGen gen = new ILGen(mb.GetILGenerator());

            Label foundLabel = gen.DefineLabel();
            Label elseLabel = gen.DefineLabel();
            Label endLabel = gen.DefineLabel();

            if (sig.ParamTypes.Length > 18)
                elseGen(gen);
            else
            {

                if (overloadFB != null)
                {
                    EmitGetVar(gen, overloadFB);
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Brtrue_S, foundLabel);
                    gen.Emit(OpCodes.Pop);
                }
                EmitGetVar(gen, regularFB);
                gen.Emit(OpCodes.Dup);
                gen.Emit(OpCodes.Brfalse_S, elseLabel);

                if (overloadFB != null)
                    gen.MarkLabel(foundLabel);
                gen.Emit(OpCodes.Castclass, typeof(IFn));

                if (!isStatic)
                    gen.EmitLoadArg(0);                     // gen.Emit(OpCodes.Ldarg_0);

                for (int i = 0; i < sig.ParamTypes.Length; i++)
                {
                    gen.EmitLoadArg(isStatic ? i : i + 1);                 // gen.Emit(OpCodes.Ldarg, i + 1);
                    if (sig.ParamTypes[i].IsValueType)
                        gen.Emit(OpCodes.Box, sig.ParamTypes[i]);

                }
                gen.EmitCall(Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
                //gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]);
                if (sig.ReturnType == typeof(void))
                    gen.Emit(OpCodes.Pop);
                else if (sig.ReturnType.IsValueType)
                    gen.Emit(OpCodes.Unbox_Any,sig.ReturnType);
                gen.Emit(OpCodes.Br_S, endLabel);

                gen.MarkLabel(elseLabel);
                gen.Emit(OpCodes.Pop);
                elseGen(gen);

                gen.MarkLabel(endLabel);
                gen.Emit(OpCodes.Ret);
            }
        }
开发者ID:ragnard,项目名称:clojure-clr,代码行数:74,代码来源:GenClass.cs

示例10: EmitExposers

        private static void EmitExposers(TypeBuilder proxyTB, Type superClass, IPersistentMap exposesFields)
        {
            for ( ISeq s = RT.seq(exposesFields); s != null; s = s.next() )
            {
                IMapEntry me = (IMapEntry)s.first();
                Symbol protectedFieldSym = (Symbol)me.key();
                IPersistentMap accessMap = (IPersistentMap)me.val();

                string fieldName = protectedFieldSym.Name;
                Symbol getterSym = (Symbol)accessMap.valAt(_getKw, null);
                Symbol setterSym = (Symbol)accessMap.valAt(_setKW, null);

                FieldInfo fld = null;

                if ( getterSym != null || setterSym != null )
                    fld = superClass.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance);

                if (getterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                        attribs |= MethodAttributes.Static;

                    MethodBuilder mb = proxyTB.DefineMethod(getterSym.Name, attribs, fld.FieldType, Type.EmptyTypes);
                    ILGen gen = new ILGen(mb.GetILGenerator());
                    //if (fld.IsStatic)
                    //    gen.Emit(OpCodes.Ldsfld, fld);
                    //else
                    //{
                    //    gen.Emit(OpCodes.Ldarg_0);
                    //    gen.Emit(OpCodes.Ldfld, fld);
                    //}
                    if (!fld.IsStatic)
                        gen.EmitLoadArg(0);
                    gen.EmitFieldGet(fld);

                    gen.Emit(OpCodes.Ret);
                }

                if (setterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                        attribs |= MethodAttributes.Static;

                    MethodBuilder mb = proxyTB.DefineMethod(setterSym.Name, attribs, typeof(void), new Type[] { fld.FieldType });
                    ILGen gen = new ILGen(mb.GetILGenerator());
                    if (fld.IsStatic)
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        //gen.Emit(OpCodes.Stsfld, fld);
                    }
                    else
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        gen.Emit(OpCodes.Ldarg_1);
                        //gen.Emit(OpCodes.Stfld, fld);
                    }
                    gen.EmitFieldSet(fld);
                    gen.Emit(OpCodes.Ret);
                }
            }
        }
开发者ID:ragnard,项目名称:clojure-clr,代码行数:63,代码来源:GenClass.cs

示例11: DefineStaticCtor

        /// <summary>
        ///  Set up Var fields and (maybe) load assembly for the namespace.
        /// </summary>
        /// <param name="proxyTB"></param>
        /// <param name="varMap"></param>
        /// <param name="loadImplNameSpace"></param>
        /// <param name="implNamespace"></param>
        private static void DefineStaticCtor(TypeBuilder proxyTB, string prefix, Dictionary<string, FieldBuilder> varMap, bool loadImplNameSpace, string implNamespace, string implCname)
        {
            ConstructorBuilder cb = proxyTB.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard,Type.EmptyTypes);
            ILGen gen = new ILGen(cb.GetILGenerator());

            foreach (KeyValuePair<string, FieldBuilder> pair in varMap)
            {
                gen.EmitString(implNamespace);                  // gen.Emit(OpCodes.Ldstr, implNamespace);
                gen.EmitString(prefix + pair.Key);              // gen.Emit(OpCodes.Ldstr, prefix + pair.Key);
                gen.EmitCall(Method_Var_internPrivate);         // gen.Emit(OpCodes.Call, Method_Var_internPrivate);
                gen.Emit(OpCodes.Stsfld, pair.Value);
            }

            if (loadImplNameSpace)
            {
                gen.EmitString("clojure.core");                 // gen.Emit(OpCodes.Ldstr, "clojure.core");
                gen.EmitString("load");                         // gen.Emit(OpCodes.Ldstr, "load");
                gen.EmitCall(Method_RT_var2);                   // gen.Emit(OpCodes.Call, Method_RT_var2);
                gen.EmitString("/" + implCname);                // gen.Emit(OpCodes.Ldstr, "/" + implCname);
                gen.EmitCall(Compiler.Methods_IFn_invoke[1]);   // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[1]);
                gen.Emit(OpCodes.Pop);
            }
            gen.Emit(OpCodes.Ret);
        }
开发者ID:ragnard,项目名称:clojure-clr,代码行数:31,代码来源:GenClass.cs

示例12: DefineCtors

        static void DefineCtors(TypeBuilder proxyTB, 
            Type superClass,
            string initName,
            string postInitName,
            ISeq ctorsTypes,
            FieldBuilder initFB,
            FieldBuilder postInitFB,
            FieldBuilder stateFB,
            string factoryName)
        {
            for (ISeq s = ctorsTypes; s != null; s = s.next())
            {
                IMapEntry me = (IMapEntry)s.first();
                ISeq thisParamTypesV = (ISeq)me.key();
                ISeq baseParamTypesV = (ISeq)me.val();

                Type[] thisParamTypes = CreateTypeArray(thisParamTypesV);
                Type[] baseParamTypes = CreateTypeArray(baseParamTypesV);

                BindingFlags flags = BindingFlags.CreateInstance| BindingFlags.NonPublic| BindingFlags.Public| BindingFlags.Instance;
                ConstructorInfo superCtor = superClass.GetConstructor(flags,null,baseParamTypes,null);

                if (superCtor == null || superCtor.IsPrivate)
                    throw new InvalidOperationException("Base class constructor missing or private");

                ConstructorBuilder cb = proxyTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, thisParamTypes);
                ILGen gen = new ILGen(cb.GetILGenerator());

                Label noInitLabel = gen.DefineLabel();
                Label noPostInitLabel = gen.DefineLabel();
                Label endPostInitLabel = gen.DefineLabel();
                Label endLabel = gen.DefineLabel();

                LocalBuilder locSuperArgs = gen.DeclareLocal(typeof(object));
                LocalBuilder locInitVal = gen.DeclareLocal(typeof(object));

                if (initFB != null)
                {
                    // init supplied
                    EmitGetVar(gen, initFB);
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Brfalse_S, noInitLabel);
                    gen.Emit(OpCodes.Castclass, typeof(IFn));

                    // box init args
                    for (int i = 0; i < thisParamTypes.Length; i++)
                    {
                        gen.EmitLoadArg(i + 1);                     // gen.Emit(OpCodes.Ldarg, i + 1);
                        if (thisParamTypes[i].IsValueType)
                            gen.Emit(OpCodes.Box,thisParamTypes[i]);
                    }

                    gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length]);   // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length]);

                    // Expecting:  [[super-ctor-args...] state]

                    // store the init return in a local
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Stloc,locInitVal);

                    // store the first element in a local
                    gen.EmitInt(0);                             // gen.Emit(OpCodes.Ldc_I4_0);
                    gen.EmitCall(Method_RT_nth);                // gen.Emit(OpCodes.Call, Method_RT_nth);
                    gen.Emit(OpCodes.Stloc, locSuperArgs);

                    // Stack this + super-ctor-args + call base-class ctor.
                    gen.EmitLoadArg(0);                         // gen.Emit(OpCodes.Ldarg_0);
                    for (int i = 0; i < baseParamTypes.Length; i++)
                    {
                        gen.Emit(OpCodes.Ldloc, locSuperArgs);
                        gen.EmitInt(i);                         // gen.Emit(OpCodes.Ldc_I4, i);
                        gen.EmitCall(Method_RT_nth);            // gen.Emit(OpCodes.Call, Method_RT_nth);
                        if (baseParamTypes[i].IsValueType)
                            gen.Emit(OpCodes.Unbox_Any, baseParamTypes[i]);
                        else
                            gen.Emit(OpCodes.Castclass, baseParamTypes[i]);
                    }

                    gen.Emit(OpCodes.Call, superCtor);

                    if (stateFB != null)
                    {
                        gen.EmitLoadArg(0);                     // gen.Emit(OpCodes.Ldarg_0);
                        gen.Emit(OpCodes.Ldloc, locInitVal);
                        gen.EmitInt(1);                         // gen.Emit(OpCodes.Ldc_I4_1);
                        gen.EmitCall(Method_RT_nth);            // gen.Emit(OpCodes.Call, Method_RT_nth);
                        gen.Emit(OpCodes.Castclass, typeof(object));
                        gen.EmitFieldSet(stateFB);              // gen.Emit(OpCodes.Stfld, stateFB);
                    }

                    gen.Emit(OpCodes.Br_S, endLabel);

                    // No init found
                    gen.MarkLabel(noInitLabel);

                    gen.Emit(OpCodes.Pop);
                    EmitUnsupported(gen, initName);

                    gen.MarkLabel(endLabel);
                }
//.........这里部分代码省略.........
开发者ID:ragnard,项目名称:clojure-clr,代码行数:101,代码来源:GenClass.cs

示例13: CreateSuperCall

        private static void CreateSuperCall(TypeBuilder proxyTB, Symbol p, MethodInfo mi)
        {
            Type[] paramTypes = CreateTypeArray(mi.GetParameters());

            MethodBuilder mb = proxyTB.DefineMethod(p.Name, MethodAttributes.Public, CallingConventions.HasThis, mi.ReturnType, paramTypes);
            ILGen gen = new ILGen(mb.GetILGenerator());
            gen.EmitLoadArg(0);                             // gen.Emit(OpCodes.Ldarg_0);
            for (int i = 0; i < paramTypes.Length; i++)
                gen.EmitLoadArg(i + 1);                     // gen.Emit(OpCodes.Ldarg, i + 1);
            gen.Emit(OpCodes.Call, mi);                     // not gen.EmitCall(mi); -- we need call versus callvirt
            gen.Emit(OpCodes.Ret);
        }
开发者ID:ragnard,项目名称:clojure-clr,代码行数:12,代码来源:GenClass.cs

示例14: SaveToAssembly

        /// <summary>
        /// This takes an assembly name including extension and saves the provided ScriptCode objects into the assembly.  
        /// 
        /// The provided script codes can constitute code from multiple languages.  The assemblyName can be either a fully qualified 
        /// or a relative path.  The DLR will simply save the assembly to the desired location.  The assembly is created by the DLR and 
        /// if a file already exists than an exception is raised.  
        /// 
        /// The DLR determines the internal format of the ScriptCode and the DLR can feel free to rev this as appropriate.  
        /// </summary>
        public static void SaveToAssembly(string assemblyName, params SavableScriptCode[] codes) {
            ContractUtils.RequiresNotNull(assemblyName, "assemblyName");
            ContractUtils.RequiresNotNullItems(codes, "codes");

            // break the assemblyName into it's dir/name/extension
            string dir = Path.GetDirectoryName(assemblyName);
            if (String.IsNullOrEmpty(dir)) {
                dir = Environment.CurrentDirectory;
            }

            string name = Path.GetFileNameWithoutExtension(assemblyName);
            string ext = Path.GetExtension(assemblyName);

            // build the assembly & type gen that all the script codes will live in...
            AssemblyGen ag = new AssemblyGen(new AssemblyName(name), dir, ext, /*emitSymbols*/false);
            TypeBuilder tb = ag.DefinePublicType("DLRCachedCode", typeof(object), true);
            TypeGen tg = new TypeGen(ag, tb);
            var symbolDict = new Dictionary<SymbolId, FieldBuilder>();
            // then compile all of the code

            Dictionary<Type, List<CodeInfo>> langCtxBuilders = new Dictionary<Type, List<CodeInfo>>();
            foreach (SavableScriptCode sc in codes) {
                List<CodeInfo> builders;
                if (!langCtxBuilders.TryGetValue(sc.LanguageContext.GetType(), out builders)) {
                    langCtxBuilders[sc.LanguageContext.GetType()] = builders = new List<CodeInfo>();
                }

                KeyValuePair<MethodBuilder, Type> compInfo = sc.CompileForSave(tg, symbolDict);

                builders.Add(new CodeInfo(compInfo.Key, sc, compInfo.Value));
            }

            MethodBuilder mb = tb.DefineMethod(
                "GetScriptCodeInfo",
                MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static,
                typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>),
                Type.EmptyTypes);

            ILGen ilgen = new ILGen(mb.GetILGenerator());

            var langsWithBuilders = langCtxBuilders.ToArray();

            // lang ctx array
            ilgen.EmitArray(typeof(Type), langsWithBuilders.Length, (index) => {
                ilgen.Emit(OpCodes.Ldtoken, langsWithBuilders[index].Key);
                ilgen.EmitCall(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
            });

            // builders array of array
            ilgen.EmitArray(typeof(Delegate[]), langsWithBuilders.Length, (index) => {
                List<CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(Delegate), builders.Count, (innerIndex) => {
                    ilgen.EmitNull();
                    ilgen.Emit(OpCodes.Ldftn, builders[innerIndex].Builder);
                    ilgen.EmitNew(
                        builders[innerIndex].DelegateType,
                        new[] { typeof(object), typeof(IntPtr) }
                    );
                });
            });

            // paths array of array
            ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
                List<CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
                    ilgen.EmitString(builders[innerIndex].Code.SourceUnit.Path);
                });
            });

            // 4th element in tuple - custom per-language data
            ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => {
                List<CodeInfo> builders = langsWithBuilders[index].Value;

                ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => {
                    ICustomScriptCodeData data = builders[innerIndex].Code as ICustomScriptCodeData;
                    if (data != null) {
                        ilgen.EmitString(data.GetCustomScriptCodeData());
                    } else {
                        ilgen.Emit(OpCodes.Ldnull);
                    }
                });
            });

            ilgen.EmitNew(
                typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>),
                new[] { typeof(Type[]), typeof(Delegate[][]), typeof(string[][]), typeof(string[][]) }
            );
            ilgen.Emit(OpCodes.Ret);

//.........这里部分代码省略.........
开发者ID:aceptra,项目名称:ironruby,代码行数:101,代码来源:SavableScriptCode.cs

示例15: BuildConstructors

        private void BuildConstructors(IList<ConstructorBuilderInfo>/*!*/ ctors) {
            foreach (var ctor in ctors) {
                // ctor(... RubyClass! class ..., <visible params>) : base(<hidden params>, <visible params>) { _class = class; }
                // ctor(... RubyClass! class ..., <visible params>) : base(... RubyOps.GetContextFromClass(class) ..., <visible params>) { _class = class; }
                // ctor(RubyClass! class) : base(RubyOps.GetDefaultExceptionMessage(class)) { _class = class; }
                ConstructorBuilder cb = _tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ctor.ParameterTypes);
                ILGen il = new ILGen(cb.GetILGenerator());

                int paramIndex = 0;
                int argIndex = 0;

                // We need to initialize before calling base ctor since the ctor can call virtual methods.
                // _immediateClass = immediateClass:
                if (!IsDerivedRubyType) {
                    il.EmitLoadArg(0);
                    il.EmitLoadArg(1 + ctor.ClassParamIndex);
                    il.EmitFieldSet(ImmediateClassField);
                }

                // base ctor call:
                il.EmitLoadArg(0);

                ConstructorInfo msgCtor;
                if (ctor.ParameterTypes.Length == 1 && ctor.Adjustment == SignatureAdjustment.InsertClass &&
                    _tb.IsSubclassOf(typeof(Exception)) && IsAvailable(msgCtor = _tb.BaseType.GetConstructor(_exceptionMessageSignature))) {

                    // a parameterless exception constructor should use Ruby default message:
                    il.EmitLoadArg(1);
                    il.EmitCall(Methods.GetDefaultExceptionMessage);
                    il.Emit(OpCodes.Call, msgCtor);
                } else {
                    if (ctor.Adjustment == SignatureAdjustment.InsertClass) {
                        paramIndex++;
                    }

                    while (paramIndex < ctor.ParameterTypes.Length) {
                        if (ctor.Adjustment == SignatureAdjustment.ConvertClassToContext && argIndex == ctor.ContextArgIndex) {
                            il.EmitLoadArg(1 + ctor.ClassParamIndex);
                            il.EmitCall(Methods.GetContextFromModule);
                        } else {
                            ClsTypeEmitter.DefineParameterCopy(cb, paramIndex, ctor.BaseParameters[argIndex]);
                            il.EmitLoadArg(1 + paramIndex);
                        }
                        argIndex++;
                        paramIndex++;
                    }
                    il.Emit(OpCodes.Call, ctor.BaseCtor);
                }

                il.Emit(OpCodes.Ret);
            }
        }
开发者ID:jschementi,项目名称:iron,代码行数:52,代码来源:RubyTypeBuilder.cs


注:本文中的ILGen.Emit方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。