// This must be called with _readerWriterLock held for Write
        private static Type?GenerateInterfaceViewProxyType(Type viewType)
        {
            // View type is an interface let's cook an implementation
            Type?       proxyType;
            TypeBuilder proxyTypeBuilder;

            Type[] interfaces       = { viewType };
            bool   requiresCritical = false;

            var proxyModuleBuilder = GetProxyModuleBuilder(requiresCritical);

            proxyTypeBuilder = proxyModuleBuilder.DefineType(
                $"_proxy_{viewType.FullName}_{Guid.NewGuid()}",
                TypeAttributes.Public,
                typeof(object),
                interfaces);
            // Implement Constructor
            ConstructorBuilder proxyCtor   = proxyTypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, CtorArgumentTypes);
            ILGenerator        proxyCtorIL = proxyCtor.GetILGenerator();

            proxyCtorIL.Emit(OpCodes.Ldarg_0);
            proxyCtorIL.Emit(OpCodes.Call, ObjectCtor);

            LocalBuilder exception      = proxyCtorIL.DeclareLocal(typeof(Exception));
            LocalBuilder exceptionData  = proxyCtorIL.DeclareLocal(typeof(IDictionary));
            LocalBuilder sourceType     = proxyCtorIL.DeclareLocal(typeof(Type));
            LocalBuilder value          = proxyCtorIL.DeclareLocal(typeof(object));
            LocalBuilder usesExportedMD = proxyCtorIL.DeclareLocal(typeof(bool));

            Label tryConstructView = proxyCtorIL.BeginExceptionBlock();

            // Implement interface properties
            foreach (PropertyInfo propertyInfo in viewType.GetAllProperties())
            {
                string fieldName = $"_{propertyInfo.Name}_{Guid.NewGuid()}";

                // Cache names and type for exception
                string propertyName = propertyInfo.Name;

                Type[] propertyTypeArguments = new Type[] { propertyInfo.PropertyType };
                Type[]? optionalModifiers = null;
                Type[]? requiredModifiers = null;

                // PropertyInfo does not support GetOptionalCustomModifiers and GetRequiredCustomModifiers on Silverlight
                optionalModifiers = propertyInfo.GetOptionalCustomModifiers();
                requiredModifiers = propertyInfo.GetRequiredCustomModifiers();
                Array.Reverse(optionalModifiers);
                Array.Reverse(requiredModifiers);

                // Generate field
                FieldBuilder proxyFieldBuilder = proxyTypeBuilder.DefineField(
                    fieldName,
                    propertyInfo.PropertyType,
                    FieldAttributes.Private);

                // Generate property
                PropertyBuilder proxyPropertyBuilder = proxyTypeBuilder.DefineProperty(
                    propertyName,
                    PropertyAttributes.None,
                    propertyInfo.PropertyType,
                    propertyTypeArguments);

                // Generate constructor code for retrieving the metadata value and setting the field
                Label tryCastValue = proxyCtorIL.BeginExceptionBlock();
                Label innerTryCastValue;

                DefaultValueAttribute[] attrs = propertyInfo.GetAttributes <DefaultValueAttribute>(false);
                if (attrs.Length > 0)
                {
                    innerTryCastValue = proxyCtorIL.BeginExceptionBlock();
                }

                // In constructor set the backing field with the value from the dictionary
                Label doneGettingDefaultValue = proxyCtorIL.DefineLabel();
                GenerateLocalAssignmentFromFlag(proxyCtorIL, usesExportedMD, true);

                proxyCtorIL.Emit(OpCodes.Ldarg_1);
                proxyCtorIL.Emit(OpCodes.Ldstr, propertyInfo.Name);
                proxyCtorIL.Emit(OpCodes.Ldloca, value);
                proxyCtorIL.Emit(OpCodes.Callvirt, _mdvDictionaryTryGet);
                proxyCtorIL.Emit(OpCodes.Brtrue, doneGettingDefaultValue);

                proxyCtorIL.GenerateLocalAssignmentFromFlag(usesExportedMD, false);
                proxyCtorIL.GenerateLocalAssignmentFromDefaultAttribute(attrs, value);

                proxyCtorIL.MarkLabel(doneGettingDefaultValue);
                proxyCtorIL.GenerateFieldAssignmentFromLocalValue(value, proxyFieldBuilder);
                proxyCtorIL.Emit(OpCodes.Leave, tryCastValue);

                // catch blocks for innerTryCastValue start here
                if (attrs.Length > 0)
                {
                    proxyCtorIL.BeginCatchBlock(typeof(InvalidCastException));
                    {
                        Label notUsesExportedMd = proxyCtorIL.DefineLabel();
                        proxyCtorIL.Emit(OpCodes.Ldloc, usesExportedMD);
                        proxyCtorIL.Emit(OpCodes.Brtrue, notUsesExportedMd);
                        proxyCtorIL.Emit(OpCodes.Rethrow);
                        proxyCtorIL.MarkLabel(notUsesExportedMd);
                        proxyCtorIL.GenerateLocalAssignmentFromDefaultAttribute(attrs, value);
                        proxyCtorIL.GenerateFieldAssignmentFromLocalValue(value, proxyFieldBuilder);
                    }
                    proxyCtorIL.EndExceptionBlock();
                }

                // catch blocks for tryCast start here
                proxyCtorIL.BeginCatchBlock(typeof(NullReferenceException));
                {
                    proxyCtorIL.Emit(OpCodes.Stloc, exception);

                    proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
                    proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemKey, propertyName);
                    proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemTargetType, propertyInfo.PropertyType);
                    proxyCtorIL.Emit(OpCodes.Rethrow);
                }

                proxyCtorIL.BeginCatchBlock(typeof(InvalidCastException));
                {
                    proxyCtorIL.Emit(OpCodes.Stloc, exception);

                    proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
                    proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemKey, propertyName);
                    proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataItemTargetType, propertyInfo.PropertyType);
                    proxyCtorIL.Emit(OpCodes.Rethrow);
                }

                proxyCtorIL.EndExceptionBlock();

                if (propertyInfo.CanWrite)
                {
                    // The MetadataView '{0}' is invalid because property '{1}' has a property set method.
                    throw new NotSupportedException(SR.Format(
                                                        SR.InvalidSetterOnMetadataField,
                                                        viewType,
                                                        propertyName));
                }
                if (propertyInfo.CanRead)
                {
                    // Generate "get" method implementation.
                    MethodBuilder getMethodBuilder = proxyTypeBuilder.DefineMethod(
                        "get_" + propertyName,
                        MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                        CallingConventions.HasThis,
                        propertyInfo.PropertyType,
                        requiredModifiers,
                        optionalModifiers,
                        Type.EmptyTypes, null, null);

                    proxyTypeBuilder.DefineMethodOverride(getMethodBuilder, propertyInfo.GetGetMethod() !);
                    ILGenerator getMethodIL = getMethodBuilder.GetILGenerator();
                    getMethodIL.Emit(OpCodes.Ldarg_0);
                    getMethodIL.Emit(OpCodes.Ldfld, proxyFieldBuilder);
                    getMethodIL.Emit(OpCodes.Ret);

                    proxyPropertyBuilder.SetGetMethod(getMethodBuilder);
                }
            }

            proxyCtorIL.Emit(OpCodes.Leave, tryConstructView);

            // catch blocks for constructView start here
            proxyCtorIL.BeginCatchBlock(typeof(NullReferenceException));
            {
                proxyCtorIL.Emit(OpCodes.Stloc, exception);

                proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
                proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataViewType, viewType);
                proxyCtorIL.Emit(OpCodes.Rethrow);
            }
            proxyCtorIL.BeginCatchBlock(typeof(InvalidCastException));
            {
                proxyCtorIL.Emit(OpCodes.Stloc, exception);

                proxyCtorIL.GetExceptionDataAndStoreInLocal(exception, exceptionData);
                proxyCtorIL.Emit(OpCodes.Ldloc, value);
                proxyCtorIL.Emit(OpCodes.Call, ObjectGetType);
                proxyCtorIL.Emit(OpCodes.Stloc, sourceType);
                proxyCtorIL.AddItemToLocalDictionary(exceptionData, MetadataViewType, viewType);
                proxyCtorIL.AddLocalToLocalDictionary(exceptionData, MetadataItemSourceType, sourceType);
                proxyCtorIL.AddLocalToLocalDictionary(exceptionData, MetadataItemValue, value);
                proxyCtorIL.Emit(OpCodes.Rethrow);
            }
            proxyCtorIL.EndExceptionBlock();

            // Finished implementing the constructor
            proxyCtorIL.Emit(OpCodes.Ret);

            // Implemet the static factory
            // public object Create(IDictionary<string, object>)
            // {
            //    return new <ProxyClass>(dictionary);
            // }
            MethodBuilder factoryMethodBuilder = proxyTypeBuilder.DefineMethod(MetadataViewGenerator.MetadataViewFactoryName, MethodAttributes.Public | MethodAttributes.Static, typeof(object), CtorArgumentTypes);
            ILGenerator   factoryIL            = factoryMethodBuilder.GetILGenerator();

            factoryIL.Emit(OpCodes.Ldarg_0);
            factoryIL.Emit(OpCodes.Newobj, proxyCtor);
            factoryIL.Emit(OpCodes.Ret);

            // Finished implementing the type
            proxyType = proxyTypeBuilder.CreateTypeInfo();

            return(proxyType);
        }
		public override void  ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
		{
			// Nothing to do
		}
        protected override Type DoEmitProxyType(Type interfaceType, Type originType)
        {
            string      typeName    = base.GetDynamicTypeName(interfaceType, originType);
            TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class);

            typeBuilder.SetParent(typeof(MarshalByRefObject));
            typeBuilder.AddInterfaceImplementation(interfaceType);

            //定义成员,用于保存传入originType实例。
            FieldBuilder    targetField                    = typeBuilder.DefineField("target", originType, FieldAttributes.Private);
            FieldBuilder    methodInterceptorField         = typeBuilder.DefineField("methodInterceptor", typeof(IMethodInterceptor), FieldAttributes.Private);
            FieldBuilder    aroundInterceptorField         = typeBuilder.DefineField("aroundInterceptor", typeof(IAroundInterceptor), FieldAttributes.Private);
            ConstructorInfo emptyMethodInterceptorCtorInfo = typeof(EmptyMethodInterceptor).GetConstructor(new Type[] { });
            ConstructorInfo emptyAroundInterceptorCtorInfo = typeof(EmptyAroundInterceptor).GetConstructor(new Type[] { });


            #region Emit Ctor
            ConstructorBuilder ctor    = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { originType, typeof(IMethodInterceptor), typeof(IAroundInterceptor) });
            ILGenerator        ctorGen = ctor.GetILGenerator();
            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[] { }));
            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Ldarg_1);
            ctorGen.Emit(OpCodes.Stfld, targetField);

            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Ldarg_2);
            ctorGen.Emit(OpCodes.Stfld, methodInterceptorField);

            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Ldarg_3);
            ctorGen.Emit(OpCodes.Stfld, aroundInterceptorField);

            Label setAroundInterceptorFieldLable = ctorGen.DefineLabel();
            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Ldfld, methodInterceptorField);
            ctorGen.Emit(OpCodes.Ldnull);
            ctorGen.Emit(OpCodes.Ceq);
            ctorGen.Emit(OpCodes.Brfalse_S, setAroundInterceptorFieldLable);
            ctorGen.Emit(OpCodes.Nop);
            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Newobj, emptyMethodInterceptorCtorInfo);
            ctorGen.Emit(OpCodes.Stfld, methodInterceptorField);
            ctorGen.MarkLabel(setAroundInterceptorFieldLable);

            Label retLable = ctorGen.DefineLabel();
            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Ldfld, aroundInterceptorField);
            ctorGen.Emit(OpCodes.Ldnull);
            ctorGen.Emit(OpCodes.Ceq);
            ctorGen.Emit(OpCodes.Brfalse_S, retLable);
            ctorGen.Emit(OpCodes.Nop);
            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Newobj, emptyAroundInterceptorCtorInfo);
            ctorGen.Emit(OpCodes.Stfld, aroundInterceptorField);
            ctorGen.MarkLabel(retLable);

            ctorGen.Emit(OpCodes.Nop);
            ctorGen.Emit(OpCodes.Ret);
            #endregion

            foreach (MethodInfo baseMethod in ESBasic.Helpers.ReflectionHelper.GetAllMethods(interfaceType))//interfaceType.GetMethods())
            {
                this.EmitMethod(interfaceType, originType, typeBuilder, baseMethod, targetField, methodInterceptorField, aroundInterceptorField);
            }

            Type target = typeBuilder.CreateType();

            return(target);
        }
		internal static CodeEmitter Create(ConstructorBuilder cb)
		{
			return new CodeEmitter(cb.GetILGenerator());
		}
