// 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()); }
// // 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; }
// // 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); }
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()); } }
private void DefineStaticConstructor(TypeBuilder fnTB) { ConstructorBuilder cb = fnTB.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); EmitStaticConstructorBody(new CljILGen(cb.GetILGenerator())); }
/// <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()); }
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()); }
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); }
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); }
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); }
/// <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()); }
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); }
// // 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); }