private void EmitCallToBaseGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo, ArgumentReference streamingContext) { var baseGetObjectData = targetType.GetMethod("GetObjectData", new[] { typeof(SerializationInfo), typeof(StreamingContext) }); codebuilder.AddStatement(new ExpressionStatement( new MethodInvocationExpression(baseGetObjectData, serializationInfo.ToExpression(), streamingContext.ToExpression()))); }
private void GenerateSerializationConstructor(ClassEmitter emitter) { var serializationInfo = new ArgumentReference(typeof(SerializationInfo)); var streamingContext = new ArgumentReference(typeof(StreamingContext)); var ctor = emitter.CreateConstructor(serializationInfo, streamingContext); ctor.CodeBuilder.AddStatement( new ConstructorInvocationStatement(serializationConstructor, serializationInfo.ToExpression(), streamingContext.ToExpression())); foreach (var field in serializedFields) { var getValue = new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.GetValue, new ConstReference(field.Reference.Name).ToExpression(), new TypeTokenExpression(field.Reference.FieldType)); ctor.CodeBuilder.AddStatement(new AssignStatement( field, new ConvertExpression(field.Reference.FieldType, typeof(object), getValue))); } ctor.CodeBuilder.AddStatement(new ReturnStatement()); }
/// <summary> /// Generates the constructor for the nested class that extends /// <see cref="AbstractInvocation"/> /// </summary> /// <param name="targetFieldType"></param> /// <param name="nested"></param> /// <param name="targetField"></param> /// <param name="version"></param> protected void CreateIInvocationConstructor( Type targetFieldType, NestedClassEmitter nested, FieldReference targetField, ConstructorVersion version) { ArgumentReference cArg0 = new ArgumentReference(targetFieldType); ArgumentReference cArg1 = new ArgumentReference(typeof(IInterceptor[])); ArgumentReference cArg2 = new ArgumentReference(typeof(Type)); ArgumentReference cArg3 = new ArgumentReference(typeof(MethodInfo)); ArgumentReference cArg4 = null; ArgumentReference cArg6 = new ArgumentReference(typeof(object)); if (version == ConstructorVersion.WithTargetMethod) { cArg4 = new ArgumentReference(typeof(MethodInfo)); } ArgumentReference cArg5 = new ArgumentReference(typeof(object[])); ConstructorEmitter constructor; if (cArg4 == null) { constructor = nested.CreateConstructor(cArg0, cArg1, cArg2, cArg3, cArg5, cArg6); } else { constructor = nested.CreateConstructor(cArg0, cArg1, cArg2, cArg3, cArg4, cArg5, cArg6); } constructor.CodeBuilder.AddStatement(new AssignStatement(targetField, cArg0.ToExpression())); if (cArg4 == null) { constructor.CodeBuilder.InvokeBaseConstructor(Constants.AbstractInvocationConstructorWithoutTargetMethod, cArg0, cArg6, cArg1, cArg2, cArg3, cArg5); } else { constructor.CodeBuilder.InvokeBaseConstructor(Constants.AbstractInvocationConstructorWithTargetMethod, cArg0, cArg6, cArg1, cArg2, cArg3, cArg4, cArg5); } constructor.CodeBuilder.AddStatement(new ReturnStatement()); }
/// <summary> /// If callbackMethod is null the InvokeOnTarget implementation /// is just the code to throw an exception /// </summary> /// <param name="emitter"></param> /// <param name="targetType"></param> /// <param name="targetForInvocation"></param> /// <param name="methodInfo"></param> /// <param name="callbackMethod"></param> /// <param name="version"></param> /// <param name="allowChangeTarget">If true the invocation will implement the IChangeProxyTarget interface</param> /// <returns></returns> protected NestedClassEmitter BuildInvocationNestedType( ClassEmitter emitter, Type targetType, Type targetForInvocation, MethodInfo methodInfo, MethodInfo callbackMethod, ConstructorVersion version, bool allowChangeTarget) { CheckNotGenericTypeDefinition(targetType, "targetType"); CheckNotGenericTypeDefinition(targetForInvocation, "targetForInvocation"); nestedCounter++; Type[] interfaces = new Type[0]; if (allowChangeTarget) { interfaces = new Type[] {typeof(IChangeProxyTarget)}; } NestedClassEmitter nested = new NestedClassEmitter(emitter, "Invocation" + methodInfo.Name + "_" + nestedCounter.ToString(), typeof(AbstractInvocation), interfaces); // invocation only needs to mirror the generic parameters of the MethodInfo // targetType cannot be a generic type definition nested.CreateGenericParameters(methodInfo.GetGenericArguments()); // Create the invocation fields FieldReference targetRef = nested.CreateField("target", targetForInvocation); // Create constructor CreateIInvocationConstructor(targetForInvocation, nested, targetRef, version); if (allowChangeTarget) { ArgumentReference argument1 = new ArgumentReference(typeof(object)); MethodEmitter methodEmitter = nested.CreateMethod("ChangeInvocationTarget", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), argument1); methodEmitter.CodeBuilder.AddStatement( new AssignStatement(targetRef, new ConvertExpression(targetType, argument1.ToExpression()) ) ); methodEmitter.CodeBuilder.AddStatement(new ReturnStatement()); } // InvokeMethodOnTarget implementation if (callbackMethod != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); CreateIInvocationInvokeOnTarget(emitter, nested, parameters, targetRef, callbackMethod); } else { CreateEmptyIInvocationInvokeOnTarget(nested); } nested.DefineCustomAttribute(new SerializableAttribute()); return nested; }
protected void GenerateSerializationConstructor(ClassEmitter emitter, FieldReference interceptorField, bool delegateToBaseGetObjectData) { ArgumentReference arg1 = new ArgumentReference(typeof(SerializationInfo)); ArgumentReference arg2 = new ArgumentReference(typeof(StreamingContext)); ConstructorEmitter constr = emitter.CreateConstructor(arg1, arg2); constr.CodeBuilder.AddStatement( new ConstructorInvocationStatement(serializationConstructor, arg1.ToExpression(), arg2.ToExpression())); Type[] object_arg = new Type[] {typeof(String), typeof(Type)}; MethodInfo getValueMethod = typeof(SerializationInfo).GetMethod("GetValue", object_arg); MethodInvocationExpression getInterceptorInvocation = new MethodInvocationExpression(arg1, getValueMethod, new ConstReference("__interceptors").ToExpression(), new TypeTokenExpression(typeof(IInterceptor[]))); constr.CodeBuilder.AddStatement(new AssignStatement( interceptorField, new ConvertExpression(typeof(IInterceptor[]), typeof(object), getInterceptorInvocation))); constr.CodeBuilder.AddStatement(new ReturnStatement()); }
protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference arg1, ArgumentReference arg2) { Type[] key_and_object = new Type[] {typeof(String), typeof(Object)}; Type[] key_and_bool = new Type[] {typeof(String), typeof(bool)}; MethodInfo addValueMethod = typeof(SerializationInfo).GetMethod("AddValue", key_and_object); MethodInfo addValueBoolMethod = typeof(SerializationInfo).GetMethod("AddValue", key_and_bool); codebuilder.AddStatement(new ExpressionStatement( new MethodInvocationExpression(arg1, addValueBoolMethod, new ConstReference("__delegateToBase").ToExpression(), new ConstReference(delegateToBaseGetObjectData ? 1 : 0). ToExpression()))); if (delegateToBaseGetObjectData) { MethodInfo baseGetObjectData = targetType.GetMethod("GetObjectData", new Type[] {typeof(SerializationInfo), typeof(StreamingContext)}); codebuilder.AddStatement(new ExpressionStatement( new MethodInvocationExpression(baseGetObjectData, arg1.ToExpression(), arg2.ToExpression()))); } else { LocalReference members_ref = codebuilder.DeclareLocal(typeof(MemberInfo[])); LocalReference data_ref = codebuilder.DeclareLocal(typeof(object[])); MethodInfo getSerMembers = typeof(FormatterServices).GetMethod("GetSerializableMembers", new Type[] {typeof(Type)}); MethodInfo getObjData = typeof(FormatterServices).GetMethod("GetObjectData", new Type[] {typeof(object), typeof(MemberInfo[])}); codebuilder.AddStatement(new AssignStatement(members_ref, new MethodInvocationExpression(null, getSerMembers, new TypeTokenExpression(targetType)))); codebuilder.AddStatement(new AssignStatement(data_ref, new MethodInvocationExpression(null, getObjData, SelfReference.Self.ToExpression(), members_ref.ToExpression()))); codebuilder.AddStatement(new ExpressionStatement( new MethodInvocationExpression(arg1, addValueMethod, new ConstReference("__data").ToExpression(), data_ref.ToExpression()))); } }
protected override void CustomizeGetObjectData(AbstractCodeBuilder codebuilder, ArgumentReference serializationInfo, ArgumentReference streamingContext, ClassEmitter emitter) { codebuilder.AddStatement(new ExpressionStatement( new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.AddValue_Bool, new ConstReference("__delegateToBase").ToExpression(), new ConstReference(delegateToBaseGetObjectData ? 1 : 0). ToExpression()))); if (delegateToBaseGetObjectData) { MethodInfo baseGetObjectData = targetType.GetMethod("GetObjectData", new[] {typeof (SerializationInfo), typeof (StreamingContext)}); codebuilder.AddStatement(new ExpressionStatement( new MethodInvocationExpression(baseGetObjectData, serializationInfo.ToExpression(), streamingContext.ToExpression()))); } else { LocalReference members_ref = codebuilder.DeclareLocal(typeof (MemberInfo[])); LocalReference data_ref = codebuilder.DeclareLocal(typeof (object[])); codebuilder.AddStatement(new AssignStatement(members_ref, new MethodInvocationExpression(null, FormatterServicesMethods. GetSerializableMembers, new TypeTokenExpression(targetType)))); codebuilder.AddStatement(new AssignStatement(data_ref, new MethodInvocationExpression(null, FormatterServicesMethods.GetObjectData, SelfReference.Self.ToExpression(), members_ref.ToExpression()))); codebuilder.AddStatement(new ExpressionStatement( new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.AddValue_Object, new ConstReference("__data").ToExpression(), data_ref.ToExpression()))); } }