Ejemplo n.º 1
0
        private void UpdateState(OpCode instr, Local param, TransitionWrapper transitions)
        {
            UpdateStackAndInstrStream(instr, transitions);

            IL.Emit(instr, param);
        }
Ejemplo n.º 2
0
        /// <summary cref="M:Sigil.Emit`1.DeclareLocal(System.Type, Sigil.Local, System.String, System.Boolean)" />
        public EmitShorthand <DelegateType> DeclareLocal(Type type, out Local local, string name = null, bool initializeReused = true)
        {
            local = DeclareLocal(type, name, initializeReused);

            return(this);
        }
Ejemplo n.º 3
0
        /// <summary cref="M:Sigil.Emit`1.LoadLocalAddress(Sigil.Local)" />
        public EmitShorthand <DelegateType> Ldloca(Local local)
        {
            InnerEmit.LoadLocalAddress(local);

            return(this);
        }
Ejemplo n.º 4
0
        /// <summary cref="M:Sigil.Emit`1.StoreLocal(Sigil.Local)" />
        public EmitShorthand <DelegateType> Stloc(Local local)
        {
            InnerEmit.StoreLocal(local);

            return(this);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// <para>Declare a new local of the given type in the current method.</para>
        /// <para>
        /// Name is optional, and only provided for debugging purposes.  It has no
        /// effect on emitted IL.
        /// </para>
        /// <para>
        /// Be aware that each local takes some space on the stack, inefficient use of locals
        /// could lead to StackOverflowExceptions at runtime.
        /// </para>
        /// <para>
        /// Jil will reuse local index on the stack if the corresponding Local instance has been disposed.
        /// By default Jil will set reused locals to their default value, you can change this behavior
        /// by passing initializeReused = false.
        /// </para>
        /// </summary>
        public Local DeclareLocal(Type type, string name = null, bool initializeReused = true)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            name = name ?? AutoNamer.Next(this, "_local", Locals.Names, Labels.Names);

            if (CurrentLocals.ContainsKey(name))
            {
                throw new InvalidOperationException("Local with name '" + name + "' already exists");
            }

            var existingLocal = FreedLocals.FirstOrDefault(l => l.LocalType == type);

            DeclareLocallDelegate local;
            ushort localIndex;

            if (existingLocal == null)
            {
                local = IL.DeclareLocal(type);

                localIndex = NextLocalIndex;
                NextLocalIndex++;
            }
            else
            {
                local      = existingLocal.LocalDel;
                localIndex = existingLocal.Index;

                FreedLocals.Remove(existingLocal);
            }

            var ret = new Local(this, localIndex, type, local, name, LocalReleased, IL.Index);

            UnusedLocals.Add(ret);

            AllLocals.Add(ret);

            CurrentLocals[ret.Name] = ret;

            // we need to initialize this local to it's default value, because otherwise
            //   it might be read from to get some non-sense
            if (existingLocal != null && initializeReused)
            {
                if (!TypeHelpers.IsValueType(type))
                {
                    // reference types all get nulled
                    LoadNull();
                    StoreLocal(ret);
                }
                else
                {
                    // handle known primitives better
                    //   so as not to confuse the JIT
                    var defaultLoaded = false;

                    if (type == typeof(bool))
                    {
                        LoadConstant(default(bool));
                        defaultLoaded = true;
                    }

                    if (type == typeof(byte))
                    {
                        LoadConstant(default(byte));
                        defaultLoaded = true;
                    }

                    if (type == typeof(sbyte))
                    {
                        LoadConstant(default(sbyte));
                        defaultLoaded = true;
                    }

                    if (type == typeof(short))
                    {
                        LoadConstant(default(short));
                        defaultLoaded = true;
                    }

                    if (type == typeof(ushort))
                    {
                        LoadConstant(default(ushort));
                        defaultLoaded = true;
                    }

                    if (type == typeof(int))
                    {
                        LoadConstant(default(int));
                        defaultLoaded = true;
                    }

                    if (type == typeof(uint))
                    {
                        LoadConstant(default(uint));
                        defaultLoaded = true;
                    }

                    if (type == typeof(long))
                    {
                        LoadConstant(default(long));
                        defaultLoaded = true;
                    }

                    if (type == typeof(ulong))
                    {
                        LoadConstant(default(ulong));
                        defaultLoaded = true;
                    }

                    if (type == typeof(float))
                    {
                        LoadConstant(default(float));
                        defaultLoaded = true;
                    }

                    if (type == typeof(double))
                    {
                        LoadConstant(default(double));
                        defaultLoaded = true;
                    }

                    if (defaultLoaded)
                    {
                        StoreLocal(ret);
                    }
                    else
                    {
                        // if it's use defined though, we've got little choice
                        LoadLocalAddress(ret);
                        InitializeObject(type);
                    }
                }
            }

            return(ret);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// <para>Declare a new local of the given type in the current method.</para>
 /// <para>
 /// Name is optional, and only provided for debugging purposes.  It has no
 /// effect on emitted IL.
 /// </para>
 /// <para>
 /// Be aware that each local takes some space on the stack, inefficient use of locals
 /// could lead to StackOverflowExceptions at runtime.
 /// </para>
 /// <para>
 /// Jil will reuse local index on the stack if the corresponding Local instance has been disposed.
 /// By default Jil will set reused locals to their default value, you can change this behavior
 /// by passing initializeReused = false.
 /// </para>
 /// </summary>
 public Emit <DelegateType> DeclareLocal <Type>(out Local local, string name = null, bool initializeReused = true)
 {
     return(DeclareLocal(typeof(Type), out local, name, initializeReused));
 }