Exemple #5
0
		//
		// Creates the ConstructorBuilder
		//
		public override bool Define ()
		{
			if (ConstructorBuilder != null)
				return true;

			if (!CheckAbstractAndExtern (block != null))
				return false;
			
			// Check if arguments were correct.
			if (!CheckBase ())
				return false;

			var ca = ModifiersExtensions.MethodAttr (ModFlags) | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;

			ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
				ca, CallingConventions,
				parameters.GetMetaInfo ());

			spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, parameters, ModFlags);
			
			Parent.MemberCache.AddMember (spec);
			
			if (block != null) {
				// It's here only to report an error
				if (block.IsIterator) {
					member_type = Compiler.BuiltinTypes.Void;
					Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
				}

				if (Compiler.Settings.WriteMetadataOnly)
					block = null;
			}

			return true;
		}
Exemple #6
0
		//
		// Creates the ConstructorBuilder
		//
		public override bool Define ()
		{
			if (ConstructorBuilder != null)
				return true;

			var ca = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
			
			if ((ModFlags & Modifiers.STATIC) != 0) {
				ca |= MethodAttributes.Static | MethodAttributes.Private;
			} else {
				ca |= ModifiersExtensions.MethodAttr (ModFlags);
			}

			if (!CheckAbstractAndExtern (block != null))
				return false;
			
			// Check if arguments were correct.
			if (!CheckBase ())
				return false;

			ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
				ca, CallingConventions,
				parameters.GetMetaInfo ());

			spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, TypeManager.void_type, ConstructorBuilder, parameters, ModFlags);
			
			Parent.MemberCache.AddMember (spec);
			
			// It's here only to report an error
			if (block != null && block.IsIterator) {
				member_type = TypeManager.void_type;
				Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
			}

			return true;
		}
					internal override void Apply(ClassLoaderWrapper loader, ConstructorBuilder cb, object annotation)
					{
						Annotation annot = type.Annotation;
						foreach (object ann in UnwrapArray(annotation))
						{
							annot.Apply(loader, cb, ann);
						}
					}
        private static TypeInfo GenerateInterfaceViewProxyType(Type viewType)
        {
            // View type is an interface let's cook an implementation
            TypeInfo    proxyType;
            TypeBuilder proxyTypeBuilder;

            Type[] interfaces = { viewType };

            var proxyModuleBuilder = GetProxyModuleBuilder();

            skipClrVisibilityChecks.SkipVisibilityChecksFor(viewType.GetTypeInfo());

            proxyTypeBuilder = proxyModuleBuilder.DefineType(
                string.Format(CultureInfo.InvariantCulture, "_proxy_{0}_{1}", viewType.FullName, Guid.NewGuid()),
                TypeAttributes.Public,
                typeof(object),
                interfaces);

            // Generate field
            const string metadataFieldName    = "metadata";
            FieldBuilder metadataFieldBuilder = proxyTypeBuilder.DefineField(
                metadataFieldName,
                CtorArgumentTypes[0],
                FieldAttributes.Private | FieldAttributes.InitOnly);
            const string metadataDefaultFieldName    = "metadataDefault";
            FieldBuilder metadataDefaultFieldBuilder = proxyTypeBuilder.DefineField(
                metadataDefaultFieldName,
                CtorArgumentTypes[1],
                FieldAttributes.Private | FieldAttributes.InitOnly);

            // Implement Constructor
            ConstructorBuilder proxyCtor   = proxyTypeBuilder.DefineConstructor(MethodAttributes.Private, CallingConventions.Standard, CtorArgumentTypes);
            ILGenerator        proxyCtorIL = proxyCtor.GetILGenerator();

            // : base()
            proxyCtorIL.Emit(OpCodes.Ldarg_0);
            proxyCtorIL.Emit(OpCodes.Call, ObjectCtor);

            // this.metadata = metadata;
            proxyCtorIL.Emit(OpCodes.Ldarg_0);
            proxyCtorIL.Emit(OpCodes.Ldarg_1);
            proxyCtorIL.Emit(OpCodes.Stfld, metadataFieldBuilder);

            // this.metadataDefault = metadataDefault;
            proxyCtorIL.Emit(OpCodes.Ldarg_0);
            proxyCtorIL.Emit(OpCodes.Ldarg_2);
            proxyCtorIL.Emit(OpCodes.Stfld, metadataDefaultFieldBuilder);

            proxyCtorIL.Emit(OpCodes.Ret);

            foreach (PropertyInfo propertyInfo in viewType.GetAllProperties())
            {
                string propertyName = propertyInfo.Name;

                Type[] propertyTypeArguments = new Type[] { propertyInfo.PropertyType };
                Type[] optionalModifiers     = null;
                Type[] requiredModifiers     = null;

                // PropertyInfo does not support GetOptionalCustomModifiers and GetRequiredCustomModifiers on Silverlight
                optionalModifiers = propertyInfo.GetOptionalCustomModifiers();
                requiredModifiers = propertyInfo.GetRequiredCustomModifiers();
                Array.Reverse(optionalModifiers);
                Array.Reverse(requiredModifiers);

                // Generate property
                PropertyBuilder proxyPropertyBuilder = proxyTypeBuilder.DefineProperty(
                    propertyName,
                    PropertyAttributes.None,
                    propertyInfo.PropertyType,
                    propertyTypeArguments);

                // Generate "get" method implementation.
                MethodBuilder getMethodBuilder = proxyTypeBuilder.DefineMethod(
                    string.Format(CultureInfo.InvariantCulture, "get_{0}", propertyName),
                    MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final,
                    CallingConventions.HasThis,
                    propertyInfo.PropertyType,
                    requiredModifiers,
                    optionalModifiers,
                    Type.EmptyTypes,
                    null,
                    null);

                proxyTypeBuilder.DefineMethodOverride(getMethodBuilder, propertyInfo.GetGetMethod());
                ILGenerator getMethodIL = getMethodBuilder.GetILGenerator();

                // object value;
                LocalBuilder valueLocal = getMethodIL.DeclareLocal(typeof(object));

                // this.metadata.TryGetValue(propertyName, out value);
                getMethodIL.Emit(OpCodes.Ldarg_0);
                getMethodIL.Emit(OpCodes.Ldfld, metadataFieldBuilder);
                getMethodIL.Emit(OpCodes.Ldstr, propertyName);
                getMethodIL.Emit(OpCodes.Ldloca_S, valueLocal);
                getMethodIL.Emit(OpCodes.Callvirt, MdvDictionaryTryGet);

                // If that succeeded, prepare to return.
                Label returnLabel = getMethodIL.DefineLabel();
                getMethodIL.Emit(OpCodes.Brtrue_S, returnLabel);

                // Otherwise get the value from the default metadata dictionary.
                getMethodIL.Emit(OpCodes.Ldarg_0);
                getMethodIL.Emit(OpCodes.Ldfld, metadataDefaultFieldBuilder);
                getMethodIL.Emit(OpCodes.Ldstr, propertyName);
                getMethodIL.Emit(OpCodes.Callvirt, MdvDictionaryIndexer);
                getMethodIL.Emit(OpCodes.Stloc_0);

                getMethodIL.MarkLabel(returnLabel);
                getMethodIL.Emit(OpCodes.Ldloc_0);
                getMethodIL.Emit(propertyInfo.PropertyType.GetTypeInfo().IsValueType ? OpCodes.Unbox_Any : OpCodes.Isinst, propertyInfo.PropertyType);
                getMethodIL.Emit(OpCodes.Ret);

                proxyPropertyBuilder.SetGetMethod(getMethodBuilder);
            }

            // Implement the static factory
            //// public static object Create(IReadOnlyDictionary<string, object>, IReadOnlyDictionary<string, object>)
            //// {
            ////    return new <ProxyClass>(dictionary);
            //// }
            MethodBuilder factoryMethodBuilder = proxyTypeBuilder.DefineMethod(MetadataViewGenerator.MetadataViewFactoryName, MethodAttributes.Public | MethodAttributes.Static, typeof(object), CtorArgumentTypes);
            ILGenerator   factoryIL            = factoryMethodBuilder.GetILGenerator();

            factoryIL.Emit(OpCodes.Ldarg_0);
            factoryIL.Emit(OpCodes.Ldarg_1);
            factoryIL.Emit(OpCodes.Newobj, proxyCtor);
            factoryIL.Emit(OpCodes.Ret);

            // Finished implementing the type
            proxyType = proxyTypeBuilder.CreateTypeInfo();

            return(proxyType);
        }
Exemple #9
0
        private static TypeInfo BuildType(Type type)
        {
            TypeInfo ti = type.GetTypeInfo();

            // order by key(important for use jump-table of switch)
            UnionAttribute[] unionAttrs = ti.GetCustomAttributes <UnionAttribute>().OrderBy(x => x.Key).ToArray();

            if (unionAttrs.Length == 0)
            {
                return(null);
            }

            if (!ti.IsInterface && !ti.IsAbstract)
            {
                throw new MessagePackDynamicUnionResolverException("Union can only be interface or abstract class. Type:" + type.Name);
            }

            var checker1 = new HashSet <int>();
            var checker2 = new HashSet <Type>();

            foreach (UnionAttribute item in unionAttrs)
            {
                if (!checker1.Add(item.Key))
                {
                    throw new MessagePackDynamicUnionResolverException("Same union key has found. Type:" + type.Name + " Key:" + item.Key);
                }

                if (!checker2.Add(item.SubType))
                {
                    throw new MessagePackDynamicUnionResolverException("Same union subType has found. Type:" + type.Name + " SubType: " + item.SubType);
                }
            }

            Type formatterType = typeof(IMessagePackFormatter <>).MakeGenericType(type);

            using (MonoProtection.EnterRefEmitLock())
            {
                TypeBuilder typeBuilder = DynamicAssembly.Value.DefineType("MessagePack.Formatters." + SubtractFullNameRegex.Replace(type.FullName, string.Empty).Replace(".", "_") + "Formatter" + +Interlocked.Increment(ref nameSequence), TypeAttributes.Public | TypeAttributes.Sealed, null, new[] { formatterType });

                FieldBuilder typeToKeyAndJumpMap = null; // Dictionary<RuntimeTypeHandle, KeyValuePair<int, int>>
                FieldBuilder keyToJumpMap        = null; // Dictionary<int, int>

                // create map dictionary
                {
                    ConstructorBuilder method = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
                    typeToKeyAndJumpMap = typeBuilder.DefineField("typeToKeyAndJumpMap", typeof(Dictionary <RuntimeTypeHandle, KeyValuePair <int, int> >), FieldAttributes.Private | FieldAttributes.InitOnly);
                    keyToJumpMap        = typeBuilder.DefineField("keyToJumpMap", typeof(Dictionary <int, int>), FieldAttributes.Private | FieldAttributes.InitOnly);

                    ILGenerator il = method.GetILGenerator();
                    BuildConstructor(type, unionAttrs, method, typeToKeyAndJumpMap, keyToJumpMap, il);
                }

                {
                    MethodBuilder method = typeBuilder.DefineMethod(
                        "Serialize",
                        MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                        null,
                        new Type[] { typeof(MessagePackWriter).MakeByRefType(), type, typeof(MessagePackSerializerOptions) });

                    ILGenerator il = method.GetILGenerator();
                    BuildSerialize(type, unionAttrs, method, typeToKeyAndJumpMap, il);
                }

                {
                    MethodBuilder method = typeBuilder.DefineMethod(
                        "Deserialize",
                        MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                        type,
                        new Type[] { refMessagePackReader, typeof(MessagePackSerializerOptions) });

                    ILGenerator il = method.GetILGenerator();
                    BuildDeserialize(type, unionAttrs, method, keyToJumpMap, il);
                }

                return(typeBuilder.CreateTypeInfo());
            }
        }
