📄 typemanager.cs
字号:
security_attr_type = CoreLookupType ("System.Security.Permissions", "SecurityAttribute"); required_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "RequiredAttributeAttribute"); guid_attr_type = CoreLookupType ("System.Runtime.InteropServices", "GuidAttribute"); assembly_culture_attribute_type = CoreLookupType ("System.Reflection", "AssemblyCultureAttribute"); comimport_attr_type = CoreLookupType ("System.Runtime.InteropServices", "ComImportAttribute"); coclass_attr_type = CoreLookupType ("System.Runtime.InteropServices", "CoClassAttribute"); // // .NET 2.0 //#if NET_2_0 compiler_generated_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute"); fixed_buffer_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "FixedBufferAttribute"); default_charset_type = CoreLookupType ("System.Runtime.InteropServices", "DefaultCharSetAttribute"); runtime_compatibility_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute");#endif // // When compiling corlib, store the "real" types here. // if (!RootContext.StdLib) { system_int32_type = typeof (System.Int32); system_array_type = typeof (System.Array); system_type_type = typeof (System.Type); system_assemblybuilder_type = typeof (System.Reflection.Emit.AssemblyBuilder); Type [] void_arg = { }; system_int_array_get_length = GetMethod ( system_array_type, "get_Length", void_arg); system_int_array_get_rank = GetMethod ( system_array_type, "get_Rank", void_arg); system_object_array_clone = GetMethod ( system_array_type, "Clone", void_arg); Type [] system_int_arg = { system_int32_type }; system_int_array_get_length_int = GetMethod ( system_array_type, "GetLength", system_int_arg); system_int_array_get_upper_bound_int = GetMethod ( system_array_type, "GetUpperBound", system_int_arg); system_int_array_get_lower_bound_int = GetMethod ( system_array_type, "GetLowerBound", system_int_arg); Type [] system_array_int_arg = { system_array_type, system_int32_type }; system_void_array_copyto_array_int = GetMethod ( system_array_type, "CopyTo", system_array_int_arg); Type [] system_3_type_arg = { system_type_type, system_type_type, system_type_type }; Type [] system_4_type_arg = { system_type_type, system_type_type, system_type_type, system_type_type }; MethodInfo set_corlib_type_builders = GetMethod ( system_assemblybuilder_type, "SetCorlibTypeBuilders", system_4_type_arg, true, false); if (set_corlib_type_builders != null) { object[] args = new object [4]; args [0] = object_type; args [1] = value_type; args [2] = enum_type; args [3] = void_type; set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args); } else { // Compatibility for an older version of the class libs. set_corlib_type_builders = GetMethod ( system_assemblybuilder_type, "SetCorlibTypeBuilders", system_3_type_arg, true, true); if (set_corlib_type_builders == null) { Report.Error (-26, "Corlib compilation is not supported in Microsoft.NET due to bugs in it"); return; } object[] args = new object [3]; args [0] = object_type; args [1] = value_type; args [2] = enum_type; set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args); } } system_object_expr.Type = object_type; system_string_expr.Type = string_type; system_boolean_expr.Type = bool_type; system_decimal_expr.Type = decimal_type; system_single_expr.Type = float_type; system_double_expr.Type = double_type; system_sbyte_expr.Type = sbyte_type; system_byte_expr.Type = byte_type; system_int16_expr.Type = short_type; system_uint16_expr.Type = ushort_type; system_int32_expr.Type = int32_type; system_uint32_expr.Type = uint32_type; system_int64_expr.Type = int64_type; system_uint64_expr.Type = uint64_type; system_char_expr.Type = char_type; system_void_expr.Type = void_type; system_asynccallback_expr.Type = asynccallback_type; system_iasyncresult_expr.Type = iasyncresult_type; system_valuetype_expr.Type = value_type; // // These are only used for compare purposes // anonymous_method_type = typeof (AnonymousMethod); null_type = typeof (NullType); } // // The helper methods that are used by the compiler // public static void InitCodeHelpers () { // // Now load the default methods that we use. // Type [] string_string = { string_type, string_type }; string_concat_string_string = GetMethod ( string_type, "Concat", string_string); Type [] string_string_string = { string_type, string_type, string_type }; string_concat_string_string_string = GetMethod ( string_type, "Concat", string_string_string); Type [] string_string_string_string = { string_type, string_type, string_type, string_type }; string_concat_string_string_string_string = GetMethod ( string_type, "Concat", string_string_string_string); Type[] params_string = { GetConstructedType (string_type, "[]") }; string_concat_string_dot_dot_dot = GetMethod ( string_type, "Concat", params_string); Type [] object_object = { object_type, object_type }; string_concat_object_object = GetMethod ( string_type, "Concat", object_object); Type [] object_object_object = { object_type, object_type, object_type }; string_concat_object_object_object = GetMethod ( string_type, "Concat", object_object_object); Type[] params_object = { GetConstructedType (object_type, "[]") }; string_concat_object_dot_dot_dot = GetMethod ( string_type, "Concat", params_object); Type [] string_ = { string_type }; string_isinterneted_string = GetMethod ( string_type, "IsInterned", string_); Type [] runtime_type_handle = { runtime_handle_type }; system_type_get_type_from_handle = GetMethod ( type_type, "GetTypeFromHandle", runtime_type_handle); Type [] delegate_delegate = { delegate_type, delegate_type }; delegate_combine_delegate_delegate = GetMethod ( delegate_type, "Combine", delegate_delegate); delegate_remove_delegate_delegate = GetMethod ( delegate_type, "Remove", delegate_delegate); // // Void arguments // Type [] void_arg = { }; ienumerator_getcurrent = GetProperty ( ienumerator_type, "Current"); bool_movenext_void = GetMethod ( ienumerator_type, "MoveNext", void_arg); void_reset_void = GetMethod ( ienumerator_type, "Reset", void_arg); void_dispose_void = GetMethod ( idisposable_type, "Dispose", void_arg); int_get_offset_to_string_data = GetMethod ( runtime_helpers_type, "get_OffsetToStringData", void_arg); int_array_get_length = GetMethod ( array_type, "get_Length", void_arg); int_array_get_rank = GetMethod ( array_type, "get_Rank", void_arg); ienumerable_getenumerator_void = GetMethod ( ienumerable_type, "GetEnumerator", void_arg); // // Int32 arguments // Type [] int_arg = { int32_type }; int_array_get_length_int = GetMethod ( array_type, "GetLength", int_arg); int_array_get_upper_bound_int = GetMethod ( array_type, "GetUpperBound", int_arg); int_array_get_lower_bound_int = GetMethod ( array_type, "GetLowerBound", int_arg); // // System.Array methods // object_array_clone = GetMethod ( array_type, "Clone", void_arg); Type [] array_int_arg = { array_type, int32_type }; void_array_copyto_array_int = GetMethod ( array_type, "CopyTo", array_int_arg); // // object arguments // Type [] object_arg = { object_type }; void_monitor_enter_object = GetMethod ( monitor_type, "Enter", object_arg); void_monitor_exit_object = GetMethod ( monitor_type, "Exit", object_arg); Type [] array_field_handle_arg = { array_type, runtime_field_handle_type }; void_initializearray_array_fieldhandle = GetMethod ( runtime_helpers_type, "InitializeArray", array_field_handle_arg); // // Array functions // int_getlength_int = GetMethod ( array_type, "GetLength", int_arg); // // Decimal constructors // Type [] dec_arg = { int32_type, int32_type, int32_type, bool_type, byte_type }; void_decimal_ctor_five_args = GetConstructor ( decimal_type, dec_arg); void_decimal_ctor_int_arg = GetConstructor (decimal_type, int_arg); // // Attributes // cons_param_array_attribute = GetConstructor (param_array_type, void_arg); unverifiable_code_ctor = GetConstructor (unverifiable_code_type, void_arg); default_member_ctor = GetConstructor (default_member_type, string_); Type[] short_arg = { short_type }; struct_layout_attribute_ctor = GetConstructor (struct_layout_attribute_type, short_arg); decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type [] { byte_type, byte_type, uint32_type, uint32_type, uint32_type } ); field_offset_attribute_ctor = GetConstructor (field_offset_attribute_type, new Type [] { int32_type }); // // .NET 2.0 types //#if NET_2_0 compiler_generated_attr = new CustomAttributeBuilder ( GetConstructor (compiler_generated_attr_type, void_arg), new object[0]); Type[] type_int_arg = { type_type, int32_type }; fixed_buffer_attr_ctor = GetConstructor (fixed_buffer_attr_type, type_int_arg);#endif // Object object_ctor = GetConstructor (object_type, void_arg); } const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance; /// <remarks> /// This is the "old", non-cache based FindMembers() function. We cannot use /// the cache here because there is no member name argument. /// </remarks> public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria) { DeclSpace decl = (DeclSpace) builder_to_declspace [t]; // // `builder_to_declspace' contains all dynamic types. // if (decl != null) { MemberList list; Timer.StartTimer (TimerType.FindMembers); list = decl.FindMembers (mt, bf, filter, criteria); Timer.StopTimer (TimerType.FindMembers); return list; } // // We have to take care of arrays specially, because GetType on // a TypeBuilder array will return a Type, not a TypeBuilder, // and we can not call FindMembers on this type. // if (TypeManager.IsSubclassOf (t, TypeManager.array_type)) return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria)); // // Since FindMembers will not lookup both static and instance // members, we emulate this behaviour here. // if ((bf & instance_and_static) == instance_and_static){ MemberInfo [] i_members = t.FindMembers ( mt, bf & ~BindingFlags.Static, filter, criteria); int i_len = i_members.Length; if (i_len == 1){ MemberInfo one = i_members [0]; // // If any of these are present, we are done! // if ((one is Type) || (one is EventInfo) || (one is FieldInfo)) return new MemberList (i_members); } MemberInfo [] s_members = t.FindMembers ( mt, bf & ~BindingFlags.Instance, filter, criteria); int s_len = s_members.Length; if (i_len > 0 || s_len > 0) return new MemberList (i_members, s_members); else { if (i_len > 0) return new MemberList (i_members); else return new MemberList (s_members); } } return new MemberList (t.FindMembers (mt, bf, filter, criteria)); } /// <summary> /// This method is only called from within MemberLookup. It tries to use the member /// cache if possible and falls back to the normal FindMembers if not. The `used_cache' /// flag tells the caller whether we used the cache or not. If we used the cache, then /// our return value will already contain all inherited members and the caller don't need /// to check base classes and interfaces anymore. /// </summary> private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf, string name, out bool used_cache) { MemberCache cache; // // We have to take care of arrays specially, because GetType on // a TypeBuilder array will return a Type, not a TypeBuilder, // and we can not call FindMembers on this type. // if (t == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) { used_cache = true; return TypeHandle.ArrayType.MemberCache.FindMembers ( mt, bf, name, FilterWithClosure_delegate, null); } // // If this is a dynamic type, it's always in the `builder_to_declspace' hash table // and we can ask the DeclSpace for the MemberCache. // if (t is TypeBuilder) { DeclSpace decl = (DeclSpace) builder_to_declspace [t]; cache = decl.MemberCache; // // If this DeclSpace has a MemberCache, use it. // if (cache != null) { used_cache = true; return cache.FindMembers ( mt, bf, name, FilterWithClosure_delegate, null); } // If there is no MemberCache, we need to use the "normal" FindMembers. // Note, this is a VERY uncommon route! MemberList list; Timer.StartTimer (TimerType.FindMembers); list = decl.FindMembers (mt, bf | BindingFlags.DeclaredOnly, FilterWithClosure_delegate, name); Timer.StopTimer (TimerType.FindMembers); used_cache = false; return (MemberInfo []) list; } // // This call will always succeed. There is exactly one TypeHandle instance per // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return // the corresponding MemberCache. // cache = TypeHandle.GetMemberCache (t); used_cache = true; return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null); } public static bool IsBuiltinType (Type t) { if (t == object_type || t == string_type || t == int32_type || t == uint32_type || t == int64_type || t == uint64_type || t == float_type || t == double_type || t == char_type || t == short_type || t == decimal_type || t == bool_type || t == sbyte_type || t == byte_type || t == ushort_type || t == void_type) return true; else return false; } public static bool IsBuiltinType (TypeContainer tc) { return IsBuiltinType (tc.TypeBuilder); } // // This is like IsBuiltinType, but lacks decimal_type, we should also clean up // the pieces in the code where we use IsBuiltinType and special case decimal_type. // public static bool IsPrimitiveType (Type t) { return (t == int32_type || t == uint32_type || t == int64_type || t == uint64_type || t == float_type || t == double_type || t == char_type || t == short_type || t == bool_type || t == sbyte_type || t == byte_type || t == ushort_type); } public static bool IsDelegateType (Type t) { if (t.IsSubclassOf (TypeManager.delegate_type)) return true; else return false; } public static bool IsEnumType (Type t) { if (builder_to_declspace [t] is Enum) return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -