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(); }