Exemple #10
0
        private void DefineStaticConstructor(TypeBuilder fnTB)
        {
            ConstructorBuilder cb = fnTB.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);

            EmitStaticConstructorBody(new CljILGen(cb.GetILGenerator()));
        }
Exemple #11
0
        /// <summary>
        /// Creates a proxy type of the specified source type.
        /// </summary>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        protected virtual Type InternalCreateProxyType(Type sourceType)
        {
            // load virtual methods
            MethodInfo[] methods = sourceType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where((item) =>
                                                                                                                                     // not constrcutor methods
                                                                                                                                     !item.IsConstructor &&

                                                                                                                                     // only overridable methods
                                                                                                                                     this.IsMethodOverridable(item) &&

                                                                                                                                     // ignore property methods and operator override method
                                                                                                                                     !item.IsSpecialName &&

                                                                                                                                     // ignore marked methods
                                                                                                                                     item.GetCustomAttributes(typeof(FilterIgnoreAttribute), true).Length == 0 &&

                                                                                                                                     // ignore common methods defined in System.Object class
                                                                                                                                     !item.DeclaringType.Equals(typeof(object))).ToArray();

            // load virtual properties
            PropertyInfo[] properties = sourceType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where((item) =>
                                                                                                                                             // ignore index properties
                                                                                                                                             item.GetIndexParameters().Length == 0 &&

                                                                                                                                             // can read or write
                                                                                                                                             (item.CanRead || item.CanWrite) &&

                                                                                                                                             // ignore special properties
                                                                                                                                             !item.IsSpecialName &&

                                                                                                                                             // ignore marked methods
                                                                                                                                             Attribute.GetCustomAttributes(item, typeof(FilterIgnoreAttribute), true).Length == 0 &&

                                                                                                                                             // ignore common properties defined in System.Object class
                                                                                                                                             !item.DeclaringType.Equals(typeof(object))).ToArray();

            // find class filters
            MethodFilterAttribute[] classFilters = sourceType.GetCustomAttributes(typeof(MethodFilterAttribute), true).Cast <MethodFilterAttribute>().OrderBy((item) => item.Order).ToArray();

            // find methods filters
            MethodFilterAttribute[][] methodFilters = new MethodFilterAttribute[methods.Length][];
            for (int i = 0; i < methods.Length; i++)
            {
                methodFilters[i] = methods[i].GetCustomAttributes(typeof(MethodFilterAttribute), true).Cast <MethodFilterAttribute>().OrderBy((item) => item.Order).ToArray();
            }

            // find properties filters
            MethodFilterAttribute[][] propertyFilters = new MethodFilterAttribute[properties.Length][];
            for (int i = 0; i < properties.Length; i++)
            {
                propertyFilters[i] = Attribute.GetCustomAttributes(properties[i], typeof(MethodFilterAttribute), true).Cast <MethodFilterAttribute>().OrderBy((item) => item.Order).ToArray();
            }

            if (methods.Length == 0 && properties.Length == 0 || classFilters.Length == 0 && methodFilters.All((item) => item.Length == 0) && propertyFilters.All((item) => item.Length == 0))
            {
                return(sourceType);
            }

            ILGenerator generator = null;

            #region Create Proxy Type

            TypeAttributes typeAttributes = sourceType.Attributes;
            typeAttributes &= ~(TypeAttributes.NestedPrivate | TypeAttributes.NestedPublic | TypeAttributes.NestedFamily | TypeAttributes.NestedAssembly | TypeAttributes.NestedFamANDAssem | TypeAttributes.NestedFamORAssem);
            typeAttributes |= TypeAttributes.Public;

            Type   typeParameter  = null;
            Type[] typeParameters = null;
            GenericTypeParameterBuilder   typeParameterBuilder  = null;
            GenericTypeParameterBuilder[] typeParameterBuilders = null;
            TypeBuilder typeBuilder = this.m_moduleBuilder.DefineType(this.GetProxyTypeName(sourceType), typeAttributes, sourceType);
            this.InjectCustomAttributes(sourceType, typeBuilder);

            // create type arguments
            if (sourceType.IsGenericTypeDefinition || sourceType.IsGenericType && sourceType.ContainsGenericParameters)
            {
                typeParameters = sourceType.GetGenericArguments().Where((item) => item.IsGenericParameter).ToArray();
                if (typeParameters.Length > 0)
                {
                    typeParameterBuilders = typeBuilder.DefineGenericParameters(typeParameters.Select((item) => item.Name).ToArray());

                    for (int j = 0; j < typeParameters.Length; j++)
                    {
                        typeParameter        = typeParameters[j];
                        typeParameterBuilder = typeParameterBuilders[j];

                        typeParameterBuilder.SetGenericParameterAttributes(typeParameter.GenericParameterAttributes);
                        foreach (Type constraint in typeParameter.GetGenericParameterConstraints())
                        {
                            if (constraint.IsClass)
                            {
                                typeParameterBuilder.SetBaseTypeConstraint(constraint);
                            }
                            else
                            {
                                typeParameterBuilder.SetInterfaceConstraints(constraint);
                            }
                        }
                    }
                }
            }

            #endregion

            #region Create Static Fields

            int            filterIndex  = 0;
            FieldBuilder[] staticFields = new FieldBuilder[classFilters.Length + methodFilters.Sum((item) => item.Length) + propertyFilters.Sum((item) => item.Length)];

            for (int i = 0; i < classFilters.Length; i++, filterIndex++)
            {
                staticFields[filterIndex] = typeBuilder.DefineField(this.GetStaticFieldName(filterIndex), typeof(IMethodFilter), FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly);
            }
            for (int i = 0; i < methods.Length; i++)
            {
                if (methodFilters[i].Length == 0)
                {
                    continue;
                }

                for (int j = 0; j < methodFilters[i].Length; j++, filterIndex++)
                {
                    staticFields[filterIndex] = typeBuilder.DefineField(this.GetStaticFieldName(filterIndex), typeof(IMethodFilter), FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly);
                }
            }
            for (int i = 0; i < properties.Length; i++)
            {
                if (propertyFilters[i].Length == 0)
                {
                    continue;
                }

                for (int j = 0; j < propertyFilters[i].Length; j++, filterIndex++)
                {
                    staticFields[filterIndex] = typeBuilder.DefineField(this.GetStaticFieldName(filterIndex), typeof(IMethodFilter), FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly);
                }
            }

            #endregion

            #region Create Static Constructor

            string          classKey = this.GetClassKey(sourceType, typeBuilder);
            IMethodFilter[] filters  = g_classFilters[classKey] = new IMethodFilter[staticFields.Length];

            ConstructorBuilder constructorBuilder = typeBuilder.DefineTypeInitializer();
            generator = constructorBuilder.GetILGenerator();

            for (int i = 0; i < classFilters.Length; i++)
            {
                filters[i] = classFilters[i];

                generator.Emit(OpCodes.Ldstr, classKey);
                generator.Emit(OpCodes.Ldc_I4, i);
                generator.Emit(OpCodes.Call, g_getClassFilterMethod);
                generator.Emit(OpCodes.Stsfld, staticFields[i]);
            }

            filterIndex = classFilters.Length;

            for (int i = 0; i < methods.Length; i++)
            {
                if (methodFilters[i].Length == 0)
                {
                    continue;
                }

                for (int j = 0; j < methodFilters[i].Length; j++, filterIndex++)
                {
                    filters[filterIndex] = methodFilters[i][j];

                    generator.Emit(OpCodes.Ldstr, classKey);
                    generator.Emit(OpCodes.Ldc_I4, filterIndex);
                    generator.Emit(OpCodes.Call, g_getClassFilterMethod);
                    generator.Emit(OpCodes.Stsfld, staticFields[filterIndex]);
                }
            }
            for (int i = 0; i < properties.Length; i++)
            {
                if (propertyFilters[i].Length == 0)
                {
                    continue;
                }

                for (int j = 0; j < propertyFilters[i].Length; j++, filterIndex++)
                {
                    filters[filterIndex] = propertyFilters[i][j];

                    generator.Emit(OpCodes.Ldstr, classKey);
                    generator.Emit(OpCodes.Ldc_I4, filterIndex);
                    generator.Emit(OpCodes.Call, g_getClassFilterMethod);
                    generator.Emit(OpCodes.Stsfld, staticFields[filterIndex]);
                }
            }

            generator.Emit(OpCodes.Ret);

            #endregion

            #region Create Instance Constructors

            ParameterInfo[] constructorParameters = null;
            foreach (ConstructorInfo constructor in sourceType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                constructorParameters = constructor.GetParameters();
                constructorBuilder    = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorParameters.Select((item) => item.ParameterType).ToArray());
                for (int i = 0; i < constructorParameters.Length; i++)
                {
                    this.InjectCustomAttributes(
                        constructorParameters[i],
                        constructorBuilder.DefineParameter(i + 1, constructorParameters[i].Attributes, constructorParameters[i].Name));
                }

                generator = constructorBuilder.GetILGenerator();

                // call base constructor
                generator.Emit(OpCodes.Ldarg_0);
                for (int i = 1; i <= constructorParameters.Length; i++)
                {
                    generator.Emit(OpCodes.Ldarg, i);
                }
                generator.Emit(OpCodes.Call, constructor);

                generator.Emit(OpCodes.Ret);
            }

            #endregion

            #region Create Methods

            filterIndex = classFilters.Length;

            for (int i = 0; i < methods.Length; i++)
            {
                if (methodFilters[i].Length + classFilters.Length == 0)
                {
                    continue;
                }

                this.CreateProxyMethod(typeBuilder, methods[i], classFilters, methodFilters[i], staticFields, filterIndex, (item) => true);

                filterIndex += methodFilters[i].Length;
            }

            PropertyInfo    property = null;
            PropertyBuilder propertyBuilder = null;
            MethodInfo      getMethod = null, setMethod = null;
            bool            isGetMethodOverridable = false, isSetMethodOverridable = false;
            bool            isPropertyFilterGetMethod = false, isPropertyFilterSetMethod = false;
            bool            isClassFilterGetMethod = classFilters.Any((item) => item.PropertyMethods.HasFlag(MethodFilterActOnPropertyMethods.GetMethod));
            bool            isClassFilterSetMethod = classFilters.Any((item) => item.PropertyMethods.HasFlag(MethodFilterActOnPropertyMethods.SetMethod));

            for (int i = 0; i < properties.Length; i++)
            {
                if (propertyFilters[i].Length + classFilters.Length == 0)
                {
                    continue;
                }

                property = properties[i];
                isPropertyFilterGetMethod = propertyFilters[i].Any((item) => item.PropertyMethods.HasFlag(MethodFilterActOnPropertyMethods.GetMethod));
                isPropertyFilterSetMethod = propertyFilters[i].Any((item) => item.PropertyMethods.HasFlag(MethodFilterActOnPropertyMethods.SetMethod));

                isGetMethodOverridable = this.IsMethodOverridable(getMethod = property.GetGetMethod(true)) && (isClassFilterGetMethod || isPropertyFilterGetMethod);
                isSetMethodOverridable = this.IsMethodOverridable(setMethod = property.GetSetMethod(true)) && (isClassFilterSetMethod || isPropertyFilterSetMethod);
                if (!isGetMethodOverridable && !isSetMethodOverridable)
                {
                    continue;
                }

                propertyBuilder = typeBuilder.DefineProperty(property.Name, property.Attributes, property.PropertyType, null);
                if (isGetMethodOverridable)
                {
                    propertyBuilder.SetGetMethod(this.CreateProxyMethod(typeBuilder, getMethod, classFilters, propertyFilters[i], staticFields, filterIndex, (item) => item.PropertyMethods.HasFlag(MethodFilterActOnPropertyMethods.GetMethod)));
                }
                if (isSetMethodOverridable)
                {
                    propertyBuilder.SetSetMethod(this.CreateProxyMethod(typeBuilder, setMethod, classFilters, propertyFilters[i], staticFields, filterIndex, (item) => item.PropertyMethods.HasFlag(MethodFilterActOnPropertyMethods.SetMethod)));
                }

                filterIndex += propertyFilters[i].Length;
            }

            #endregion

            return(typeBuilder.CreateType());
        }
