示例#1
0
        private void EmitWithFinallyBlock(CodeGen cg, Slot exc, Slot exit, Slot isTryYielded)
        {
            // we are certain that Finally will never yield
            cg.PushFinallyBlock(null, null);
            cg.BeginFinallyBlock();

            //finally body
            Label endOfFinally = cg.DefineLabel();

            // isTryYielded == True ?
            isTryYielded.EmitGet(cg);
            cg.EmitTestTrue();
            cg.Emit(OpCodes.Brtrue, endOfFinally);

            // exc == False ?
            exc.EmitGet(cg);
            cg.EmitTestTrue();
            cg.Emit(OpCodes.Brfalse, endOfFinally);

            //exit(None, None, None)
            cg.EmitCallerContext();
            exit.EmitGet(cg);
            cg.Emit(OpCodes.Ldnull);
            cg.Emit(OpCodes.Ldnull);
            cg.Emit(OpCodes.Ldnull);
            cg.EmitCall(typeof(Ops), "CallWithContext", new Type[] { typeof(ICallerContext), typeof(object), typeof(object), typeof(object), typeof(object) });
            cg.Emit(OpCodes.Pop);

            cg.MarkLabel(endOfFinally);
            cg.PopTargets();

            // finally end
        }
示例#2
0
        private void EmitYieldDispatch(List<YieldTarget> yieldTargets, Slot isYielded, Slot choiceVar, CodeGen cg)
        {
            if (IsBlockYieldable(yieldTargets)) {
                cg.EmitFieldGet(typeof(Ops).GetField("FALSE"));
                isYielded.EmitSet(cg);

                int index = 0;
                foreach (YieldTarget yt in yieldTargets) {
                    choiceVar.EmitGet(cg);
                    cg.EmitInt(index);
                    cg.Emit(OpCodes.Beq, yt.YieldContinuationTarget);
                    index++;
                }
            }
        }
示例#3
0
        private void EmitWithCatchBlock(CodeGen cg, Slot exc, Slot exit)
        {
            cg.BeginCatchBlock(typeof(Exception));
            // Extract state from the carrier exception
            cg.EmitCallerContext();
            cg.EmitCall(typeof(Ops), "ExtractException",
                new Type[] { typeof(Exception), typeof(ICallerContext) });
            cg.Emit(OpCodes.Pop);

            // except body
            cg.PushExceptionBlock(Targets.TargetBlockType.Catch, null, null);
            cg.EmitConstantBoxed(false);
            exc.EmitSet(cg);

            cg.EmitCallerContext();
            exit.EmitGet(cg);
            cg.EmitObjectArray(new Expression[0]);
            cg.EmitCallerContext();
            cg.EmitCall(typeof(Ops), "ExtractSysExcInfo");
            cg.EmitCall(typeof(Ops), "CallWithArgsTupleAndContext", new Type[] { typeof(ICallerContext), typeof(object), typeof(object[]), typeof(object) });

            Label afterRaise = cg.DefineLabel();

            cg.EmitTestTrue();
            cg.Emit(OpCodes.Brtrue, afterRaise);
            cg.EmitCall(typeof(Ops), "Raise", new Type[0]); //, new Type[] { typeof(object), typeof(SymbolId) });
            cg.MarkLabel(afterRaise);
            cg.EmitCallerContext();
            cg.EmitCall(typeof(Ops), "ClearException", new Type[] { typeof(ICallerContext) });
            cg.PopTargets();
        }
 public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     contextSlot.EmitGet(cg);
 }
