示例#1
0
        public override void EmitGet(CodeGen cg)
        {
            Contract.RequiresNotNull(cg, "cg");

            _instance.EmitGet(cg);
            cg.Emit(OpCodes.Ldfld, _field);
        }
示例#2
0
 public override void EmitGet(CodeGen cg)
 {
     // RuntimeHelpers.LookupName(context, name)
     _frame.EmitGet(cg);
     cg.EmitSymbolId(_name);
     cg.EmitCall(typeof(RuntimeHelpers), "LookupName");
 }
示例#3
0
        public override void EmitGet(CodeGen cg)
        {
            Contract.RequiresNotNull(cg, "cg");

            _instance.EmitGet(cg);
            cg.EmitInt(_index);
            if (Type == typeof(object))
            {
                cg.Emit(OpCodes.Ldelem_Ref);
            }
            else
            {
                cg.Emit(OpCodes.Ldelem, Type);
            }
        }
示例#4
0
        /// <summary>
        /// Generates stub to receive the CLR call and then call the dynamic language code.
        /// </summary>
        public static void  EmitClrCallStub(CodeGen cg, Slot callTarget, int firstArg, CallType functionAttributes) {
            List<ReturnFixer> fixers = new List<ReturnFixer>(0);
            IList<Slot> args = cg.ArgumentSlots;
            int nargs = args.Count - firstArg;
            
            CallAction action;
            if ((functionAttributes & CallType.ArgumentList) != 0) {
                ArgumentInfo[] infos = CompilerHelpers.MakeRepeatedArray(ArgumentInfo.Simple, nargs);
                infos[nargs - 1] = new ArgumentInfo(ArgumentKind.List);

                action = CallAction.Make(new CallSignature(infos));
            } else {
                action = CallAction.Make(nargs);
            }

            bool fast;
            Slot site = cg.CreateDynamicSite(action, 
                CompilerHelpers.MakeRepeatedArray(typeof(object), nargs + 2), 
                out fast);

            site.EmitGet(cg);
            if (!fast) cg.EmitCodeContext();

            if (DynamicSiteHelpers.IsBigTarget(site.Type)) {
                cg.EmitTuple(site.Type.GetGenericArguments()[0], args.Count + 1, delegate(int index) {
                    if (index == 0) {
                        callTarget.EmitGet(cg);
                    } else {
                        ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[index - 1]);
                        if (rf != null) fixers.Add(rf);
                    }
                });
            } else {
                callTarget.EmitGet(cg);

                for (int i = firstArg; i < args.Count; i++) {
                    ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[i]);
                    if (rf != null) fixers.Add(rf);
                }
            }

            cg.EmitCall(site.Type, "Invoke"); 

            foreach (ReturnFixer rf in fixers) {
                rf.FixReturn(cg);
            }
            cg.EmitReturnFromObject();
        }
示例#5
0
 public void FixReturn(CodeGen cg)
 {
     _argSlot.EmitGet(cg);
     _refSlot.EmitGet(cg);
     cg.EmitCall(typeof(BinderOps).GetMethod("GetBox").MakeGenericMethod(_argSlot.Type.GetElementType()));
     cg.EmitStoreValueIndirect(_argSlot.Type.GetElementType());
 }
示例#6
0
文件: Slot.cs 项目: clorton/IDM-CMS
        // Must override at least one of these two methods or get infinite loop
        public virtual void EmitSet(CodeGen cg, Slot val)
        {
            Contract.RequiresNotNull(val, "val");
            Contract.RequiresNotNull(cg, "cg");

            val.EmitGet(cg);
            EmitSet(cg);
        }
示例#7
0
        public override void EmitGet(CodeGen cg)
        {
            Contract.RequiresNotNull(cg, "cg");

            _param.EmitGet(cg);
            cg.EmitInt(_index);
            cg.Emit(OpCodes.Ldelem_Ref);
        }
