Exemplo n.º 1
0
 public override void EmitGet(CodeGen cg)
 {
     instance.EmitGet(cg);
     cg.EmitInt(index);
     cg.Emit(OpCodes.Ldelem_Ref);
     cg.EmitCastFromObject(Type);
 }
Exemplo n.º 2
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     val.EmitGet(cg);
     cg.EmitCastToObject(Type);
     val = cg.GetLocalTmp(typeof(object));
     val.EmitSet(cg);
     instance.EmitGet(cg);
     cg.EmitInt(index);
     val.EmitGet(cg);
     cg.Emit(OpCodes.Stelem_Ref);
 }
Exemplo n.º 3
0
        private CodeGen MakeWrapperMethodN(CodeGen cg, MethodInfo impl, bool context)
        {
            CodeGen icg;
            int     index = 0;

            if (context)
            {
                Type environmentType = IsClosure ? cg.EnvironmentSlot.Type : cg.ContextSlot.Type;
                icg = cg.DefineUserHiddenMethod(impl.Name, typeof(object), new Type[] { environmentType, typeof(object[]) });
                Slot env = icg.GetArgumentSlot(index++);
                env.EmitGet(icg);
            }
            else
            {
                icg = cg.DefineUserHiddenMethod(impl.Name, typeof(object), new Type[] { typeof(object[]) });
            }

            Slot arg = icg.GetArgumentSlot(index);

            for (int pi = 0; pi < parameters.Length; pi++)
            {
                arg.EmitGet(icg);
                icg.EmitInt(pi);
                icg.Emit(OpCodes.Ldelem_Ref);
            }
            icg.EmitCall(impl);
            icg.Emit(OpCodes.Ret);
            return(icg);
        }
Exemplo n.º 4
0
 public override void EmitGet(CodeGen cg)
 {
     instance.EmitGet(cg);
     if (!type.IsAssignableFrom(instance.Type))
     {
         cg.Emit(OpCodes.Castclass, type);
     }
 }
Exemplo n.º 5
0
 public void EmitTryGetNonInheritedValue(CodeGen cg, Slot valueOut)
 {
     typeSlot.EmitGet(cg);
     cg.EmitCall(typeof(UserType), "GetNamespaceDictionary");
     cg.EmitInt(index);
     valueOut.EmitGetAddr(cg);
     cg.EmitCall(typeof(NamespaceDictionary), "TryGetNonInheritedValue");
 }
Exemplo n.º 6
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     // Emit the following:
     //    frame.SetGlobal("name", val)
     frame.EmitGet(cg);
     cg.EmitString(name.GetString());
     val.EmitGet(cg);
     cg.EmitCall(typeof(IFrameEnvironment), "SetGlobal");
 }
Exemplo n.º 7
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     // Emit the following:
     //    frame.SetName("name", val)
     frame.EmitGet(cg);
     cg.EmitString(name.GetString());
     val.EmitGet(cg);
     cg.EmitCall(typeof(Frame), "SetLocal");
 }
