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 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(); }
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(); }
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; }
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); }
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); }
public void Weave(ILGenerator ilGenerator) { ilGenerator.EndExceptionBlock(); }
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(); }
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(); }
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(); }
public override void Emit(IMemberEmitter member, ILGenerator gen) { gen.EndExceptionBlock(); }
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); }
/// <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(); }
/// <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 }
///<inheritdoc/> public override void EndExceptionBlock() { Generator.EndExceptionBlock(); }
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); }
/// <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; } } }
/// <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); }
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); }