示例#8
0
        public override void EmitSet(CodeGen cg, Slot val)
        {
            Contract.RequiresNotNull(cg, "cg");
            Contract.RequiresNotNull(val, "val");

            _instance.EmitGet(cg);
            val.EmitGet(cg);
            cg.Emit(OpCodes.Stfld, _field);
        }
示例#9
0
        public override void EmitSet(CodeGen cg, Slot val)
        {
            Contract.RequiresNotNull(cg, "cg");
            Contract.RequiresNotNull(val, "val");

            _instance.EmitGet(cg);
            cg.EmitInt(_index);
            val.EmitGet(cg);
            cg.EmitStoreElement(Type);
        }
        private static void EmitNestedTupleInit(CodeGen cg, Type storageType)
        {
            if (Tuple.GetSize(storageType) > Tuple.MaxSize)
            {
                Slot tmp = cg.GetLocalTmp(storageType);
                tmp.EmitSet(cg);

                Type[] nestedTuples = storageType.GetGenericArguments();
                for (int i = 0; i < nestedTuples.Length; i++)
                {
                    Type t = nestedTuples[i];
                    if (t.IsSubclassOf(typeof(Tuple)))
                    {
                        tmp.EmitGet(cg);

                        cg.EmitNew(t.GetConstructor(ArrayUtils.EmptyTypes));
                        cg.EmitPropertySet(storageType, String.Format("Item{0:D3}", i));

                        tmp.EmitGet(cg);
                        cg.EmitPropertyGet(storageType, String.Format("Item{0:D3}", i));

                        EmitNestedTupleInit(cg, t);
                    }
                }

                cg.FreeLocalTmp(tmp);
            }
            else
            {
                int capacity = 0;
                foreach (Type t in storageType.GetGenericArguments())
                {
                    if (t == typeof(None))
                    {
                        break;
                    }
                    capacity++;
                }
                cg.EmitInt(capacity);
                cg.EmitCall(typeof(RuntimeHelpers), "UninitializeEnvironmentTuple");
            }
        }
