private FieldReference BuildDelegateToken(ClassEmitter proxy)
		{
			var callback = proxy.CreateStaticField(namingScope.GetUniqueName("callback_" + method.Method.Name), delegateType);
			var createDelegate = new MethodInvocationExpression(
				null,
				DelegateMethods.CreateDelegate,
				new TypeTokenExpression(delegateType),
				NullExpression.Instance,
				new MethodTokenExpression(method.MethodOnTarget));
			var bindDelegate = new AssignStatement(callback, new ConvertExpression(delegateType, createDelegate));

			proxy.ClassConstructor.CodeBuilder.AddStatement(bindDelegate);
			return callback;
		}
예제 #2
0
		protected FieldReference CreateOptionsField(ClassEmitter emitter)
		{
			return emitter.CreateStaticField("proxyGenerationOptions", typeof (ProxyGenerationOptions));
		}
		protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class, ProxyGenerationOptions options,INamingScope namingScope)
		{
			var invocationType = invocation;

			Trace.Assert(MethodToOverride.IsGenericMethod == invocationType.IsGenericTypeDefinition);
			Type[] genericMethodArgs = Type.EmptyTypes;

			ConstructorInfo constructor = invocation.GetConstructors()[0];


			Expression proxiedMethodTokenExpression;
			if (MethodToOverride.IsGenericMethod)
			{
				// bind generic method arguments to invocation's type arguments
				genericMethodArgs = emitter.MethodBuilder.GetGenericArguments();
				invocationType = invocationType.MakeGenericType(genericMethodArgs);
				constructor = TypeBuilder.GetConstructor(invocationType, constructor);

				// Not in the cache: generic method
				proxiedMethodTokenExpression = new MethodTokenExpression(MethodToOverride.MakeGenericMethod(genericMethodArgs));
			}
			else
			{
				var proxiedMethodToken = @class.CreateStaticField(namingScope.GetUniqueName("token_" + MethodToOverride.Name), typeof(MethodInfo));
				@class.ClassConstructor.CodeBuilder.AddStatement(new AssignStatement(proxiedMethodToken, new MethodTokenExpression(MethodToOverride)));
				
				proxiedMethodTokenExpression = proxiedMethodToken.ToExpression();
			}

			var dereferencedArguments = IndirectReference.WrapIfByRef(emitter.Arguments);


			var ctorArguments = GetCtorArguments(@class, namingScope, proxiedMethodTokenExpression, dereferencedArguments);

			var invocationLocal = emitter.CodeBuilder.DeclareLocal(invocationType);
			emitter.CodeBuilder.AddStatement(new AssignStatement(invocationLocal,
			                                                     new NewInstanceExpression(constructor, ctorArguments)));

			if (MethodToOverride.ContainsGenericParameters)
			{
				EmitLoadGenricMethodArguments(emitter, MethodToOverride.MakeGenericMethod(genericMethodArgs), invocationLocal);
			}

			emitter.CodeBuilder.AddStatement(
				new ExpressionStatement(new MethodInvocationExpression(invocationLocal, InvocationMethods.Proceed)));

			GeneratorUtil.CopyOutAndRefParameters(dereferencedArguments, invocationLocal, MethodToOverride, emitter);

			if (MethodToOverride.ReturnType != typeof(void))
			{
				// Emit code to return with cast from ReturnValue
				var getRetVal = new MethodInvocationExpression(invocationLocal, InvocationMethods.GetReturnValue);
				emitter.CodeBuilder.AddStatement(new ReturnStatement(new ConvertExpression(emitter.ReturnType, getRetVal)));
			}
			else
			{
				emitter.CodeBuilder.AddStatement(new ReturnStatement());
			}

			return emitter;
		}
예제 #4
0
		public void CreateStaticFieldWithAttributes()
		{
			ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "Foo", typeof (object), Type.EmptyTypes);
			emitter.CreateStaticField("myField", typeof (string), FieldAttributes.FamANDAssem | FieldAttributes.InitOnly);
			Type t = emitter.BuildType();
			FieldInfo field = t.GetField("myField", BindingFlags.NonPublic | BindingFlags.Static);
			Assert.IsNotNull(field);
			Assert.AreEqual(FieldAttributes.Static | FieldAttributes.FamANDAssem | FieldAttributes.InitOnly, field.Attributes);
		}
예제 #5
0
		protected void SetGenerationOptions (ProxyGenerationOptions options, ClassEmitter emitter)
		{
			if (proxyGenerationOptions != null)
			{
				throw new InvalidOperationException ("ProxyGenerationOptions can only be set once.");
			}
			proxyGenerationOptions = options;
			proxyGenerationOptionsField = emitter.CreateStaticField ("proxyGenerationOptions", typeof (ProxyGenerationOptions));
		}
예제 #6
0
		protected void AddFieldToCacheMethodTokenAndStatementsToInitialize(
			MethodInfo method, ConstructorEmitter typeInitializerConstructor, ClassEmitter classEmitter)
		{
			if (!method2TokenField.ContainsKey(method))
			{
				FieldReference fieldCache =
					classEmitter.CreateStaticField("tokenCache" + fieldCount++, typeof(MethodInfo));

				method2TokenField.Add(method, fieldCache);

				typeInitializerConstructor.CodeBuilder.AddStatement(
					new AssignStatement(fieldCache, new MethodTokenExpression(method)));
			}
		}
