BeginFinallyBlock() public method

public BeginFinallyBlock ( ) : void
return void
コード例 #1
0
ファイル: CopyExceptions.cs プロジェクト: Tyelpion/IronAHK
        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();
            }
        }
コード例 #2
0
        public override void Emit(IEasyMember member, ILGenerator gen)
        {
            ArgumentsUtil.EmitLoadOwnerAndReference(_syncLockSource, gen);

            gen.Emit(OpCodes.Call, typeof(Monitor).GetMethod("Enter"));

            Label tryBlock = gen.BeginExceptionBlock();

            foreach(Statement stmt in _stmts)
            {
                stmt.Emit(member, gen);
            }

            gen.BeginFinallyBlock();
            ArgumentsUtil.EmitLoadOwnerAndReference(_syncLockSource, gen);
            gen.Emit(OpCodes.Call, typeof(Monitor).GetMethod("Exit"));
            gen.EndExceptionBlock();
        }
コード例 #3
0
ファイル: CodeTryBlock.cs プロジェクト: Profit0004/mono
		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 ();
		}
コード例 #4
0
ファイル: FinallyStatement.cs プロジェクト: JohnsonYuan/n2cms
 public override void Emit(IMemberEmitter member, ILGenerator gen)
 {
     gen.BeginFinallyBlock();
 }
コード例 #5
0
ファイル: try.cs プロジェクト: ArildF/masters
 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();
 }
コード例 #6
0
      internal override void TranslateToIL(ILGenerator il, Type rtype){
        //This assumes that rtype == Void.class
        this.context.EmitLineInfo(il);
        Globals.ScopeStack.Push(new WithObject(Globals.ScopeStack.Peek(), new JSObject(null, false)));
        bool savedInsideProtectedRegion = compilerGlobals.InsideProtectedRegion;
        compilerGlobals.InsideProtectedRegion = true;
        Label lab = il.DefineLabel();
        compilerGlobals.BreakLabelStack.Push(lab);
        compilerGlobals.ContinueLabelStack.Push(lab);
        this.obj.TranslateToIL(il, Typeob.Object);
        this.EmitILToLoadEngine(il);
        il.Emit(OpCodes.Call, CompilerGlobals.jScriptWithMethod); // JScriptWith returns the with object as an 'Object' (used by the debugger EE)
        
        // define a local named 'with()' that the debugger EE will use to bind to the with object
        LocalBuilder withObj = null;
        if (context.document.debugOn){
          il.BeginScope(); // used by the debugger to mark a with block 
          withObj = il.DeclareLocal(Typeob.Object);
          withObj.SetLocalSymInfo("with()");
          il.Emit(OpCodes.Stloc, withObj);
        }else
          il.Emit(OpCodes.Pop);

        il.BeginExceptionBlock();
        this.block.TranslateToILInitializer(il);
        this.block.TranslateToIL(il, Typeob.Void);
        il.BeginFinallyBlock();
        if (context.document.debugOn){
          // null the local used by the debugger EE
          il.Emit(OpCodes.Ldnull);
          il.Emit(OpCodes.Stloc, withObj);
        }
        this.EmitILToLoadEngine(il);
        il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
        il.Emit(OpCodes.Pop);
        il.EndExceptionBlock();
        if (context.document.debugOn)
          il.EndScope(); // used by the debugger to mark a with block 
        il.MarkLabel(lab);
        compilerGlobals.BreakLabelStack.Pop();
        compilerGlobals.ContinueLabelStack.Pop();
        compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
        Globals.ScopeStack.Pop();
      }