示例#11
0
        public override void EmitSet(CodeGen cg, Slot val)
        {
            Contract.RequiresNotNull(cg, "cg");
            Contract.RequiresNotNull(val, "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);
        }
示例#12
0
 public static ReturnFixer EmitArgument(CodeGen cg, Slot argSlot)
 {
     argSlot.EmitGet(cg);
     if (argSlot.Type.IsByRef) {
         Type elementType = argSlot.Type.GetElementType();
         Type concreteType = typeof(StrongBox<>).MakeGenericType(elementType);
         Slot refSlot = cg.GetLocalTmp(concreteType);
         cg.EmitLoadValueIndirect(elementType);
         cg.EmitNew(concreteType, new Type[] { elementType });
         refSlot.EmitSet(cg);
         refSlot.EmitGet(cg);
         return new ReturnFixer(refSlot, argSlot);
     } else {
         cg.EmitBoxing(argSlot.Type);
         return null;
     }
 }
示例#13
0
        public override void EmitGet(CodeGen cg)
        {
            Contract.RequiresNotNull(cg, "cg");

            _instance.EmitGet(cg);
            if (!_type.IsAssignableFrom(_instance.Type))
            {
                if (_type.IsValueType)
                {
                    Debug.Assert(_instance.Type == typeof(object));
                    cg.Emit(OpCodes.Unbox_Any, _type);
                }
                else
                {
                    cg.Emit(OpCodes.Castclass, _type);
                }
            }
        }
示例#14
0
        private CodeGen MakeRawKeysMethod(LanguageInfo li, Dictionary <SymbolId, Slot> fields)
        {
            Slot    rawKeysCache = li.TypeGen.AddStaticField(typeof(SymbolId[]), "ExtraKeysCache");
            CodeGen init         = li.TypeGen.TypeInitializer;

            init.EmitInt(0);
            init.Emit(OpCodes.Newarr, typeof(SymbolId));

            rawKeysCache.EmitSet(init);

            CodeGen cg = li.TypeGen.DefineMethodOverride(typeof(CustomSymbolDictionary).GetMethod("GetExtraKeys", BindingFlags.Public | BindingFlags.Instance));

            rawKeysCache.EmitGet(cg);
            cg.EmitReturn();
            cg.Finish();

            return(cg);
        }
示例#15
0
 public static ReturnFixer EmitArgument(CodeGen cg, Slot argSlot)
 {
     argSlot.EmitGet(cg);
     if (argSlot.Type.IsByRef)
     {
         Type elementType  = argSlot.Type.GetElementType();
         Type concreteType = typeof(StrongBox <>).MakeGenericType(elementType);
         Slot refSlot      = cg.GetLocalTmp(concreteType);
         cg.EmitLoadValueIndirect(elementType);
         cg.EmitNew(concreteType, new Type[] { elementType });
         refSlot.EmitSet(cg);
         refSlot.EmitGet(cg);
         return(new ReturnFixer(refSlot, argSlot));
     }
     else
     {
         cg.EmitBoxing(argSlot.Type);
         return(null);
     }
 }
        public override void EmitNewEnvironment(CodeGen cg)
        {
            ConstructorInfo ctor = EnvironmentType.GetConstructor(
                ScriptDomainManager.Options.DebugMode ?
                new Type[] {
                StorageType,
                typeof(SymbolId[]),
            } :
                new Type[] {
                StorageType,
            });

            // emit: dict.Tuple[.Item000...].Item000 = dict, and then leave dict on the stack

            cg.EmitNew(ctor);
            cg.Emit(OpCodes.Dup);

            Slot tmp = cg.GetLocalTmp(EnvironmentType);

            tmp.EmitSet(cg);

            cg.EmitPropertyGet(EnvironmentType, "TupleData");

            PropertyInfo last = null;

            foreach (PropertyInfo pi in Tuple.GetAccessPath(StorageType, 0))
            {
                if (last != null)
                {
                    cg.EmitPropertyGet(last);
                }
                last = pi;
            }

            tmp.EmitGet(cg);
            cg.EmitPropertySet(last);

            cg.FreeLocalTmp(tmp);
        }
        public override void EmitNewEnvironment(CodeGen cg)
        {
            ConstructorInfo ctor = EnvironmentType.GetConstructor(new Type[] { StorageType });

            // emit: dict.Tuple[.Item000...].Item000 = dict, and then leave dict on the stack

            cg.EmitNew(ctor);
            cg.Emit(OpCodes.Dup);

            Slot tmp = cg.GetLocalTmp(EnvironmentType);

            tmp.EmitSet(cg);

            cg.EmitPropertyGet(EnvironmentType, "Data");

            var fld = StorageType.GetField("$parent$");

            //cg.EmitFieldGet(fld);

            tmp.EmitGet(cg);
            cg.EmitFieldSet(fld);

            cg.FreeLocalTmp(tmp);
        }
示例#18
0
 public override void EmitGet(CodeGen cg)
 {
     _storage.EmitGet(cg);
 }
示例#19
0
        // Must override at least one of these two methods or get infinite loop
        public virtual void EmitSet(CodeGen cg, Slot val)
        {
            Contract.RequiresNotNull(val, "val");
            Contract.RequiresNotNull(cg, "cg");

            val.EmitGet(cg);
            EmitSet(cg);
        }
示例#20
0
        /// <summary>
        /// Generates stub to receive the CLR call and then call the dynamic language code.
        /// </summary>
        public static void  EmitClrCallStub(CodeGen cg, Slot callTarget, int firstArg, CallType functionAttributes)
        {
            List <ReturnFixer> fixers = new List <ReturnFixer>(0);
            IList <Slot>       args   = cg.ArgumentSlots;
            int nargs = args.Count - firstArg;

            CallAction action;

            if ((functionAttributes & CallType.ArgumentList) != 0)
            {
                ArgumentInfo[] infos = CompilerHelpers.MakeRepeatedArray(ArgumentInfo.Simple, nargs);
                infos[nargs - 1] = new ArgumentInfo(ArgumentKind.List);

                action = CallAction.Make(new CallSignature(infos));
            }
            else
            {
                action = CallAction.Make(nargs);
            }

            bool fast;
            Slot site = cg.CreateDynamicSite(action,
                                             CompilerHelpers.MakeRepeatedArray(typeof(object), nargs + 2),
                                             out fast);

            site.EmitGet(cg);
            if (!fast)
            {
                cg.EmitCodeContext();
            }

            if (DynamicSiteHelpers.IsBigTarget(site.Type))
            {
                cg.EmitTuple(site.Type.GetGenericArguments()[0], args.Count + 1, delegate(int index) {
                    if (index == 0)
                    {
                        callTarget.EmitGet(cg);
                    }
                    else
                    {
                        ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[index - 1]);
                        if (rf != null)
                        {
                            fixers.Add(rf);
                        }
                    }
                });
            }
            else
            {
                callTarget.EmitGet(cg);

                for (int i = firstArg; i < args.Count; i++)
                {
                    ReturnFixer rf = ReturnFixer.EmitArgument(cg, args[i]);
                    if (rf != null)
                    {
                        fixers.Add(rf);
                    }
                }
            }

            cg.EmitCall(site.Type, "Invoke");

            foreach (ReturnFixer rf in fixers)
            {
                rf.FixReturn(cg);
            }
            cg.EmitReturnFromObject();
        }
