2002-04-17 Patrik Torstensson <patrik.torstensson@labs2.com>
[mono.git] / mono / metadata / reflection.c
index d8c07f25b5ca29d02bd36100d6d8f504ca38b810..e1b347a72dc8c5d3efe08746c94da6ee523cc428 100644 (file)
@@ -213,7 +213,6 @@ encode_type (MonoDynamicAssembly *assembly, MonoType *type, char *p, char **endb
                mono_metadata_encode_value (type->type, p, &p);
                break;
        case MONO_TYPE_PTR:
-               g_print ("encode pointer\n");
        case MONO_TYPE_SZARRAY:
                mono_metadata_encode_value (type->type, p, &p);
                encode_type (assembly, type->data.type, p, &p);
@@ -490,7 +489,7 @@ fat_header:
                                        mono_image_add_stream_data (&assembly->code, (char*)&clause, sizeof (clause));
                                }
                        } else {
-                               g_error ("No clauses");
+                               g_error ("No clauses for ex info block %d", i);
                        }
                }
        }
@@ -826,6 +825,9 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicAssembly *
        guint32 *values;
        char *name;
 
+       /* maybe this fixup should be done in the C# code */
+       if (fb->attrs & FIELD_ATTRIBUTE_LITERAL)
+               fb->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
        table = &assembly->tables [MONO_TABLE_FIELD];
        fb->table_idx = table->next_idx ++;
        values = table->values + fb->table_idx * MONO_FIELD_SIZE;
@@ -1023,7 +1025,7 @@ resolution_scope_from_image (MonoDynamicAssembly *assembly, MonoImage *image)
        guint32 *values;
        guint32 cols [MONO_ASSEMBLY_SIZE];
 
-       if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, image))))
+       if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, image))))
                return token;
 
        mono_metadata_decode_row (&image->tables [MONO_TABLE_ASSEMBLY], 0, cols, MONO_ASSEMBLY_SIZE);
@@ -1048,10 +1050,51 @@ resolution_scope_from_image (MonoDynamicAssembly *assembly, MonoImage *image)
 
        token <<= RESOLTION_SCOPE_BITS;
        token |= RESOLTION_SCOPE_ASSEMBLYREF;
-       g_hash_table_insert (assembly->typeref, image, GUINT_TO_POINTER (token));
+       g_hash_table_insert (assembly->handleref, image, GUINT_TO_POINTER (token));
        return token;
 }
 
+static guint32
+create_typespec (MonoDynamicAssembly *assembly, MonoType *type)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       guint32 token;
+       char sig [128];
+       char *p = sig;
+       char blob_size [6];
+       char *b = blob_size;
+
+       switch (type->type) {
+       case MONO_TYPE_FNPTR:
+       case MONO_TYPE_PTR:
+       case MONO_TYPE_SZARRAY:
+       case MONO_TYPE_ARRAY:
+               encode_type (assembly, type, p, &p);
+               break;
+       default:
+               return 0;
+       }
+       
+       g_assert (p-sig < 128);
+       mono_metadata_encode_value (p-sig, b, &b);
+       token = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+       mono_image_add_stream_data (&assembly->blob, sig, p-sig);
+
+       table = &assembly->tables [MONO_TABLE_TYPESPEC];
+       alloc_table (table, table->rows + 1);
+       values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
+       values [MONO_TYPESPEC_SIGNATURE] = token;
+
+       token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
+       g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
+       table->next_idx ++;
+       return token;
+}
+
+/*
+ * Despite the name, we handle also TypeSpec (with the above helper).
+ */
 static guint32
 mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type)
 {
@@ -1061,6 +1104,9 @@ mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type)
        MonoClass *klass;
 
        token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
+       if (token)
+               return token;
+       token = create_typespec (assembly, type);
        if (token)
                return token;
        klass = mono_class_from_mono_type (type);
@@ -1131,12 +1177,12 @@ mono_image_get_methodref_token (MonoDynamicAssembly *assembly, MonoMethod *metho
 {
        guint32 token;
        
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, method));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
        if (token)
                return token;
        token = mono_image_get_memberref_token (assembly, method->klass, 
                method->name,  method_encode_signature (assembly, method->signature));
-       g_hash_table_insert (assembly->typeref, method, GUINT_TO_POINTER(token));
+       g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -1145,12 +1191,12 @@ mono_image_get_fieldref_token (MonoDynamicAssembly *assembly, MonoClassField *fi
 {
        guint32 token;
        
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, field));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
        if (token)
                return token;
        token = mono_image_get_memberref_token (assembly, klass, 
                field->name,  fieldref_encode_signature (assembly, field));
-       g_hash_table_insert (assembly->typeref, field, GUINT_TO_POINTER(token));
+       g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -1315,7 +1361,12 @@ mono_image_fill_module_table (MonoDomain *domain, MonoReflectionModuleBuilder *m
        name = mono_string_to_utf8 (mb->module.name);
        table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, name);
        g_free (name);