コード例 #7
0
        protected override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder, System.Reflection.Emit.ILGenerator il)
        {
            var convention = config.Conventions.OfType <TransactionProxyConvention>().First();

            var listType           = typeof(IEnumerable <>).MakeGenericType(config.BaseType);
            var enumeratorType     = typeof(IEnumerator <>).MakeGenericType(config.BaseType);
            var enumeratorVariable = il.DeclareLocal(enumeratorType);
            var currentVariable    = il.DeclareLocal(config.BaseType);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, convention.TargetsField.Field);
            il.EmitCall(OpCodes.Callvirt, listType.GetMethod("GetEnumerator"), null);
            il.Emit(OpCodes.Stloc, enumeratorVariable);

            var loopLabel = il.DefineLabel();
            var nextLabel = il.DefineLabel();

            var tryBlock = il.BeginExceptionBlock();

            il.MarkLabel(loopLabel);
            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.EmitCall(OpCodes.Callvirt, typeof(IEnumerator).GetMethod("MoveNext"), null);
            il.Emit(OpCodes.Brfalse, nextLabel);

            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.EmitCall(OpCodes.Callvirt, enumeratorType.GetProperty("Current").GetGetMethod(), null);
            il.Emit(OpCodes.Stloc, currentVariable);

            foreach (var item in convention.TransactionProxyProperties)
            {
                var done = il.DefineLabel();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, item.HasMultipleValuesProperty.BackingField);
                il.Emit(OpCodes.Ldc_I4_1);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Brtrue_S, done);

                il.Emit(OpCodes.Ldloc, currentVariable);
                il.Emit(OpCodes.Ldarg_0);
                il.EmitCall(OpCodes.Callvirt, item.Property.GetGetMethod(true), null);
                il.EmitCall(OpCodes.Callvirt, item.Property.GetSetMethod(true), null);

                il.MarkLabel(done);
            }

            il.Emit(OpCodes.Br, loopLabel);

            var endFinally = il.DefineLabel();

            il.BeginFinallyBlock();
            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ceq);
            il.Emit(OpCodes.Brtrue_S, endFinally);
            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.EmitCall(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose"), null);
            il.MarkLabel(endFinally);
            il.EndExceptionBlock();

            il.MarkLabel(nextLabel);

            il.Emit(OpCodes.Ret);
        }
コード例 #8
0
 private void TranslateToMethodWithStackFrame(ILGenerator il, CompilerGlobals compilerGlobals, bool staticInitializer)
 {
     if (this.isStatic)
     {
         il.Emit(OpCodes.Ldtoken, ((ClassScope) this.own_scope.GetParent()).GetTypeBuilder());
     }
     else
     {
         il.Emit(OpCodes.Ldarg_0);
     }
     int length = this.fields.Length;
     ConstantWrapper.TranslateToILInt(il, length);
     il.Emit(OpCodes.Newarr, Typeob.JSLocalField);
     for (int i = 0; i < length; i++)
     {
         JSLocalField field = this.fields[i];
         il.Emit(OpCodes.Dup);
         ConstantWrapper.TranslateToILInt(il, i);
         il.Emit(OpCodes.Ldstr, field.Name);
         il.Emit(OpCodes.Ldtoken, field.FieldType);
         ConstantWrapper.TranslateToILInt(il, field.slotNumber);
         il.Emit(OpCodes.Newobj, CompilerGlobals.jsLocalFieldConstructor);
         il.Emit(OpCodes.Stelem_Ref);
     }
     this.TranslateToILToLoadEngine(il, true);
     if (this.isStatic)
     {
         il.Emit(OpCodes.Call, CompilerGlobals.pushStackFrameForStaticMethod);
     }
     else
     {
         il.Emit(OpCodes.Call, CompilerGlobals.pushStackFrameForMethod);
     }
     bool insideProtectedRegion = compilerGlobals.InsideProtectedRegion;
     compilerGlobals.InsideProtectedRegion = true;
     il.BeginExceptionBlock();
     this.body.TranslateToILInitializer(il);
     this.body.TranslateToIL(il, Typeob.Void);
     il.MarkLabel(this.returnLabel);
     this.TranslateToILToSaveLocals(il);
     Label label = il.DefineLabel();
     il.Emit(OpCodes.Leave, label);
     il.BeginFinallyBlock();
     this.TranslateToILToLoadEngine(il);
     il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
     il.Emit(OpCodes.Pop);
     il.EndExceptionBlock();
     il.MarkLabel(label);
     if (!staticInitializer)
     {
         if (this.body.context.document.debugOn)
         {
             this.EmitLastLineInfo(il);
             il.Emit(OpCodes.Nop);
         }
         if (this.own_scope.returnVar != null)
         {
             il.Emit(OpCodes.Ldloc, (LocalBuilder) this.own_scope.returnVar.GetMetaData());
         }
         il.Emit(OpCodes.Ret);
     }
     compilerGlobals.InsideProtectedRegion = insideProtectedRegion;
 }
コード例 #9
0
        /// <summary>
        /// Emits IL code to pack a Map based on IDictionary.
        /// </summary>
        /// <param name="currentMethod">Current method info.</param>
        /// <param name="gen">il buffer/generator</param>
        /// <param name="type">Current type</param>
        /// <param name="arg_writer">packer object</param>
        /// <param name="arg_obj">current object</param>
        /// <param name="lookupPackMethod">dictionary to look for methods</param>
        public static void EmitPackIL(MethodInfo currentMethod, ILGenerator gen, Type type, Variable arg_writer, Variable arg_obj, Func<Type, MethodInfo> lookupPackMethod)
        {
            Type keyType = type.GetGenericArguments()[0];
            Type valueType = type.GetGenericArguments()[1];
            Type keyValuePairType = typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType);

            // Preparing Reflection instances
            MethodInfo getCount = typeof(ICollection<>).MakeGenericType(keyValuePairType).GetMethod(
                "get_Count",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{
            },
                null
                );
            MethodInfo writeMapHeader = typeof(MsgPackWriter).GetMethod(
                "WriteMapHeader",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{
            typeof(Int32)
            },
                null
                );
            MethodInfo getEnumerator = typeof(IEnumerable<>).MakeGenericType(keyValuePairType).GetMethod(
                "GetEnumerator",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{
            },
                null
                );
            MethodInfo getCurrent = typeof(IEnumerator<>).MakeGenericType(keyValuePairType).GetMethod(
                "get_Current",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{ },
                null
                );
            MethodInfo getKey = keyValuePairType.GetMethod(
                "get_Key",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{ },
                null
                );

            MethodInfo getValue = keyValuePairType.GetMethod(
                "get_Value",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{ },
                null
                );
            MethodInfo moveNext = typeof(IEnumerator).GetMethod(
                "MoveNext",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{ },
                null
                );
            MethodInfo dispose = typeof(IDisposable).GetMethod(
                "Dispose",
                BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[]{ },
                null
                );

            // Preparing locals
            LocalBuilder keyValuepair = gen.DeclareLocal(keyValuePairType);
            LocalBuilder enumerator = gen.DeclareLocal(typeof(System.Collections.Generic.IEnumerator<>).MakeGenericType(keyValuePairType));
            Variable localValue = Variable.CreateLocal(gen.DeclareLocal(valueType));

            // Preparing labels
            Label getNext = gen.DefineLabel();
            Label work = gen.DefineLabel();
            Label end = gen.DefineLabel();
            Label endFinally = gen.DefineLabel();

            // Writing body
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Callvirt, getCount);
            gen.Emit(OpCodes.Callvirt, writeMapHeader);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Callvirt, getEnumerator);
            gen.Emit(OpCodes.Stloc_1);
            gen.BeginExceptionBlock();
            gen.Emit(OpCodes.Br_S, getNext);
            gen.MarkLabel(work);
            gen.Emit(OpCodes.Ldloc_1);
            gen.Emit(OpCodes.Callvirt, getCurrent);
            gen.Emit(OpCodes.Stloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldloca_S, 0);
            gen.Emit(OpCodes.Call, getKey);
            EmitPack(gen, keyType, type, currentMethod, lookupPackMethod);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldloca_S, 0);
            gen.Emit(OpCodes.Call, getValue);
            EmitPack(gen, valueType, type, currentMethod, lookupPackMethod);
            gen.MarkLabel(getNext);
            gen.Emit(OpCodes.Ldloc_1);
            gen.Emit(OpCodes.Callvirt, moveNext);
            gen.Emit(OpCodes.Brtrue_S, work);
            gen.Emit(OpCodes.Leave_S, end);
            gen.BeginFinallyBlock();
            gen.Emit(OpCodes.Ldloc_1);
            gen.Emit(OpCodes.Brfalse_S, endFinally);
            gen.Emit(OpCodes.Ldloc_1);
            gen.Emit(OpCodes.Callvirt, dispose);
            gen.MarkLabel(endFinally);
            gen.Emit(OpCodes.Endfinally);
            gen.EndExceptionBlock();
            gen.MarkLabel(end);
            gen.Emit(OpCodes.Ret); // <- Yep, I know there is a Ret in the calling function.
            // finished
        }
コード例 #10
0
 ///<inheritdoc/>
 public override void BeginFinallyBlock()
 {
     Generator.BeginFinallyBlock();
 }