예제 #7
0
		/// <summary>
		/// Improvement: this cache should be static. We should generate a
		/// type constructor instead
		/// </summary>
		protected void CreateInitializeCacheMethodBody(
			Type targetType, MethodInfo[] methods, ClassEmitter classEmitter, ConstructorEmitter typeInitializerConstructor)
		{
			typeTokenField = classEmitter.CreateStaticField("typeTokenCache", typeof(Type));

			typeInitializerConstructor.CodeBuilder.AddStatement(
				new AssignStatement(typeTokenField, new TypeTokenExpression(targetType)));

			CacheMethodTokens(classEmitter, methods, typeInitializerConstructor);
		}
        protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, ClassEmitter @class,
		                                                        ProxyGenerationOptions options, INamingScope namingScope)
        {
            var invocationType = invocation;

            Trace.Assert(MethodToOverride.IsGenericMethod == invocationType.IsGenericTypeDefinition());
            var genericArguments = TypeExtender.EmptyTypes;

            var constructor = invocation.GetConstructors()[0];

            Expression proxiedMethodTokenExpression;
            if (MethodToOverride.IsGenericMethod)
            {
                // bind generic method arguments to invocation's type arguments
                genericArguments = emitter.MethodBuilder.GetGenericArguments();
                invocationType = invocationType.MakeGenericType(genericArguments);
                constructor = TypeBuilder.GetConstructor(invocationType, constructor);

                // Not in the cache: generic method
                proxiedMethodTokenExpression = new MethodTokenExpression(MethodToOverride.MakeGenericMethod(genericArguments));
            }
            else
            {
                var proxiedMethodToken = @class.CreateStaticField(namingScope.GetUniqueName("token_" + MethodToOverride.Name),
                                                                  typeof(MethodInfo));
                @class.ClassConstructor.CodeBuilder.AddStatement(new AssignStatement(proxiedMethodToken,
                                                                                     new MethodTokenExpression(MethodToOverride)));

                proxiedMethodTokenExpression = proxiedMethodToken.ToExpression();
            }

            var dereferencedArguments = IndirectReference.WrapIfByRef(emitter.Arguments);
            var hasByRefArguments = HasByRefArguments(emitter.Arguments);

            var arguments = GetCtorArguments(@class, namingScope, proxiedMethodTokenExpression,
                                             dereferencedArguments);
            var ctorArguments = ModifyArguments(@class, arguments);

            var invocationLocal = emitter.CodeBuilder.DeclareLocal(invocationType);
            emitter.CodeBuilder.AddStatement(new AssignStatement(invocationLocal,
                                                                 new NewInstanceExpression(constructor, ctorArguments)));

            if (MethodToOverride.ContainsGenericParameters)
            {
                EmitLoadGenricMethodArguments(emitter, MethodToOverride.MakeGenericMethod(genericArguments), invocationLocal);
            }

            if (hasByRefArguments)
            {
                emitter.CodeBuilder.AddStatement(new TryStatement());
            }

            var proceed = new ExpressionStatement(new MethodInvocationExpression(invocationLocal, InvocationMethods.Proceed));
            emitter.CodeBuilder.AddStatement(proceed);

            if (hasByRefArguments)
            {
                emitter.CodeBuilder.AddStatement(new FinallyStatement());
            }

            GeneratorUtil.CopyOutAndRefParameters(dereferencedArguments, invocationLocal, MethodToOverride, emitter);

            if (hasByRefArguments)
            {
                emitter.CodeBuilder.AddStatement(new EndExceptionBlockStatement());
            }

            if (MethodToOverride.ReturnType != typeof(void))
            {
                // Emit code to return with cast from ReturnValue

                // @mbrit - 2012-05-31 - see the note associated with the GetReturnValueForWinRt declaration
                // for more information on this...

                var useWinRtGenericHandler = false;
            #if NETFX_CORE
                if (emitter.ReturnType == typeof(int) || emitter.ReturnType == typeof(bool))
                    useWinRtGenericHandler = true;
            #endif
                if(!(useWinRtGenericHandler))
                {
                    var getRetVal = new MethodInvocationExpression(invocationLocal, InvocationMethods.GetReturnValue);
                    emitter.CodeBuilder.AddStatement(new ReturnStatement(new ConvertExpression(emitter.ReturnType, getRetVal)));
                }
                else
                {
            #if NETFX_CORE
                    var grvArgs = new Type[] { emitter.ReturnType };
                    var grvCall = InvocationMethods.GetReturnValueForWinRt.MakeGenericMethod(grvArgs);
                    var getRetVal = new MethodInvocationExpression(invocationLocal, grvCall);
                    emitter.CodeBuilder.AddStatement(new ReturnStatement(getRetVal));
            #endif
                }
            }
            else
            {
                emitter.CodeBuilder.AddStatement(new ReturnStatement());
            }

            return emitter;
        }
예제 #9
0
		protected void CreateOptionsField(ClassEmitter emitter)
		{
			proxyGenerationOptionsField = emitter.CreateStaticField("proxyGenerationOptions", typeof(ProxyGenerationOptions));
		}