-       /* need to set mvid? */
+       i = mono_image_add_stream_data (&assembly->guid, mono_array_addr (mb->guid, char, 0), 16);
+       i /= 16;
+       ++i;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_MVID] = i;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENC] = 0;
+       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENCBASE] = 0;
 
        mono_image_add_cattrs (assembly, mb->table_idx, CUSTOM_ATTR_MODULE, mb->cattrs);
        /*
@@ -1615,6 +1666,7 @@ mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb)
        values [MONO_ASSEMBLY_MINOR_VERSION] = 0;
        values [MONO_ASSEMBLY_REV_NUMBER] = 0;
        values [MONO_ASSEMBLY_BUILD_NUMBER] = 0;
+       values [MONO_ASSEMBLY_FLAGS] = 0;
 
        mono_image_add_cattrs (assembly, 1, CUSTOM_ATTR_ASSEMBLY, assemblyb->cattrs);
 
@@ -1657,6 +1709,13 @@ mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb)
        build_compressed_metadata (assembly);
 }
 
+/*
+ * mono_image_insert_string:
+ * @assembly: assembly builder object
+ * @str: a string
+ *
+ * Insert @str into the user string stream of @assembly.
+ */
 guint32
 mono_image_insert_string (MonoReflectionAssemblyBuilder *assembly, MonoString *str)
 {
@@ -1675,8 +1734,12 @@ mono_image_insert_string (MonoReflectionAssemblyBuilder *assembly, MonoString *s
 }
 
 /*
+ * mono_image_create_token:
+ * @assembly: a dynamic assembly
+ * @obj:
+ *
  * Get a token to insert in the IL code stream for the given MemberInfo.
- * obj can be:
+ * @obj can be one of:
  *     ConstructorBuilder
  *     MethodBuilder
  *     FieldBuilder
@@ -1739,6 +1802,9 @@ mono_image_create_token (MonoDynamicAssembly *assembly, MonoObject *obj)
 }
 
 /*
+ * mono_image_basic_ini:
+ * @assembly: an assembly builder object
+ *
  * Create the MonoImage that represents the assembly builder and setup some
  * of the helper hash table and the basic metadata streams.
  */
@@ -1759,7 +1825,8 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
 #endif
 
        assembly->token_fixups = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
-       assembly->typeref = g_hash_table_new (g_direct_hash, g_direct_equal);
+       assembly->handleref = g_hash_table_new (g_direct_hash, g_direct_equal);
+       assembly->typeref = g_hash_table_new (mono_metadata_type_hash, mono_metadata_type_equal);
 
        string_heap_init (&assembly->sheap);
        mono_image_add_stream_data (&assembly->us, "", 1);
@@ -1786,10 +1853,16 @@ mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
 }
 
 /*
+ * mono_image_get_heade:
+ * @assemblyb: an assembly builder object
+ * @buffer:
+ * @maxsize
+ * 
  * When we need to save an assembly, we first call this function that ensures the metadata 
  * tables are built for all the modules in the assembly. This function creates the PE-COFF
  * header, the image sections, the CLI header etc. The header is written in @buffer
  * and the length of the data written is returned.
+ * If @buffer is not big enough (@maxsize), -1 is returned.
  */
 int
 mono_image_get_header (MonoReflectionAssemblyBuilder *assemblyb, char *buffer, int maxsize)
@@ -1928,7 +2001,14 @@ static MonoGHashTable *type_cache = NULL;
        do {    \
                mono_g_hash_table_insert (object_cache, p,o);   \
        } while (0)
-       
+
+/*
+ * mono_assembly_get_object:
+ * @domain: an app domain
+ * @assembly: an assembly
+ *
+ * Return an System.Reflection.Assembly object representing the MonoAssembly @assembly.
+ */
 MonoReflectionAssembly*
 mono_assembly_get_object (MonoDomain *domain, MonoAssembly *assembly)
 {
@@ -2009,6 +2089,13 @@ mymono_metadata_type_hash (MonoType *t1)
        return hash;
 }
 
+/*
+ * mono_type_get_object:
+ * @domain: an app domain
+ * @type: a type
+ *
+ * Return an System.MonoType object representing the type @type.
+ */
 MonoReflectionType*
 mono_type_get_object (MonoDomain *domain, MonoType *type)
 {
@@ -2032,6 +2119,13 @@ mono_type_get_object (MonoDomain *domain, MonoType *type)
        return res;
 }
 
+/*
+ * mono_method_get_object:
+ * @domain: an app domain
+ * @method: a method
+ *
+ * Return an System.Reflection.MonoMethod object representing the method @method.
+ */
 MonoReflectionMethod*
 mono_method_get_object (MonoDomain *domain, MonoMethod *method)
 {
@@ -2052,10 +2146,20 @@ mono_method_get_object (MonoDomain *domain, MonoMethod *method)
 
        ret = (MonoReflectionMethod*)mono_object_new (domain, klass);
        ret->method = method;
+       ret->name = mono_string_new (domain, method->name);
        CACHE_OBJECT (method, ret);
        return ret;
 }
 
+/*
+ * mono_field_get_object:
+ * @domain: an app domain
+ * @klass: a type
+ * @field: a field
+ *
+ * Return an System.Reflection.MonoField object representing the field @field
+ * in class @klass.
+ */
 MonoReflectionField*
 mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *field)
 {
@@ -2071,6 +2175,15 @@ mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *fie
        return res;
 }
 
