public void AddModuleField(Type moduleType)
 {
     FieldBuilder moduleField = this.myType.DefineField(CompiledModule.ModuleFieldName,
         moduleType, FieldAttributes.Public | FieldAttributes.Static);
     moduleField.SetCustomAttribute(new CustomAttributeBuilder(typeof(PythonHiddenFieldAttribute).GetConstructor(new Type[0]), Runtime.Operations.Ops.EMPTY));
     this.moduleSlot = new StaticFieldSlot(moduleField);
 }
            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();
            }
        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();
        }
        private void EmitTopYieldTargetLabels(List<YieldTarget> yieldTargets, Slot choiceVar, CodeGen cg)
        {
            if (IsBlockYieldable(yieldTargets)) {
                Label label = cg.DefineLabel();
                cg.EmitInt(-1);
                choiceVar.EmitSet(cg);
                cg.Emit(OpCodes.Br, label);

                int index = 0;
                foreach (YieldTarget yt in yieldTargets) {
                    cg.MarkLabel(yt.TopBranchTarget);
                    cg.EmitInt(index++);
                    choiceVar.EmitSet(cg);
                    cg.Emit(OpCodes.Br, label);
                }
                cg.MarkLabel(label);
            }
        }
 public SignatureInfo(Type[] paramTypes, SymbolId[] paramNames, bool hasContext, Slot contextSlot)
 {
     ParamTypes = paramTypes;
     ParamNames = paramNames;
     HasContext = hasContext;
     ContextSlot = contextSlot;
 }
            public Delegate MakeCallTarget(bool needsContext)
            {
                if (!CanMakeCallTarget()) return null;

                if (IsDirectTarget(needsContext)) {
                    Delegate ret = FastCallable.MakeDelegate((MethodInfo)method.Method);
                    if (ret != null) return ret;
                }

                if (IronPython.Compiler.Options.EngineDebug) {
                    PerfTrack.NoteEvent(PerfTrack.Categories.Compiler, "CT:" + this.ToString());
                }

                int contextOffset = needsContext ? 1 : 0;
                Type[] paramTypes = new Type[parameters.Count + contextOffset];
                if (needsContext) paramTypes[0] = typeof(ICallerContext);

                for (int i = 0; i < parameters.Count; i++) {
                    paramTypes[i + contextOffset] = typeof(object);
                }

                CodeGen cg = OutputGenerator.Snippets.DefineDynamicMethod(method.Name, typeof(object), paramTypes);

                Slot contextSlot = needsContext ? cg.argumentSlots[0] : null;
                Slot[] argSlots = new Slot[parameters.Count];
                for (int i = 0; i < argSlots.Length; i++) {
                    argSlots[i] = cg.argumentSlots[i + contextOffset];
                }

                if (!method.IsStatic) {
                    if (method.DeclaringType.IsValueType) {
                        SimpleArgBuilder sb = instanceBuilder as SimpleArgBuilder;
                        argSlots[sb.index].EmitGet(cg);
                        cg.Emit(OpCodes.Unbox, method.DeclaringType);
                    } else {
                        instanceBuilder.Generate(cg, contextSlot, argSlots);
                    }
                }

                for (int i = 0; i < argBuilders.Count; i++) {
                    argBuilders[i].Generate(cg, contextSlot, argSlots);
                }

                Type returnType = GenerateCall(cg);

                //!!! add support for reference arg remapping

                returnBuilder.Generate(cg, contextSlot, argSlots);

                cg.Finish();

                return cg.CreateDelegate(FastCallable.GetTargetType(needsContext, parameters.Count));
            }
 public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     contextSlot.EmitGet(cg);
 }
 public abstract void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots);
 public static void EmitCallFromClrToPython(CodeGen cg, Slot callTarget, int firstArg)
 {
     EmitCallFromClrToPython(cg, callTarget, firstArg, IronPython.Compiler.Ast.FunctionAttributes.None);
 }
 public void SetSlot(SymbolId name, Slot slot)
 {
     slots[name] = slot;
 }
 public void AddTempSlot(Slot slot)
 {
     temps.Add(slot);
 }
 public IndexSlotFactory(Slot instance)
 {
     this.instance = instance;
 }
 public FieldSlotFactory(TypeGen typeGen, Slot instance)
 {
     this.typeGen = typeGen;
     this.instance = instance;
 }
 public LocalFrameSlotFactory(Slot frame)
 {
     this.frame = frame;
 }
 public static Slot MakeParentSlot(Slot instance)
 {
     return new FieldSlot(instance, typeof(FunctionEnvironmentDictionary).GetField("parent"));
 }
 public virtual void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     cg.EmitConvertToObject(returnType);
     cg.EmitReturn();
 }
 public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     argSlots[index].EmitGet(cg);
     cg.EmitConvertFromObject(parameter.Type);
 }
        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();
        }
 public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     throw new NotImplementedException();
 }
 public ReturnFixer(Slot refSlot, Slot argSlot)
 {
     Debug.Assert(refSlot.Type.IsGenericType && refSlot.Type.GetGenericTypeDefinition() == typeof(ClrModule.Reference<>));
     Debug.Assert(argSlot.Type.IsByRef);
     this.refSlot = refSlot;
     this.argSlot = argSlot;
 }
 public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     if (argumentType.IsByRef) {
         Type baseType = argumentType.GetElementType();
         Slot tmp = cg.GetLocalTmp(baseType);
         // Emit the default value as the base type
         EmitDefaultValue(cg, defaultValue, baseType);
         tmp.EmitSet(cg);
         // And pass the reference to the callee
         tmp.EmitGetAddr(cg);
     } else {
         // Emit the default value directly as the argument type
         EmitDefaultValue(cg, defaultValue, argumentType);
     }
 }
        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 void CreateClosureSlots(Slot staticLink, Namespace nspace)
        {
            foreach (KeyValuePair<SymbolId, Binding> kv in names) {
                if (!kv.Value.IsFree) continue;

                // Find the slot
                Slot instance = staticLink;
                ScopeStatement current = parent;

                for (; ; ) {
                    instance = new CastSlot(instance, current.environmentFactory.EnvironmentType);
                    Debug.Assert(current != null, "cannot resolve closure", kv.Key.GetString());
                    if (current.environment != null) {
                        EnvironmentReference er;

                        // Is the slot in this environment?
                        if (current.TryGetEnvironmentReference(kv.Key, out er)) {
                            nspace.SetSlot(kv.Key, er.CreateSlot(instance));
                            break;
                        }
                    }
                    instance = EnvironmentFactory.MakeParentSlot(instance);
                    current = current.parent;
                }
            }
        }
 private void GetOrDefineClass()
 {
     FieldInfo baseTypeField = baseType.GetField("__class__");
     if (baseTypeField == null) {
         typeField = tg.AddField(typeof(UserType), "__class__");
     } else {
         Debug.Assert(baseTypeField.FieldType == typeof(UserType));
         typeField = new FieldSlot(new ThisSlot(tg.myType), baseTypeField);
         hasBaseTypeField = true;
     }
 }
 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);
     }
 }
        internal override void Emit(CodeGen cg)
        {
            Slot list = cg.GetLocalTmp(typeof(List));
            cg.EmitCall(typeof(Ops), "MakeList", Type.EmptyTypes);
            list.EmitSet(cg);

            // first loop: how many For; initialize labels/slots
            int iFors = 0;
            foreach (ListComprehensionIterator iter in iters) {
                if (iter is ListComprehensionFor) iFors++;
            }

            Label[] continueTargets = new Label[iFors];
            Slot[] enumerators = new Slot[iFors];
            int jIters = iters.Length;
            Label[] exitTargets = new Label[jIters];

            for (int i = 0; i < iFors; i++) {
                continueTargets[i] = cg.DefineLabel();
                enumerators[i] = cg.GetLocalTmp(typeof(IEnumerator));
            }
            for (int i = 0; i < jIters; i++) {
                exitTargets[i] = cg.DefineLabel();
            }

            // second loop: before emiting item
            iFors = jIters = 0;
            foreach (ListComprehensionIterator iter in iters) {
                if (iter is ListComprehensionFor) {
                    ListComprehensionFor cfor = iter as ListComprehensionFor;
                    cfor.List.Emit(cg);
                    cg.EmitCall(typeof(Ops), "GetEnumeratorForIteration");
                    enumerators[iFors].EmitSet(cg);

                    cg.MarkLabel(continueTargets[iFors]);

                    enumerators[iFors].EmitGet(cg);
                    cg.EmitCall(typeof(IEnumerator), "MoveNext", Type.EmptyTypes);
                    cg.Emit(OpCodes.Brfalse, exitTargets[jIters]);

                    enumerators[iFors].EmitGet(cg);
                    cg.EmitCall(typeof(IEnumerator).GetProperty("Current").GetGetMethod());

                    cfor.Left.EmitSet(cg);
                    iFors++;
                } else if (iter is ListComprehensionIf) {
                    ListComprehensionIf cif = iter as ListComprehensionIf;

                    cg.EmitTestTrue(cif.Test);
                    cg.Emit(OpCodes.Brfalse, exitTargets[jIters]);
                }

                jIters++;
            }

            // append the item
            list.EmitGet(cg);
            this.item.Emit(cg);
            cg.EmitCall(typeof(List), "Append");

            // third loop: in reverse order
            iFors = continueTargets.Length - 1;
            jIters = iters.Length - 1;
            while (jIters >= 0) {
                ListComprehensionIterator iter = iters[jIters];
                if (iter is ListComprehensionFor) {
                    cg.Emit(OpCodes.Br, continueTargets[iFors]);
                    cg.FreeLocalTmp(enumerators[iFors]);
                    iFors--;
                }

                cg.MarkLabel(exitTargets[jIters]);
                jIters--;
            }

            list.EmitGet(cg);
            cg.FreeLocalTmp(list);
        }
        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++;
                }
            }
        }
 public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     cg.EmitRawConstant(null);
 }
        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
        }
 public override void Generate(CodeGen cg, Slot contextSlot, Slot[] argSlots)
 {
     cg.EmitInt(count);
     cg.Emit(OpCodes.Newarr, parameter.Type);
     for (int i = 0; i < count; i++) {
         cg.Emit(OpCodes.Dup);
         cg.EmitInt(i);
         argSlots[start + i].EmitGet(cg);
         cg.EmitConvertFromObject(parameter.Type);
         cg.EmitStelem(parameter.Type);
     }
 }