コード例 #11
0
 public void Weave(ILGenerator ilGenerator)
 {
     ilGenerator.BeginFinallyBlock();
     finallyWeaversQueue.Weave(ilGenerator);
 }
コード例 #12
0
        static void EmitILForEachView(Type viewType, ILGenerator il, Action forEachAction)
        {
            // Declare the locals we need
            var viewLocal = il.DeclareLocal(viewType);
            var enumeratorLocal = il.DeclareLocal(typeof(IEnumerable<>).MakeGenericType(viewType));
            var enumeratorContinueLocal = il.DeclareLocal(typeof(bool));

            // Load the view instance on to the evaluation stack
            il.Emit(OpCodes.Ldarg, viewLocal.LocalIndex);

            // Call CompositeView<IViewType>.get_Views
            var getViews = typeof(CompositeView<>)
                .MakeGenericType(viewType)
                .GetProperties(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic)
                .First(pi => pi.Name == "Views" &&
                    pi.PropertyType == typeof(IEnumerable<>).MakeGenericType(viewType))
                .GetGetMethod(true);
            il.EmitCall(OpCodes.Call, getViews, null);

            // Call IEnumerable<>.GetEnumerator
            var getViewsEnumerator = typeof(IEnumerable<>)
                .MakeGenericType(viewType)
                .GetMethod("GetEnumerator",
                    BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);
            il.EmitCall(OpCodes.Callvirt, getViewsEnumerator, null);

            // Push the enumerator from the evaluation stack to the local variable
            il.Emit(OpCodes.Stloc, enumeratorLocal.LocalIndex);

            // Start a new exception block so that we can reliably dispose
            // the enumerator
            il.BeginExceptionBlock();

            // Define some of the labels we need
            var moveNextLabel = il.DefineLabel();
            var continueLabel = il.DefineLabel();
            var endFinallyLabel = il.DefineLabel();
            var exitLabel = il.DefineLabel();

            // Skip straight ahead to moveNextLabel
            il.Emit(OpCodes.Br_S, moveNextLabel);

            // Mark this point with with continueLabel
            il.MarkLabel(continueLabel);

            // Push the enumerator on to the evaluation stack
            il.Emit(OpCodes.Ldloc, enumeratorLocal);

            // Call IEnumerator<>.get_Current on the enumerator
            var getCurrent =
                typeof(IEnumerator<>)
                .MakeGenericType(viewType)
                .GetProperty("Current")
                .GetGetMethod();
            il.EmitCall(OpCodes.Callvirt, getCurrent, null);

            // Store the output from IEnumerator<>.get_Current into a local
            il.Emit(OpCodes.Stloc, viewLocal);

            // Push the view local back onto the evaluation stack
            il.Emit(OpCodes.Ldloc, viewLocal);

            // Push the incoming set value onto the evaluation stack
            il.Emit(OpCodes.Ldarg, 1);

            // Let the calling method inject some IL here
            forEachAction();

            // Mark this point with the moveNextLabel
            il.MarkLabel(moveNextLabel);

            // Push the enumerator local back onto the evaluation stack
            il.Emit(OpCodes.Ldloc, enumeratorLocal);

            // Call IEnumerator.MoveNext on the enumerator
            var moveNext =
                typeof(IEnumerator)
                .GetMethod("MoveNext");
            il.EmitCall(OpCodes.Callvirt, moveNext, null);

            // Push the result of MoveNext from the evaluation stack to the local variable
            il.Emit(OpCodes.Stloc, enumeratorContinueLocal.LocalIndex);

            // Pull the result of MoveNext from the evaluation stack back onto the evaluation stack
            il.Emit(OpCodes.Ldloc, enumeratorContinueLocal.LocalIndex);

            // If MoveNext returned true, jump back to the continue label
            il.Emit(OpCodes.Brtrue_S, continueLabel);

            // Jump out of the try block
            il.Emit(OpCodes.Leave_S, exitLabel);

            // Start the finally block
            il.BeginFinallyBlock();

            // Push the enumerator onto the evaluation stack, then compare against null
            il.Emit(OpCodes.Ldloc, enumeratorLocal);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ceq);

            // Pop the comparison result into our local
            il.Emit(OpCodes.Stloc, enumeratorContinueLocal);

            // If the comparison result was true, jump to the end of the finally block
            il.Emit(OpCodes.Ldloc, enumeratorContinueLocal);
            il.Emit(OpCodes.Brtrue_S, endFinallyLabel);

            // Push the enumerator onto the evaluation stack
            il.Emit(OpCodes.Ldloc, enumeratorLocal);

            // Call IDisposable.Dispose
            var dispose =
                typeof(IDisposable)
                .GetMethod("Dispose");
            il.Emit(OpCodes.Callvirt, dispose);

            // Mark this point as exit point for our finally block
            il.MarkLabel(endFinallyLabel);

            // Close the try block
            il.EndExceptionBlock();

            // Mark this point as our exit point (used to get out of the try block)
            il.MarkLabel(exitLabel);
        }
