BeginExceptFilterBlock() public method

public BeginExceptFilterBlock ( ) : void
return void
Example #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(typeof(Exception));
       this.handler.context.EmitLineInfo(il);
       this.EmitILToLoadEngine(il);
       il.Emit(OpCodes.Call, CompilerGlobals.jScriptExceptionValueMethod);
     }else{
       Type filterType = this.type.ToType();
       if (typeof(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, typeof(Try).GetMethod("PushHandlerScope"));
         Globals.ScopeStack.Push(this.handler_scope);
       }
       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
         this.EmitILToLoadEngine(il);
         il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
         il.Emit(OpCodes.Pop);
         Globals.ScopeStack.Pop();
       }
     }
     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(typeof(BreakOutOfFinally));
       il.Emit(OpCodes.Ldfld, typeof(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(typeof(ContinueOutOfFinally));
       il.Emit(OpCodes.Ldfld, typeof(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(typeof(ReturnOutOfFinally));
         il.Emit(OpCodes.Pop);
         il.Emit(OpCodes.Leave, ((FunctionScope)scope).owner.returnLabel);
       }
       il.EndExceptionBlock();
     }
   }
   compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
   compilerGlobals.BreakLabelStack.Pop();
   compilerGlobals.ContinueLabelStack.Pop();
 }
Example #2
0
		/// <summary>
		/// Try to emit something like that:
		///
		/// .method public static bool TestFilter (bool execute_handler)
		/// {
		/// 	.locals init(bool)
		/// 	try {
		/// 		newobj  instance void [mscorlib]System.Exception::.ctor()
		/// 		throw
		/// 	} filter {
		/// 		pop
		/// 		ldarg.0
		/// 		endfilter
		/// 	} {
		/// 		ldc.i4.1
		/// 		stloc.0
		/// 		leave quit
		/// 	}
		/// 	ldc.i4.0
		/// 	stloc.0
		/// quit:
		/// 	ldloc.0
		/// 	ret
		/// }
		///
		/// It should return true if the handler has been executed
		/// Otherwise, the exception should not be catched
		/// </summary>
		void DefineTestFilterMethod ()
		{
			MethodBuilder mb = tb.DefineMethod("TestFilter",
				MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new Type [] { typeof (bool) });

			ConstructorInfo exCtor = typeof (Exception).GetConstructor (new Type [0]);

			il_gen = mb.GetILGenerator ();
			il_gen.DeclareLocal (typeof (bool));
			Label quit = il_gen.DefineLabel ();
			il_gen.BeginExceptionBlock ();
			il_gen.Emit (OpCodes.Newobj, exCtor);
			il_gen.Emit (OpCodes.Throw);
			il_gen.BeginExceptFilterBlock ();
			il_gen.Emit (OpCodes.Pop);
			il_gen.Emit (OpCodes.Ldarg_0);
			il_gen.BeginCatchBlock (null);
			il_gen.Emit (OpCodes.Ldc_I4_1);
			il_gen.Emit (OpCodes.Stloc_0);
			il_gen.Emit (OpCodes.Leave, quit);
			il_gen.EndExceptionBlock ();
			il_gen.Emit (OpCodes.Ldc_I4_0);
			il_gen.Emit (OpCodes.Stloc_0);
			il_gen.MarkLabel (quit);
			il_gen.Emit (OpCodes.Ldloc_0);
			il_gen.Emit (OpCodes.Ret);
		}
Example #3
0
 ///<inheritdoc/>
 public override void BeginFilterBlock()
 {
     Generator.BeginExceptFilterBlock();
 }