Exemple #12
0
        private static Type EmitProxy(TypeDescription typeDescription)
        {
            var       interfaceType        = typeDescription.Type;
            var       additionalProperties = typeDescription.AdditionalProperties;
            var       propertyNames        = string.Join("_", additionalProperties.Select(p => p.Name));
            var       typeName             = $"Proxy_{interfaceType.FullName}_{typeDescription.GetHashCode()}_{propertyNames}";
            const int MaxTypeNameLength    = 1023;

            typeName = typeName.Substring(0, Math.Min(MaxTypeNameLength, typeName.Length));
            var allInterfaces = new List <Type> {
                interfaceType
            };

            allInterfaces.AddRange(interfaceType.GetTypeInfo().ImplementedInterfaces);
            Debug.WriteLine(typeName, "Emitting proxy type");
            TypeBuilder typeBuilder = proxyModule.DefineType(typeName,
                                                             TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public, typeof(ProxyBase),
                                                             interfaceType.IsInterface() ? new[] { interfaceType } : Type.EmptyTypes);
            ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public,
                                                                                  CallingConventions.Standard, Type.EmptyTypes);
            ILGenerator ctorIl = constructorBuilder.GetILGenerator();

            ctorIl.Emit(OpCodes.Ldarg_0);
            ctorIl.Emit(OpCodes.Call, proxyBase_ctor);
            ctorIl.Emit(OpCodes.Ret);
            FieldBuilder propertyChangedField = null;

            if (typeof(INotifyPropertyChanged).IsAssignableFrom(interfaceType))
            {
                propertyChangedField = typeBuilder.DefineField("PropertyChanged", typeof(PropertyChangedEventHandler),
                                                               FieldAttributes.Private);
                MethodBuilder addPropertyChangedMethod = typeBuilder.DefineMethod("add_PropertyChanged",
                                                                                  MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName |
                                                                                  MethodAttributes.NewSlot | MethodAttributes.Virtual, typeof(void),
                                                                                  new[] { typeof(PropertyChangedEventHandler) });
                ILGenerator addIl = addPropertyChangedMethod.GetILGenerator();
                addIl.Emit(OpCodes.Ldarg_0);
                addIl.Emit(OpCodes.Dup);
                addIl.Emit(OpCodes.Ldfld, propertyChangedField);
                addIl.Emit(OpCodes.Ldarg_1);
                addIl.Emit(OpCodes.Call, delegate_Combine);
                addIl.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
                addIl.Emit(OpCodes.Stfld, propertyChangedField);
                addIl.Emit(OpCodes.Ret);
                MethodBuilder removePropertyChangedMethod = typeBuilder.DefineMethod("remove_PropertyChanged",
                                                                                     MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName |
                                                                                     MethodAttributes.NewSlot | MethodAttributes.Virtual, typeof(void),
                                                                                     new[] { typeof(PropertyChangedEventHandler) });
                ILGenerator removeIl = removePropertyChangedMethod.GetILGenerator();
                removeIl.Emit(OpCodes.Ldarg_0);
                removeIl.Emit(OpCodes.Dup);
                removeIl.Emit(OpCodes.Ldfld, propertyChangedField);
                removeIl.Emit(OpCodes.Ldarg_1);
                removeIl.Emit(OpCodes.Call, delegate_Remove);
                removeIl.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
                removeIl.Emit(OpCodes.Stfld, propertyChangedField);
                removeIl.Emit(OpCodes.Ret);
                typeBuilder.DefineMethodOverride(addPropertyChangedMethod,
                                                 iNotifyPropertyChanged_PropertyChanged.GetAddMethod());
                typeBuilder.DefineMethodOverride(removePropertyChangedMethod,
                                                 iNotifyPropertyChanged_PropertyChanged.GetRemoveMethod());
            }
            var propertiesToImplement = new List <PropertyDescription>();

            // first we collect all properties, those with setters before getters in order to enable less specific redundant getters
            foreach (var property in
                     allInterfaces.Where(intf => intf != typeof(INotifyPropertyChanged))
                     .SelectMany(intf => intf.GetProperties())
                     .Select(p => new PropertyDescription(p))
                     .Concat(additionalProperties))
            {
                if (property.CanWrite)
                {
                    propertiesToImplement.Insert(0, property);
                }
                else
                {
                    propertiesToImplement.Add(property);
                }
            }
            var fieldBuilders = new Dictionary <string, PropertyEmitter>();

            foreach (var property in propertiesToImplement)
            {
                if (fieldBuilders.TryGetValue(property.Name, out var propertyEmitter))
                {
                    if ((propertyEmitter.PropertyType != property.Type) &&
                        ((property.CanWrite) || (!property.Type.IsAssignableFrom(propertyEmitter.PropertyType))))
                    {
                        throw new ArgumentException(
                                  $"The interface has a conflicting property {property.Name}",
                                  nameof(interfaceType));
                    }
                }
                else
                {
                    fieldBuilders.Add(property.Name,
                                      new PropertyEmitter(typeBuilder, property, propertyChangedField));
                }
            }
            return(typeBuilder.CreateType());
        }
Exemple #13
0
        Constructor GetOperatorTypeConstructor(OperatorData data)
        {
            Constructor constructorfunc;

            if (m_types.TryGetValue(data.Name, out constructorfunc) == true)
            {
                return(constructorfunc);
            }

            Int32 argcount = (data is BinaryOperatorData) ? 2 : 1;

            Type[] paramtypes = new Type[argcount];
            for (Int32 i = 0; i != argcount; ++i)
            {
                paramtypes[i] = typeof(EvaluationCallback);
            }

            TypeBuilder typebuilder = m_module.DefineType(data.Name, TypeAttributes.Public);

            typebuilder.AddInterfaceImplementation(typeof(IFunction));

            FieldBuilder[] fields = new FieldBuilder[argcount];
            for (Int32 i = 0; i != argcount; ++i)
            {
                fields[i] = typebuilder.DefineField("m_arg" + i, typeof(EvaluationCallback), FieldAttributes.Private);
            }

            ConstructorBuilder constructor          = typebuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, paramtypes);
            ILGenerator        constructorgenerator = constructor.GetILGenerator();

            constructorgenerator.Emit(OpCodes.Ldarg, 0);
            constructorgenerator.Emit(OpCodes.Call, typeof(Object).GetConstructor(Type.EmptyTypes));

            for (Int32 i = 0; i != argcount; ++i)
            {
                constructorgenerator.Emit(OpCodes.Ldarg, 0);
                constructorgenerator.Emit(OpCodes.Ldarg, i + 1);
                constructorgenerator.Emit(OpCodes.Stfld, fields[i]);
            }

            constructorgenerator.Emit(OpCodes.Ret);

            MethodBuilder method          = typebuilder.DefineMethod("Evaluate", MethodAttributes.Public | MethodAttributes.Virtual, typeof(Number), new Type[] { typeof(Object) });
            ILGenerator   methodgenerator = method.GetILGenerator();

            for (Int32 i = 0; i != argcount; ++i)
            {
                methodgenerator.Emit(OpCodes.Ldarg, 0);
                methodgenerator.Emit(OpCodes.Ldfld, fields[i]);
                methodgenerator.Emit(OpCodes.Ldarg, 1);
                methodgenerator.Emit(OpCodes.Callvirt, typeof(EvaluationCallback).GetMethod("Invoke", BindingFlags.Public | BindingFlags.Instance));
            }

            methodgenerator.Emit(OpCodes.Call, typeof(Number).GetMethod(data.Name, BindingFlags.Public | BindingFlags.Static));
            methodgenerator.Emit(OpCodes.Ret);

            constructorfunc    = FastConstruct(typebuilder.CreateType(), paramtypes);
            m_types[data.Name] = constructorfunc;

            return(constructorfunc);
        }
Exemple #14
0
        Constructor GetCustomFunctionConstructor(String name, Type functiontype, Object[] args)
        {
            Constructor constructorfunc;

            if (m_types.TryGetValue(name, out constructorfunc) == true)
            {
                return(constructorfunc);
            }

            TypeBuilder typebuilder = m_module.DefineType(name, TypeAttributes.Public);

            typebuilder.AddInterfaceImplementation(typeof(IFunction));

            MethodInfo evalmethod = functiontype.GetMethod("RedirectState", BindingFlags.Static | BindingFlags.Public) ?? functiontype.GetMethod("Evaluate", BindingFlags.Static | BindingFlags.Public);

            ParameterInfo[] parameters = evalmethod.GetParameters();
            Type[]          paramtypes = new Type[parameters.Length - 1];
            FieldBuilder[]  fields     = new FieldBuilder[parameters.Length - 1];

            for (Int32 i = 1; i != parameters.Length; ++i)
            {
                Type type = parameters[i].ParameterType;
                if (type == typeof(Number))
                {
                    type = typeof(EvaluationCallback);
                }

                paramtypes[i - 1] = type;

                fields[i - 1] = typebuilder.DefineField("m_arg" + i, paramtypes[i - 1], FieldAttributes.Private);
            }

            ConstructorBuilder constructor          = typebuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, paramtypes);
            ILGenerator        constructorgenerator = constructor.GetILGenerator();

            constructorgenerator.Emit(OpCodes.Ldarg, 0);
            constructorgenerator.Emit(OpCodes.Call, typeof(Object).GetConstructor(Type.EmptyTypes));

            for (Int32 i = 0; i != fields.Length; ++i)
            {
                constructorgenerator.Emit(OpCodes.Ldarg, 0);
                constructorgenerator.Emit(OpCodes.Ldarg, i + 1);
                constructorgenerator.Emit(OpCodes.Stfld, fields[i]);
            }

            constructorgenerator.Emit(OpCodes.Ret);

            MethodBuilder method          = typebuilder.DefineMethod("Evaluate", MethodAttributes.Public | MethodAttributes.Virtual, typeof(Number), new Type[] { typeof(Object) });
            ILGenerator   methodgenerator = method.GetILGenerator();

            methodgenerator.Emit(OpCodes.Ldarg, 1);

            for (Int32 i = 0; i != fields.Length; ++i)
            {
                methodgenerator.Emit(OpCodes.Ldarg, 0);
                methodgenerator.Emit(OpCodes.Ldfld, fields[i]);

                if (evalmethod.Name == "Evaluate" && fields[i].FieldType == typeof(EvaluationCallback))
                {
                    methodgenerator.Emit(OpCodes.Ldarg, 1);
                    methodgenerator.Emit(OpCodes.Callvirt, typeof(EvaluationCallback).GetMethod("Invoke", BindingFlags.Public | BindingFlags.Instance));
                }
            }

            methodgenerator.Emit(OpCodes.Call, evalmethod);
            methodgenerator.Emit(OpCodes.Ret);

            constructorfunc = FastConstruct(typebuilder.CreateType(), paramtypes);

            m_types[name] = constructorfunc;
            return(constructorfunc);
        }