+/*
+ * mono_property_get_object:
+ * @domain: an app domain
+ * @klass: a type
+ * @property: a property
+ *
+ * Return an System.Reflection.MonoProperty object representing the property @property
+ * in class @klass.
+ */
 MonoReflectionProperty*
 mono_property_get_object (MonoDomain *domain, MonoClass *klass, MonoProperty *property)
 {
@@ -2086,6 +2199,15 @@ mono_property_get_object (MonoDomain *domain, MonoClass *klass, MonoProperty *pr
        return res;
 }
 
+/*
+ * mono_event_get_object:
+ * @domain: an app domain
+ * @klass: a type
+ * @event: a event
+ *
+ * Return an System.Reflection.MonoEvent object representing the event @event
+ * in class @klass.
+ */
 MonoReflectionEvent*
 mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
 {
@@ -2101,6 +2223,14 @@ mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
        return res;
 }
 
+/*
+ * mono_param_get_objects:
+ * @domain: an app domain
+ * @method: a method
+ *
+ * Return an System.Reflection.ParameterInfo array object representing the parameters
+ * in the method @method.
+ */
 MonoReflectionParameter**
 mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
 {
@@ -2142,6 +2272,9 @@ mono_param_get_objects (MonoDomain *domain, MonoMethod *method)
 }
 
 /*
+ * mono_reflection_parse_type:
+ * @name: type name
+ *
  * Parse a type name as accepted by the GetType () method and output the info
  * extracted in the info structure.
  * the name param will be mangled, so, make a copy before passing it to this function.
@@ -2303,6 +2436,10 @@ mono_type_get_name_recurse (MonoType *type, GString *str)
 }
 
 /*
+ * mono_type_get_name:
+ * @type: a type
+ *
+ * Returns the string representation for type as required by System.Reflection.
  * The inverse of mono_reflection_parse_type ().
  */
 char*
@@ -2317,6 +2454,15 @@ mono_type_get_name (MonoType *type)
        return g_string_free (result, FALSE);
 }
 
+/*
+ * mono_reflection_get_type:
+ * @image: a metadata context
+ * @info: type description structure
+ * @ignorecase: flag for case-insensitive string compares
+ *
+ * Build a MonoType from the type description in @info.
+ * 
+ */
 MonoType*
 mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase)
 {
@@ -2368,29 +2514,6 @@ mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ig
        return &klass->byval_arg;
 }
 
-static MonoObject*
-dummy_runtime_invoke (MonoMethod *method, void *obj, void **params)
-{
-       g_error ("runtime invoke called on uninitialized runtime");
-       return NULL;
-}
-
-MonoInvokeFunc mono_default_runtime_invoke = dummy_runtime_invoke;
-
-void
-mono_install_runtime_invoke (MonoInvokeFunc func) {
-       if (func)
-               mono_default_runtime_invoke = func;
-       else
-               mono_default_runtime_invoke = dummy_runtime_invoke;
-}
-
-MonoObject*
-mono_runtime_invoke (MonoMethod *method, void *obj, void **params)
-{
-       return mono_default_runtime_invoke (method, obj, params);;
-}
-
 /*
  * Optimization we could avoid mallocing() an little-endian archs that
  * don't crash with unaligned accesses.
@@ -2557,6 +2680,13 @@ find_event_index (MonoClass *klass, MonoEvent *event) {
        return 0;
 }
 
+/*
+ * mono_reflection_get_custom_attrs:
+ * @obj: a reflection object handle
+ *
+ * Return an array with all the custom attributes defined of the
+ * reflection handle @obj. The objects are fully build.
+ */
 MonoArray*
 mono_reflection_get_custom_attrs (MonoObject *obj)
 {
@@ -2694,8 +2824,21 @@ mono_reflection_get_custom_attrs (MonoObject *obj)
        return result;
 }
 
+/*
+ * mono_reflection_get_custom_attrs_blob:
+ * @ctor: custom attribute constructor
+ * @ctorArgs: arguments o the constructor
+ * @properties:
+ * @propValues:
+ * @fields:
+ * @fieldValues:
+ * 
+ * Creates the blob of data that needs to be saved in the metadata and that represents
+ * the custom attributed described by @ctor, @ctorArgs etc.
+ * Returns: a Byte array representing the blob of data.
+ */
 MonoArray*
-mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *porpValues, MonoArray *fields, MonoArray* fieldValues) {
+mono_reflection_get_custom_attrs_blob (MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) {
        MonoArray *result;
        MonoMethodSignature *sig;
        MonoObject *arg;
@@ -2803,6 +2946,14 @@ handle_enum:
        return result;
 }
 
+/*
+ * mono_reflection_setup_internal_class:
+ * @tb: a TypeBuilder object
+ *
+ * Creates a MonoClass that represents the TypeBuilder.
+ * This is a trick that lets us simplify a lot of reflection code
+ * (and will allow us to support Build and Run assemblies easier).
+ */
 void
 mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 {
@@ -2888,3 +3039,4 @@ mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig)
 
        return result;
 }
+