Exemplo n.º 8
0
        /// <summary>
        /// Generates a static entry point for stand-alone EXEs.  We just new up our module dstructure
        /// and then call into Ops to get running.
        /// </summary>
        internal static CodeGen GenerateModuleEntryPoint(TypeGen tg, CodeGen init, string moduleName, IList <string> referencedAssemblies)
        {
            CodeGen main = tg.DefineMethod(MethodAttributes.Static | MethodAttributes.Public, "Main", typeof(int), Type.EmptyTypes, new string[] { });

            main.SetCustomAttribute(new CustomAttributeBuilder(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new object[0]));

            //  Create instance of the module
            Slot instance = main.GetLocalTmp(tg.myType);

            main.EmitNew(tg.DefaultConstructor);
            instance.EmitSet(main);

            // Emit instance for the ExecuteCompiled call
            instance.EmitGet(main);

            // Emit the delegate to the init method
            main.EmitDelegate(init, typeof(InitializeModule), instance);
            main.EmitString(moduleName);

            // 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 ExecuteCompiled
            main.EmitCall(typeof(IronPython.Hosting.PythonEngine),
                          "ExecuteCompiled",
                          new Type[] { typeof(CustomFieldIdDict), typeof(InitializeModule), typeof(string), typeof(string[]) });

            main.EmitReturn();
            return(main);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
        public override void EmitCheck(CodeGen cg)
        {
            Label initialized = cg.DefineLabel();

            cg.Emit(OpCodes.Dup);
            cg.Emit(OpCodes.Isinst, typeof(Uninitialized));
            cg.Emit(OpCodes.Brfalse, initialized);
            cg.Emit(OpCodes.Pop);
            global.EmitGet(cg);
            global.EmitCheck(cg);
            cg.MarkLabel(initialized);
        }
Exemplo n.º 11
0
        public override void EmitSet(CodeGen cg)
        {
            Slot val = cg.GetLocalTmp(Type);

            val.EmitSet(cg);

            base.EmitGet(cg);
            val.EmitGet(cg);
            cg.EmitCall(typeof(BuiltinWrapper), "set_CurrentValue");

            cg.FreeLocalTmp(val);
        }
Exemplo n.º 12
0
        public override void Emit(CodeGen cg)
        {
            cg.EmitPosition(start, end);

            cg.EmitModuleInstance();
            cg.EmitString(root.MakeString());
            if (names == Star)
            {
                cg.EmitCall(typeof(Ops), "ImportStar"); //!!! this is tricky
            }
            else
            {
                Slot fromObj = cg.GetLocalTmp(typeof(object));
                cg.EmitStringArray(Name.ToStrings(names));

                if (asNames != null)
                {
                    cg.EmitStringArray(Name.ToStrings(asNames));
                    cg.EmitCall(typeof(Ops), "ImportFromAs");
                }
                else
                {
                    cg.EmitCall(typeof(Ops), "ImportFrom");
                }

                fromObj.EmitSet(cg);

                for (int i = 0; i < names.Length; i++)
                {
                    cg.EmitCallerContext();
                    fromObj.EmitGet(cg);
                    cg.EmitString(names[i].GetString());
                    cg.EmitCall(typeof(Ops), "ImportOneFrom");

                    Name asName;
                    if (i < asNames.Length && asNames[i] != null)
                    {
                        asName = asNames[i];
                    }
                    else
                    {
                        asName = names[i];
                    }

                    cg.EmitSet(asName);
                }
            }
        }
Exemplo n.º 13
0
        private void MakeRawKeysMethod()
        {
            Slot    rawKeysCache = tg.AddStaticField(typeof(SymbolId[]), "ExtraKeysCache");
            CodeGen init         = tg.GetOrMakeInitializer();

            SymbolId[] nameArray = new SymbolId[names.Slots.Count];

            init.EmitSymbolIdArray(new List <Name>(names.Slots.Keys));

            rawKeysCache.EmitSet(init);

            CodeGen cg = tg.DefineMethodOverride(typeof(CustomFieldIdDict).GetMethod("GetExtraKeys"));

            rawKeysCache.EmitGet(cg);
            cg.EmitReturn();
            cg.Finish();
        }
Exemplo n.º 14
0
        //!!! code review
        protected void FinishCompare(CodeGen cg)
        {
            BinaryExpr bright = (BinaryExpr)right;

            Slot valTmp = cg.GetLocalTmp(typeof(object));
            Slot retTmp = cg.GetLocalTmp(typeof(object));

            bright.left.Emit(cg);
            cg.Emit(OpCodes.Dup);
            valTmp.EmitSet(cg);

            cg.EmitCall(op.target.Method);
            cg.Emit(OpCodes.Dup);
            retTmp.EmitSet(cg);
            cg.EmitTestTrue();

            Label end = cg.DefineLabel();

            cg.Emit(OpCodes.Brfalse, end);

            valTmp.EmitGet(cg);

            if (IsComparision(bright.right))
            {
                bright.FinishCompare(cg);
            }
            else
            {
                bright.right.Emit(cg);
                cg.EmitCall(bright.op.target.Method);
            }

            retTmp.EmitSet(cg);
            cg.MarkLabel(end);
            retTmp.EmitGet(cg);
        }
Exemplo n.º 15
0
 public override void EmitGet(CodeGen cg)
 {
     frame.EmitGet(cg);
     cg.EmitString(name.GetString());
     cg.EmitCall(typeof(IFrameEnvironment), "GetGlobal");
 }
Exemplo n.º 16
0
 public override void EmitGet(CodeGen cg)
 {
     frame.EmitGet(cg);
     cg.EmitString(name.GetString());
     cg.EmitCall(typeof(Frame), "GetLocal");
 }
Exemplo n.º 17
0
        public override void EmitSet(CodeGen cg)
        {
            // Disallow "[] = l", "[], a = l, l", "[[]] = [l]", etc
            if (items.Length == 0)
            {
                cg.Context.AddError("can't assign to " + EmptySequenceString, this);
                return;
            }

            // int leftCount = items.Length;
            Slot leftCount = cg.GetLocalTmp(typeof(int));

            cg.EmitInt(items.Length);
            leftCount.EmitSet(cg);

            // object[] values = new object[leftCount];
            Slot values = cg.GetLocalTmp(typeof(object[]));

            leftCount.EmitGet(cg);
            cg.Emit(OpCodes.Newarr, typeof(object));
            values.EmitSet(cg);

            // ie = Ops.GetEnumerator(<value on stack>)
            Slot ie = cg.GetLocalTmp(typeof(IEnumerator));

            cg.EmitCall(typeof(Ops), "GetEnumerator");
            ie.EmitSet(cg);

            // int rightCount = Ops.GetEnumeratorValues(ie, ref values);
            Slot rightCount = cg.GetLocalTmp(typeof(int));

            ie.EmitGet(cg);
            values.EmitGetAddr(cg);
            cg.EmitCall(typeof(Ops), "GetEnumeratorValues");
            rightCount.EmitSet(cg);

            // if (leftCount != rightCount)
            //      throw Ops.ValueErrorForUnpackMismatch(leftCount, rightCount);
            Label equalSizes = cg.DefineLabel();

            leftCount.EmitGet(cg);
            rightCount.EmitGet(cg);
            cg.Emit(OpCodes.Ceq);
            cg.Emit(OpCodes.Brtrue_S, equalSizes);

            leftCount.EmitGet(cg);
            rightCount.EmitGet(cg);
            cg.EmitCall(typeof(Ops).GetMethod("ValueErrorForUnpackMismatch"));
            cg.Emit(OpCodes.Throw);

            cg.MarkLabel(equalSizes);

            // for (int i = 0; i < leftCount; i++)
            //     items[i].Assign(values[i], env);

            int i = 0;

            foreach (Expr expr in items)
            {
                values.EmitGet(cg);
                cg.EmitInt(i++);
                cg.Emit(OpCodes.Ldelem_Ref);
                expr.EmitSet(cg);
            }

            cg.FreeLocalTmp(leftCount);
            cg.FreeLocalTmp(rightCount);
            cg.FreeLocalTmp(values);
            cg.FreeLocalTmp(ie);
        }
Exemplo n.º 18
0
        public 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 (ListCompIter iter in iters)
            {
                if (iter is ListCompFor)
                {
                    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 (ListCompIter iter in iters)
            {
                if (iter is ListCompFor)
                {
                    ListCompFor cfor = iter as ListCompFor;
                    cfor.list.Emit(cg);
                    cg.EmitCall(typeof(Ops), "GetEnumerator");
                    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.lhs.EmitSet(cg);
                    iFors++;
                }
                else if (iter is ListCompIf)
                {
                    ListCompIf cif = iter as ListCompIf;

                    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)
            {
                ListCompIter iter = iters[jIters];
                if (iter is ListCompFor)
                {
                    cg.Emit(OpCodes.Br, continueTargets[iFors]);
                    cg.FreeLocalTmp(enumerators[iFors]);
                    iFors--;
                }

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

            list.EmitGet(cg);
            cg.FreeLocalTmp(list);
        }
Exemplo n.º 19
0
 public override void EmitGet(CodeGen cg)
 {
     instance.EmitGet(cg);
     cg.Emit(OpCodes.Ldfld, field);
 }
Exemplo n.º 20
0
 public override void EmitGet(CodeGen cg)
 {
     attribute.EmitGet(cg);
 }
Exemplo n.º 21
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     instance.EmitGet(cg);
     val.EmitGet(cg);
     cg.Emit(OpCodes.Stfld, field);
 }
Exemplo n.º 22
0
 public override void EmitGet(CodeGen cg)
 {
     param.EmitGet(cg);
     cg.EmitInt(index);
     cg.Emit(OpCodes.Ldelem_Ref);
 }
Exemplo n.º 23
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);
 }
Exemplo n.º 24
0
        //!!! need to evaluate break/continue through a try block
        public override void Emit(CodeGen cg)
        {
            Slot choiceVar = null;

            cg.EmitPosition(start, header);

            if (yieldTargets.Count > 0)
            {
                Label startOfBlock = cg.DefineLabel();
                choiceVar = cg.GetLocalTmp(typeof(int));
                cg.EmitInt(-1);
                choiceVar.EmitSet(cg);
                cg.Emit(OpCodes.Br, startOfBlock);

                int index = 0;
                foreach (YieldTarget yt in yieldTargets)
                {
                    cg.MarkLabel(yt.topBranchTarget);
                    cg.EmitInt(index++);
                    choiceVar.EmitSet(cg);
                    cg.Emit(OpCodes.Br, startOfBlock);
                }

                cg.MarkLabel(startOfBlock);
            }

            Label afterCatch = new Label();
            Label afterElse  = cg.DefineLabel();

            cg.PushTryBlock();
            cg.BeginExceptionBlock();

            if (yieldTargets.Count > 0)
            {
                int index = 0;
                foreach (YieldTarget yt in yieldTargets)
                {
                    choiceVar.EmitGet(cg);
                    cg.EmitInt(index);
                    cg.Emit(OpCodes.Beq, yt.tryBranchTarget);
                    index++;
                }
                cg.FreeLocalTmp(choiceVar);
            }

            body.Emit(cg);
            if (yieldInExcept)
            {
                afterCatch = cg.DefineLabel();
                cg.Emit(OpCodes.Leave, afterCatch);
            }
            cg.BeginCatchBlock(typeof(Exception));
            // Extract state from the carrier exception
            cg.EmitCallerContext();
            cg.EmitCall(typeof(Ops), "ExtractException");
            Slot pyExc  = cg.GetLocalTmp(typeof(object));
            Slot tmpExc = cg.GetLocalTmp(typeof(object));

            pyExc.EmitSet(cg);
            if (yieldInExcept)
            {
                cg.EndExceptionBlock();
                cg.PopTargets();
            }

            foreach (TryStmtHandler handler in handlers)
            {
                cg.EmitPosition(handler.start, handler.header);
                Label next = cg.DefineLabel();
                if (handler.test != null)
                {
                    pyExc.EmitGet(cg);
                    handler.test.Emit(cg);
                    cg.EmitCall(typeof(Ops), "CheckException");
                    if (handler.target != null)
                    {
                        tmpExc.EmitSet(cg);
                        tmpExc.EmitGet(cg);
                    }
                    cg.EmitPythonNone();
                    cg.Emit(OpCodes.Ceq);
                    cg.Emit(OpCodes.Brtrue, next);
                }

                if (handler.target != null)
                {
                    tmpExc.EmitGet(cg);
                    handler.target.EmitSet(cg);
                }

                cg.PushExceptionBlock(Targets.TargetBlockType.Catch, null);

                handler.body.Emit(cg);
                cg.EmitCallerContext();
                cg.EmitCall(typeof(Ops), "ClearException");

                cg.PopTargets();

                if (yieldInExcept)
                {
                    cg.Emit(OpCodes.Br, afterElse);
                }
                else
                {
                    cg.Emit(OpCodes.Leave, afterElse);
                }
                cg.MarkLabel(next);
            }

            cg.FreeLocalTmp(tmpExc);
            if (yieldInExcept)
            {
                pyExc.EmitGet(cg);
                cg.Emit(OpCodes.Throw);
                cg.MarkLabel(afterCatch);
            }
            else
            {
                cg.Emit(OpCodes.Rethrow);
                cg.EndExceptionBlock();
                cg.PopTargets();
            }

            if (elseStmt != null)
            {
                elseStmt.Emit(cg);
            }
            cg.MarkLabel(afterElse);

            cg.FreeLocalTmp(pyExc);

            yieldTargets.Clear();
        }
Exemplo n.º 25
0
        public override void Emit(CodeGen cg)
        {
            cg.EmitPosition(start, header);
            Slot  choiceVar = null;
            Slot  returnVar = null;
            Label endOfTry  = new Label();

            if (yieldTargets.Count > 0)
            {
                Label startOfBlock = cg.DefineLabel();
                choiceVar = cg.GetLocalTmp(typeof(int));
                returnVar = cg.GetLocalTmp(typeof(bool));
                cg.EmitInt(0);
                returnVar.EmitSet(cg);
                cg.EmitInt(-1);
                choiceVar.EmitSet(cg);
                cg.Emit(OpCodes.Br, startOfBlock);

                int index = 0;
                foreach (YieldTarget yt in yieldTargets)
                {
                    cg.MarkLabel(yt.topBranchTarget);
                    cg.EmitInt(index++);
                    choiceVar.EmitSet(cg);
                    cg.Emit(OpCodes.Br, startOfBlock);
                }

                cg.MarkLabel(startOfBlock);
            }

            cg.PushTryBlock();
            cg.BeginExceptionBlock();

            if (yieldTargets.Count > 0)
            {
                int index = 0;
                endOfTry = cg.DefineLabel();
                foreach (YieldTarget yt in yieldTargets)
                {
                    choiceVar.EmitGet(cg);
                    cg.EmitInt(index++);
                    cg.Emit(OpCodes.Beq, endOfTry);
                }
            }

            body.Emit(cg);

            if (yieldTargets.Count > 0)
            {
                cg.MarkLabel(endOfTry);
            }

            cg.PopTargets();
            cg.PushFinallyBlock(returnVar);
            cg.BeginFinallyBlock();

            if (yieldTargets.Count > 0)
            {
                int index = 0;
                foreach (YieldTarget yt in yieldTargets)
                {
                    choiceVar.EmitGet(cg);
                    cg.EmitInt(index++);
                    cg.Emit(OpCodes.Beq, yt.tryBranchTarget);
                }
            }

            finallyStmt.Emit(cg);

            cg.EndExceptionBlock();
            cg.PopTargets();

            if (yieldTargets.Count > 0)
            {
                Label noReturn = cg.DefineLabel();
                returnVar.EmitGet(cg);
                cg.Emit(OpCodes.Brfalse_S, noReturn);
                cg.Emit(OpCodes.Ldc_I4_1);
                cg.EmitReturn();
                cg.MarkLabel(noReturn);
            }

            yieldTargets.Clear();
        }
Exemplo n.º 26
0
        protected Slot CreateEnvironment(CodeGen cg)
        {
            // Get the environment size
            int size = CalculateEnvironmentSize();

            // Create the array for the names
            Slot namesSlot = cg.GetLocalTmp(typeof(SymbolId[]));

            cg.EmitInt(size - tempsCount);
            cg.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(SymbolId));
            namesSlot.EmitSet(cg);

            // Find the right environment type
            ConstructorInfo    ctor;
            EnvironmentFactory esf;
            Type envType = GetEnvironmentType(size, cg, out ctor, out esf);

            // Emit the static link for the environment constructor
            cg.EmitStaticLinkOrNull();
            cg.EmitCallerContext();
            // Emit the names array for the environment constructor
            namesSlot.EmitGet(cg);
            cg.EmitNew(ctor);

            // Store the environment reference in the local
            Slot environmentSlot = cg.GetFrameSlot(envType);

            environmentSlot.EmitSet(cg);

            // Remember the environment factory for parent access
            environmentFactory = esf;

            // Create environment references
            environment = new Dictionary <Name, EnvironmentReference>();

            foreach (KeyValuePair <Name, Binding> kv in names)
            {
                if (!kv.Value.IsEnvironment)
                {
                    continue;
                }
                Name name = kv.Key;
                EnvironmentReference er = esf.MakeEnvironmentReference(name);
                Slot slot = er.CreateSlot(environmentSlot);
                Slot current;
                if (cg.Names.Slots.TryGetValue(name, out current))
                {
                    slot.EmitSet(cg, current);
                }
                else
                {
                    slot.EmitSetUninitialized(cg, name);
                }

                // Set the name into the array
                namesSlot.EmitGet(cg);
                cg.EmitInt(er.Index);
                cg.Emit(OpCodes.Ldelema, typeof(SymbolId));
                cg.EmitSymbolIdInt(name.GetString());
                cg.Emit(OpCodes.Call, typeof(SymbolId).GetConstructor(new Type[] { typeof(int) }));

                // The full slot goes to the codegen's namespace
                cg.Names.SetSlot(name, slot);
                // Environment reference goes to the environment
                environment[name] = er;
            }

            return(environmentSlot);
        }