static public Type float_type;
static public Type double_type;
static public Type char_type;
+ static public Type char_ptr_type;
static public Type short_type;
static public Type decimal_type;
static public Type bool_type;
static public Type runtime_field_handle_type;
static public Type attribute_usage_type;
static public Type dllimport_type;
+ static public Type unverifiable_code_type;
+ static public Type methodimpl_attr_type;
static public Type param_array_type;
+ static public Type void_ptr_type;
+
+ static public Type [] NoTypes;
//
// Internal, not really used outside
static public MethodInfo int_getlength_int;
static public MethodInfo delegate_combine_delegate_delegate;
static public MethodInfo delegate_remove_delegate_delegate;
+ static public MethodInfo int_get_offset_to_string_data;
//
// The attribute constructors.
// (either because it is the default or the user used the
// -r command line option)
// </remarks>
- ArrayList assemblies;
+ Assembly [] assemblies;
// <remarks>
// Keeps a list of module builders. We used this to do lookups
// on the modulebuilder using GetType -- needed for arrays
// </remarks>
- ArrayList modules;
+ ModuleBuilder [] modules;
// <remarks>
// This is the type_cache from the assemblies to avoid
public TypeManager ()
{
- assemblies = new ArrayList ();
- modules = new ArrayList ();
+ assemblies = null;
+ modules = null;
user_types = new ArrayList ();
types = new Hashtable ();
typecontainers = new Hashtable ();
method_internal_params = new PtrHashtable ();
builder_to_container = new PtrHashtable ();
type_interface_cache = new PtrHashtable ();
+ NoTypes = new Type [0];
}
public void AddUserType (string name, TypeBuilder t)
/// </summary>
public void AddAssembly (Assembly a)
{
- assemblies.Add (a);
+ int top = assemblies != null ? assemblies.Length : 0;
+ Assembly [] n = new Assembly [top + 1];
+
+ if (assemblies != null)
+ assemblies.CopyTo (n, 0);
+ n [top] = a;
+ assemblies = n;
}
/// <summary>
/// </summary>
public void AddModule (ModuleBuilder mb)
{
- modules.Add (mb);
+ int top = modules != null ? modules.Length : 0;
+ ModuleBuilder [] n = new ModuleBuilder [top + 1];
+
+ if (modules != null)
+ modules.CopyTo (n, 0);
+ n [top] = mb;
+ modules = n;
}
/// <summary>
return "string";
else if (t == object_type)
return "object";
+ else if (t == void_type)
+ return "void";
else
return t.FullName;
}
byte_type = CoreLookupType ("System.Byte");
sbyte_type = CoreLookupType ("System.SByte");
char_type = CoreLookupType ("System.Char");
+ char_ptr_type = CoreLookupType ("System.Char*");
short_type = CoreLookupType ("System.Int16");
ushort_type = CoreLookupType ("System.UInt16");
decimal_type = CoreLookupType ("System.Decimal");
attribute_usage_type = CoreLookupType ("System.AttributeUsageAttribute");
dllimport_type = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute");
+ methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute");
param_array_type = CoreLookupType ("System.ParamArrayAttribute");
+
+ unverifiable_code_type = CoreLookupType ("System.Security.UnverifiableCodeAttribute");
+
+ void_ptr_type = CoreLookupType ("System.Void*");
//
// Now load the default methods that we use.
ienumerator_type, "MoveNext", 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);
//
// object arguments
param_array_type, void_arg);
}
+
+ const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
public MemberInfo [] FindMembers (Type t, MemberTypes mt, BindingFlags bf,
MemberFilter filter, object criteria)
if (t.IsSubclassOf (TypeManager.array_type))
return TypeManager.array_type.FindMembers (mt, bf, filter, criteria);
- if (!(t is TypeBuilder))
+ if (!(t is TypeBuilder)){
+ //
+ // 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);
+ MemberInfo [] s_members = t.FindMembers (
+ mt, bf & ~BindingFlags.Instance, filter, criteria);
+
+ int i_len = i_members.Length;
+ int s_len = s_members.Length;
+ if (i_len > 0 || s_len > 0){
+ MemberInfo [] both = new MemberInfo [i_len + s_len];
+
+ i_members.CopyTo (both, 0);
+ s_members.CopyTo (both, i_len);
+
+ return both;
+ } else
+ return i_members;
+ }
return t.FindMembers (mt, bf, filter, criteria);
+ }
+ //
+ // FIXME: We should not have builder_to_blah everywhere,
+ // we should just have a builder_to_findmemberizable
+ // and have them implement a new ICanFindMembers interface
+ //
Enum e = (Enum) builder_to_enum [t];
if (e != null)
return (Const) builder_to_constant [fb];
}
- //
- // Gigantic work around for stupidity in System.Reflection.Emit follows
- //
- // Since System.Reflection.Emit can not return MethodBase.GetParameters
- // for anything which is dynamic, and we need this in a number of places,
- // we register this information here, and use it afterwards.
- //
+ /// <summary>
+ /// Gigantic work around for missing features in System.Reflection.Emit follows.
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Since System.Reflection.Emit can not return MethodBase.GetParameters
+ /// for anything which is dynamic, and we need this in a number of places,
+ /// we register this information here, and use it afterwards.
+ /// </remarks>
static public bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
{
- if (method_arguments.Contains (mb))
- return false;
-
+ if (args == null)
+ args = NoTypes;
+
method_arguments.Add (mb, args);
method_internal_params.Add (mb, ip);
static public InternalParameters LookupParametersByBuilder (MethodBase mb)
{
- object o = method_arguments [mb];
-
if (! (mb is ConstructorBuilder || mb is MethodBuilder))
return null;
// This is a workaround the fact that GetValue is not
// supported for dynamic types
// </remarks>
- static Hashtable fields;
-
- static public bool RegisterField (FieldBuilder fb, object value)
+ static Hashtable fields = new Hashtable ();
+ static public bool RegisterFieldValue (FieldBuilder fb, object value)
{
- if (fields == null)
- fields = new Hashtable ();
-
if (fields.Contains (fb))
return false;
return fields [fb];
}
+ static Hashtable fieldbuilders_to_fields = new Hashtable ();
+ static public bool RegisterField (FieldBuilder fb, Field f)
+ {
+ if (fieldbuilders_to_fields.Contains (fb))
+ return false;
+
+ fieldbuilders_to_fields.Add (fb, f);
+ return true;
+ }
+
+ static public Field GetField (FieldInfo fb)
+ {
+ return (Field) fieldbuilders_to_fields [fb];
+ }
+
static Hashtable events;
static public bool RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
return false;
}
-
+
+ //
+ // This is needed, because enumerations from assemblies
+ // do not report their underlyingtype, but they report
+ // themselves
+ //
+ public static Type EnumToUnderlying (Type t)
+ {
+ t = t.UnderlyingSystemType;
+ if (!TypeManager.IsEnumType (t))
+ return t;
+
+ TypeCode tc = Type.GetTypeCode (t);
+
+ switch (tc){
+ case TypeCode.Boolean:
+ return TypeManager.bool_type;
+ case TypeCode.Byte:
+ return TypeManager.byte_type;
+ case TypeCode.SByte:
+ return TypeManager.sbyte_type;
+ case TypeCode.Char:
+ return TypeManager.char_type;
+ case TypeCode.Int16:
+ return TypeManager.short_type;
+ case TypeCode.UInt16:
+ return TypeManager.ushort_type;
+ case TypeCode.Int32:
+ return TypeManager.int32_type;
+ case TypeCode.UInt32:
+ return TypeManager.uint32_type;
+ case TypeCode.Int64:
+ return TypeManager.int64_type;
+ case TypeCode.UInt64:
+ return TypeManager.uint64_type;
+ }
+ throw new Exception ("Unhandled typecode in enum" + tc);
+ }
+ /// <summary>
+ /// Utility function that can be used to probe whether a type
+ /// is managed or not.
+ /// </summary>
+ public static bool VerifyUnManaged (Type t, Location loc)
+ {
+ if (t.IsValueType){
+ //
+ // FIXME: this is more complex, we actually need to
+ // make sure that the type does not contain any
+ // classes itself
+ //
+ return true;
+ }
+
+ Report.Error (
+ 208, loc,
+ "Cannot take the address or size of a variable of a managed type ('" +
+ CSharpName (t) + "')");
+ return false;
+ }
+
/// <summary>
/// Returns the name of the indexer in a given type.
/// </summary>
public static string IndexerPropertyName (Type t)
{
- //
- // FIXME: Replace with something that works around S.R.E failure
- //
-//#if FIXME
-// System.Attribute attr;
-//
-// attr = System.Attribute.GetCustomAttribute (t, TypeManager.default_member_type);
-//
-// if (attr != null)
-// {
-// DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
-//
-// return dma.MemberName;
-// }
-//#endif
+ if (t is TypeBuilder) {
+ TypeContainer tc = (TypeContainer) builder_to_container [t];
+
+ Attributes attrs = tc.OptAttributes;
+
+ if (attrs == null || attrs.AttributeSections == null)
+ return "Item";
+
+ foreach (AttributeSection asec in attrs.AttributeSections) {
+
+ if (asec.Attributes == null)
+ continue;
+
+ foreach (Attribute a in asec.Attributes) {
+ if (a.Name.IndexOf ("DefaultMember") != -1) {
+ ArrayList pos_args = (ArrayList) a.Arguments [0];
+ Expression e = ((Argument) pos_args [0]).expr;
+
+ if (e is StringConstant)
+ return ((StringConstant) e).Value;
+ }
+ }
+ }
+
+ return "Item";
+ }
+
+ System.Attribute attr = System.Attribute.GetCustomAttribute (t, TypeManager.default_member_type);
+
+ if (attr != null)
+ {
+ DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
+
+ return dma.MemberName;
+ }
+
return "Item";
}
+ public static void MakePinned (LocalBuilder builder)
+ {
+ //
+ // FIXME: Flag the "LocalBuilder" type as being
+ // pinned. Figure out API.
+ //
+ }
}
}