private void CopyTryCatch(ILGenerator Gen, int i, MethodBody Body, List<int> ExceptionTrinkets) { // Quick check to see if we want to walk through the list if (!ExceptionTrinkets.Contains(i)) return; foreach (ExceptionHandlingClause Clause in Body.ExceptionHandlingClauses) { if (Clause.Flags != ExceptionHandlingClauseOptions.Clause && Clause.Flags != ExceptionHandlingClauseOptions.Finally) continue; // Look for an ending of an exception block first! if (Clause.HandlerOffset + Clause.HandlerLength == i) Gen.EndExceptionBlock(); // If this marks the beginning of a try block, emit that if (Clause.TryOffset == i) Gen.BeginExceptionBlock(); // Also check for the beginning of a catch block if (Clause.HandlerOffset == i && Clause.Flags == ExceptionHandlingClauseOptions.Clause) Gen.BeginCatchBlock(Clause.CatchType); // Lastly, check for a finally block if (Clause.HandlerOffset == i && Clause.Flags == ExceptionHandlingClauseOptions.Finally) Gen.BeginFinallyBlock(); } }
public void Weave(ILGenerator ilGenerator) { var typeofException = typeof(Exception); LocalBuilder exceptionLocalBuilder = null; var typeofFlowBehavior = typeof(FlowBehavior); LocalBuilder flowBehavoiurLocalBuilder = null; var afterRethrowLabel = ilGenerator.DefineLabel(); var throwFlowBehaviorLabel = ilGenerator.DefineLabel(); var rethrowFlowBehaviorLabel = ilGenerator.DefineLabel(); var argsImplLocalBuilder = localBuilderRepository.Get(aspectArgumentType); var jumpTable = new[] { throwFlowBehaviorLabel, rethrowFlowBehaviorLabel }; var setExceptionMethodInfo = aspectArgumentType.GetProperty("Exception").GetSetMethod(); var flowBehaviorMethodInfo = aspectArgumentType.GetProperty("FlowBehavior").GetGetMethod(); exceptionLocalBuilder = localBuilderRepository.GetOrDeclare(typeofException, () => { return ilGenerator.DeclareLocal(typeofException); }); flowBehavoiurLocalBuilder = localBuilderRepository.GetOrDeclare(typeofFlowBehavior, () => { return ilGenerator.DeclareLocal(typeofFlowBehavior); }); ilGenerator.BeginCatchBlock(typeofException); ilGenerator.EmitStoreLocal(exceptionLocalBuilder); ilGenerator.EmitLoadLocal(argsImplLocalBuilder); ilGenerator.EmitLoadLocal(exceptionLocalBuilder); ilGenerator.Emit(OpCodes.Callvirt, setExceptionMethodInfo); catchWeavers.ForEach(weaver => weaver.Weave(ilGenerator)); ilGenerator.EmitLoadLocal(argsImplLocalBuilder); ilGenerator.Emit(OpCodes.Callvirt, flowBehaviorMethodInfo); ilGenerator.EmitStoreLocal(flowBehavoiurLocalBuilder); ilGenerator.EmitLoadLocal(flowBehavoiurLocalBuilder); ilGenerator.EmitPushInteger(1); ilGenerator.Emit(OpCodes.Sub); ilGenerator.Emit(OpCodes.Switch, jumpTable); ilGenerator.Emit(OpCodes.Br_S, afterRethrowLabel); ilGenerator.MarkLabel(throwFlowBehaviorLabel); ilGenerator.EmitLoadLocal(exceptionLocalBuilder); ilGenerator.Emit(OpCodes.Throw); ilGenerator.MarkLabel(rethrowFlowBehaviorLabel); ilGenerator.Emit(OpCodes.Rethrow); ilGenerator.MarkLabel(afterRethrowLabel); }
public override void Generate (ILGenerator gen) { gen.BeginExceptionBlock (); tryBlock.Generate (gen); foreach (DictionaryEntry de in catchBlocks) { CodeVariableDeclaration vd = (CodeVariableDeclaration) de.Key; gen.BeginCatchBlock (vd.Variable.Type); if (vd.Variable.Name.Length > 0) { vd.Generate (gen); // FIXME: assign exception to this local declaration } ((CodeBlock) de.Value).Generate (gen); } if (!finallyBlock.IsEmpty) { gen.BeginFinallyBlock (); finallyBlock.Generate (gen); } gen.EndExceptionBlock (); }
public override void Emit(ILGenerator gen, bool labelSetAlready) { if (!labelSetAlready) MarkLabel(gen); MarkSequencePoint(gen); inputPrompt.Emit(gen, true); Label begin = gen.DefineLabel(); gen.MarkLabel(begin); gen.BeginExceptionBlock(); // Expected number of inputs: gen.Emit(OpCodes.Ldc_I4, inputs.Length); gen.Emit(OpCodes.Call, readLineMethod); // reads a line from console into a buffer and checks to make sure number of values equals expected number of values. inputs.Emit(gen, true); gen.BeginCatchBlock(typeof(InvalidCastException)); gen.Emit(OpCodes.Leave, begin); gen.EndExceptionBlock(); }
/// <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); }
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(); }
///<inheritdoc/> public override void BegineCatchBlock(Type exceptionType) { Generator.BeginCatchBlock(exceptionType); }
/// <summary> /// Generate MSIL code to emit an instruction marker at the current /// sequence in the output. /// </summary> /// <param name="il">ILGenerator object</param> public override void Generate(ILGenerator il) { if (il == null) { throw new ArgumentNullException("il"); } if (Deleted) { return; } switch (TryCatchType) { case EmitExceptionHandlerType.Try: il.BeginExceptionBlock(); break; case EmitExceptionHandlerType.Catch: { Type runtimeException = typeof(JComLib.JComRuntimeException); LocalBuilder tmp2 = il.DeclareLocal(runtimeException); il.BeginCatchBlock(runtimeException); il.Emit(OpCodes.Stloc_S, tmp2); il.Emit(OpCodes.Ldstr, "JCom Runtime Error: {0}"); il.Emit(OpCodes.Ldloc_S, tmp2); il.EmitCall(OpCodes.Call, runtimeException.GetMethod("get_Message"), null); MethodInfo meth = typeof(Console).GetMethod("WriteLine", new [] {typeof(string), typeof(object)}); il.EmitCall(OpCodes.Call, meth, null); il.EndExceptionBlock(); il.Emit(OpCodes.Ret); break; } } }