Ejemplo n.º 1
0
        protected void CodeGen(ILGenerator il)
        {
            int n = 0, d = 0, c = 0;
            Stack <FuncCall> stack = null;
            FuncCall         call = null;

            for (int i = 0; ; i++)
            {
                Code op = this.code[i];

                if (CodeHelper.IsOp(op))
                {
                    if (this.emitChecks)
                    {
                        Generic.CheckedOp(il, (int)op);
                    }
                    else
                    {
                        Generic.Operation(il, (int)op);
                    }
                }
                else if (op == Code.Number) // ================================
                {
                    if (SupportLiterals)
                    {
                        Generic.LoadConst(il, this.numbers[n++]);
                    }
                    else
                    {
                        EmitLoadObj(il, this.data[d++]);
                    }
                }
                else if (op == Code.Argument) // ==============================
                {
                    EmitLoadArg(il, this.data[d++]);
                }
                else if (op == Code.Separator) // =============================
                {
                    // separator needed only for params calls:
                    Debug.Assert(call != null);
                    if (call.VarCount >= 0)
                    {
                        EmitSeparator(il, call);
                    }
                }
                else if (op == Code.Function) // ==============================
                {
                    EmitFunctionCall(il, call);

                    // parent call info:
                    if (stack == null || stack.Count == 0)
                    {
                        call = null;
                    }
                    else
                    {
                        call = stack.Pop();
                    }
                }
                else if (op == Code.BeginCall) // =============================
                {
                    if (call != null)
                    {
                        // allocate if needed:
                        if (stack == null)
                        {
                            stack = new Stack <FuncCall>();
                        }
                        stack.Push(call);
                    }

                    call = this.calls[c++];

                    // need for local to store params array:
                    if (call.VarCount > 0)
                    {
                        call.Local = il.DeclareLocal(
                            TypeHelper <T> .ArrayType);
                    }

                    if (call.TargetID >= 0)
                    {
                        EmitLoadObj(il, call.TargetID);
                    }

                    if (call.Current == 0 && call.VarCount > 0)
                    {
                        EmitParamArr(il, call);
                    }
                }
                else // =======================================================
                {
                    break;
                }
            }
        }