示例#5
0
 private void EmitOnYieldBranchToLabel(List<YieldTarget> yieldTargets, Slot isYielded, Label label, CodeGen cg)
 {
     if (IsBlockYieldable(yieldTargets)) {
         isYielded.EmitGet(cg);
         cg.EmitUnbox(typeof(bool));
         cg.Emit(OpCodes.Brtrue, label);
     }
 }
        public static void EmitCallFromClrToPython(CodeGen cg, Slot callTarget, int firstArg, Ast.FunctionAttributes functionAttributes)
        {
            callTarget.EmitGet(cg);

            List<ReturnFixer> fixers = new List<ReturnFixer>(0);
            Slot[] args = cg.argumentSlots;
            int nargs = args.Length - firstArg;
            if (nargs <= Ops.MaximumCallArgs && (functionAttributes & IronPython.Compiler.Ast.FunctionAttributes.ArgumentList) == 0) {
                for (int i = firstArg; i < args.Length; i++) {
                    ReturnFixer rf = CompilerHelpers.EmitArgument(cg, args[i]);
                    if (rf != null) fixers.Add(rf);
                }

                cg.EmitCall(typeof(Ops), "Call", CompilerHelpers.MakeRepeatedArray(typeof(object), nargs + 1));
            } else if ((functionAttributes & IronPython.Compiler.Ast.FunctionAttributes.ArgumentList) == 0) {
                cg.EmitObjectArray(nargs, delegate(int index) {
                    ReturnFixer rf = CompilerHelpers.EmitArgument(cg, args[index + firstArg]);
                    if (rf != null) fixers.Add(rf);
                });

                cg.EmitCall(typeof(Ops), "Call", new Type[] { typeof(object), typeof(object[]) });
            } else {
                cg.EmitObjectArray(nargs - 1, delegate(int index) {
                    ReturnFixer rf = CompilerHelpers.EmitArgument(cg, args[index + firstArg]);
                    if (rf != null) fixers.Add(rf);
                });

                args[args.Length - 1].EmitGet(cg);
                cg.EmitCall(typeof(Tuple), "Make");

                cg.EmitCall(typeof(Ops), "CallWithArgsTuple");
            }

            foreach (ReturnFixer rf in fixers) {
                rf.FixReturn(cg);
            }
            cg.EmitReturnFromObject();
        }
        private void CreateVirtualMethodOverride(MethodInfo mi, Slot methField)
        {
            CodeGen cg = tg.DefineMethodOverride(mi);
            Label baseCall = cg.DefineLabel();

            methField.EmitGet(cg);
            cg.EmitCall(typeof(MethodWrapper), "IsBuiltinMethod");
            cg.Emit(OpCodes.Brtrue, baseCall);

            methField.EmitGet(cg);
            cg.EmitThis();
            for (int i = 0; i < mi.GetParameters().Length; i++) {
                cg.EmitArgGet(i);
                cg.EmitConvertToObject(mi.GetParameters()[i].ParameterType);
            }

            if (mi.GetParameters().Length > 3) {
                throw new NotImplementedException("OverrideBaseMethod: " + mi);
            }

            cg.EmitCall(typeof(MethodWrapper), "Invoke", CompilerHelpers.MakeRepeatedArray(typeof(object), 1 + mi.GetParameters().Length));
            MethodInfo object_ToString = typeof(object).GetMethod("ToString");

            if (mi.MethodHandle != object_ToString.MethodHandle) {
                cg.EmitReturnFromObject();
            } else {
                cg.EmitCall(typeof(UserType), "ToStringReturnHelper");
                cg.EmitReturn();
            }

            cg.MarkLabel(baseCall);

            if (mi.MethodHandle == object_ToString.MethodHandle) {
                // object.ToString() displays the CLI type name. However, __class__ is the real type for Python type instances
                cg.EmitThis();
                cg.EmitCall(typeof(UserType).GetMethod("ToStringHelper"));
                cg.EmitReturn();
            } else if (mi.IsAbstract) {
                EmitBadCallThrow(cg, mi, "must override abstract method"); //@todo better exception
            } else {
                // Just forward to the base method implementation
                EmitBaseMethodDispatch(mi, cg);
            }

            cg.Finish();
        }
            private static CodeGen AddIDynamicObject(TypeGen newType, Slot dictSlot)
            {
                Slot classSlot = newType.AddStaticField(typeof(DynamicType), FieldAttributes.Private, "$class");

                newType.myType.AddInterfaceImplementation(typeof(ISuperDynamicObject));
                /* GetDynamicType */

                CodeGen gdtCg = newType.DefineMethodOverride(typeof(IDynamicObject).GetMethod("GetDynamicType"));

                CodeGen cg = newType.DefineUserHiddenMethod(MethodAttributes.FamORAssem | MethodAttributes.Static,
                    "$$GetOrMakeDynamicType", typeof(DynamicType), new Type[0]);
                DoLazyInitCheck(cg, classSlot,
                    delegate() {
                        // if not null, just return the value.
                        classSlot.EmitGet(cg);
                        cg.EmitReturn();
                    },
                    delegate() {
                        // initialization code

                        // CompiledType GetTypeForType(Type t)
                        cg.EmitType(newType.myType);
                        cg.EmitCall(typeof(CompiledType), "GetTypeForType");
                        cg.Emit(OpCodes.Dup);
                        classSlot.EmitSet(cg);

                        cg.EmitReturn();
                    });

                cg.Finish();
                CodeGen ret = cg;

                // just a call to the helper method
                gdtCg.EmitThis();
                gdtCg.EmitCall(typeof(object), "GetType");
                gdtCg.EmitType(newType.myType);
                Label differ = gdtCg.DefineLabel();
                gdtCg.Emit(OpCodes.Bne_Un, differ);

                gdtCg.EmitCall(cg.MethodInfo);
                gdtCg.EmitReturn();

                gdtCg.MarkLabel(differ);

                gdtCg.EmitThis();
                gdtCg.EmitCall(typeof(object), "GetType");
                gdtCg.EmitCall(typeof(Ops), "GetDynamicTypeFromType");
                gdtCg.EmitReturn();

                gdtCg.Finish();

                /* GetDict */
                cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("GetDict"));
                DoLazyInitCheck(cg, dictSlot,
                    delegate() {
                        // if not null, just return the value.
                        dictSlot.EmitGet(cg);
                        cg.EmitReturn();
                    },
                    delegate() {
                        // initialization code - dictSlot = new CustomOldClassDict()
                        cg.EmitNew(typeof(CustomOldClassDict).GetConstructor(new Type[0]));
                        cg.Emit(OpCodes.Dup);
                        dictSlot.EmitSet(cg);

                        cg.EmitReturn();
                    });
                cg.Finish();

                /* SetDict */
                cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("SetDict"));
                cg.EmitString("SetDict");
                cg.EmitInt(0);
                cg.Emit(OpCodes.Newarr, typeof(object));
                cg.EmitCall(typeof(Ops), "NotImplementedError");
                cg.Emit(OpCodes.Throw);

                /* SetDynamicType */
                cg = newType.DefineMethodOverride(typeof(ISuperDynamicObject).GetMethod("SetDynamicType"));
                cg.EmitString("SetDynamicType");
                cg.EmitInt(0);
                cg.Emit(OpCodes.Newarr, typeof(object));
                cg.EmitCall(typeof(Ops), "NotImplementedError");
                cg.Emit(OpCodes.Throw);

                return ret;
            }
            private static void DoLazyInitCheck(CodeGen cg, Slot val, LazyInitHelper ifNotNull, LazyInitHelper initCode)
            {
                Label initType = cg.DefineLabel();

                val.EmitGet(cg);
                cg.Emit(OpCodes.Ldnull);
                cg.Emit(OpCodes.Beq, initType);

                ifNotNull();

                cg.MarkLabel(initType);

                initCode();
            }
