public MessageArgumentsFormatter(MethodBodyTransformationContext context) { this.context = context; this.targetMethod = context.TargetElement as MethodDefDeclaration; if (this.targetMethod == null) { throw new InvalidOperationException("Target element is not a method"); } }
public GuardPropertyEqualityMethodBodyWrappingImplementation(IPropertyTransformationContext transformationContext, AspectInfrastructureTask task, MethodBodyTransformationContext context) : base(task, context) { if (transformationContext == null) throw new ArgumentNullException("transformationContext"); _transformationContext = transformationContext; _assets = _transformationContext.Module.Cache.GetItem( () => new TransformationAssets(_transformationContext.Module)); }
public MessageArgumentsFormatter(MethodBodyTransformationContext context) { this.context = context; this.targetMethod = context.TargetElement as MethodDefDeclaration; if (this.targetMethod == null) { throw new InvalidOperationException("Target element is not a method"); } }
protected ComposedMethodBodyWrappingImplementation(MethodBodyWrappingImplementationOptions wrappingImplementationOptions, AspectInfrastructureTask task, MethodBodyTransformationContext context) : base(task, context) { if (wrappingImplementationOptions == null) throw new ArgumentNullException("wrappingImplementationOptions"); _wrappingImplementationOptions = wrappingImplementationOptions; try { CompositionInitializer.SatisfyImports(this); } catch (Exception ex) { throw; } }
public static void AddPropertyGuard(PropertyDeclaration property, MethodBodyTransformationContext context, InstructionBlock block, InstructionWriter writer) { var propertyType = property.PropertyType; var methodBody = block.MethodBody; var sequence = block.AddInstructionSequence(null, NodePosition.After, null); if (sequence == null) return; var oldValueVariable = block.DefineLocalVariable(propertyType, string.Format("old{0}Value", property.Name)); var assets = GetTransformationAssets(property.Module); writer.AttachInstructionSequence(sequence); var isLocationBinding = CheckIfIsLocationBinding(methodBody,assets); if (isLocationBinding) { writer.AssignValue_LocalVariable(oldValueVariable , () => writer.Call_MethodOnTarget(property.GetGetter() , () => { //Load the instance parameter of the SetValue method //and convert it to the type writer.EmitInstruction(OpCodeNumber.Ldarg_1); //writer.EmitInstructionLoadIndirect(Assets.ObjectTypeSignature); writer.EmitInstructionType(OpCodeNumber.Ldobj, assets.ObjectTypeSignature); writer.EmitConvertFromObject(property.Parent); } ) ); //On the location binding the value parameter is at psotion 3 writer.EmitInstruction(OpCodeNumber.Ldarg_3); } else { writer.AssignValue_LocalVariable(oldValueVariable, () => writer.Get_PropertyValue(property)); //For a normal property the value parameter is at position 1 writer.EmitInstruction(OpCodeNumber.Ldarg_1); } if (propertyType.IsStruct()) { writer.EmitInstructionType(OpCodeNumber.Box, propertyType); } writer.Box_LocalVariableIfNeeded(oldValueVariable); var isPrimitive = propertyType.IsPrimitive(); if (isPrimitive) { writer.Compare_Primitives(); } else { //TODO: Try and use the equality operator when present writer.Compare_Objects(assets.ObjectEqualsMethod); } //writer.Leave_IfTrue(_context.LeaveBranchTarget); writer.Leave_IfTrue(context.LeaveBranchTarget); writer.DetachInstructionSequence(); }
public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context) : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context) { this.transformationInstance = transformationInstance; this.backendInstance = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance); this.options = new ConfigurationOptions(this.transformationInstance.AspectWeaverInstance); this.argumentsFormatter = new MessageArgumentsFormatter(context); this.methodMappingWriter = context.MethodMapping.CreateWriter(); }
public override void Implement(MethodBodyTransformationContext context) { Implementation implementation = new Implementation(this, context); implementation.Implement(); }
public EnhancePropertySetterMethodBodyWrappingImplementation(IPropertyTransformationContext transformationContext, AspectInfrastructureTask task, MethodBodyTransformationContext context) : base(task, context) { if (transformationContext == null) throw new ArgumentNullException("transformationContext"); _transformationContext = transformationContext; _assets = _transformationContext.Module.Cache.GetItem( () => new TransformationAssets(_transformationContext.Module)); _stringTypeSignature = _transformationContext.Module.Cache.GetIntrinsic(typeof(string)); }
public Visitor(Instance instance, MethodBodyTransformationContext context) { this.instance = instance; this.context = context; }
public override void Implement(MethodBodyTransformationContext context) { context.InstructionBlock.MethodBody.Visit(new[] { new Visitor(this, context) }); }
public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context) : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context) { this.transformationInstance = transformationInstance; this.backendInstance = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance); // todo fix configuration this.onEntryOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue <LogAspectConfiguration, LogOptions>(c => c.OnEntryOptions); this.onSuccessOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue <LogAspectConfiguration, LogOptions>(c => c.OnSuccessOptions); this.onExceptionOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue <LogAspectConfiguration, LogOptions>(c => c.OnExceptionOptions); }
public override void Implement(MethodBodyTransformationContext context) { Implementation implementation = new Implementation(this, context); implementation.Implement(); }
public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context) : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context) { this.transformationInstance = transformationInstance; this.backendInstance = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance); this.options = new ConfigurationOptions(this.transformationInstance.AspectWeaverInstance); this.argumentsFormatter = new MessageArgumentsFormatter(context); this.methodMappingWriter = context.MethodMapping.CreateWriter(); }
private void AddGuard(MethodBodyTransformationContext context) { var property = Property; var propertyType = property.PropertyType; var methodBody = context.InstructionBlock.MethodBody; methodBody.InitLocalVariables = true; Instruction firstInstruction; InstructionBlock firstBlockWithInstruction = null; InstructionSequence firstSequenceWithInstruction = null; methodBody.ForEachInstruction(rdr => { //if (rdr.CurrentInstruction != null && rdr.CurrentInstruction.OpCodeNumber == OpCodeNumber.Nop) // return true; firstInstruction = rdr.CurrentInstruction; firstSequenceWithInstruction = rdr.CurrentInstructionSequence; firstBlockWithInstruction = rdr.CurrentInstructionBlock; //firstSequenceWithInstruction.SplitAroundReaderPosition(rdr, out beforeSequence, out afterSequence); return false; }); if(firstSequenceWithInstruction == null) return; var beforeSequence = firstBlockWithInstruction .AddInstructionSequence(null, NodePosition.Before,firstSequenceWithInstruction); var isLocationBinding = CheckIfIsLocationBinding(methodBody); var writer = new InstructionWriter(); if(beforeSequence != null) { var oldValueVariable = firstBlockWithInstruction .DefineLocalVariable(propertyType, string.Format("old{0}Value",property.Name)); writer.AttachInstructionSequence(beforeSequence); if(isLocationBinding) { writer.AssignValue_LocalVariable(oldValueVariable , () => writer.Call_MethodOnTarget(property.GetGetter(), () => { //Load the instance parameter of the SetValue method //and convert it to the type writer.EmitInstruction(OpCodeNumber.Ldarg_1); //writer.EmitInstructionLoadIndirect(Assets.ObjectTypeSignature); writer.EmitInstructionType(OpCodeNumber.Ldobj, Assets.ObjectTypeSignature); writer.EmitConvertFromObject(property.Parent); } ) ); //On the location binding the value parameter is at psotion 3 writer.EmitInstruction(OpCodeNumber.Ldarg_3); }else { writer.AssignValue_LocalVariable(oldValueVariable, () => writer.Get_PropertyValue(property)); //For a normal property the value parameter is at position 1 writer.EmitInstruction(OpCodeNumber.Ldarg_1); } if (propertyType.IsStruct()) { writer.EmitInstructionType(OpCodeNumber.Box, propertyType); } writer.Box_LocalVariableIfNeeded(oldValueVariable); var isPrimitive = propertyType.IsPrimitive(); if (isPrimitive) { writer.Compare_Primitives(); } else { //TODO: Try and use the equality operator when present writer.Compare_Objects(Assets.ObjectEqualsMethod); } //writer.Leave_IfTrue(_context.LeaveBranchTarget); writer.Leave_IfTrue(context.LeaveBranchTarget); writer.DetachInstructionSequence(); } }
public override void Implement(MethodBodyTransformationContext context) { AddSymJoinPoint(context); AddGuard(context); //context.InstructionBlock.MethodBody.Visit(new IMethodBodyVisitor[] { new Visitor(this, context) }); }
public override void Implement(MethodBodyTransformationContext context) { var methodWrapper = new EnhancePropertySetterMethodBodyWrappingImplementation(_transformationContext, AspectWeaver.AspectInfrastructureTask, context); methodWrapper.Execute(); }
public override void Implement(MethodBodyTransformationContext context) { context.InstructionBlock.MethodBody.Visit(new[] { new Visitor(this, context) }); }
public Visitor(Instance instance, MethodBodyTransformationContext context) { this.instance = instance; this.context = context; }
public Implementation(LoggingAspectTransformationInstance transformationInstance, MethodBodyTransformationContext context) : base(transformationInstance.AspectWeaver.AspectInfrastructureTask, context) { this.transformationInstance = transformationInstance; this.backendInstance = this.transformationInstance.parent.backend.CreateInstance(transformationInstance.AspectWeaverInstance); // todo fix configuration this.onEntryOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue<LogAspectConfiguration, LogOptions>(c => c.OnEntryOptions); this.onSuccessOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue<LogAspectConfiguration, LogOptions>(c => c.OnSuccessOptions); this.onExceptionOptions = this.transformationInstance.AspectWeaverInstance.GetConfigurationValue<LogAspectConfiguration, LogOptions>(c => c.OnExceptionOptions); }
public override void Implement(MethodBodyTransformationContext context) { /* We want to generate the following * if ( !this.<>4__this.Dispatcher.CheckAccess() ) * { * SynchronizationContext oldContext = SynchronizationContext.Current; * SynchronizationContext.SetSynchronizationContext( this.<>4__this.Dispatcher.SynchronizationContext ); * this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter(); * this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref this.<>t__dispatchAwaiter, ref this); * SynchronizationContext.SetSynchronizationContext( oldContext ); * return; * } * */ MethodDefDeclaration targetMethod = (MethodDefDeclaration)context.TargetElement; TypeDefDeclaration targetType = targetMethod.DeclaringType; targetMethod.MethodBody.MaxStack = -1; // Add the field where we will store the awaiter. FieldDefDeclaration awaiterFieldDef = new FieldDefDeclaration { Name = "<>t__dispatchAwaiter", FieldType = this.parent.yieldAwaiter_Type, Attributes = FieldAttributes.Private }; targetType.Fields.Add(awaiterFieldDef); IField awaiterField = awaiterFieldDef.GetCanonicalGenericInstance(); // Find other fields. IField thisField = targetType.Fields.Single <FieldDefDeclaration>(f => f.Name.EndsWith("__this")).GetCanonicalGenericInstance(); IField builderField = targetType.Fields.GetByName("<>t__builder").GetCanonicalGenericInstance(); // Emit instructions. InstructionBlock myBlock = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null); InstructionBlock theirBlock = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null); LocalVariableSymbol awaitableLocal = myBlock.DefineLocalVariable(this.parent.task_Yield_Method.ReturnType, "awaitable"); LocalVariableSymbol synchronizationContextLocal = myBlock.DefineLocalVariable(this.parent.synchronizationContext_Type, "oldContext"); InstructionSequence entrySequence = myBlock.AddInstructionSequence(null, NodePosition.After, null); InstructionSequence exitSequence = myBlock.AddInstructionSequence(null, NodePosition.After, null); InstructionWriter writer = new InstructionWriter(); writer.AttachInstructionSequence(entrySequence); // Emit: if ( this.<>4__this.Dispatcher.CheckAccess() ) goto exitSequence; writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method); writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_CheckAccess_Method); writer.EmitBranchingInstruction(OpCodeNumber.Brtrue, exitSequence); // Emit: this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter() writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.task_Yield_Method); writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, awaitableLocal); writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloca, awaitableLocal); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.yieldAwaitable_GetAwaiter_Method); writer.EmitInstructionField(OpCodeNumber.Stfld, awaiterField); // Emit: oldContext = SynchronizationContext.Current writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_getCurrent_Method); writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, synchronizationContextLocal); // Emit: SynchronizationContext.SetSynchronizationContext(this.<>4__this.Dispatcher.SynchronizationContext) writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method); writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_getSynchronizationContext_Method); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method); // Choose which AwaitUnsafeOnCompleted method to call. IGenericMethodDefinition awaitUnsafeOnCompletedMethod; ITypeSignature[] awaitUnsafeOnCompletedGenericTypeParameters; if (builderField.FieldType == this.parent.asyncVoidMethodBuilder_Type) { awaitUnsafeOnCompletedMethod = this.parent.asyncVoidMethodBuilder_AwaitUnsafeOnCompleted_Method; awaitUnsafeOnCompletedGenericTypeParameters = null; } else if (builderField.FieldType == this.parent.asyncTaskMethodBuilder_Type) { awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilder_AwaitUnsafeOnCompleted_Method; awaitUnsafeOnCompletedGenericTypeParameters = null; } else { // This is a generic task. awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilderGeneric_AwaitUnsafeOnCompleted_Method; awaitUnsafeOnCompletedGenericTypeParameters = builderField.FieldType.GetGenericContext(GenericContextOptions.None).GetGenericTypeParameters(); } IMethod awaitUnsafeOnCompletedGenericMethod = awaitUnsafeOnCompletedMethod.GetGenericInstance(new GenericMap(awaitUnsafeOnCompletedGenericTypeParameters, new ITypeSignature[] { this.parent.yieldAwaiter_Type, targetType.GetCanonicalGenericInstance() })); // Emit: this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref this.<>t__dispatchAwaiter, ref this); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldflda, builderField); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldflda, awaiterField); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionMethod(OpCodeNumber.Call, awaitUnsafeOnCompletedGenericMethod); // Emit: SynchronizationContext.SetSynchronizationContext( oldContext ); writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, synchronizationContextLocal); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method); writer.EmitBranchingInstruction(OpCodeNumber.Leave, context.LeaveBranchTarget); writer.DetachInstructionSequence(); // We are done. Give the pipeline to the next node. context.AddRedirection(theirBlock, context.LeaveBranchTarget); }