コード例 #13
0
        protected override void Implement(DynamicTypeBuilder config, System.Reflection.Emit.TypeBuilder typeBuilder, System.Reflection.Emit.ILGenerator il)
        {
            var convention               = config.Conventions.OfType <TransactionProxyConvention>().First();
            var addValueMethod           = typeof(TransactionProxyHelper).GetMethod("AddValue", BindingFlags.Static | BindingFlags.Public);
            var getValueMethod           = typeof(TransactionProxyHelper).GetMethod("GetValue", BindingFlags.Static | BindingFlags.Public);
            var setCollectionValueMethod = typeof(TransactionProxyHelper).GetMethod("SetCollectionValue", BindingFlags.Static | BindingFlags.Public);


            var listType           = typeof(IEnumerable <>).MakeGenericType(config.BaseType);
            var enumeratorType     = typeof(IEnumerator <>).MakeGenericType(config.BaseType);
            var enumeratorVariable = il.DeclareLocal(enumeratorType);
            var currentVariable    = il.DeclareLocal(config.BaseType);

            foreach (var item in convention.TransactionProxyProperties)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Newobj, item.ValuesProperty.MemberType.GetConstructor(new Type[] { }));
                il.Emit(OpCodes.Stfld, item.ValuesProperty.BackingField);
            }


            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, convention.TargetsField.Field);
            il.EmitCall(OpCodes.Callvirt, listType.GetMethod("GetEnumerator"), null);
            il.Emit(OpCodes.Stloc, enumeratorVariable);

            var loopLabel = il.DefineLabel();
            var nextLabel = il.DefineLabel();

            var tryBlock = il.BeginExceptionBlock();

            il.MarkLabel(loopLabel);
            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.EmitCall(OpCodes.Callvirt, typeof(IEnumerator).GetMethod("MoveNext"), null);
            il.Emit(OpCodes.Brfalse, nextLabel);

            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.EmitCall(OpCodes.Callvirt, enumeratorType.GetProperty("Current").GetGetMethod(), null);
            il.Emit(OpCodes.Stloc, currentVariable);

            foreach (var item in convention.TransactionProxyProperties)
            {
                il.Emit(OpCodes.Ldloc, currentVariable);
                il.EmitCall(OpCodes.Callvirt, item.Property.GetGetMethod(true), null);
                il.Emit(OpCodes.Ldloc, currentVariable);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField);
                il.EmitCall(OpCodes.Call, addValueMethod.MakeGenericMethod(item.Property.PropertyType, config.BaseType), null);
            }

            il.Emit(OpCodes.Br, loopLabel);

            var endFinally = il.DefineLabel();

            il.BeginFinallyBlock();
            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ceq);
            il.Emit(OpCodes.Brtrue_S, endFinally);
            il.Emit(OpCodes.Ldloc, enumeratorVariable);
            il.EmitCall(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose"), null);
            il.MarkLabel(endFinally);
            il.EndExceptionBlock();

            il.MarkLabel(nextLabel);

            foreach (var item in convention.TransactionProxyProperties)
            {
                Type itemType;
                if (IsCollectionType(item.Property.PropertyType, out itemType))
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField);
                    il.Emit(OpCodes.Ldarg_0);
                    il.EmitCall(OpCodes.Callvirt, item.Property.GetGetMethod(true), null);
                    il.EmitCall(OpCodes.Call, setCollectionValueMethod.MakeGenericMethod(itemType, item.Property.PropertyType, config.BaseType), null);
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField);
                    il.EmitCall(OpCodes.Call, getValueMethod.MakeGenericMethod(item.Property.PropertyType, config.BaseType), null);
                    il.EmitCall(OpCodes.Callvirt, item.Property.GetSetMethod(true), null);
                }

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, item.ValuesProperty.BackingField);
                il.EmitCall(OpCodes.Callvirt, item.ValuesProperty.BackingField.FieldType.GetProperty("Count").GetGetMethod(), null);
                il.Emit(OpCodes.Ldc_I4_1);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.EmitCall(OpCodes.Callvirt, item.HasMultipleValuesProperty.PropertySetMethod, null);
            }

            il.Emit(OpCodes.Ret);
        }
