public DeclareLocallDelegate DeclareLocal(Type type)
        {
            ILGenerator  forIl = null;
            LocalBuilder l     = null;

            DeclareLocallDelegate ret =
                il =>
            {
                if (forIl != null && il != forIl)
                {
                    l = null;
                }

                if (l != null)
                {
                    return(l);
                }

                forIl = il;
                l     = forIl.DeclareLocal(type);

                return(l);
            };

            InstructionSizes.Add(() => InstructionSize.DeclareLocal());

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    ret(il);
                }
            }
                );

            TraversableBuffer.Add(new BufferedILInstruction {
                DeclaresLocal = true
            });

            Operations.Add(null);

            return(ret);
        }
        public void Insert(int ix, OpCode op)
        {
            if (ix < 0 || ix > Buffer.Count)
            {
                throw new ArgumentOutOfRangeException("ix", "Expected value between 0 and " + Buffer.Count);
            }

            LengthCache.Clear();

            InstructionSizes.Insert(ix, () => InstructionSize.Get(op));

            Buffer.Insert(
                ix,
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.Emit(op);
                }

                if (ExtensionMethods.IsPrefix(op))
                {
                    log.Append(op.ToString());
                }
                else
                {
                    log.AppendLine(op.ToString());
                }
            }
                );

            TraversableBuffer.Insert(
                ix,
                new BufferedILInstruction
            {
                IsInstruction = op
            }
                );

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = new object[0]
            });
        }
        public void EndFinallyBlock()
        {
            InstructionSizes.Add(() => InstructionSize.EndFinallyBlock());

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                log.AppendLine("--EndFinallyBlock--");
            }
                );

            TraversableBuffer.Add(new BufferedILInstruction {
                EndsFinallyBlock = true
            });

            Operations.Add(null);
        }
        public void Emit(OpCode op, MethodInfo method, IEnumerable <Type> parameterTypes)
        {
            InstructionSizes.Add(() => InstructionSize.Get(op));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.Emit(op, method);
                }

                var mtdString = method is MethodBuilder ? method.Name : method.ToString();

                log.AppendLine(op + " " + mtdString);
            }
                );

            var parameters = new LinqList <Type>(parameterTypes);

            if (!method.IsStatic)
            {
                var declaring = method.DeclaringType;

                if (TypeHelpers.IsValueType(declaring))
                {
                    declaring = declaring.MakePointerType();
                }

                parameters.Insert(0, declaring);
            }

            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = op, MethodReturnType = method.ReturnType, MethodParameterTypes = parameters
            });

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = new object[] { method }
            });
        }
        public void Emit(OpCode op, ConstructorInfo cons, IEnumerable <Type> parameterTypes)
        {
            InstructionSizes.Add(() => InstructionSize.Get(op));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.Emit(op, cons);
                }

                var mtdString = cons is ConstructorBuilder ? cons.Name : cons.ToString();

                log.AppendLine(op + " " + mtdString);
            }
                );

            var parameters = new LinqList <Type>(parameterTypes);
            var declaring  = cons.DeclaringType;

            if (TypeHelpers.IsValueType(declaring))
            {
                declaring = declaring.MakePointerType();
            }

            parameters.Insert(0, declaring);


            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = op, MethodReturnType = typeof(void), MethodParameterTypes = parameters
            });

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = new object[] { cons }
            });
        }
        public void EmitCalli(CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] arglist)
        {
            InstructionSizes.Add(() => InstructionSize.Get(OpCodes.Calli));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.EmitCalli(OpCodes.Calli, callingConvention, returnType, parameterTypes, arglist);
                }

                log.AppendLine(OpCodes.Calli + " " + callingConvention + " " + returnType + " " + Join(" ", (IEnumerable <Type>)parameterTypes) + " __arglist(" + Join(", ", arglist) + ")");
            }
                );

            var ps = new LinqList <Type>(parameterTypes);

            ps.AddRange(arglist);

            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = OpCodes.Calli, MethodReturnType = returnType, MethodParameterTypes = ps
            });

            var paras = new List <object>()
            {
                callingConvention, returnType
            };

            paras.AddRange(parameterTypes);
            paras.AddRange(arglist);

            Operations.Add(new Operation <DelegateType> {
                OpCode = OpCodes.Calli, Parameters = paras.ToArray()
            });
        }
        public void Emit(OpCode op, Sigil.Label[] labels, out UpdateOpCodeDelegate update)
        {
            var localOp = op;

            update =
                newOpcode =>
            {
                LengthCache.Clear();

                localOp = newOpcode;
            };

            InstructionSizes.Add(() => InstructionSize.Get(localOp, labels));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    var ls = LinqAlternative.Select(labels, l => l.LabelDel(il)).ToArray();
                    il.Emit(localOp, ls);
                }

                log.AppendLine(localOp + " " + Join(", ", ((LinqArray <Label>)labels).AsEnumerable()));
            }
                );

            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = op
            });

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = labels
            });
        }
        public void Emit(OpCode op, Sigil.Label label, out UpdateOpCodeDelegate update)
        {
            var localOp = op;

            update =
                newOpcode =>
            {
                LengthCache.Clear();

                localOp = newOpcode;
            };

            InstructionSizes.Add(() => InstructionSize.Get(localOp));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    var l = label.LabelDel(il);
                    il.Emit(localOp, l);
                }

                log.AppendLine(localOp + " " + label);
            }
                );

            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = op
            });

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = new object[] { label }
            });
        }
        public void BeginFinallyBlock()
        {
            InstructionSizes.Add(() => InstructionSize.BeginFinallyBlock());

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.BeginFinallyBlock();
                }

                log.AppendLine("--BeginFinallyBlock--");
            }
                );

            TraversableBuffer.Add(new BufferedILInstruction {
                StartsFinallyBlock = true
            });

            Operations.Add(null);
        }
        public void BeginCatchBlock(Type exception)
        {
            InstructionSizes.Add(() => InstructionSize.BeginCatchBlock());

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.BeginCatchBlock(exception);
                }

                log.AppendLine("--BeginCatchBlock(" + exception + ")--");
            }
                );

            TraversableBuffer.Add(new BufferedILInstruction {
                StartsCatchBlock = true
            });

            Operations.Add(null);
        }