Exemple #15
0
        private static CreateTypeResult CreateProxyType(Type proxyDefinitionType, Type targetType)
        {
            try
            {
                // Define parent type, interface types
                Type           parentType;
                TypeAttributes typeAttributes;
                Type[]         interfaceTypes;
                if (proxyDefinitionType.IsInterface || proxyDefinitionType.IsValueType)
                {
                    // If the proxy type definition is an interface we create an struct proxy
                    // If the proxy type definition is an struct then we use that struct to copy the values from the target type
                    parentType     = typeof(ValueType);
                    typeAttributes = TypeAttributes.Public | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.SequentialLayout | TypeAttributes.Sealed | TypeAttributes.Serializable;
                    if (proxyDefinitionType.IsInterface)
                    {
                        interfaceTypes = new[] { proxyDefinitionType, typeof(IDuckType) };
                    }
                    else
                    {
                        interfaceTypes = new[] { typeof(IDuckType) };
                    }
                }
                else
                {
                    // If the proxy type definition is a class then we create a class proxy
                    parentType     = proxyDefinitionType;
                    typeAttributes = TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout | TypeAttributes.Sealed;
                    interfaceTypes = new[] { typeof(IDuckType) };
                }

                // Ensures the module builder
                if (_moduleBuilder is null)
                {
                    lock (_locker)
                    {
                        if (_moduleBuilder is null)
                        {
                            AssemblyName aName = new AssemblyName("DuckTypeAssembly");
                            _assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
                            _moduleBuilder   = _assemblyBuilder.DefineDynamicModule("MainModule");
                        }
                    }
                }

                string assembly = string.Empty;
                if (targetType.Assembly != null)
                {
                    // Include target assembly name and public token.
                    AssemblyName asmName = targetType.Assembly.GetName();
                    assembly = asmName.Name;
                    byte[] pbToken = asmName.GetPublicKeyToken();
                    assembly += "__" + BitConverter.ToString(pbToken).Replace("-", string.Empty);
                }

                // Create a valid type name that can be used as a member of a class. (BenchmarkDotNet fails if is an invalid name)
                string proxyTypeName = $"{proxyDefinitionType.FullName.Replace(".", "_").Replace("+", "__")}____{targetType.FullName.Replace(".", "_").Replace("+", "__")}___{assembly.Replace(".", "_").Replace("+", "__")}";

                // Create Type
                TypeBuilder proxyTypeBuilder = _moduleBuilder.DefineType(
                    proxyTypeName,
                    typeAttributes,
                    parentType,
                    interfaceTypes);

                // Create IDuckType and IDuckTypeSetter implementations
                FieldInfo instanceField = CreateIDuckTypeImplementation(proxyTypeBuilder, targetType);

                // Define .ctor to store the instance field
                ConstructorBuilder ctorBuilder = proxyTypeBuilder.DefineConstructor(
                    MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
                    CallingConventions.Standard,
                    new[] { targetType });
                ILGenerator ctorIL = ctorBuilder.GetILGenerator();
                ctorIL.Emit(OpCodes.Ldarg_0);
                ctorIL.Emit(OpCodes.Ldarg_1);
                ctorIL.Emit(OpCodes.Stfld, instanceField);
                ctorIL.Emit(OpCodes.Ret);

                if (proxyDefinitionType.IsValueType)
                {
                    // Create Fields and Properties from the struct information
                    CreatePropertiesFromStruct(proxyTypeBuilder, proxyDefinitionType, targetType, instanceField);

                    // Create Type
                    Type proxyType = proxyTypeBuilder.CreateTypeInfo().AsType();
                    return(new CreateTypeResult(proxyDefinitionType, proxyType, targetType, CreateStructCopyMethod(proxyDefinitionType, proxyType, targetType), null));
                }
                else
                {
                    // Create Fields and Properties
                    CreateProperties(proxyTypeBuilder, proxyDefinitionType, targetType, instanceField);

                    // Create Methods
                    CreateMethods(proxyTypeBuilder, proxyDefinitionType, targetType, instanceField);

                    // Create Type
                    Type proxyType = proxyTypeBuilder.CreateTypeInfo().AsType();
                    return(new CreateTypeResult(proxyDefinitionType, proxyType, targetType, GetCreateProxyInstanceDelegate(proxyDefinitionType, proxyType, targetType), null));
                }
            }
            catch (Exception ex)
            {
                return(new CreateTypeResult(proxyDefinitionType, null, targetType, null, ExceptionDispatchInfo.Capture(ex)));
            }
        }
        private Type CreateType(IProxyInvocationHandler handler, Type[] interfaces, string dynamicTypeName)
        {
            Type retVal = null;

            if (handler != null && interfaces != null)
            {
                Type objType     = typeof(System.Object);
                Type handlerType = typeof(IProxyInvocationHandler);

                AppDomain    domain       = Thread.GetDomain();
                AssemblyName assemblyName = new AssemblyName();
                assemblyName.Name    = ASSEMBLY_NAME;
                assemblyName.Version = new Version(1, 0, 0, 0);

                // create a new assembly for this proxy, one that isn't presisted on the file system
                AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(
                    assemblyName, AssemblyBuilderAccess.Run);

                // create a new module for this proxy
                ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(MODULE_NAME);

                // Set the class to be public and sealed
                TypeAttributes typeAttributes =
                    TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed;

                // Gather up the proxy information and create a new type builder.  One that
                // inherits from Object and implements the interface passed in
                TypeBuilder typeBuilder = moduleBuilder.DefineType(
                    dynamicTypeName, typeAttributes, objType, interfaces);

                // Define a member variable to hold the delegate
                FieldBuilder handlerField = typeBuilder.DefineField(
                    HANDLER_NAME, handlerType, FieldAttributes.Private);


                // build a constructor that takes the delegate object as the only argument
                //ConstructorInfo defaultObjConstructor = objType.GetConstructor( new Type[0] );
                ConstructorInfo    superConstructor    = objType.GetConstructor(new Type[0]);
                ConstructorBuilder delegateConstructor = typeBuilder.DefineConstructor(
                    MethodAttributes.Public, CallingConventions.Standard, new Type[] { handlerType });

                #region ( "Constructor IL Code" )
                ILGenerator constructorIL = delegateConstructor.GetILGenerator();

                // Load "this"
                constructorIL.Emit(OpCodes.Ldarg_0);
                // Load first constructor parameter
                constructorIL.Emit(OpCodes.Ldarg_1);
                // Set the first parameter into the handler field
                constructorIL.Emit(OpCodes.Stfld, handlerField);
                // Load "this"
                constructorIL.Emit(OpCodes.Ldarg_0);
                // Call the super constructor
                constructorIL.Emit(OpCodes.Call, superConstructor);
                // Constructor return
                constructorIL.Emit(OpCodes.Ret);
                #endregion

                // for every method that the interfaces define, build a corresponding
                // method in the dynamic type that calls the handlers invoke method.
                foreach (Type interfaceType in interfaces)
                {
                    GenerateMethod(interfaceType, handlerField, typeBuilder);
                }

                retVal = typeBuilder.CreateType();
            }

            return(retVal);
        }