コード例 #14
0
 internal override void TranslateToIL(ILGenerator il, Type rtype)
 {
     base.context.EmitLineInfo(il);
     base.Globals.ScopeStack.Push(new WithObject(base.Globals.ScopeStack.Peek(), new JSObject(null, false)));
     bool insideProtectedRegion = base.compilerGlobals.InsideProtectedRegion;
     base.compilerGlobals.InsideProtectedRegion = true;
     Label item = il.DefineLabel();
     base.compilerGlobals.BreakLabelStack.Push(item);
     base.compilerGlobals.ContinueLabelStack.Push(item);
     this.obj.TranslateToIL(il, Typeob.Object);
     base.EmitILToLoadEngine(il);
     il.Emit(OpCodes.Call, CompilerGlobals.jScriptWithMethod);
     LocalBuilder local = null;
     if (base.context.document.debugOn)
     {
         il.BeginScope();
         local = il.DeclareLocal(Typeob.Object);
         local.SetLocalSymInfo("with()");
         il.Emit(OpCodes.Stloc, local);
     }
     else
     {
         il.Emit(OpCodes.Pop);
     }
     il.BeginExceptionBlock();
     this.block.TranslateToILInitializer(il);
     this.block.TranslateToIL(il, Typeob.Void);
     il.BeginFinallyBlock();
     if (base.context.document.debugOn)
     {
         il.Emit(OpCodes.Ldnull);
         il.Emit(OpCodes.Stloc, local);
     }
     base.EmitILToLoadEngine(il);
     il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
     il.Emit(OpCodes.Pop);
     il.EndExceptionBlock();
     if (base.context.document.debugOn)
     {
         il.EndScope();
     }
     il.MarkLabel(item);
     base.compilerGlobals.BreakLabelStack.Pop();
     base.compilerGlobals.ContinueLabelStack.Pop();
     base.compilerGlobals.InsideProtectedRegion = insideProtectedRegion;
     base.Globals.ScopeStack.Pop();
 }
コード例 #15
0
        static void WriteSerializerDictionary(TypeBuilder typeBuilder, ILGenerator il, Type type, MethodInfo getValueMethod,
            int? valueLocalIndex = null, OpCode? valueLocalOpCode = null)
        {
            var keyType = typeof(object);
            var valueType = typeof(object);

            if (type.ContainsGenericParameters) {
                var arguments = type.GetGenericArguments();
                keyType = arguments[0];
                valueType = arguments[1];
            } else {
                // Custom IDictionary implementation
                var interfaces = type.GetInterfaces();
                for (int i = 0; i < interfaces.Length; i++) {
                    var @interface = interfaces[i];
                    if (@interface.IsGenericType && @interface.GetGenericTypeDefinition() == GenericIDictType) {
                        var arguments = @interface.GetGenericArguments();
                        keyType = arguments[0];
                        valueType = arguments[1];
                        break;
                    }
                }
            }

            var keyValuePairType = GenericKeyValuePairType.MakeGenericType(keyType, valueType);
            var enumeratorType = GenericDictionaryEnumerator.MakeGenericType(keyType, valueType);
            var enumeratorLocal = il.DeclareLocal(enumeratorType);
            var entryLocal = il.DeclareLocal(keyValuePairType);
            var startEnumeratorLabel = il.DefineLabel();
            var moveNextLabel = il.DefineLabel();
            var endEnumeratorLabel = il.DefineLabel();

            if (valueLocalIndex != null) il.Emit(valueLocalOpCode.Value, valueLocalIndex.Value);
            if (getValueMethod != null) {
                if (valueLocalIndex == null) il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Callvirt, getValueMethod);
            }

            if (type.ContainsGenericParameters)
                il.Emit(OpCodes.Callvirt, GenericDictType.MakeGenericType(keyType, valueType).GetMethod("GetEnumerator"));
            else
                il.Emit(OpCodes.Callvirt, type.GetMethod("GetEnumerator"));

            il.Emit(OpCodes.Stloc_S, enumeratorLocal.LocalIndex);
            il.BeginExceptionBlock();
            il.Emit(OpCodes.Br, startEnumeratorLabel);
            il.MarkLabel(moveNextLabel);
            il.Emit(OpCodes.Ldloca_S, enumeratorLocal.LocalIndex);
            il.Emit(OpCodes.Call,
                enumeratorLocal.LocalType.GetProperty("Current")
                .GetGetMethod());
            il.Emit(OpCodes.Stloc, entryLocal.LocalIndex);
            if (keyType.IsComplexType()) {
                var keyMethod = keyValuePairType.GetProperty("Key").GetGetMethod();
                if (keyType.IsCollectionType())
                    WriteSerializerClass(typeBuilder, il, keyType, 1, keyMethod, callerType: keyType, valueLocalIndex: entryLocal.LocalIndex,
                    valueLocalOpCode: OpCodes.Ldloca_S);
                else
                    WriteSerializerCallClassMethod(typeBuilder, il, keyType, OpCodes.Ldloca_S, entryLocal.LocalIndex, 1, keyMethod,
                    needClassHeader: false);
            } else {
                var keyMethod = keyValuePairType.GetProperty("Key").GetGetMethod();
                WriteSerializerBytesToStream(il, keyType, OpCodes.Ldloca_S, entryLocal.LocalIndex, 1, keyMethod, isTargetCollection: true);
            }
            if (valueType.IsComplexType()) {
                var valueMethod = keyValuePairType.GetProperty("Value").GetGetMethod();
                if (valueType.IsCollectionType())
                    WriteSerializerClass(typeBuilder, il, valueType, 2, valueMethod, callerType: valueType, valueLocalIndex: entryLocal.LocalIndex,
                    valueLocalOpCode: OpCodes.Ldloca_S);
                else
                    WriteSerializerCallClassMethod(typeBuilder, il, valueType, OpCodes.Ldloca_S, entryLocal.LocalIndex, 2, valueMethod,
                    needClassHeader: false);
            } else {
                var valueMethod = keyValuePairType.GetProperty("Value").GetGetMethod();
                WriteSerializerBytesToStream(il, valueType, OpCodes.Ldloca_S, entryLocal.LocalIndex, 2, valueMethod, isTargetCollection: true);
            }
            il.MarkLabel(startEnumeratorLabel);
            il.Emit(OpCodes.Ldloca_S, enumeratorLocal.LocalIndex);
            il.Emit(OpCodes.Call, enumeratorType.GetMethod("MoveNext", MethodBinding));
            il.Emit(OpCodes.Brtrue, moveNextLabel);
            il.Emit(OpCodes.Leave, endEnumeratorLabel);
            il.BeginFinallyBlock();
            il.Emit(OpCodes.Ldloca_S, enumeratorLocal.LocalIndex);
            il.Emit(OpCodes.Constrained, enumeratorLocal.LocalType);
            il.Emit(OpCodes.Callvirt, IDisposableDisposeMethod);
            il.EndExceptionBlock();
            il.MarkLabel(endEnumeratorLabel);
        }