示例#10
0
 // Must override at least one of these two methods or get infinite loop
 public virtual void EmitSet(CodeGen cg, Slot val)
 {
     val.EmitGet(cg);
     EmitSet(cg);
 }
        /// <summary>
        /// Emits a call into the PythonModule to register this module, and then
        /// returns the resulting PythonModule 
        /// </summary>
        public static void EmitModuleConstruction(TypeGen tg, CodeGen main, string moduleName, Slot initialize, IList<string> referencedAssemblies)
        {
            // calling PythonModule InitializeModule(CustomDict compiled, string fullName)

            main.EmitNew(tg.DefaultConstructor); // Emit instance for the InitializeModule call (compiled)

            initialize.EmitSet(main);
            initialize.EmitGet(main);

            main.EmitString(moduleName);         // emit module name (fullName)

            // emit the references assemblies
            if (referencedAssemblies != null) {
                for (int i = 0; i < referencedAssemblies.Count; i++) {
                    if (referencedAssemblies[i].ToLower().EndsWith("\\ironpython.dll")) {
                        referencedAssemblies.RemoveAt(i);
                        i--;
                    } else {
                        if (referencedAssemblies[i].IndexOf(Path.DirectorySeparatorChar) != -1) {
                            referencedAssemblies[i] = referencedAssemblies[i].Substring(referencedAssemblies[i].LastIndexOf(Path.DirectorySeparatorChar) + 1);
                        }

                        if (referencedAssemblies[i].ToLower().EndsWith(".dll")) {
                            referencedAssemblies[i] = referencedAssemblies[i].Substring(0, referencedAssemblies[i].Length - 4);
                        }
                    }
                }
                main.EmitStringArray(referencedAssemblies);
            } else main.Emit(OpCodes.Ldnull);

            // Call InitializeModule
            main.EmitCall(typeof(Ops), "InitializeModule");
        }
示例#12
0
        public override void EmitSet(CodeGen cg, Slot val)
        {
            MethodInfo method = property.GetSetMethod();
            Debug.Assert(method != null, "Cannot set property");
            Debug.Assert(method.GetParameters().Length == 1, "Wrong number of parameters on the property setter");

            //  Emit instance
            if (!method.IsStatic) {
                Debug.Assert(instance != null, "need instance slot for instance property");
                instance.EmitGet(cg);
            }

            //  Emit value
            val.EmitGet(cg);

            //  Emit call
            cg.EmitCall(method);
        }
示例#13
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     //
     // frame.SetGlobal(symbol_id, val)
     //
     frame.EmitGet(cg);
     cg.EmitSymbolId(name);
     val.EmitGet(cg);
     cg.EmitCall(typeof(IModuleScope), "SetGlobal");
 }
示例#14
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     // Emit the following:
     //    frame.SetLocal(symbol_id, val)
     frame.EmitGet(cg);
     cg.EmitSymbolId(name);
     val.EmitGet(cg);
     cg.EmitCall(typeof(ModuleScope), "SetLocal");
 }
示例#15
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     val.EmitGet(cg);
     cg.EmitConvertToObject(Type);
     val = cg.GetLocalTmp(typeof(object));
     val.EmitSet(cg);
     instance.EmitGet(cg);
     cg.EmitInt(index);
     val.EmitGet(cg);
     cg.Emit(OpCodes.Stelem_Ref);
 }
示例#16
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     instance.EmitGet(cg);
     val.EmitGet(cg);
     cg.Emit(OpCodes.Stfld, field);
 }