示例#21
0
        public override void EmitSet(CodeGen cg, Slot val)
        {
            Contract.RequiresNotNull(cg, "cg");
            Contract.RequiresNotNull(val, "val");

            _instance.EmitGet(cg);
            cg.EmitInt(_index);
            val.EmitGet(cg);
            cg.EmitStoreElement(Type);
        }
示例#22
0
        public override void EmitSet(CodeGen cg, Slot val)
        {
            Contract.RequiresNotNull(cg, "cg");
            Contract.RequiresNotNull(val, "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);
        }
示例#23
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     _wrapper.EmitGet(cg);
     val.EmitGet(cg);
     cg.EmitPropertySet(typeof(ModuleGlobalWrapper), "CurrentValue");
 }
示例#24
0
 public override void EmitSet(CodeGen cg, Slot val)
 {
     _wrapper.EmitGet(cg);
     val.EmitGet(cg);
     cg.EmitPropertySet(typeof(ModuleGlobalWrapper), "CurrentValue");
 }
示例#25
0
        /// <summary>
        /// If the finally statement contains break, continue, return or yield, we need to
        /// handle the control flow statement after we exit out of finally via OpCodes.Endfinally.
        /// </summary>
        private static void EmitFinallyFlowControl(CodeGen cg, TryFlowResult flow, Slot flag)
        {
            if (flow.Return || flow.Yield) {
                Debug.Assert(flag != null);

                Label noReturn = cg.DefineLabel();

                flag.EmitGet(cg);
                cg.EmitInt(CodeGen.BranchForReturn);
                cg.Emit(OpCodes.Bne_Un, noReturn);

                if (cg.IsGenerator) {
                    // return true from the generator method
                    cg.Emit(OpCodes.Ldc_I4_1);
                    cg.EmitReturn();
                } else if (flow.Any) {
                    // return the actual value
                    cg.EmitReturnValue();
                    cg.EmitReturn();
                }
                cg.MarkLabel(noReturn);
            }

            // Only emit break handling if it is actually needed
            if (flow.Break) {
                Debug.Assert(flag != null);

                Label noReturn = cg.DefineLabel();
                flag.EmitGet(cg);
                cg.EmitInt(CodeGen.BranchForBreak);
                cg.Emit(OpCodes.Bne_Un, noReturn);
                cg.EmitBreak();
                cg.MarkLabel(noReturn);
            }

            // Only emit continue handling if it if actually needed
            if (flow.Continue) {
                Debug.Assert(flag != null);

                Label noReturn = cg.DefineLabel();
                flag.EmitGet(cg);
                cg.EmitInt(CodeGen.BranchForContinue);
                cg.Emit(OpCodes.Bne_Un, noReturn);
                cg.EmitContinue();
                cg.MarkLabel(noReturn);
            }
        }