コード例 #16
0
        static void WriteSerializerList(TypeBuilder typeBuilder, ILGenerator il, Type type, MethodInfo valueMethod,
            int? valueLocalIndex = null, OpCode? valueLocalOpCode = null)
        {
            //var arguments = type.GetGenericArguments();
            bool useGenericArguments;
            var listType = GetGenericListType(type, out useGenericArguments);//arguments.Length > 0 ? arguments[0] : ObjectType;
            var genericListType = GenericListType.MakeGenericType(listType);
            var iEnumerableType = !useGenericArguments ? GenericIEnumeratorType.MakeGenericType(listType) : null;
            var hasIEnumerable = iEnumerableType != null;
            var enumeratorType = hasIEnumerable ? iEnumerableType : GenericListEnumerator.MakeGenericType(listType);
            var enumeratorLocal = il.DeclareLocal(enumeratorType);
            var moveNextType = hasIEnumerable ? EnumeratorType : enumeratorType;
            var entryLocal = il.DeclareLocal(listType);
            var startEnumeratorLabel = il.DefineLabel();
            var moveNextLabel = il.DefineLabel();
            var endEnumeratorLabel = il.DefineLabel();

            if (valueLocalIndex != null) il.Emit(valueLocalOpCode.Value, valueLocalIndex.Value);

            if (valueLocalIndex == null) il.Emit(OpCodes.Ldarg_2);

            if (valueMethod != null) {

                il.Emit(OpCodes.Callvirt, valueMethod);
            }

            if (type.Name == "IList`1") il.Emit(OpCodes.Castclass, genericListType);
            il.Emit(OpCodes.Callvirt, (hasIEnumerable ? type : genericListType).GetMethod("GetEnumerator"));
            il.Emit(OpCodes.Stloc_S, enumeratorLocal.LocalIndex);
            il.BeginExceptionBlock();
            il.Emit(OpCodes.Br, startEnumeratorLabel);
            il.MarkLabel(moveNextLabel);
            il.Emit(hasIEnumerable ? OpCodes.Ldloc : OpCodes.Ldloca_S, enumeratorLocal.LocalIndex);
            il.Emit(hasIEnumerable ? OpCodes.Callvirt : OpCodes.Call,
                enumeratorLocal.LocalType.GetProperty("Current")
                .GetGetMethod());

            il.Emit(OpCodes.Stloc, entryLocal.LocalIndex);
            if (listType.IsComplexType()) {
                if (listType.IsCollectionType())
                    WriteSerializerClass(typeBuilder, il, listType, 1, null, callerType: listType, valueLocalIndex: entryLocal.LocalIndex,
                    valueLocalOpCode: OpCodes.Ldloc);
                else
                    WriteSerializerCallClassMethod(typeBuilder, il, listType, OpCodes.Ldloc, entryLocal.LocalIndex, 1, null, needClassHeader: false);
            } else {
                WriteSerializerBytesToStream(il, listType, OpCodes.Ldloc, entryLocal.LocalIndex, 1, null, isTargetCollection: true);
            }
            il.MarkLabel(startEnumeratorLabel);
            il.Emit(hasIEnumerable ? OpCodes.Ldloc : OpCodes.Ldloca_S, enumeratorLocal.LocalIndex);
            il.Emit(hasIEnumerable ? OpCodes.Callvirt : OpCodes.Call, moveNextType.GetMethod("MoveNext", MethodBinding));
            il.Emit(OpCodes.Brtrue, moveNextLabel);
            il.Emit(OpCodes.Leave, endEnumeratorLabel);
            il.BeginFinallyBlock();
            il.Emit(hasIEnumerable ? OpCodes.Ldloc : OpCodes.Ldloca_S, enumeratorLocal.LocalIndex);
            if (!hasIEnumerable)
                il.Emit(OpCodes.Constrained, enumeratorLocal.LocalType);
            il.Emit(OpCodes.Callvirt, IDisposableDisposeMethod);
            il.EndExceptionBlock();
            il.MarkLabel(endEnumeratorLabel);
        }
コード例 #17
0
        /// <summary>
        /// Generates method logic.
        /// </summary>
        /// <param name="il">The IL generator to use.</param>
        /// <param name="method">The method to proxy.</param>
        /// <param name="interfaceMethod">
        /// The interface definition of the method, if applicable.
        /// </param>
        protected override void GenerateMethodLogic(
            ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
        {
            Label jmpEndFinally = il.DefineLabel();

            // save target source so we can call Dispose later
            PushAdvisedProxy(il);
            il.Emit(OpCodes.Ldfld, References.TargetSourceWrapperField);
            il.Emit(OpCodes.Stloc, targetSource);

            // open try/finally block
            il.BeginExceptionBlock();

            base.GenerateMethodLogic(il, method, interfaceMethod);

            // open finally block
            il.BeginFinallyBlock();

            // call Dispose on target source
            il.Emit(OpCodes.Ldloc, targetSource);
            il.Emit(OpCodes.Brfalse, jmpEndFinally);
            il.Emit(OpCodes.Ldloc, targetSource);
            il.EmitCall(OpCodes.Callvirt, References.DisposeMethod, null);
            
            il.MarkLabel(jmpEndFinally);

            // close try/finally block
            il.EndExceptionBlock();
        }