Exemple #17
0
            /// <summary>
            /// 创建 TCP 服务端
            /// </summary>
            /// <param name="type"></param>
            /// <param name="attribute"></param>
            /// <param name="serverInterfaceType"></param>
            /// <param name="serverCallType"></param>
            /// <param name="constructorParameterTypes"></param>
            /// <param name="methods"></param>
            /// <returns></returns>
            internal Type Build(Type type, ServerAttribute attribute, Type serverInterfaceType, Type serverCallType, Type[] constructorParameterTypes, Method <attributeType, methodAttributeType, serverSocketSenderType>[] methods)
            {
                string             serverIdentity       = Interlocked.Increment(ref Metadata.Identity).toString();
                TypeBuilder        typeBuilder          = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ServerTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.ServerType);
                FieldBuilder       valueFieldBuilder    = typeBuilder.DefineField("_value_", typeof(object), FieldAttributes.Private | FieldAttributes.InitOnly);
                ConstructorBuilder constructorBuilder   = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorParameterTypes);
                ILGenerator        constructorGenerator = constructorBuilder.GetILGenerator();
                Label serverAttributeNotNull            = constructorGenerator.DefineLabel();

                #region base(attribute, verify, log)
                constructorGenerator.Emit(OpCodes.Ldarg_0);
                constructorGenerator.Emit(OpCodes.Ldarg_1);
                constructorGenerator.Emit(OpCodes.Ldarg_2);
                constructorGenerator.Emit(OpCodes.Ldarg_S, 4);
                constructorGenerator.Emit(OpCodes.Call, Metadata.ServerConstructorInfo);
                #endregion
                #region _value_ = value;
                constructorGenerator.Emit(OpCodes.Ldarg_0);
                constructorGenerator.Emit(OpCodes.Ldarg_3);
                constructorGenerator.Emit(OpCodes.Stfld, valueFieldBuilder);
                #endregion
                constructorGenerator.Emit(OpCodes.Ret);

                ConstructorBuilder staticConstructorBuilder   = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null);
                ILGenerator        staticConstructorGenerator = staticConstructorBuilder.GetILGenerator();
                #region public override void DoCommand(int index, AutoCSer.Net.TcpInternalServer.ServerSocketSender socket, ref SubArray<byte> data)
                MethodBuilder doCommandMethodBuilder = typeBuilder.DefineMethod("DoCommand", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot, typeof(void), Metadata.DoCommandParameterTypes);
                #endregion
                ILGenerator doCommandGenerator = doCommandMethodBuilder.GetILGenerator();
                doCommandGenerator.DeclareLocal(typeof(int));
                Label   doCommandReturnLabel = doCommandGenerator.DefineLabel();
                Label[] doCommandLabels      = new Label[methods.Length];
                int     doCommandLabelIndex  = 0;
                foreach (Method <attributeType, methodAttributeType, serverSocketSenderType> method in methods)
                {
                    doCommandLabels[doCommandLabelIndex++] = method == null ? doCommandReturnLabel : (method.DoCommandLabel = doCommandGenerator.DefineLabel());
                }
                #region switch (index - @CommandStartIndex)
                doCommandGenerator.Emit(OpCodes.Ldarg_1);
                doCommandGenerator.int32(TcpServer.Server.CommandStartIndex);
                doCommandGenerator.Emit(OpCodes.Sub);
                doCommandGenerator.Emit(OpCodes.Stloc_0);
                doCommandGenerator.Emit(OpCodes.Ldloc_0);
                doCommandGenerator.Emit(OpCodes.Switch, doCommandLabels);
                doCommandGenerator.MarkLabel(doCommandReturnLabel);
                doCommandGenerator.Emit(OpCodes.Ret);
                #endregion
                Outputs = new TcpServer.OutputInfo[methods.Length];
                FieldInfo outputsField = serverInterfaceType.GetField("Outputs", BindingFlags.Static | BindingFlags.NonPublic);
                foreach (Method <attributeType, methodAttributeType, serverSocketSenderType> method in methods)
                {
                    if (method != null)
                    {
                        FieldBuilder outputInfoFieldBuilder;
                        if (method.OutputParameterType == null && !method.IsAsynchronousCallback)
                        {
                            outputInfoFieldBuilder = null;
                        }
                        else
                        {
                            TcpServer.OutputInfo outputInfo = new TcpServer.OutputInfo();
                            Outputs[method.Attribute.CommandIdentity] = outputInfo;
                            if (method.IsJsonSerialize)
                            {
                                outputInfo.IsKeepCallback = 1;
                            }
                            if (method.IsClientSendOnly)
                            {
                                outputInfo.IsClientSendOnly = 1;
                            }
                            if (method.OutputParameterType != null)
                            {
                                outputInfo.OutputParameterIndex = method.OutputParameterType.Index;
                                if (attribute.IsSimpleSerialize)
                                {
                                    outputInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType);
                                }
                            }
                            #region private static readonly AutoCSer.Net.TcpServer.OutputInfo @MethodIdentityCommand = AutoCSer.Net.TcpInternalServer.Emit.Server<interfaceType>.Outputs[@CommandIdentity];
                            staticConstructorGenerator.Emit(OpCodes.Ldsfld, outputsField);
                            staticConstructorGenerator.int32(method.Attribute.CommandIdentity);
                            staticConstructorGenerator.Emit(OpCodes.Ldelem_Ref);
                            staticConstructorGenerator.Emit(OpCodes.Stsfld, outputInfoFieldBuilder = typeBuilder.DefineField("_o" + method.Attribute.CommandIdentity.toString(), typeof(TcpServer.OutputInfo), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static));
                            #endregion
                        }
                        ParameterInfo[] parameters = method.MethodInfo.GetParameters();
                        TypeBuilder     serverCallTypeBuilder;
                        FieldInfo       returnTypeField  = method.ReturnValueType == null ? null : (method.ReturnValueType == typeof(TcpServer.ReturnValue) ? TcpServer.Emit.ServerMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ServerMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public));
                        FieldInfo       returnValueField = method.ReturnValueType == null ? null : method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public);
                        if (method.IsMethodServerCall)
                        {
                            Type      baseType            = method.ParameterType == null ? Metadata.ServerCallType : serverCallType.MakeGenericType(method.ParameterType.Type);
                            FieldInfo inputParameterField = method.ParameterType == null ? null : baseType.GetField("inputParameter", BindingFlags.Instance | BindingFlags.NonPublic);
                            serverCallTypeBuilder = typeBuilder.DefineNestedType(Metadata.ServerCallTypeName + ".Emit." + serverIdentity + "_" + method.Attribute.CommandIdentity.toString(), TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic, baseType);
                            Type      returnOutputType       = method.OutputParameterType == null ? typeof(AutoCSer.Net.TcpServer.ReturnValue) : typeof(AutoCSer.Net.TcpServer.ReturnValue <>).MakeGenericType(method.OutputParameterType.Type);
                            FieldInfo returnOutputValueField = method.OutputParameterType == null ? null : returnOutputType.GetField("Value", BindingFlags.Instance | BindingFlags.Public);
                            Type      returnOutputRefType    = returnOutputType.MakeByRefType();
                            #region private void get(ref AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName> value)
                            MethodBuilder getMethodBuilder = serverCallTypeBuilder.DefineMethod("get", MethodAttributes.Private, typeof(void), new Type[] { returnOutputRefType });
                            #endregion
                            ILGenerator  getGenerator               = getMethodBuilder.GetILGenerator();
                            Label        getReturnLabel             = getGenerator.DefineLabel();
                            LocalBuilder exceptionErrorLocalBuilder = getGenerator.DeclareLocal(typeof(Exception));
                            #region try
                            getGenerator.BeginExceptionBlock();
                            #endregion
                            #region @MethodReturnType.FullName @ReturnName = serverValue.@MethodName(Sender, inputParameter.@ParameterName);
                            LocalBuilder returnLocalBuilder = method.IsReturnType ? getGenerator.DeclareLocal(method.ReturnValueType ?? method.ReturnType) : null;
                            getGenerator.Emit(OpCodes.Ldarg_0);
                            getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallServerValueField);
                            foreach (ParameterInfo parameter in parameters)
                            {
                                if (StreamParameterType.IsInputParameter(parameter))
                                {
                                    getGenerator.Emit(OpCodes.Ldarg_0);
                                    getGenerator.Emit(OpCodes.Ldflda, inputParameterField);
                                    getGenerator.Emit(parameter.ParameterType.IsByRef ? OpCodes.Ldflda : OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                }
                                else if (parameter.IsOut)
                                {
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField);
                                    getGenerator.Emit(OpCodes.Ldflda, method.OutputParameterType.GetField(parameter.Name));
                                }
                                else if (parameter.ParameterType == Metadata.SenderType)
                                {
                                    getGenerator.Emit(OpCodes.Ldarg_0);
                                    getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSenderField);
                                }
                                else
                                {
                                    getGenerator.Emit(OpCodes.Ldnull);
                                }
                            }
                            getGenerator.call(method.MethodInfo);
                            if (method.IsReturnType)
                            {
                                getGenerator.Emit(OpCodes.Stloc_S, returnLocalBuilder);
                            }
                            #endregion
                            FieldInfo returnValueTypeField = method.OutputParameterType == null ? TcpServer.Emit.ServerMetadata.ReturnValueTypeField : returnOutputType.GetField(TcpServer.Emit.ServerMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public);
                            if (method.OutputParameterType == null)
                            {
                                if (method.ReturnValueType != null)
                                {
                                    Label returnTypeErrorLabel = getGenerator.DefineLabel();
                                    #region if(@ReturnName.Type != AutoCSer.Net.TcpServer.ReturnType.Success)
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                    getGenerator.Emit(OpCodes.Beq_S, returnTypeErrorLabel);
                                    #endregion
                                    #region value.Type = @ReturnName.Type;
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                    #endregion
                                    getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                                    getGenerator.MarkLabel(returnTypeErrorLabel);
                                }
                                #region value.Type = AutoCSer.Net.TcpServer.ReturnType.Success;
                                getGenerator.Emit(OpCodes.Ldarg_1);
                                getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                #endregion
                                getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                            }
                            else
                            {
                                Label returnTypeErrorLabel;
                                if (method.ReturnValueType == null)
                                {
                                    returnTypeErrorLabel = default(Label);
                                }
                                else
                                {
                                    #region if(@ReturnName.Type != AutoCSer.Net.TcpServer.ReturnType.Success)
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                    getGenerator.Emit(OpCodes.Bne_Un, returnTypeErrorLabel = getGenerator.DefineLabel());
                                    #endregion
                                }
                                if (method.Attribute.IsVerifyMethod)
                                {
                                    Label verifyEndLabel = getGenerator.DefineLabel();
                                    #region if (@ReturnName / @ReturnName.Value)
                                    if (method.ReturnValueType == null)
                                    {
                                        getGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                    }
                                    else
                                    {
                                        getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        getGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                    }
                                    getGenerator.Emit(OpCodes.Brfalse_S, verifyEndLabel);
                                    #endregion
                                    #region Sender.SetVerifyMethod();
                                    getGenerator.Emit(OpCodes.Ldarg_0);
                                    getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSenderField);
                                    getGenerator.call(TcpServer.Emit.ServerMetadata.ServerSocketSenderSetVerifyMethod);
                                    #endregion
                                    getGenerator.MarkLabel(verifyEndLabel);
                                }
                                LocalBuilder valueLocalBuilder = getGenerator.DeclareLocal(method.OutputParameterType.Type);
                                #region value.Value.@ParameterName = inputParameter.@ParameterName;
                                foreach (ParameterInfo parameter in method.OutputParameters)
                                {
                                    if (!parameter.IsOut)
                                    {
                                        getGenerator.Emit(OpCodes.Ldarg_1);
                                        getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField);
                                        getGenerator.Emit(OpCodes.Ldarg_0);
                                        getGenerator.Emit(OpCodes.Ldflda, inputParameterField);
                                        getGenerator.Emit(OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                        getGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(parameter.Name));
                                    }
                                }
                                #endregion
                                if (method.ReturnType != typeof(void))
                                {
                                    #region value.Value.@ReturnName = @ReturnName / @ReturnName.Value;
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField);
                                    if (method.ReturnValueType == null)
                                    {
                                        getGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                    }
                                    else
                                    {
                                        getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        getGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                    }
                                    getGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName));
                                    #endregion
                                }
                                #region value.Type = AutoCSer.Net.TcpServer.ReturnType.Success;
                                getGenerator.Emit(OpCodes.Ldarg_1);
                                getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                #endregion
                                getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                                if (method.ReturnValueType != null)
                                {
                                    getGenerator.MarkLabel(returnTypeErrorLabel);
                                    #region value.Type = @ReturnName.Type;
                                    getGenerator.Emit(OpCodes.Ldarg_1);
                                    getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                    getGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                    getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                                    #endregion
                                    getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                                }
                            }
                            #region catch (Exception error)
                            getGenerator.BeginCatchBlock(typeof(Exception));
                            getGenerator.Emit(OpCodes.Stloc_S, exceptionErrorLocalBuilder);
                            #endregion
                            #region value.Type = AutoCSer.Net.TcpServer.ReturnType.ServerException;
                            getGenerator.Emit(OpCodes.Ldarg_1);
                            getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerException);
                            getGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                            #endregion
                            #region Sender.Log(error);
                            getGenerator.Emit(OpCodes.Ldarg_0);
                            getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSenderField);
                            getGenerator.Emit(OpCodes.Ldloc_S, exceptionErrorLocalBuilder);
                            getGenerator.call(Metadata.ServerSocketSenderAddLogMethod);
                            #endregion
                            getGenerator.Emit(OpCodes.Leave_S, getReturnLabel);
                            #region try end
                            getGenerator.EndExceptionBlock();
                            #endregion
                            getGenerator.MarkLabel(getReturnLabel);
                            getGenerator.Emit(OpCodes.Ret);

                            #region public override void Call()
                            MethodBuilder callMethodBuilder = serverCallTypeBuilder.DefineMethod("Call", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot, typeof(void), null);
                            #endregion
                            ILGenerator callGenerator = callMethodBuilder.GetILGenerator();
                            #region AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName> value = new AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName>();
                            LocalBuilder valueBuilder = callGenerator.DeclareLocal(returnOutputType);
                            if (method.OutputParameterType == null || method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj)
                            {
                                callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                callGenerator.Emit(OpCodes.Initobj, returnOutputType);
                            }
                            else
                            {
                                callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                callGenerator.int32(0);
                                callGenerator.Emit(OpCodes.Stfld, returnValueTypeField);
                            }
                            #endregion
                            Label pushLabel = callGenerator.DefineLabel();
                            #region if (Sender.IsSocket)
                            callGenerator.Emit(OpCodes.Ldarg_0);
                            callGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSenderField);
                            callGenerator.call(TcpServer.Emit.ServerMetadata.ServerSocketSenderGetIsSocketMethod);
                            callGenerator.Emit(OpCodes.Brfalse_S, pushLabel);
                            #endregion
                            #region get(ref value);
                            callGenerator.Emit(OpCodes.Ldarg_0);
                            callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                            callGenerator.call(getMethodBuilder);
                            #endregion
                            if (!method.IsClientSendOnly)
                            {
                                #region Sender.Push(@MethodIdentityCommand, ref value);
                                callGenerator.Emit(OpCodes.Ldarg_0);
                                callGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSenderField);
                                if (method.OutputParameterType == null)
                                {
                                    callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                    callGenerator.Emit(OpCodes.Ldfld, returnValueTypeField);
                                    callGenerator.call(Metadata.ServerSocketSenderPushReturnTypeMethod);
                                }
                                else
                                {
                                    callGenerator.Emit(OpCodes.Ldsfld, outputInfoFieldBuilder);
                                    callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder);
                                    callGenerator.call(Metadata.ServerSocketSenderPushOutputRefMethod.MakeGenericMethod(method.OutputParameterType.Type));
                                }
                                callGenerator.Emit(OpCodes.Pop);
                                #endregion
                            }
                            callGenerator.MarkLabel(pushLabel);
                            #region push(this);
                            callGenerator.Emit(OpCodes.Ldarg_0);
                            callGenerator.Emit(OpCodes.Ldarg_0);
                            callGenerator.call((method.ParameterType == null ? Metadata.ServerCallPushMethod : serverCallType.MakeGenericType(method.ParameterType.Type).GetMethod("push", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)).MakeGenericMethod(serverCallTypeBuilder));
                            #endregion
                            callGenerator.Emit(OpCodes.Ret);
                            serverCallTypeBuilder.CreateType();
                        }
                        else
                        {
                            serverCallTypeBuilder = null;
                        }

                        #region private void @MethodIndexName(AutoCSer.Net.TcpInternalServer.ServerSocketSender sender, ref SubArray<byte> data)
                        MethodBuilder methodBuilder = typeBuilder.DefineMethod("_m" + method.Attribute.CommandIdentity.toString(), MethodAttributes.Private, typeof(void), Metadata.MethodParameterTypes);
                        #endregion
                        ILGenerator methodGenerator = methodBuilder.GetILGenerator();
                        if (method.Attribute.IsExpired)
                        {
                            if (!method.IsClientSendOnly)
                            {
                                #region sender.Push(AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired);
                                methodGenerator.call(Metadata.ServerSocketSenderPushReturnTypeMethod);
                                methodGenerator.Emit(OpCodes.Pop);
                                #endregion
                            }
                        }
                        else
                        {
                            Label        pushLabel = methodGenerator.DefineLabel(), returnLable = methodGenerator.DefineLabel();
                            LocalBuilder returnTypeLocalBuilder;
                            if (method.IsClientSendOnly)
                            {
                                returnTypeLocalBuilder = null;
                            }
                            else
                            {
                                #region AutoCSer.Net.TcpServer.ReturnType returnType = AutoCSer.Net.TcpServer.ReturnType.Unknown;
                                returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType));
                                methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Unknown);
                                methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                #endregion
                            }
                            #region try
                            methodGenerator.BeginExceptionBlock();
                            #endregion
                            LocalBuilder parameterLocalBuilder, outputParameterLocalBuilder = null;
                            Label        serverDeSerializeErrorLabel;
                            if (method.ParameterType == null)
                            {
                                parameterLocalBuilder       = null;
                                serverDeSerializeErrorLabel = default(Label);
                            }
                            else
                            {
                                #region @InputParameterTypeName inputParameter = new @InputParameterTypeName();
                                parameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type);
                                if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj)
                                {
                                    methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                    methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type);
                                }
                                #endregion
                                #region if (sender.DeSerialize(ref data, ref inputParameter))
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.Emit(OpCodes.Ldarg_2);
                                methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                methodGenerator.int32(method.ParameterType.IsSimpleSerialize ? 1 : 0);
                                methodGenerator.call(TcpServer.Emit.ServerMetadata.ServerSocketSenderDeSerializeMethod.MakeGenericMethod(method.ParameterType.Type));
                                methodGenerator.Emit(OpCodes.Brfalse, serverDeSerializeErrorLabel = methodGenerator.DefineLabel());
                                #endregion
                            }
                            if (method.IsMethodServerCall)
                            {
                                #region @MethodStreamName.Call(sender, _value_, ref inputParameter);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.Emit(OpCodes.Ldarg_0);
                                methodGenerator.Emit(OpCodes.Ldfld, valueFieldBuilder);
                                if (method.ParameterType == null)
                                {
                                    methodGenerator.call(Metadata.ServerCallCallMethod.MakeGenericMethod(serverCallTypeBuilder));
                                }
                                else
                                {
                                    methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                    methodGenerator.call(serverCallType.MakeGenericType(method.ParameterType.Type).GetMethod("Call", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly).MakeGenericMethod(serverCallTypeBuilder));
                                }
                                #endregion
                            }
                            else
                            {
                                if (method.OutputParameterType != null)
                                {
                                    #region @OutputParameterTypeName outputParameter = new @OutputParameterTypeName();
                                    outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type);
                                    if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type);
                                    }
                                    #endregion
                                }
                                #region @MethodReturnType.FullName @ReturnName = _value_.@MethodName(sender, inputParameter.@ParameterName);
                                LocalBuilder returnLocalBuilder = method.IsReturnType ? methodGenerator.DeclareLocal(method.ReturnValueType ?? method.ReturnType) : null;
                                methodGenerator.Emit(OpCodes.Ldarg_0);
                                methodGenerator.Emit(OpCodes.Ldfld, valueFieldBuilder);
                                foreach (ParameterInfo parameter in parameters)
                                {
                                    if (StreamParameterType.IsInputParameter(parameter))
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                        methodGenerator.Emit(parameter.ParameterType.IsByRef ? OpCodes.Ldflda : OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                    }
                                    else if (parameter.IsOut)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldflda, method.OutputParameterType.GetField(parameter.Name));
                                    }
                                    else if (parameter.ParameterType == Metadata.SenderType)
                                    {
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                    }
                                    else
                                    {
                                        methodGenerator.Emit(OpCodes.Ldnull);
                                    }
                                }
                                methodGenerator.call(method.MethodInfo);
                                if (method.IsReturnType)
                                {
                                    methodGenerator.Emit(OpCodes.Stloc_S, returnLocalBuilder);
                                }
                                #endregion
                                if (method.OutputParameterType == null)
                                {
                                    if (method.ReturnValueType == null)
                                    {
                                        if (!method.IsClientSendOnly)
                                        {
                                            #region sender.Push();
                                            methodGenerator.Emit(OpCodes.Ldarg_1);
                                            methodGenerator.call(Metadata.ServerSocketSenderPushMethod);
                                            methodGenerator.Emit(OpCodes.Pop);
                                            #endregion
                                        }
                                    }
                                    else
                                    {
                                        #region sender.Push(@ReturnName.Type);
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                        methodGenerator.call(Metadata.ServerSocketSenderPushReturnTypeMethod);
                                        methodGenerator.Emit(OpCodes.Pop);
                                        #endregion
                                    }
                                }
                                else
                                {
                                    Label returnTypeErrorLabel;
                                    if (method.ReturnValueType == null)
                                    {
                                        returnTypeErrorLabel = default(Label);
                                    }
                                    else
                                    {
                                        #region if(@ReturnName.Type == AutoCSer.Net.TcpServer.ReturnType.Success)
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                        methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success);
                                        methodGenerator.Emit(OpCodes.Bne_Un, returnTypeErrorLabel = methodGenerator.DefineLabel());
                                        #endregion
                                    }
                                    if (method.Attribute.IsVerifyMethod)
                                    {
                                        Label verifyEndLabel = methodGenerator.DefineLabel();
                                        #region if (@ReturnName / @ReturnName.Value)
                                        if (method.ReturnValueType == null)
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                        }
                                        else
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                        }
                                        methodGenerator.Emit(OpCodes.Brfalse_S, verifyEndLabel);
                                        #endregion
                                        #region sender.SetVerifyMethod();
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                        methodGenerator.call(TcpServer.Emit.ServerMetadata.ServerSocketSenderSetVerifyMethod);
                                        #endregion
                                        methodGenerator.MarkLabel(verifyEndLabel);
                                    }
                                    foreach (ParameterInfo parameter in method.OutputParameters)
                                    {
                                        if (!parameter.IsOut)
                                        {
                                            #region outputParameter.@ParameterName = inputParameter.@ParameterName
                                            methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name));
                                            methodGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(parameter.Name));
                                            #endregion
                                        }
                                    }
                                    if (method.ReturnType != typeof(void))
                                    {
                                        #region _outputParameter_.Ret = @ReturnName / @ReturnName.Value
                                        methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                        if (method.ReturnValueType == null)
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder);
                                        }
                                        else
                                        {
                                            methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                            methodGenerator.Emit(OpCodes.Ldfld, returnValueField);
                                        }
                                        methodGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName));
                                        #endregion
                                    }

                                    #region sender.Push(@MethodIdentityCommand, ref outputParameter)
                                    methodGenerator.Emit(OpCodes.Ldarg_1);
                                    methodGenerator.Emit(OpCodes.Ldsfld, outputInfoFieldBuilder);
                                    methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder);
                                    methodGenerator.call(Metadata.ServerSocketSenderPushOutputMethod.MakeGenericMethod(method.OutputParameterType.Type));
                                    methodGenerator.Emit(OpCodes.Pop);
                                    #endregion
                                    methodGenerator.Emit(OpCodes.Leave_S, returnLable);
                                    if (method.ReturnValueType != null)
                                    {
                                        methodGenerator.MarkLabel(returnTypeErrorLabel);
                                        #region sender.Push(@ReturnValue.Type);
                                        methodGenerator.Emit(OpCodes.Ldarg_1);
                                        methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder);
                                        methodGenerator.Emit(OpCodes.Ldfld, returnTypeField);
                                        methodGenerator.call(Metadata.ServerSocketSenderPushReturnTypeMethod);
                                        methodGenerator.Emit(OpCodes.Pop);
                                        #endregion
                                    }
                                }
                            }
                            methodGenerator.Emit(OpCodes.Leave_S, returnLable);
                            if (method.ParameterType != null)
                            {
                                methodGenerator.MarkLabel(serverDeSerializeErrorLabel);
                                if (!method.IsClientSendOnly)
                                {
                                    #region returnType = AutoCSer.Net.TcpServer.ReturnType.ServerDeSerializeError;
                                    methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerDeSerializeError);
                                    methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                    #endregion
                                }
                                methodGenerator.Emit(OpCodes.Leave_S, pushLabel);
                            }
                            #region catch (Exception error)
                            methodGenerator.BeginCatchBlock(typeof(Exception));
                            LocalBuilder errorLocalBuilder = methodGenerator.DeclareLocal(typeof(Exception));
                            methodGenerator.Emit(OpCodes.Stloc_S, errorLocalBuilder);
                            #endregion
                            if (!method.IsClientSendOnly)
                            {
                                #region returnType = AutoCSer.Net.TcpServer.ReturnType.ServerException;
                                methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerException);
                                methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder);
                                #endregion
                            }
                            #region sender.Log(error);
                            methodGenerator.Emit(OpCodes.Ldarg_1);
                            methodGenerator.Emit(OpCodes.Ldloc_S, errorLocalBuilder);
                            methodGenerator.call(Metadata.ServerSocketSenderAddLogMethod);
                            #endregion
                            methodGenerator.Emit(OpCodes.Leave_S, pushLabel);
                            #region try end
                            methodGenerator.EndExceptionBlock();
                            #endregion
                            methodGenerator.MarkLabel(pushLabel);
                            if (!method.IsClientSendOnly)
                            {
                                #region sender.Push(returnType);
                                methodGenerator.Emit(OpCodes.Ldarg_1);
                                methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder);
                                methodGenerator.call(Metadata.ServerSocketSenderPushReturnTypeMethod);
                                methodGenerator.Emit(OpCodes.Pop);
                                #endregion
                            }
                            methodGenerator.MarkLabel(returnLable);
                        }
                        methodGenerator.Emit(OpCodes.Ret);

                        #region case @MethodIndex: @MethodIndexName(socket, ref data);
                        doCommandGenerator.MarkLabel(method.DoCommandLabel);
                        doCommandGenerator.Emit(OpCodes.Ldarg_0);
                        doCommandGenerator.Emit(OpCodes.Ldarg_2);
                        doCommandGenerator.Emit(OpCodes.Ldarg_3);
                        doCommandGenerator.call(methodBuilder);
                        #endregion
                        doCommandGenerator.Emit(OpCodes.Ret);
                        method.DoCommandLabel = default(Label);
                    }
                }
                doCommandGenerator.Emit(OpCodes.Ret);
                staticConstructorGenerator.Emit(OpCodes.Ret);

                return(typeBuilder.CreateType());
            }
