protected void ImplementProxyTargetAccessor(ClassEmitter emitter, FieldReference interceptorsField) { var dynProxyGetTarget = emitter.CreateMethod("DynProxyGetTarget", typeof(object)); dynProxyGetTarget.CodeBuilder.AddStatement( new ReturnStatement(new ConvertExpression(typeof(object), targetType, GetTargetReferenceExpression(emitter)))); var dynProxySetTarget = emitter.CreateMethod("DynProxySetTarget", typeof(void), typeof(object)); // we can only change the target of the interface proxy var targetField = GetTargetReference(emitter) as FieldReference; if (targetField != null) { dynProxySetTarget.CodeBuilder.AddStatement( new AssignStatement(targetField, new ConvertExpression(targetField.Fieldbuilder.FieldType, dynProxySetTarget.Arguments[0].ToExpression()))); } else { dynProxySetTarget.CodeBuilder.AddStatement( new ThrowStatement(typeof(InvalidOperationException), "Cannot change the target of the class proxy.")); } dynProxySetTarget.CodeBuilder.AddStatement(new ReturnStatement()); var getInterceptors = emitter.CreateMethod("GetInterceptors", typeof(IInterceptor[])); getInterceptors.CodeBuilder.AddStatement( new ReturnStatement(interceptorsField)); }
public void Generate(ClassEmitter emitter) { var interceptorsField = emitter.GetField("__interceptors"); var targetReference = getTargetReference(); var dynProxyGetTarget = emitter.CreateMethod(nameof(IProxyTargetAccessor.DynProxyGetTarget), typeof(object)); dynProxyGetTarget.CodeBuilder.AddStatement( new ReturnStatement(new ConvertExpression(typeof(object), targetType, targetReference))); var dynProxySetTarget = emitter.CreateMethod(nameof(IProxyTargetAccessor.DynProxySetTarget), typeof(void), typeof(object)); // we can only change the target of the interface proxy if (targetReference is FieldReference targetField) { dynProxySetTarget.CodeBuilder.AddStatement( new AssignStatement(targetField, new ConvertExpression(targetField.FieldBuilder.FieldType, dynProxySetTarget.Arguments[0]))); } else { dynProxySetTarget.CodeBuilder.AddStatement( new ThrowStatement(typeof(InvalidOperationException), "Cannot change the target of the class proxy.")); } dynProxySetTarget.CodeBuilder.AddStatement(new ReturnStatement()); var getInterceptors = emitter.CreateMethod(nameof(IProxyTargetAccessor.GetInterceptors), typeof(IInterceptor[])); getInterceptors.CodeBuilder.AddStatement( new ReturnStatement(interceptorsField)); }
protected void ImplementProxyTargetAccessor(ClassEmitter emitter, FieldReference interceptorsField) { var dynProxyGetTarget = emitter.CreateMethod("DynProxyGetTarget", typeof(object)); dynProxyGetTarget.CodeBuilder.AddStatement( new ReturnStatement(new ConvertExpression(typeof(object), targetType, GetTargetReferenceExpression(emitter)))); var getInterceptors = emitter.CreateMethod("GetInterceptors", typeof(IInterceptor[])); getInterceptors.CodeBuilder.AddStatement( new ReturnStatement(interceptorsField)); }
public void AddStatement() { var method = ClassEmitter.CreateMethod("Statement", MethodAttributes.Public, typeof(void), new Type[0]) .AddStatement(new ReturnStatement()); BuildInstanceAndInvokeMethod(method); }
private MethodBuilder CreateCallbackMethod(ClassEmitter emitter, MethodInfo methodInfo, MethodInfo methodOnTarget) { MethodInfo targetMethod = methodOnTarget ?? methodInfo; // MethodBuild creation MethodEmitter callBackMethod = emitter.CreateMethod(namingScope.GetUniqueName(methodInfo.Name + "_callback")); callBackMethod.CopyParametersAndReturnTypeFrom(targetMethod, emitter); // Generic definition if (targetMethod.IsGenericMethod) { targetMethod = targetMethod.MakeGenericMethod(callBackMethod.GenericTypeParams); } // Parameters exp Expression[] exps = new Expression[callBackMethod.Arguments.Length]; for (int i = 0; i < callBackMethod.Arguments.Length; i++) { exps[i] = callBackMethod.Arguments[i].ToExpression(); } // invocation on base class callBackMethod.CodeBuilder.AddStatement( new ReturnStatement(new MethodInvocationExpression(SelfReference.Self, targetMethod, exps))); return(callBackMethod.MethodBuilder); }
public void ImplementByReturningVoid() { var method = ClassEmitter.CreateMethod("MethodReturningVoid", MethodAttributes.Public, typeof(void), new Type[0]) .ImplementByReturningVoid(); Assert.That(BuildInstanceAndInvokeMethod(method), Is.EqualTo(null)); }
public void ImplementByReturning() { var method = ClassEmitter.CreateMethod("MethodReturning", MethodAttributes.Public, typeof(string), new Type[0]) .ImplementByReturning(new ConstReference("none").ToExpression()); Assert.That(BuildInstanceAndInvokeMethod(method), Is.EqualTo("none")); }
private MethodBuilder CreateCallbackMethod(ClassEmitter emitter, MethodInfo methodInfo, MethodInfo methodOnTarget) { var targetMethod = methodOnTarget ?? methodInfo; var callBackMethod = emitter.CreateMethod(namingScope.GetUniqueName(methodInfo.Name + "_callback"), targetMethod); if (targetMethod.IsGenericMethod) { targetMethod = targetMethod.MakeGenericMethod(callBackMethod.GenericTypeParams.AsTypeArray()); } var exps = new Expression[callBackMethod.Arguments.Length]; for (var i = 0; i < callBackMethod.Arguments.Length; i++) { exps[i] = callBackMethod.Arguments[i].ToExpression(); } // invocation on base class callBackMethod.CodeBuilder.AddStatement( new ReturnStatement( new MethodInvocationExpression(SelfReference.Self, targetMethod, exps))); return(callBackMethod.MethodBuilder); }
public void DeclareLocal() { var method = ClassEmitter.CreateMethod("Statement", MethodAttributes.Public, typeof(int), new Type[0]); LocalReference local = method.DeclareLocal(typeof(int)); method.ImplementByReturning(local.ToExpression()); Assert.That(BuildInstanceAndInvokeMethod(method), Is.EqualTo(0)); }
public void ImplementByReturningDefaultVoid() { var voidMethod = ClassEmitter.CreateMethod("VoidMethod", MethodAttributes.Public, typeof(void), new Type[0]) .ImplementByReturningDefault(); object instance = BuildInstance(); Assert.That(InvokeMethod(instance, voidMethod), Is.EqualTo(null)); Assert.That(GetMethod(instance, voidMethod).ReturnType, Is.EqualTo(typeof(void))); }
public void AddCustomAttribute() { var method = ClassEmitter.CreateMethod("Statement", MethodAttributes.Public, typeof(void), new Type[0]); method.AddCustomAttribute(new CustomAttributeBuilder(typeof(SimpleAttribute).GetConstructor(Type.EmptyTypes), new object[0])); MethodInfo methodInfo = BuildTypeAndGetMethod(method); Assert.That(methodInfo.GetCustomAttributes(typeof(SimpleAttribute), false).Length, Is.EqualTo(1)); }
public void AcceptExpression() { var fakeGenerator = new DynamicMethod("Test", typeof(void), Type.EmptyTypes).GetILGenerator(); var expressionMock = MockRepository.GenerateMock <Expression> (); var method = ClassEmitter.CreateMethod("AcceptStatement", MethodAttributes.Public, typeof(void), new Type[0]); method.AcceptExpression(expressionMock, fakeGenerator); expressionMock.AssertWasCalled(mock => mock.Emit(Arg <IMemberEmitter> .Matches(e => e.Member == method.MethodBuilder), Arg.Is(fakeGenerator))); }
public void ImplementByBaseCall() { var method = ClassEmitter.CreateMethod("NewEquals", MethodAttributes.Public, typeof(bool), new[] { typeof(object) }); method.ImplementByBaseCall(typeof(object).GetMethod("Equals", new[] { typeof(object) })); object instance = BuildInstance(); Assert.That(InvokeMethod(instance, method, 5), Is.EqualTo(false)); Assert.That(InvokeMethod(instance, method, instance), Is.EqualTo(true)); }
protected override void CreateFields(ClassEmitter emitter) { base.CreateFields(emitter); var method = emitter.CreateMethod("__deserialize", MethodAttributes.Public | MethodAttributes.HideBySig, typeof(void), typeof(System.Runtime.Serialization.StreamingContext)); method.MethodBuilder.SetCustomAttribute(new CustomAttributeBuilder(deserializingAttribute, new object[0])); var il = method.MethodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.EmitCall(OpCodes.Call, initProxyMethod.MakeGenericMethod(targetType), null); }
public void ImplementByDelegating() { var method = ClassEmitter.CreateMethod( "EqualsSelf", MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new[] { typeof(object) }); method.ImplementByDelegating(method.ArgumentReferences[0], typeof(object).GetMethod("Equals", new[] { typeof(object) })); object instance = BuildInstance(); Assert.That(InvokeMethod(instance, method, 5), Is.EqualTo(true)); Assert.That(InvokeMethod(instance, method, "five"), Is.EqualTo(true)); }
public void ImplementByReturningDefaultReferenceType() { var objectMethod = ClassEmitter.CreateMethod("ObjectMethod", MethodAttributes.Public, typeof(object), new Type[0]) .ImplementByReturningDefault(); var stringMethod = ClassEmitter.CreateMethod("StringMethod", MethodAttributes.Public, typeof(string), new Type[0]) .ImplementByReturningDefault(); object instance = BuildInstance(); Assert.That(InvokeMethod(instance, objectMethod), Is.EqualTo(null)); Assert.That(InvokeMethod(instance, stringMethod), Is.EqualTo(null)); }
public void ImplementByReturningDefaultValueType() { var intMethod = ClassEmitter.CreateMethod("IntMethod", MethodAttributes.Public, typeof(int), new Type[0]) .ImplementByReturningDefault(); var dateTimeMethod = ClassEmitter.CreateMethod("DateTimeMethod", MethodAttributes.Public, typeof(DateTime), new Type[0]) .ImplementByReturningDefault(); object instance = BuildInstance(); Assert.That(InvokeMethod(instance, intMethod), Is.EqualTo(0)); Assert.That(InvokeMethod(instance, dateTimeMethod), Is.EqualTo(new DateTime())); }
public void StaticMethodArguments() { ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "Foo", typeof(List <object>), Type.EmptyTypes); MethodEmitter methodEmitter = emitter.CreateMethod("StaticMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(string), typeof(string)); methodEmitter.CodeBuilder.AddStatement(new ReturnStatement(methodEmitter.Arguments[0])); Type t = emitter.BuildType(); Assert.AreEqual("five", t.GetMethod("StaticMethod").Invoke(null, new object[] { "five" })); }
public void ImplementByDelegatingToValueType() { var method = ClassEmitter.CreateMethod( "IntEqualsSelf", MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new[] { typeof(int) }); LocalReference local = method.DeclareLocal(typeof(int)); method.AddStatement(new AssignStatement(local, method.ArgumentReferences[0].ToExpression())); method.ImplementByDelegating(local, typeof(int).GetMethod("Equals", new[] { typeof(int) })); object instance = BuildInstance(); Assert.That(InvokeMethod(instance, method, 5), Is.EqualTo(true)); }
public void InstanceMethodArguments() { ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "Foo", typeof(List <object>), Type.EmptyTypes); MethodEmitter methodEmitter = emitter.CreateMethod("InstanceMethod", MethodAttributes.Public, typeof(string), typeof(string)); methodEmitter.CodeBuilder.AddStatement(new ReturnStatement(methodEmitter.Arguments[0])); Type t = emitter.BuildType(); object instance = Activator.CreateInstance(t); Assert.AreEqual("six", t.GetMethod("InstanceMethod").Invoke(instance, new object[] { "six" })); }
public void UsingClassEmitterForInterfaces() { ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "IFoo", null, Type.EmptyTypes, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false); emitter.CreateMethod("MyMethod", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, typeof(void)); Type t = emitter.BuildType(); Assert.IsTrue(t.IsInterface); MethodInfo method = t.GetMethod("MyMethod"); Assert.IsNotNull(method); }
public void ILGenerator() { var method = ClassEmitter.CreateMethod("StaticMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(string), new Type[0]); ILGenerator gen = method.ILGenerator; Assert.That(gen, Is.Not.Null); gen.Emit(OpCodes.Ldstr, "manual retval"); gen.Emit(OpCodes.Ret); object returnValue = BuildTypeAndInvokeMethod(method); Assert.That(returnValue, Is.EqualTo("manual retval")); }
public IMethodEmitter GetMethodEmitter(bool isStatic, Type returnType, Type[] parameterTypes) { if (_methodEmitter == null) { MethodAttributes flags = MethodAttributes.Public; if (isStatic) { flags |= MethodAttributes.Static; } _methodEmitter = ClassEmitter.CreateMethod("TestMethod", flags, returnType, parameterTypes); } return(_methodEmitter); }
public void ImplementByThrowing() { var method = ClassEmitter.CreateMethod("ThrowingMethod", MethodAttributes.Public, typeof(void), new Type[0]) .ImplementByThrowing(typeof(NotFiniteNumberException), "Who would have expected this?"); try { BuildInstanceAndInvokeMethod(method); } catch (TargetInvocationException ex) { throw ex.InnerException; } }
public void CopiedMethod() { var method = ClassEmitter.CreateMethod("SimpleMethod", MethodAttributes.Public, typeof(List <int>).GetMethod("Contains", new[] { typeof(int) })); method.ImplementByReturning(new ConstReference(false).ToExpression()); object returnValue = BuildInstanceAndInvokeMethod(method, 12); Assert.That(returnValue, Is.EqualTo(false)); Assert.That(method.MethodBuilder, Is.Not.Null); Assert.That(method.ReturnType, Is.EqualTo(typeof(bool))); Assert.That(method.ParameterTypes, Is.EqualTo(new[] { typeof(int) })); }
public void SimpleMethod() { var method = ClassEmitter.CreateMethod("SimpleMethod", MethodAttributes.Public, typeof(string), new[] { typeof(string) }); method.ImplementByReturning( new MethodInvocationExpression(null, typeof(string).GetMethod("Concat", new[] { typeof(string), typeof(string) }), method.ArgumentReferences[0].ToExpression(), new ConstReference("Simple").ToExpression())); object returnValue = BuildInstanceAndInvokeMethod(method, "Param"); Assert.That(returnValue, Is.EqualTo("ParamSimple")); Assert.That(method.MethodBuilder, Is.Not.Null); Assert.That(method.ParameterTypes, Is.EqualTo(new[] { typeof(string) })); }
public void GetArgumentExpressions() { var method = ClassEmitter.CreateMethod( "StaticMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(string), new[] { typeof(string) }); Expression[] argumentExpressions = method.GetArgumentExpressions(); Assert.That(argumentExpressions.Length, Is.EqualTo(method.ArgumentReferences.Length)); for (int i = 0; i < argumentExpressions.Length; ++i) { Assert.That(PrivateInvoke.GetNonPublicField(argumentExpressions[i], "reference"), Is.EqualTo(method.ArgumentReferences[i])); } }
public void CopiedMethod_Generic() { var method = ClassEmitter.CreateMethod("SimpleMethod", MethodAttributes.Public, typeof(ClassWithSimpleGenericMethod).GetMethod("GenericMethod")); method.ImplementByReturning(new ConstReference("done").ToExpression()); object returnValue = BuildInstanceAndInvokeMethod(method, new[] { typeof(int), typeof(string), typeof(bool) }, 12, "", false); Assert.That(returnValue, Is.EqualTo("done")); Assert.That(method.MethodBuilder, Is.Not.Null); Assert.That(method.ReturnType, Is.EqualTo(typeof(string))); Assert.That(method.ParameterTypes, Has.Length.EqualTo(3)); Assert.That(method.ParameterTypes[0].IsGenericParameter, Is.True); Assert.That(method.ParameterTypes[0].Name, Is.EqualTo("T1")); Assert.That(method.ParameterTypes[1].IsGenericParameter, Is.True); Assert.That(method.ParameterTypes[1].Name, Is.EqualTo("T2")); Assert.That(method.ParameterTypes[2].IsGenericParameter, Is.True); Assert.That(method.ParameterTypes[2].Name, Is.EqualTo("T3")); }
protected void ImplementGetObjectData(ClassEmitter emitter) { var getObjectData = emitter.CreateMethod( "GetObjectData", typeof(void), new[] { typeof(SerializationInfo), typeof(StreamingContext) } ); var info = getObjectData.Arguments[0]; var typeLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(Type)); getObjectData.CodeBuilder.AddStatement( new AssignStatement( typeLocal, new MethodInvocationExpression( null, TypeMethods.StaticGetType, new LiteralStringExpression( typeof(ProxyObjectReference).AssemblyQualifiedName ), new LiteralBoolExpression(true), new LiteralBoolExpression(false) ) ) ); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression(info, SerializationInfoMethods.SetType, typeLocal) ); foreach (var field in emitter.GetAllFields()) { if (field.Reference.IsStatic) { continue; } if (field.Reference.IsNotSerialized) { continue; } AddAddValueInvocation(info, getObjectData, field); } var interfacesLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(string[])); getObjectData.CodeBuilder.AddStatement( new AssignStatement( interfacesLocal, new NewArrayExpression(interfaces.Length, typeof(string)) ) ); for (var i = 0; i < interfaces.Length; i++) { getObjectData.CodeBuilder.AddStatement( new AssignArrayStatement( interfacesLocal, i, new LiteralStringExpression(interfaces[i].AssemblyQualifiedName) ) ); } getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, new LiteralStringExpression("__interfaces"), interfacesLocal ) ); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, new LiteralStringExpression("__baseType"), new LiteralStringExpression(emitter.BaseType.AssemblyQualifiedName) ) ); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, new LiteralStringExpression("__proxyGenerationOptions"), emitter.GetField("proxyGenerationOptions") ) ); getObjectData.CodeBuilder.AddStatement( new MethodInvocationExpression( info, SerializationInfoMethods.AddValue_Object, new LiteralStringExpression("__proxyTypeId"), new LiteralStringExpression(proxyTypeId) ) ); CustomizeGetObjectData( getObjectData.CodeBuilder, info, getObjectData.Arguments[1], emitter ); getObjectData.CodeBuilder.AddStatement(new ReturnStatement()); }
protected void ImplementGetObjectData(ClassEmitter emitter) { var serializationInfo = new ArgumentReference(typeof(SerializationInfo)); var streamingContext = new ArgumentReference(typeof(StreamingContext)); MethodEmitter getObjectData = emitter.CreateMethod("GetObjectData", serializationInfo, streamingContext); LocalReference typeLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(Type)); getObjectData.CodeBuilder.AddStatement( new AssignStatement( typeLocal, new MethodInvocationExpression( null, TypeMethods.StaticGetType, new ConstReference(typeof(ProxyObjectReference).AssemblyQualifiedName).ToExpression(), new ConstReference(1).ToExpression(), new ConstReference(0).ToExpression()))); getObjectData.CodeBuilder.AddStatement( new ExpressionStatement( new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.SetType, typeLocal.ToExpression()))); foreach (var field in emitter.GetAllFields()) { if (field.Reference.IsStatic) { continue; } if (field.Reference.IsNotSerialized) { continue; } AddAddValueInvocation(serializationInfo, getObjectData, field); } LocalReference interfacesLocal = getObjectData.CodeBuilder.DeclareLocal(typeof(string[])); getObjectData.CodeBuilder.AddStatement( new AssignStatement( interfacesLocal, new NewArrayExpression(interfaces.Length, typeof(string)))); for (int i = 0; i < interfaces.Length; i++) { getObjectData.CodeBuilder.AddStatement( new AssignArrayStatement( interfacesLocal, i, new ConstReference(interfaces[i].AssemblyQualifiedName).ToExpression())); } getObjectData.CodeBuilder.AddStatement( new ExpressionStatement( new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, new ConstReference("__interfaces").ToExpression(), interfacesLocal.ToExpression()))); getObjectData.CodeBuilder.AddStatement( new ExpressionStatement( new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, new ConstReference("__baseType").ToExpression(), new ConstReference(emitter.BaseType.AssemblyQualifiedName).ToExpression()))); getObjectData.CodeBuilder.AddStatement( new ExpressionStatement( new MethodInvocationExpression( serializationInfo, SerializationInfoMethods.AddValue_Object, new ConstReference("__proxyGenerationOptions").ToExpression(), emitter.GetField("proxyGenerationOptions").ToExpression()))); getObjectData.CodeBuilder.AddStatement( new ExpressionStatement( new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.AddValue_Object, new ConstReference("__proxyTypeId").ToExpression(), new ConstReference(proxyTypeId).ToExpression()))); CustomizeGetObjectData(getObjectData.CodeBuilder, serializationInfo, streamingContext, emitter); getObjectData.CodeBuilder.AddStatement(new ReturnStatement()); }