EmitLdarg() static private method

static private EmitLdarg ( ILGenerator il, short argNum ) : void
il ILGenerator
argNum short
return void
コード例 #1
0
        internal override void TranslateToIL(ILGenerator il, Type rtype)
        {
            //This assumes that rtype == Void.class.
            bool savedInsideProtectedRegion = compilerGlobals.InsideProtectedRegion;

            compilerGlobals.InsideProtectedRegion = true;
            compilerGlobals.BreakLabelStack.Push(compilerGlobals.BreakLabelStack.Peek(0));
            compilerGlobals.ContinueLabelStack.Push(compilerGlobals.ContinueLabelStack.Peek(0));
            il.BeginExceptionBlock();
            if (this.finally_block != null)
            {
                if (this.finallyHasControlFlowOutOfIt)
                {
                    il.BeginExceptionBlock();
                }
                if (this.handler != null)
                {
                    il.BeginExceptionBlock();
                }
            }
            this.body.TranslateToIL(il, Typeob.Void);
            if (this.tryEndContext != null)
            {
                this.tryEndContext.EmitLineInfo(il);
            }
            if (this.handler != null)
            {
                if (this.type == null)
                {
                    il.BeginCatchBlock(Typeob.Exception);
                    this.handler.context.EmitLineInfo(il);
                    this.EmitILToLoadEngine(il);
                    il.Emit(OpCodes.Call, CompilerGlobals.jScriptExceptionValueMethod);
                }
                else
                {
                    Type filterType = this.type.ToType();
                    if (Typeob.Exception.IsAssignableFrom(filterType))
                    {
                        il.BeginCatchBlock(filterType);
                        this.handler.context.EmitLineInfo(il);
                    }
                    else
                    {
                        il.BeginExceptFilterBlock();
                        this.handler.context.EmitLineInfo(il);
                        this.EmitILToLoadEngine(il);
                        il.Emit(OpCodes.Call, CompilerGlobals.jScriptExceptionValueMethod);
                        il.Emit(OpCodes.Isinst, filterType);
                        il.Emit(OpCodes.Ldnull);
                        il.Emit(OpCodes.Cgt_Un);
                        il.BeginCatchBlock(null);
                        this.EmitILToLoadEngine(il);
                        il.Emit(OpCodes.Call, CompilerGlobals.jScriptExceptionValueMethod);
                        Convert.Emit(this, il, Typeob.Object, filterType);
                    }
                }
                Object tok = this.field is JSVariableField ? ((JSVariableField)this.field).GetMetaData() : this.field;
                if (tok is LocalBuilder)
                {
                    il.Emit(OpCodes.Stloc, (LocalBuilder)tok);
                }
                else if (tok is FieldInfo)
                {
                    il.Emit(OpCodes.Stsfld, (FieldInfo)tok);
                }
                else
                {
                    Convert.EmitLdarg(il, (short)tok);
                }

                if (this.handler_scope != null)
                {
                    if (!this.handler_scope.isKnownAtCompileTime) //I.e. eval or nested func
                    {
                        this.EmitILToLoadEngine(il);
                        il.Emit(OpCodes.Ldstr, this.fieldName);
                        ConstantWrapper.TranslateToILInt(il, this.handler_scope.scopeId);
                        il.Emit(OpCodes.Call, Typeob.Try.GetMethod("PushHandlerScope"));
                        Globals.ScopeStack.Push(this.handler_scope);
                        il.BeginExceptionBlock();
                    }
                    il.BeginScope(); // so that we can emit local scoped information for the handler variable
                    if (this.context.document.debugOn)
                    {
                        this.handler_scope.EmitLocalInfoForFields(il);
                    }
                }
                this.handler.TranslateToIL(il, Typeob.Void);
                if (this.handler_scope != null)
                {
                    il.EndScope();
                    if (!this.handler_scope.isKnownAtCompileTime) //I.e. eval or nested func
                    {
                        il.BeginFinallyBlock();
                        this.EmitILToLoadEngine(il);
                        il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
                        il.Emit(OpCodes.Pop);
                        Globals.ScopeStack.Pop();
                        il.EndExceptionBlock();
                    }
                }
                il.EndExceptionBlock();
            }
            if (this.finally_block != null)
            {
                bool savedInsideFinally   = compilerGlobals.InsideFinally;
                int  savedFinallyStackTop = compilerGlobals.FinallyStackTop;
                compilerGlobals.InsideFinally   = true;
                compilerGlobals.FinallyStackTop = compilerGlobals.BreakLabelStack.Size();
                il.BeginFinallyBlock();
                this.finally_block.TranslateToIL(il, Typeob.Void);
                il.EndExceptionBlock();
                compilerGlobals.InsideFinally   = savedInsideFinally;
                compilerGlobals.FinallyStackTop = savedFinallyStackTop;
                if (this.finallyHasControlFlowOutOfIt)
                {
                    il.BeginCatchBlock(Typeob.BreakOutOfFinally);
                    il.Emit(OpCodes.Ldfld, Typeob.BreakOutOfFinally.GetField("target"));
                    // don't need to go to 0 in the loop because 0 is the outmost block (i.e. function body)
                    // and that would generate a JIT assert because the jump is sometimes outside the function
                    for (int i = compilerGlobals.BreakLabelStack.Size() - 1, n = i; i > 0; i--)
                    {
                        il.Emit(OpCodes.Dup);
                        ConstantWrapper.TranslateToILInt(il, i);
                        Label lab = il.DefineLabel();
                        il.Emit(OpCodes.Blt_S, lab);
                        il.Emit(OpCodes.Pop);
                        if (savedInsideFinally && i < savedFinallyStackTop)
                        {
                            il.Emit(OpCodes.Rethrow);
                        }
                        else
                        {
                            il.Emit(OpCodes.Leave, (Label)compilerGlobals.BreakLabelStack.Peek(n - i));
                        }
                        il.MarkLabel(lab);
                    }
                    il.Emit(OpCodes.Pop);
                    il.BeginCatchBlock(Typeob.ContinueOutOfFinally);
                    il.Emit(OpCodes.Ldfld, Typeob.ContinueOutOfFinally.GetField("target"));
                    // don't need to go to 0 in the loop because 0 is the outmost block (i.e. function body)
                    for (int i = compilerGlobals.ContinueLabelStack.Size() - 1, n = i; i > 0; i--)
                    {
                        il.Emit(OpCodes.Dup);
                        ConstantWrapper.TranslateToILInt(il, i);
                        Label lab = il.DefineLabel();
                        il.Emit(OpCodes.Blt_S, lab);
                        il.Emit(OpCodes.Pop);
                        if (savedInsideFinally && i < savedFinallyStackTop)
                        {
                            il.Emit(OpCodes.Rethrow);
                        }
                        else
                        {
                            il.Emit(OpCodes.Leave, (Label)compilerGlobals.ContinueLabelStack.Peek(n - i));
                        }
                        il.MarkLabel(lab);
                    }
                    il.Emit(OpCodes.Pop);
                    ScriptObject scope = Globals.ScopeStack.Peek();
                    while (scope != null && !(scope is FunctionScope))
                    {
                        scope = scope.GetParent();
                    }
                    if (scope != null && !savedInsideFinally)
                    {
                        il.BeginCatchBlock(Typeob.ReturnOutOfFinally);
                        il.Emit(OpCodes.Pop);
                        il.Emit(OpCodes.Leave, ((FunctionScope)scope).owner.returnLabel);
                    }
                    il.EndExceptionBlock();
                }
            }
            compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
            compilerGlobals.BreakLabelStack.Pop();
            compilerGlobals.ContinueLabelStack.Pop();
        }