Exemple #18
0
        internal static void CreateMetadata(Symbol sym)
        {
            switch (sym.kind)
            {
            case Symbol.Kinds.Global:
            {
                if (sym.type != Tab.noType)
                {
                    sym.fld = program.DefineField(sym.name, sym.type.sysType, GLOBALATTR);
                }
                break;
            }

            case Symbol.Kinds.Field:
            {
                if (sym.type != Tab.noType)
                {
                    sym.fld = inner.DefineField(sym.name, sym.type.sysType, FIELDATTR);
                }
                break;
            }

            case Symbol.Kinds.Local:
            {
                LocalBuilder vbleLocalDin = il.DeclareLocal(sym.type.sysType);
                if (primeraVez)
                {
                    ultimaVbleLocalDin = vbleLocalDin;
                    primeraVez         = false;
                }
                break;
            }

            case Symbol.Kinds.Type:
                inner            = module.DefineType(sym.name, INNERATTR);
                sym.type.sysType = inner;
                // define default contructor (calls base constructor)
                sym.ctor = inner.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]);
                il       = sym.ctor.GetILGenerator();
                il.Emit(LDARG0);
                il.Emit(CALL, typeof(object).GetConstructor(new Type[0]));
                il.Emit(RET);
                break;

            case Symbol.Kinds.Meth:
            {
                sym.meth = program.DefineMethod(sym.name, MethodAttributes.Public, typeof(void), null);
                il       = sym.meth.GetILGenerator();
                if (sym.name == "Main")
                {
                    assembly.SetEntryPoint(sym.meth);
                }
                break;
            }

            case Symbol.Kinds.Prog:
            {
                AssemblyName assemblyName = new AssemblyName();
                assemblyName.Name = sym.name;
                assembly          =
                    AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
                module  = assembly.DefineDynamicModule(sym.name + "Module", sym.name + ".exe"); //".exe"
                program = module.DefineType(sym.name, PROGATTR);                                //clase din para el program
                Type               objType   = Type.GetType("System.Object");
                ConstructorInfo    objCtor   = objType.GetConstructor(new Type[0]);
                ConstructorBuilder pointCtor = program.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]);
                ILGenerator        ctorIL    = pointCtor.GetILGenerator();
                // First, you build the constructor.
                ctorIL.Emit(OpCodes.Ldarg_0);
                ctorIL.Emit(OpCodes.Call, objCtor);
                ctorIL.Emit(OpCodes.Ret);
                inner = null;
                // build methods for I/O keywords (read, write)
                BuildReadChar();
                BuildReadInt();
                BuildWriteChar();
                BuildWriteInt();
                break;
            }
            }
        }
					internal override void Apply(ClassLoaderWrapper loader, ConstructorBuilder cb, object annotation)
					{
					}
 public void ConstructWithParametersContextTest()
 {
     this.testObject = new ConstructorBuilder(this.context);
     Assert.Throws<ArgumentNullException>(() => new ConstructorBuilder(null));
 }
				internal override void Apply(ClassLoaderWrapper loader, ConstructorBuilder cb, object annotation)
				{
					if (type.IsSubclassOf(Types.SecurityAttribute))
					{
#if STATIC_COMPILER
						cb.__AddDeclarativeSecurity(MakeCustomAttributeBuilder(loader, annotation));
#elif STUB_GENERATOR
#else
						SecurityAction action;
						PermissionSet permSet;
						if (MakeDeclSecurity(type, annotation, out action, out permSet))
						{
							cb.AddDeclarativeSecurity(action, permSet);
						}
#endif
					}
					else
					{
						cb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation));
					}
				}
 public void SetUp()
 {
     this.mocks = new MockRepository();
     this.context = this.mocks.StrictMock<NStub.CSharp.BuildContext.IMemberBuildContext>();
     this.testObject = new ConstructorBuilder(this.context);
 }
Exemple #23
0
		//
		// Creates the ConstructorBuilder
		//
		public override bool Define ()
		{
			if (ConstructorBuilder != null)
				return true;

			if (!CheckAbstractAndExtern (block != null))
				return false;
			
			// Check if arguments were correct.
			if (!CheckBase ())
				return false;

			if (Parent.PrimaryConstructorParameters != null && !IsPrimaryConstructor && !IsStatic) {
				if (Parent.Kind == MemberKind.Struct && Initializer is ConstructorThisInitializer && Initializer.Arguments == null) {
					Report.Error (8043, Location, "`{0}': Structs with primary constructor cannot specify default constructor initializer",
						GetSignatureForError ());
				} else if (Initializer == null || Initializer is ConstructorBaseInitializer) {
					Report.Error (8037, Location, "`{0}': Instance constructor of type with primary constructor must specify `this' constructor initializer",
						GetSignatureForError ());
				}
			}

			var ca = ModifiersExtensions.MethodAttr (ModFlags) | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;

			ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
				ca, CallingConventions,
				parameters.GetMetaInfo ());

			spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, parameters, ModFlags);
			
			Parent.MemberCache.AddMember (spec);
			
			if (block != null) {
				// It's here only to report an error
				if (block.IsIterator) {
					member_type = Compiler.BuiltinTypes.Void;
					Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
				}

				if (Compiler.Settings.WriteMetadataOnly)
					block = null;
			}

			return true;
		}
 public void TearDown()
 {
     this.testObject = null;
     this.context = null;
     this.mocks = null;
 }
		public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
		{
			base.ApplyAttributes (mb, cb, index, pa);
			pa.ParamArray.EmitAttribute (builder);
		}
            // Generate the declaration for the IgnoresAccessChecksToAttribute type.
            // This attribute will be both defined and used in the dynamic assembly.
            // Each usage identifies the name of the assembly containing non-public
            // types the dynamic assembly needs to access.  Normally those types
            // would be inaccessible, but this attribute allows them to be visible.
            // It works like a reverse InternalsVisibleToAttribute.
            // This method returns the TypeInfo of the generated attribute.
            private TypeInfo GenerateTypeInfoOfIgnoresAccessChecksToAttribute()
            {
                TypeBuilder attributeTypeBuilder =
                    _mb.DefineType("System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute",
                                   TypeAttributes.Public | TypeAttributes.Class,
                                   typeof(Attribute));

                // Create backing field as:
                // private string assemblyName;
                FieldBuilder assemblyNameField =
                    attributeTypeBuilder.DefineField("assemblyName", typeof(String), FieldAttributes.Private);

                // Create ctor as:
                // public IgnoresAccessChecksToAttribute(string)
                ConstructorBuilder constructorBuilder = attributeTypeBuilder.DefineConstructor(MethodAttributes.Public,
                                                                                               CallingConventions.HasThis,
                                                                                               new Type[] { assemblyNameField.FieldType });

                ILGenerator il = constructorBuilder.GetILGenerator();

                // Create ctor body as:
                // this.assemblyName = {ctor parameter 0}
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg, 1);
                il.Emit(OpCodes.Stfld, assemblyNameField);

                // return
                il.Emit(OpCodes.Ret);

                // Define property as:
                // public string AssemblyName {get { return this.assemblyName; } }
                PropertyBuilder getterPropertyBuilder = attributeTypeBuilder.DefineProperty(
                    "AssemblyName",
                    PropertyAttributes.None,
                    CallingConventions.HasThis,
                    returnType: typeof(String),
                    parameterTypes: null);

                MethodBuilder getterMethodBuilder = attributeTypeBuilder.DefineMethod(
                    "get_AssemblyName",
                    MethodAttributes.Public,
                    CallingConventions.HasThis,
                    returnType: typeof(String),
                    parameterTypes: null);

                // Generate body:
                // return this.assemblyName;
                il = getterMethodBuilder.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, assemblyNameField);
                il.Emit(OpCodes.Ret);

                // Generate the AttributeUsage attribute for this attribute type:
                // [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
                TypeInfo attributeUsageTypeInfo = typeof(AttributeUsageAttribute).GetTypeInfo();

                // Find the ctor that takes only AttributeTargets
                ConstructorInfo attributeUsageConstructorInfo =
                    attributeUsageTypeInfo.DeclaredConstructors
                    .Single(c => c.GetParameters().Count() == 1 &&
                            c.GetParameters()[0].ParameterType == typeof(AttributeTargets));

                // Find the property to set AllowMultiple
                PropertyInfo allowMultipleProperty =
                    attributeUsageTypeInfo.DeclaredProperties
                    .Single(f => String.Equals(f.Name, "AllowMultiple"));

                // Create a builder to construct the instance via the ctor and property
                CustomAttributeBuilder customAttributeBuilder =
                    new CustomAttributeBuilder(attributeUsageConstructorInfo,
                                               new object[] { AttributeTargets.Assembly },
                                               new PropertyInfo[] { allowMultipleProperty },
                                               new object[] { true });

                // Attach this attribute instance to the newly defined attribute type
                attributeTypeBuilder.SetCustomAttribute(customAttributeBuilder);

                // Make the TypeInfo real so the constructor can be used.
                return(attributeTypeBuilder.CreateTypeInfo());
            }
		public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa)
		{
			if (builder != null)
				throw new InternalErrorException ("builder already exists");

			var pattrs = ParametersCompiled.GetParameterAttribute (modFlags);
			if (HasOptionalExpression)
				pattrs |= ParameterAttributes.Optional;

			if (mb == null)
				builder = cb.DefineParameter (index, pattrs, Name);
			else
				builder = mb.DefineParameter (index, pattrs, Name);

			if (OptAttributes != null)
				OptAttributes.Emit ();

			if (HasDefaultValue) {
				//
				// Emit constant values for true constants only, the other
				// constant-like expressions will rely on default value expression
				//
				var def_value = DefaultValue;
				Constant c = def_value != null ? def_value.Child as Constant : default_expr as Constant;
				if (c != null) {
					if (c.Type.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
						pa.DecimalConstant.EmitAttribute (builder, (decimal) c.GetValue (), c.Location);
					} else {
						builder.SetConstant (c.GetValue ());
					}
				} else if (default_expr.Type.IsStruct) {
					//
					// Handles special case where default expression is used with value-type
					//
					// void Foo (S s = default (S)) {}
					//
					builder.SetConstant (null);
				}
			}

			if (parameter_type != null) {
				if (parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
					pa.Dynamic.EmitAttribute (builder);
				} else if (parameter_type.HasDynamicElement) {
					pa.Dynamic.EmitAttribute (builder, parameter_type, Location);
				}
			}
		}
        public Type EmitDynamicNTierDictionaryType <TObject>(Type[] nestedKeyTypes)
        {
            Type entityType = typeof(TObject);
            int  tierNumber = nestedKeyTypes.Length;

            string typeContactStr = entityType.ToString();

            for (int i = 0; i < nestedKeyTypes.Length; i++)
            {
                typeContactStr += "_" + TypeHelper.GetClassSimpleName(nestedKeyTypes[i]);
            }

            Type        baseType    = typeof(IObjectClassifier <TObject>);
            string      typeName    = string.Format("{0}_Classifier", typeContactStr);
            TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class);

            typeBuilder.AddInterfaceImplementation(baseType);
            typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new object[] {}));

            //定义成员
            Type innerDicType = typeof(Dictionary <,>).MakeGenericType(nestedKeyTypes[tierNumber - 1], typeof(IObjectContainer <TObject>));

            if (tierNumber > 1)
            {
                for (int i = nestedKeyTypes.Length - 2; i >= 0; i--)
                {
                    innerDicType = typeof(Dictionary <,>).MakeGenericType(nestedKeyTypes[i], innerDicType);
                }
            }


            FieldBuilder dicField = typeBuilder.DefineField("dic", innerDicType, FieldAttributes.Private);
            FieldBuilder columns4ClassifyField = typeBuilder.DefineField("columns4Classify", typeof(string[]), FieldAttributes.Private);
            FieldBuilder containerListField    = typeBuilder.DefineField("containerList", typeof(List <IObjectContainer <TObject> >), FieldAttributes.Private);

            FieldBuilder containerCreatorField = typeBuilder.DefineField("containerCreator", typeof(IObjectContainerCreator <TObject>), FieldAttributes.Private);

            containerCreatorField.SetCustomAttribute(new CustomAttributeBuilder(typeof(NonSerializedAttribute).GetConstructor(Type.EmptyTypes), new object[] { }));
            FieldBuilder propertyQuickerField = typeBuilder.DefineField("propertyQuicker", typeof(IPropertyQuicker <TObject>), FieldAttributes.Private);

            propertyQuickerField.SetCustomAttribute(new CustomAttributeBuilder(typeof(NonSerializedAttribute).GetConstructor(Type.EmptyTypes), new object[] { }));

            Dictionary <int, FieldBuilder> distinctArrayFieldInfoDic = new Dictionary <int, FieldBuilder>();

            for (int i = 0; i < nestedKeyTypes.Length; i++)
            {
                distinctArrayFieldInfoDic.Add(i, typeBuilder.DefineField("distinctArray" + i.ToString(), typeof(SortedArray <>).MakeGenericType(nestedKeyTypes[i]), FieldAttributes.Private));
            }

            #region Emit Ctor
            ConstructorBuilder ctor    = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(string[]) });
            ILGenerator        ctorGen = ctor.GetILGenerator();

            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Newobj, innerDicType.GetConstructor(Type.EmptyTypes)); //值类型用 OpCodes.Initobj
            ctorGen.Emit(OpCodes.Stfld, dicField);

            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Newobj, typeof(List <IObjectContainer <TObject> >).GetConstructor(Type.EmptyTypes));
            ctorGen.Emit(OpCodes.Stfld, containerListField);

            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); //调用基类的构造函数

            ctorGen.Emit(OpCodes.Ldarg_0);
            ctorGen.Emit(OpCodes.Ldarg_1);
            ctorGen.Emit(OpCodes.Stfld, columns4ClassifyField);

            for (int i = 0; i < nestedKeyTypes.Length; i++)
            {
                ctorGen.Emit(OpCodes.Ldarg_0);
                ctorGen.Emit(OpCodes.Newobj, typeof(SortedArray <>).MakeGenericType(nestedKeyTypes[i]).GetConstructor(Type.EmptyTypes));
                ctorGen.Emit(OpCodes.Stfld, distinctArrayFieldInfoDic[i]);
            }

            ctorGen.Emit(OpCodes.Ret);
            #endregion

            this.EmitInitializeMethod <TObject>(baseType, typeBuilder, containerCreatorField, propertyQuickerField);
            this.EmitAddMethod <TObject>(tierNumber, entityType, baseType, innerDicType, typeBuilder, nestedKeyTypes, dicField, columns4ClassifyField, containerListField, distinctArrayFieldInfoDic, containerCreatorField, propertyQuickerField);
            MethodBuilder doGetContainerMethodBuilder = this.EmitDoGetContainerMethod <TObject>(tierNumber, entityType, baseType, innerDicType, typeBuilder, nestedKeyTypes, dicField, columns4ClassifyField);
            this.EmitGetContainersMethod <TObject>(baseType, typeBuilder, nestedKeyTypes, distinctArrayFieldInfoDic, doGetContainerMethodBuilder);
            this.EmitGetAllContainersMethod(baseType, typeBuilder, containerListField);
            this.EmitGetDistinctValuesMethod(baseType, typeBuilder, nestedKeyTypes, columns4ClassifyField, distinctArrayFieldInfoDic);
            this.EmitProperties4ClassifyProperty(baseType, typeBuilder, columns4ClassifyField);

            Type target = typeBuilder.CreateType();

            return(target);
        }