Fri Nov 2 19:06:54 CET 2001 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Mon, 5 Nov 2001 06:22:05 +0000 (06:22 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Mon, 5 Nov 2001 06:22:05 +0000 (06:22 -0000)
* interp.c: hanlde field refs. Throw an exception on NULL references.
Check consistency of corlib types with the C struct representation.

Fri Nov 2 19:37:51 CET 2001 Paolo Molaro <lupus@ximian.com>

* class.h, class.c: include name in MonoClassField.
* class.c: fix fundamental type of System.Object and System.String.
Set the right fundamental type for SZARRAY, too. Handle TypeSpec
tokens in ldtoken.
* icall.c: remove internalcalls for the Reflection stuff that is now
done in C# code.
* loader.c: mono_field_from_memberref () implementation.
* mono-endian.c: thinko (s/struct/union/g).
* object.c, object.h: make the mono_string_* prototypes actually use
MonoString instead of MonoObject.
* reflection.c, reflection.h: updates for changes in the reflection
code in corlib: we use C structures that map to the actual C# classes.
Handle SZARRAYs when encoding types. Handle locals in methods. Use a
fat method header if needed and use the info from the ILGenerator for
methods. Handle fields in types. Misc fixes.

svn path=/trunk/mono/; revision=1262

15 files changed:
mono/interpreter/ChangeLog
mono/interpreter/interp.c
mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/class.h
mono/metadata/icall.c
mono/metadata/loader.c
mono/metadata/mono-endian.c
mono/metadata/object.c
mono/metadata/object.h
mono/metadata/reflection.c
mono/metadata/reflection.h
mono/tests/codegen.cs
mono/tests/codegen2.cs [new file with mode: 0644]
mono/tests/thread.cs

index 9e63dd928f4fa2127d8b558c1ff606e35f6e96ce..699c0544ec82bcc1a32bf5e7cd0840e7debadf4c 100644 (file)
@@ -1,3 +1,9 @@
+
+Fri Nov 2 19:06:54 CET 2001 Paolo Molaro <lupus@ximian.com>
+
+       * interp.c: hanlde field refs. Throw an exception on NULL references.
+       Check consistency of corlib types with the C struct representation.
+
 2001-10-25  Dietmar Maurer  <dietmar@ximian.com>
 
        * interp.c (ves_exec_method): use relative numbering for runtime
index 1d671840ecfc6d2d68e7b322e8fe5e79ee0ff442..c5b985da73cbab9863f4075b45f0a3d0728feb42 100644 (file)
@@ -34,6 +34,7 @@
 #include <mono/metadata/tokentype.h>
 #include <mono/metadata/loader.h>
 #include <mono/metadata/threads.h>
+#include <mono/metadata/reflection.h>
 #include <mono/arch/x86/x86-codegen.h>
 /*#include <mono/cli/types.h>*/
 #include "interp.h"
@@ -613,6 +614,17 @@ dump_stack (stackval *stack, stackval *sp)
                case VAL_I64: printf ("[%lld] ", s->data.l); break;
                case VAL_DOUBLE: printf ("[%0.5f] ", s->data.f); break;
                case VAL_VALUET: printf ("[vt: %p] ", s->data.vt.vt); break;
+#if 0
+               case VAL_OBJ: {
+                       MonoObject *obj =  s->data.p;
+                       if (obj && obj->klass == mono_defaults.string_class) {
+                               char *str = mono_string_to_utf8 ((MonoString*)obj);
+                               printf ("\"%s\" ", str);
+                               g_free (str);
+                               break;
+                       }
+               }
+#endif
                default: printf ("[%p] ", s->data.p); break;
                }
                ++s;
@@ -1122,7 +1134,10 @@ ves_exec_method (MonoInvocation *frame)
                        if (csignature->hasthis) {
                                g_assert (sp >= frame->stack);
                                --sp;
-                               g_assert (sp->type == VAL_OBJ || sp->type == VAL_VALUETA);
+                               /*
+                                * It may also be a TP from LD(S)FLDA
+                                * g_assert (sp->type == VAL_OBJ || sp->type == VAL_VALUETA);
+                                */
                                if (sp->type == VAL_OBJ && child_frame.method->klass->valuetype) /* unbox it */
                                        child_frame.obj = (char*)sp->data.p + sizeof (MonoObject);
                                else
@@ -1981,7 +1996,7 @@ ves_exec_method (MonoInvocation *frame)
                        index = mono_metadata_token_index (read32 (ip));
                        ip += 4;
 
-                       o = mono_ldstr (image, index);
+                       o = (MonoObject*)mono_ldstr (image, index);
                        sp->type = VAL_OBJ;
                        sp->data.p = o;
                        sp->data.vt.klass = NULL;
@@ -2207,11 +2222,17 @@ ves_exec_method (MonoInvocation *frame)
                        ip += 4;
                        
                        /* need to handle fieldrefs */
-                       klass = mono_class_get (image, 
-                               MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
-                       if (!klass->inited)
-                               init_class (klass);
-                       field = mono_class_get_field (klass, token);
+                       if (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF) {
+                               field = mono_field_from_memberref (image, token, &klass);
+                               if (!klass->inited)
+                                       init_class (klass);
+                       } else {
+                               klass = mono_class_get (image, 
+                                       MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
+                               if (!klass->inited)
+                                       init_class (klass);
+                               field = mono_class_get_field (klass, token);
+                       }
                        g_assert (field);
                        if (load_addr) {
                                sp->type = VAL_TP;
@@ -2430,7 +2451,8 @@ ves_exec_method (MonoInvocation *frame)
                        g_assert (sp [-1].type == VAL_OBJ);
 
                        o = sp [-1].data.p;
-                       g_assert (o != NULL);
+                       if (!o)
+                               THROW_EX (get_exception_null_reference (), ip - 1);
                        
                        g_assert (MONO_CLASS_IS_ARRAY (o->obj.klass));
 
@@ -3270,6 +3292,113 @@ test_load_class (MonoImage* image)
 }
 #endif
 
+typedef struct {
+       char *name;
+       gulong offset;
+} FieldDesc;
+
+typedef struct {
+       char *name;
+       FieldDesc *fields;
+} ClassDesc;
+
+static FieldDesc 
+typebuilder_fields[] = {
+       {"name", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, name)},
+       {"nspace", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, nspace)},
+       {"parent", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, parent)},
+       {"interfaces", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, interfaces)},
+       {"methods", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, methods)},
+       {"properties", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, properties)},
+       {"fields", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, fields)},
+       {"attrs", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, attrs)},
+       {"table_idx", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, table_idx)},
+       {NULL, 0}
+};
+
+static FieldDesc 
+modulebuilder_fields[] = {
+       {"types", G_STRUCT_OFFSET (MonoReflectionModuleBuilder, types)},
+       {"table_idx", G_STRUCT_OFFSET (MonoReflectionModuleBuilder, table_idx)},
+       {NULL, 0}
+};
+
+static FieldDesc 
+assemblybuilder_fields[] = {
+       {"entry_point", G_STRUCT_OFFSET (MonoReflectionAssemblyBuilder, entry_point)},
+       {"modules", G_STRUCT_OFFSET (MonoReflectionAssemblyBuilder, modules)},
+       {"name", G_STRUCT_OFFSET (MonoReflectionAssemblyBuilder, name)},
+       {NULL, 0}
+};
+
+static FieldDesc 
+methodbuilder_fields[] = {
+       {"rtype", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, rtype)},
+       {"parameters", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, parameters)},
+       {"attrs", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, attrs)},
+       {"name", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, name)},
+       {"table_idx", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, table_idx)},
+       {"code", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, code)},
+       {NULL, 0}
+};
+
+static FieldDesc 
+fieldbuilder_fields[] = {
+       {"attrs", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, attrs)},
+       {"type", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, type)},
+       {"name", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, name)},
+       {"def_value", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, def_value)},
+       {"offset", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, offset)},
+       {"table_idx", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, table_idx)},
+       {NULL, 0}
+};
+
+static FieldDesc 
+propertybuilder_fields[] = {
+       {"attrs", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, attrs)},
+       {"name", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, name)},
+       {"type", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, type)},
+       {"parameters", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, parameters)},
+       {"def_value", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, def_value)},
+       {"set_method", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, set_method)},
+       {"get_method", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, get_method)},
+       {"table_idx", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, table_idx)},
+       {NULL, 0}
+};
+
+static ClassDesc
+classes_to_check [] = {
+       {"TypeBuilder", typebuilder_fields},
+       {"ModuleBuilder", modulebuilder_fields},
+       {"AssemblyBuilder", assemblybuilder_fields},
+       {"MethodBuilder", methodbuilder_fields},
+       {"FieldBuilder", fieldbuilder_fields},
+       {"PropertyBuilder", propertybuilder_fields},
+       {NULL, NULL}
+};
+
+static void
+check_corlib (MonoImage *corlib)
+{
+       MonoClass *klass;
+       MonoClassField *field;
+       FieldDesc *fdesc;
+       ClassDesc *cdesc;
+       const char *refl = "System.Reflection.Emit";
+
+       for (cdesc = classes_to_check; cdesc->name; ++cdesc) {
+               klass = mono_class_from_name (corlib, refl, cdesc->name);
+               if (!klass)
+                       g_error ("Cannot find class %s", cdesc->name);
+               mono_class_metadata_init (klass);
+               for (fdesc = cdesc->fields; fdesc->name; ++fdesc) {
+                       field = mono_class_get_field_from_name (klass, fdesc->name);
+                       if (!field || (field->offset != fdesc->offset))
+                               g_error ("filed %s mismatch in class %s (%d != %d)", fdesc->name, cdesc->name, fdesc->offset, field?field->offset:-1);
+               }
+       }
+}
+
 int 
 main (int argc, char *argv [])
 {
@@ -3315,6 +3444,7 @@ main (int argc, char *argv [])
 #ifdef RUN_TEST
        test_load_class (assembly->image);
 #else
+       check_corlib (mono_defaults.corlib);
        /*
         * skip the program name from the args.
         */
index 9940f63b1c6bbccdaac9fefda5ce00d586102334..eb07e5ec3b0c7fd3dc1aa2757bb9892f8d7c3c38 100644 (file)
@@ -1,3 +1,22 @@
+
+Fri Nov 2 19:37:51 CET 2001 Paolo Molaro <lupus@ximian.com>
+
+       * class.h, class.c: include name in MonoClassField.
+       * class.c: fix fundamental type of System.Object and System.String.
+       Set the right fundamental type for SZARRAY, too. Handle TypeSpec
+       tokens in ldtoken.
+       * icall.c: remove internalcalls for the Reflection stuff that is now
+       done in C# code.
+       * loader.c: mono_field_from_memberref () implementation.
+       * mono-endian.c: thinko (s/struct/union/g).
+       * object.c, object.h: make the mono_string_* prototypes actually use
+       MonoString instead of MonoObject.
+       * reflection.c, reflection.h: updates for changes in the reflection
+       code in corlib: we use C structures that map to the actual C# classes.
+       Handle SZARRAYs when encoding types. Handle locals in methods. Use a
+       fat method header if needed and use the info from the ILGenerator for
+       methods. Handle fields in types. Misc fixes.
+
 2001-10-17  Dietmar Maurer  <dietmar@ximian.com>
 
        * class.c (mono_class_metadata_init): bug fix: always allocate
index 67eb7e27ef8442b97b9769ed76168d233e79888e..13d3c45d301a2d82299b9d8770f9c4a392609827 100644 (file)
@@ -88,11 +88,13 @@ class_compute_field_layout (MonoClass *class)
         */
        for (i = 0; i < top; i++){
                const char *sig;
-               guint32 cols [3];
+               guint32 cols [MONO_FIELD_SIZE];
                int idx = class->field.first + i;
                
                mono_metadata_decode_row (t, idx, cols, CSIZE (cols));
-               sig = mono_metadata_blob_heap (m, cols [2]);
+               /* The name is needed for fieldrefs */
+               class->fields [i].name = mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]);
+               sig = mono_metadata_blob_heap (m, cols [MONO_FIELD_SIGNATURE]);
                mono_metadata_decode_value (sig, &sig);
                /* FIELD signature == 0x06 */
                g_assert (*sig == 0x06);
@@ -502,6 +504,10 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
                } else if (!strcmp (name, "Enum")) {
                        class->valuetype = 1;
                        class->enumtype = 1;
+               } else if (!strcmp (name, "Object")) {
+                       class->this_arg.type = class->byval_arg.type = MONO_TYPE_OBJECT;
+               } else if (!strcmp (name, "String")) {
+                       class->this_arg.type = class->byval_arg.type = MONO_TYPE_STRING;
                }
        }
        
@@ -537,16 +543,9 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
                                        t = MONO_TYPE_I;
                                }
                                break;
-                       case 'O':
-                               if (!strcmp (name, "Object")) {
-                                       t = MONO_TYPE_OBJECT;
-                               }
-                               break;
                        case 'S':
                                if (!strcmp (name, "Single")) {
                                        t = MONO_TYPE_R4;
-                               } else if (!strcmp(name, "String")) {
-                                       t = MONO_TYPE_STRING;
                                } else if (!strcmp(name, "SByte")) {
                                        t = MONO_TYPE_I1;
                                }
@@ -761,6 +760,15 @@ mono_array_class_get (MonoClass *eclass, guint32 rank)
 
        class->rank = rank;
        class->element_class = eclass;
+       if (rank > 1) {
+               class->byval_arg.type = MONO_TYPE_ARRAY;
+               /* FIXME: complete.... */
+       } else {
+               class->byval_arg.type = MONO_TYPE_SZARRAY;
+               class->byval_arg.data.type = &eclass->byval_arg;
+       }
+       class->this_arg = class->byval_arg;
+       class->this_arg.byref = 1;
        
        g_hash_table_insert (image->array_cache, GUINT_TO_POINTER (key), class);
        return class;
@@ -977,10 +985,22 @@ mono_ldtoken (MonoImage *image, guint32 token, MonoClass **handle_class)
                /* We return a MonoType* as handle */
                return &class->byval_arg;
        }
+       case MONO_TOKEN_TYPE_SPEC: {
+               MonoClass *class;
+               if (handle_class)
+                       *handle_class = mono_defaults.typehandle_class;
+               if ((class = g_hash_table_lookup (image->class_cache, 
+                                                 GUINT_TO_POINTER (token))))
+                       return &class->byval_arg;
+               class = mono_class_create_from_typespec (image, token);
+               return &class->byval_arg;
+               break;
+       }
        case MONO_TOKEN_METHOD_DEF:
        case MONO_TOKEN_FIELD_DEF:
        case MONO_TOKEN_MEMBER_REF:
        default:
+               g_warning ("Unknown token 0x%08x in ldtoken", token);
                break;
        }
        return NULL;
index 84ff7fbb95e8e3af7b1aa4a4a3bbfe942c39fe1c..c1649c0c1011d419cf172d1379ef6aebc5581516 100644 (file)
@@ -12,6 +12,7 @@
 typedef struct {
        MonoType *type;
        int       offset;
+       char     *name;
 } MonoClassField;
 
 struct _MonoClass {
@@ -86,6 +87,9 @@ mono_class_metadata_init   (MonoClass *klass);
 MonoClass *
 mono_class_from_name       (MonoImage *image, const char* name_space, const char *name);
 
+MonoClassField*
+mono_field_from_memberref  (MonoImage *image, guint32 token, MonoClass **retklass);
+
 MonoClass *
 mono_array_class_get       (MonoClass *eclass, guint32 rank);
 
index a602de6f0a53fc71d22c12083081a0b658a334d0..5424409213cb7edfdeb8570529599104959356a6 100644 (file)
@@ -205,59 +205,17 @@ my_mono_new_object (MonoClass *klass, gpointer data)
        return res;
 }
 
-static gpointer
-object_field_pointer (MonoObject *obj, char *name)
-{
-       MonoClassField *field;
-       gpointer *slot;
-
-       field = mono_class_get_field_from_name (obj->klass, name);
-       slot = (gpointer*)((char*)obj + field->offset);
-       return *slot;
-}
-
-static gpointer
-object_impl_pointer (MonoObject *obj)
-{
-       return object_field_pointer (obj, "_impl");
-}
-
-static MonoObject *
-ves_icall_app_define_assembly (MonoObject *appdomain, MonoObject *assembly_name, int access)
-{
-       MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "AssemblyBuilder");
-       MonoDynamicAssembly *ass = g_new0 (MonoDynamicAssembly, 1);
-       MonoClassField *field;
-       MonoObject *name;
-
-       field = mono_class_get_field_from_name (assembly_name->klass, "name");
-       name = *(MonoObject**)((char*)assembly_name + field->offset);
-
-       ass->name = mono_string_to_utf8 (name);
-
-       return my_mono_new_object (klass, ass);
-}
-
 static gint32
-ves_icall_get_data_chunk (MonoObject *assb, gint32 type, MonoArray *buf)
+ves_icall_get_data_chunk (MonoReflectionAssemblyBuilder *assb, gint32 type, MonoArray *buf)
 {
-       MonoDynamicAssembly *ass = object_impl_pointer (assb);
-       MonoObject *ep;
        int count;
-       /*
-        * get some info from the object
-        */
-       ep = object_field_pointer (assb, "entry_point");
-       if (ep)
-               ass->entry_point = object_impl_pointer (ep);
-       else
-               ass->entry_point = 0;
 
        if (type == 0) { /* get the header */
-               count = mono_image_get_header (ass, buf->vector, buf->bounds->length);
+               count = mono_image_get_header (assb, buf->vector, buf->bounds->length);
                if (count != -1)
                        return count;
        } else {
+               MonoDynamicAssembly *ass = assb->dynamic_assembly;
                count = ass->code.index + ass->meta_size;
                if (count > buf->bounds->length)
                        return 0;
@@ -269,81 +227,6 @@ ves_icall_get_data_chunk (MonoObject *assb, gint32 type, MonoArray *buf)
        return 0;
 }
 
-static MonoObject *
-ves_icall_define_module (MonoObject *assb, MonoObject *name, MonoObject *fname)
-{
-       MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "ModuleBuilder");
-       MonoModuleBuilder *mb = g_new0 (MonoModuleBuilder, 1);
-       MonoDynamicAssembly *ass = object_impl_pointer (assb);
-       ass->modules = g_list_prepend (ass->modules, mb);
-
-       mb->name = mono_string_to_utf8 (name);
-       mb->fname = mono_string_to_utf8 (fname);
-
-       return my_mono_new_object (klass, mb);
-}
-
-static MonoObject *
-ves_icall_define_type (MonoObject *moduleb, MonoObject *name, int attrs)
-{
-       MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "TypeBuilder");
-       MonoTypeBuilder *tb = g_new0 (MonoTypeBuilder, 1);
-       MonoModuleBuilder *mb = object_impl_pointer (moduleb);
-       char *nspace = mono_string_to_utf8 (name);
-       char *tname = strrchr (nspace, '.');
-       
-       if (tname) {
-               *tname = 0;
-               tname++;
-       } else {
-               nspace = "";
-       }
-       
-       tb->name = tname;
-       tb->nspace = nspace;
-       tb->attrs = attrs;
-       mb->types = g_list_prepend (mb->types, tb);
-
-       return my_mono_new_object (klass, tb);
-}
-
-static MonoObject *
-ves_icall_define_method (MonoObject *typeb, MonoObject *name, int attrs, int callconv, MonoObject *rettype, MonoArray *paramtypes)
-{
-       MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "MethodBuilder");
-       MonoMethodBuilder *mb = g_new0 (MonoMethodBuilder, 1);
-       MonoTypeBuilder *tb = object_impl_pointer (typeb);
-
-       mb->name = mono_string_to_utf8 (name);
-       mb->attrs = attrs;
-       mb->callconv = callconv;
-       mb->ret = object_impl_pointer (rettype);
-       /* ignore params ... */
-
-       if (!tb->has_default_ctor) {
-               if (strcmp (".ctor", mb->name) == 0 && paramtypes->bounds->length == 0)
-                       tb->has_default_ctor = 1;
-       }
-       
-       tb->methods = g_list_prepend (tb->methods, mb);
-
-       return my_mono_new_object (klass, mb);
-}
-
-static void
-ves_icall_set_method_body (MonoObject *methodb, MonoArray *code, gint32 count)
-{
-       MonoMethodBuilder *mb = object_impl_pointer (methodb);
-       if (code->bounds->length < count) {
-               g_warning ("code len is less than count");
-               return;
-       }
-       g_free (mb->code);
-       mb->code = g_malloc (count);
-       mb->code_size = count;
-       memcpy (mb->code, code->vector, count);
-}
-
 static MonoObject*
 ves_icall_type_from_name (MonoObject *name)
 {
@@ -384,28 +267,23 @@ static gpointer icall_map [] = {
         * System.AppDomain
         */
        "System.AppDomain::getCurDomain", ves_icall_app_get_cur_domain,
-       "System.AppDomain::defineAssembly", ves_icall_app_define_assembly,
 
        /*
         * ModuleBuilder
         */
-       "System.Reflection.Emit.ModuleBuilder::defineType", ves_icall_define_type,
        
        /*
         * AssemblyBuilder
         */
-       "System.Reflection.Emit.AssemblyBuilder::defineModule", ves_icall_define_module,
        "System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_get_data_chunk,
        
        /*
         * TypeBuilder
         */
-       "System.Reflection.Emit.TypeBuilder::defineMethod", ves_icall_define_method,
        
        /*
         * MethodBuilder
         */
-       "System.Reflection.Emit.MethodBuilder::set_method_body", ves_icall_set_method_body,
        
        /*
         * System.Type
index 10ace00228c82598a890021ac894db19fa33d87a..a8852ddaa367e6379de3c03ff18012ca00f328fd 100644 (file)
@@ -213,6 +213,78 @@ mono_lookup_internal_call (const char *name)
        return res;
 }
 
+MonoClassField*
+mono_field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass)
+{
+       MonoImage *mimage;
+       MonoClass *klass;
+       MonoTableInfo *tables = image->tables;
+       guint32 cols[6];
+       guint32 nindex, class, i;
+       const char *fname, *name, *nspace;
+       const char *ptr;
+       guint32 index = mono_metadata_token_index (token);
+
+       mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], index-1, cols, MONO_MEMBERREF_SIZE);
+       nindex = cols [MONO_MEMBERREF_CLASS] >> MEMBERREF_PARENT_BITS;
+       class = cols [MONO_MEMBERREF_CLASS] & MEMBERREF_PARENT_MASK;
+
+       fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
+       
+       ptr = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
+       mono_metadata_decode_blob_size (ptr, &ptr);
+       /* we may want to check the signature here... */
+
+       switch (class) {
+       case MEMBERREF_PARENT_TYPEREF: {
+               guint32 scopeindex, scopetable;
+
+               mono_metadata_decode_row (&tables [MONO_TABLE_TYPEREF], nindex-1, cols, MONO_TYPEREF_SIZE);
+               scopeindex = cols [MONO_TYPEREF_SCOPE] >> RESOLTION_SCOPE_BITS;
+               scopetable = cols [MONO_TYPEREF_SCOPE] & RESOLTION_SCOPE_MASK;
+               /*g_print ("typeref: 0x%x 0x%x %s.%s\n", scopetable, scopeindex,
+                       mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]),
+                       mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]));*/
+               switch (scopetable) {
+               case RESOLTION_SCOPE_ASSEMBLYREF:
+                       /*
+                        * To find the field we have the following info:
+                        * *) name and namespace of the class from the TYPEREF table
+                        * *) name and signature of the field from the MEMBERREF table
+                        */
+                       nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
+                       name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
+
+                       /* this will triggered by references to mscorlib */
+                       if (image->references [scopeindex-1] == NULL)
+                               g_error ("Reference to mscorlib? Probably need to implement %s.%s::%s in corlib", nspace, name, fname);
+
+                       mimage = image->references [scopeindex-1]->image;
+
+                       klass = mono_class_from_name (mimage, nspace, name);
+                       mono_class_metadata_init (klass);
+
+                       /* mostly dumb search for now */
+                       for (i = 0; i < klass->field.count; ++i) {
+                               MonoClassField *f = &klass->fields [i];
+                               if (!strcmp (fname, f->name)) {
+                                       if (retklass)
+                                               *retklass = klass;
+                                       return f;
+                               }
+                       }
+                       g_warning ("Missing field %s.%s::%s", nspace, name, fname);
+                       return NULL;
+               default:
+                       return NULL;
+               }
+               break;
+       }
+       default:
+               return NULL;
+       }
+}
+
 static MonoMethod *
 method_from_memberref (MonoImage *image, guint32 index)
 {
index bfaddefb453c63298398993c62c0a9bbe8fca4a1..2b1fdd0f42c88eb9ce374ac14a5f4e8fb34aaca2 100644 (file)
@@ -2,17 +2,17 @@
 
 #if NO_UNALIGNED_ACCESS
 
-typedef struct {
+typedef union {
        char c [2];
        guint16 i;
 } mono_rint16;
 
-typedef struct {
+typedef union {
        char c [4];
        guint32 i;
 } mono_rint32;
 
-typedef struct {
+typedef union {
        char c [8];
        guint64 i;
 } mono_rint64;
index 1e18763152bd95c011fcc7201283962d3bb80153..60661fbaf4f48976e03beddfdf884c6dff723454 100644 (file)
@@ -144,20 +144,20 @@ mono_array_new (MonoClass *eclass, guint32 n)
  *
  * Returns: A newly created string object which contains @text.
  */
-MonoObject *
+MonoString *
 mono_string_new_utf16 (const guint16 *text, gint32 len)
 {
-       MonoObject *s;
+       MonoString *s;
        MonoArray *ca;
 
-       s = mono_object_new (mono_defaults.string_class);
+       s = (MonoString*)mono_object_new (mono_defaults.string_class);
        g_assert (s != NULL);
 
        ca = (MonoArray *)mono_array_new (mono_defaults.string_class, len);
        g_assert (ca != NULL);
        
-       ((MonoString *)s)->c_str = ca;
-       ((MonoString *)s)->length = len;
+       s->c_str = ca;
+       s->length = len;
 
        memcpy (ca->vector, text, len * 2);
 
@@ -170,10 +170,10 @@ mono_string_new_utf16 (const guint16 *text, gint32 len)
  *
  * Returns: A newly created string object which contains @text.
  */
-MonoObject *
+MonoString*
 mono_string_new (const char *text)
 {
-       MonoObject *o;
+       MonoString *o;
        guint16 *ut;
        int i, l;
 
@@ -267,19 +267,19 @@ ldstr_equal (const char *str1, const char *str2) {
 }
 
 typedef struct {
-       MonoObject *obj;
-       MonoObject *found;
+       MonoString *obj;
+       MonoString *found;
 } InternCheck;
 
 static void
-check_interned (gpointer key, MonoObject *value, InternCheck *check)
+check_interned (gpointer key, MonoString *value, InternCheck *check)
 {
        if (value == check->obj)
                check->found = value;
 }
 
-MonoObject*
-mono_string_is_interned (MonoObject *o)
+MonoString*
+mono_string_is_interned (MonoString *o)
 {
        InternCheck check;
        check.obj = o;
@@ -292,11 +292,10 @@ mono_string_is_interned (MonoObject *o)
        return check.found;
 }
 
-MonoObject*
-mono_string_intern (MonoObject *o)
+MonoString*
+mono_string_intern (MonoString *str)
 {
-       MonoObject *res;
-       MonoString *str = (MonoString*) o;
+       MonoString *res;
        char *ins = g_malloc (4 + str->length * 2);
        char *p;
        
@@ -310,14 +309,14 @@ mono_string_intern (MonoObject *o)
                return res;
        }
        g_hash_table_insert (ldstr_table, ins, str);
-       return (MonoObject*)str;
+       return str;
 }
 
-MonoObject*
+MonoString*
 mono_ldstr (MonoImage *image, guint32 index)
 {
        const char *str, *sig;
-       MonoObject *o;
+       MonoString *o;
        guint len;
        
        if (!ldstr_table)
@@ -336,15 +335,14 @@ mono_ldstr (MonoImage *image, guint32 index)
 }
 
 char *
-mono_string_to_utf8 (MonoObject *o)
+mono_string_to_utf8 (MonoString *s)
 {
-       MonoString *s = (MonoString *)o;
        char *as, *vector;
        int i;
 
-       g_assert (o != NULL);
+       g_assert (s != NULL);
 
-       if (!s->length)
+       if (!s->length || !s->c_str)
                return g_strdup ("");
 
        vector = s->c_str->vector;
index 24fdadbe356e0b796dd6918fed28829f91a38c49..07b165c98c53499cec5adcee3ca5779fd31e30c0 100644 (file)
@@ -45,23 +45,23 @@ mono_object_new_from_token  (MonoImage *image, guint32 token);
 MonoObject *
 mono_array_new              (MonoClass *eclass, guint32 n);
 
-MonoObject *
+MonoString*
 mono_string_new_utf16       (const guint16 *text, gint32 len);
 
-MonoObject*
+MonoString*
 mono_ldstr                  (MonoImage *image, guint32 index);
 
-MonoObject*
-mono_string_is_interned     (MonoObject *o);
+MonoString*
+mono_string_is_interned     (MonoString *str);
 
-MonoObject*
-mono_string_intern          (MonoObject *o);
+MonoString*
+mono_string_intern          (MonoString *str);
 
-MonoObject *
+MonoString*
 mono_string_new             (const char *text);
 
 char *
-mono_string_to_utf8         (MonoObject *string_obj);
+mono_string_to_utf8         (MonoString *string_obj);
 
 void       
 mono_object_free            (MonoObject *o);
index 65cc14c1ddde8a8db7e72124bc17e14fe56e5c81..0dc99e5fcd47e08c4dfca1ac41f8731bd53a22e0 100644 (file)
@@ -122,7 +122,7 @@ static void
 string_heap_free (MonoStringHeap *sh)
 {
        g_free (sh->data);
-       g_hash_table_foreach (sh->hash, g_free, NULL);
+       g_hash_table_foreach (sh->hash, (GHFunc)g_free, NULL);
        g_hash_table_destroy (sh->hash);
 }
 
@@ -168,18 +168,27 @@ encode_type (MonoType *type, char *p, char **endbuf)
        case MONO_TYPE_TYPEDBYREF:
                mono_metadata_encode_value (type->type, p, endbuf);
                break;
+       case MONO_TYPE_SZARRAY:
+               mono_metadata_encode_value (type->type, p, endbuf);
+               encode_type (type->data.type, p, endbuf);
+               break;
+       case MONO_TYPE_CLASS:
+               mono_metadata_encode_value (type->type, p, endbuf);
+               g_warning ("need to encode class %s", type->data.klass->name);
+               break;
        default:
-               g_error ("need to encode type %d", type->type);
+               g_error ("need to encode type %x", type->type);
        }
 }
 
 static guint32
-method_encode_signature (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
+method_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionMethodBuilder *mb)
 {
        char *buf;
        char *p;
        int i;
-       guint32 size = 10 + mb->nparams * 10;
+       guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
+       guint32 size = 10 + nparams * 10;
        guint32 idx;
        char blob_size [6];
        char *b = blob_size;
@@ -191,10 +200,11 @@ method_encode_signature (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
         * FIXME: set also call convention and explict_this if needed.
         */
        p++;
-       mono_metadata_encode_value (mb->nparams, p, &p);
-       encode_type (mb->ret, p, &p);
-       for (i = 0; i < mb->nparams; ++i) {
-               encode_type (mb->params [i], p, &p);
+       mono_metadata_encode_value (nparams, p, &p);
+       encode_type (mb->rtype->type, p, &p);
+       for (i = 0; i < nparams; ++i) {
+               MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
+               encode_type (pt->type, p, &p);
        }
        /* store length */
        mono_metadata_encode_value (p-buf, b, &b);
@@ -205,41 +215,227 @@ method_encode_signature (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
 }
 
 static guint32
-method_encode_code (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
+encode_locals (MonoDynamicAssembly *assembly, MonoReflectionILGen *ilgen)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       char *name, *p;
+       guint32 idx, sig_idx;
+       guint nl = mono_array_length (ilgen->locals);
+       char *buf;
+       char blob_size [6];
+       char *b = blob_size;
+       int i;
+
+       p = buf = g_malloc (10 + nl * 10);
+       table = &assembly->tables [MONO_TABLE_STANDALONESIG];
+       idx = table->next_idx ++;
+       table->rows ++;
+       alloc_table (table, table->rows);
+       values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
+
+       mono_metadata_encode_value (0x07, p, &p);
+       mono_metadata_encode_value (nl, p, &p);
+       for (i = 0; i < nl; ++i) {
+               MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
+               encode_type (lb->type->type, p, &p);
+       }
+       mono_metadata_encode_value (p-buf, b, &b);
+       sig_idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+       mono_image_add_stream_data (&assembly->blob, buf, p-buf);
+       g_free (buf);
+
+       values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
+
+       return idx;
+}
+
+static guint32
+method_encode_code (MonoDynamicAssembly *assembly, MonoReflectionMethodBuilder *mb)
 {
        /* we use only tiny formats now: need  to implement ILGenerator */
        char flags = 0;
        guint32 idx;
-       /* check for exceptions, maxstack, locals */
-       if (mb->code_size < 64 && !(mb->code_size & 1)) {
-               flags = (mb->code_size << 2) | 0x2;
-       } else if (mb->code_size < 32 && (mb->code_size & 1)) {
-               flags = (mb->code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
+       guint32 code_size;
+       gint32 max_stack;
+       gint32 num_locals = 0;
+       gint32 num_exception = 0;
+       gint maybe_small;
+       guint32 fat_flags;
+       char fat_header [12];
+       guint32 *intp;
+       guint16 *shortp;
+       guint32 local_sig = 0;
+       MonoArray *code;
+
+       if (mb->ilgen) {
+               code = mb->ilgen->code;
+               code_size = mb->ilgen->code_len;
+               max_stack = mb->ilgen->max_stack;
+               num_locals = mb->ilgen->locals ? mono_array_length (mb->ilgen->locals) : 0;
        } else {
-               g_error ("fat method headers not yet supported");
+               code = mb->code;
+               code_size = mono_array_length (code);
+               max_stack = 8; /* we probably need to run a verifier on the code... */
        }
-       idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
-       mono_image_add_stream_data (&assembly->code, mb->code, mb->code_size);
+
+       /* check for exceptions, maxstack, locals */
+       maybe_small = (max_stack <= 8) && (!num_locals) && (!num_exception);
+       if (maybe_small) {
+               if (code_size < 64 && !(code_size & 1)) {
+                       flags = (code_size << 2) | 0x2;
+               } else if (code_size < 32 && (code_size & 1)) {
+                       flags = (code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
+               } else {
+                       goto fat_header;
+               }
+               idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
+               mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
+               return assembly->text_rva + idx + CLI_H_SIZE;
+       } 
+fat_header:
+       if (num_locals)
+               local_sig = encode_locals (assembly, mb->ilgen);
+       /* 
+        * FIXME: need to set also the header size in fat_flags.
+        * (and more sects and init locals flags)
+        */
+       fat_flags =  0x03;
+       shortp = (guint16*)(fat_header);
+       *shortp = fat_flags;
+       shortp = (guint16*)(fat_header + 2);
+       *shortp = max_stack;
+       intp = (guint32*)(fat_header + 4);
+       *intp = code_size;
+       intp = (guint32*)(fat_header + 8);
+       *intp = local_sig;
+       idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
+       mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
        return assembly->text_rva + idx + CLI_H_SIZE;
 }
 
 static void
-mono_image_get_method_info (MonoMethodBuilder *mb, MonoDynamicAssembly *assembly)
+mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicAssembly *assembly)
 {
        MonoDynamicTable *table;
        guint32 *values;
+       char *name;
 
        table = &assembly->tables [MONO_TABLE_METHOD];
        mb->table_idx = table->next_idx ++;
        values = table->values + mb->table_idx * MONO_METHOD_SIZE;
-       values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, mb->name);
+       name = mono_string_to_utf8 (mb->name);
+       values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, name);
+       g_free (name);
        values [MONO_METHOD_FLAGS] = mb->attrs;
        values [MONO_METHOD_IMPLFLAGS] = 0;
        values [MONO_METHOD_SIGNATURE] = method_encode_signature (assembly, mb);
-       values [MONO_METHOD_PARAMLIST] = 1; /* FIXME: add support later */
+       values [MONO_METHOD_PARAMLIST] = 0; /* FIXME: add support later */
        values [MONO_METHOD_RVA] = method_encode_code (assembly, mb);
 }
 
+static guint32
+field_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionFieldBuilder *fb)
+{
+       char blob_size [64];
+       char *b = blob_size;
+       char *p;
+       char* buf;
+       guint32 idx;
+       
+       p = buf = g_malloc (64);
+       
+       mono_metadata_encode_value (0x06, p, &p);
+       /* encode custom attributes before the type */
+       encode_type (fb->type->type, p, &p);
+       g_assert (p-buf < 64);
+       mono_metadata_encode_value (p-buf, b, &b);
+       idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+       mono_image_add_stream_data (&assembly->blob, buf, p-buf);
+       g_free (buf);
+       return idx;
+}
+
+static void
+mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicAssembly *assembly)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       char *name;
+
+       table = &assembly->tables [MONO_TABLE_FIELD];
+       fb->table_idx = table->next_idx ++;
+       values = table->values + fb->table_idx * MONO_FIELD_SIZE;
+       name = mono_string_to_utf8 (fb->name);
+       values [MONO_FIELD_NAME] = string_heap_insert (&assembly->sheap, name);
+       g_free (name);
+       values [MONO_FIELD_FLAGS] = fb->attrs;
+       values [MONO_FIELD_SIGNATURE] = field_encode_signature (assembly, fb);
+}
+
+static guint32
+property_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionPropertyBuilder *fb)
+{
+       /* 
+        * FIXME: fill me in 
+        */
+       return 0;
+}
+
+static void
+mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicAssembly *assembly)
+{
+       MonoDynamicTable *table;
+       guint32 *values;
+       char *name;
+       guint num_methods = 0;
+       guint32 semaidx;
+
+       /* 
+        * we need to set things in the following tables:
+        * PROPERTYMAP (info already filled in _get_type_info ())
+        * PROPERTY    (rows already preallocated in _get_type_info ())
+        * METHOD
+        * METHODSEMANTICS
+        */
+       table = &assembly->tables [MONO_TABLE_PROPERTY];
+       pb->table_idx = table->next_idx ++;
+       values = table->values + pb->table_idx * MONO_FIELD_SIZE;
+       name = mono_string_to_utf8 (pb->name);
+       values [MONO_PROPERTY_NAME] = string_heap_insert (&assembly->sheap, name);
+       g_free (name);
+       values [MONO_PROPERTY_FLAGS] = pb->attrs;
+       values [MONO_PROPERTY_TYPE] = property_encode_signature (assembly, pb);
+
+       /* alloc room for the methods (we still don't handle 'other' methods) */
+       if (pb->get_method) num_methods ++;
+       if (pb->set_method) num_methods ++;
+       table = &assembly->tables [MONO_TABLE_METHOD];
+       table->rows += num_methods;
+       alloc_table (table, table->rows);
+
+       table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
+       table->rows += num_methods;
+       alloc_table (table, table->rows);
+
+       if (pb->get_method) {
+               mono_image_get_method_info (pb->get_method, assembly);
+               semaidx = table->next_idx ++;
+               values = table->values + semaidx *      MONO_METHOD_SEMA_SIZE;
+               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER;
+               values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << 1) | 1;
+       }
+       if (pb->set_method) {
+               mono_image_get_method_info (pb->set_method, assembly);
+               semaidx = table->next_idx ++;
+               values = table->values + semaidx *      MONO_METHOD_SEMA_SIZE;
+               values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER;
+               values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
+               values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << 1) | 0;
+       }
+}
+
 static guint32
 mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoClass *klass)
 {
@@ -269,49 +465,87 @@ mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoClass *klass)
 }
 
 static void
-mono_image_get_type_info (MonoTypeBuilder *tb, MonoDynamicAssembly *assembly)
+mono_image_get_type_info (MonoReflectionTypeBuilder *tb, MonoDynamicAssembly *assembly)
 {
        MonoDynamicTable *table;
        guint *values;
+       int i;
+       char *n;
 
        table = &assembly->tables [MONO_TABLE_TYPEDEF];
        tb->table_idx = table->next_idx ++;
        values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
        values [MONO_TYPEDEF_FLAGS] = tb->attrs;
-       /* use tb->base later */
+       /* FIXME: use tb->base later */
        values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, mono_defaults.object_class);
-       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, tb->name);
-       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, tb->nspace);
+       n = mono_string_to_utf8 (tb->name);
+       values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, n);
+       g_free (n);
+       n = mono_string_to_utf8 (tb->nspace);
+       values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, n);
+       g_free (n);
        values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
        values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;
 
-       table = &assembly->tables [MONO_TABLE_METHOD];
-       table->rows += g_list_length (tb->methods);
-       /*if (!tb->has_default_ctor)
-               table->rows++;*/
-       alloc_table (table, table->rows);
-       g_list_foreach (tb->methods, mono_image_get_method_info, assembly);
+       /* handle methods */
+       if (tb->methods) {
+               table = &assembly->tables [MONO_TABLE_METHOD];
+               table->rows += mono_array_length (tb->methods);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (tb->methods); ++i)
+                       mono_image_get_method_info (
+                               mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), assembly);
+       }
+
+       /* handle fields */
+       if (tb->fields) {
+               table = &assembly->tables [MONO_TABLE_FIELD];
+               table->rows += mono_array_length (tb->fields);
+               alloc_table (table, table->rows);
+               for (i = 0; i < mono_array_length (tb->fields); ++i)
+                       mono_image_get_field_info (
+                               mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i), assembly);
+       }
 
-       /* Do the same with fields, properties etc.. */
+       /* Do the same with properties etc.. */
+       if (tb->properties && mono_array_length (tb->properties)) {
+               table = &assembly->tables [MONO_TABLE_PROPERTY];
+               table->rows += mono_array_length (tb->properties);
+               alloc_table (table, table->rows);
+               table = &assembly->tables [MONO_TABLE_PROPERTYMAP];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + (table->rows - 1) * MONO_PROPERTY_MAP_SIZE;
+               values [MONO_PROPERTY_MAP_PARENT] = tb->table_idx;
+               values [MONO_PROPERTY_MAP_PROPERTY_LIST] = assembly->tables [MONO_TABLE_PROPERTY].next_idx ++;
+               for (i = 0; i < mono_array_length (tb->properties); ++i)
+                       mono_image_get_property_info (
+                               mono_array_get (tb->fields, MonoReflectionPropertyBuilder*, i), assembly);
+       }
 }
 
 static void
-mono_image_fill_module_table (MonoModuleBuilder *mb, MonoDynamicAssembly *assembly)
+mono_image_fill_module_table (MonoReflectionModuleBuilder *mb, MonoDynamicAssembly *assembly)
 {
        MonoDynamicTable *table;
+       int i;
+       char *name;
 
        table = &assembly->tables [MONO_TABLE_MODULE];
        mb->table_idx = table->next_idx ++;
-       table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, mb->name);
+       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? */
 
        /*
         * fill-in info in other tables as well.
         */
        table = &assembly->tables [MONO_TABLE_TYPEDEF];
-       table->rows += g_list_length (mb->types);
+       table->rows += mono_array_length (mb->types);
        alloc_table (table, table->rows);
-       g_list_foreach (mb->types, mono_image_get_type_info, assembly);
+       for (i = 0; i < mono_array_length (mb->types); ++i)
+               mono_image_get_type_info (mono_array_get (mb->types, MonoReflectionTypeBuilder*, i), assembly);
 }
 
 static void
@@ -501,13 +735,15 @@ build_compressed_metadata (MonoDynamicAssembly *assembly)
 }
 
 static void
-mono_image_build_metadata (MonoDynamicAssembly *assembly)
+mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb)
 {
        char *meta;
        MonoDynamicTable *table;
+       MonoDynamicAssembly *assembly = assemblyb->dynamic_assembly;
        GList *type;
        guint32 len;
        guint32 *values;
+       char *name;
        int i;
        
        /*
@@ -528,16 +764,19 @@ mono_image_build_metadata (MonoDynamicAssembly *assembly)
        alloc_table (table, 1);
        values = table->values + MONO_ASSEMBLY_SIZE;
        values [MONO_ASSEMBLY_HASH_ALG] = 0x8004;
-       values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, assembly->name);
+       name = mono_string_to_utf8 (assemblyb->name);
+       values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, name);
+       g_free (name);
        values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, "");
 
        assembly->tables [MONO_TABLE_TYPEDEF].rows = 1; /* .<Module> */
        assembly->tables [MONO_TABLE_TYPEDEF].next_idx++;
 
-       len = g_list_length (assembly->modules);
+       len = mono_array_length (assemblyb->modules);
        table = &assembly->tables [MONO_TABLE_MODULE];
        alloc_table (table, len);
-       g_list_foreach (assembly->modules, mono_image_fill_module_table, assembly);
+       for (i = 0; i < len; ++i)
+               mono_image_fill_module_table (mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i), assembly);
 
        table = &assembly->tables [MONO_TABLE_TYPEDEF];
        /* 
@@ -565,13 +804,14 @@ mono_image_build_metadata (MonoDynamicAssembly *assembly)
 }
 
 int
-mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
+mono_image_get_header (MonoReflectionAssemblyBuilder *assemblyb, char *buffer, int maxsize)
 {
        MonoMSDOSHeader *msdos;
        MonoDotNetHeader *header;
        MonoSectionTable *section;
        MonoCLIHeader *cli_header;
        guint32 header_size =  TEXT_OFFSET + CLI_H_SIZE;
+       MonoDynamicAssembly *assembly;
 
        static const unsigned char msheader[] = {
                0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,  0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
@@ -587,7 +827,8 @@ mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
        if (maxsize < header_size)
                return -1;
 
-       mono_image_build_metadata (assembly);
+       assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
+       mono_image_build_metadata (assemblyb);
 
        memset (buffer, 0, header_size);
        memcpy (buffer, msheader, sizeof (MonoMSDOSHeader));
@@ -664,8 +905,8 @@ mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
        cli_header->ch_size = CLI_H_SIZE;
        cli_header->ch_runtime_major = 2;
        cli_header->ch_flags = CLI_FLAGS_ILONLY;
-       if (assembly->entry_point) 
-               cli_header->ch_entry_point = assembly->entry_point->table_idx | MONO_TOKEN_METHOD_DEF;
+       if (assemblyb->entry_point) 
+               cli_header->ch_entry_point = assemblyb->entry_point->table_idx | MONO_TOKEN_METHOD_DEF;
        else
                cli_header->ch_entry_point = 0;
        cli_header->ch_metadata.rva = assembly->text_rva + assembly->code.index + CLI_H_SIZE;
index 5e9fcef3fd3688dbfab203535a1a30b52cb6f9d7..b57dceb51d8907c8e3ecaca6965314b103c3a55d 100644 (file)
@@ -4,6 +4,7 @@
 #include <mono/metadata/image.h>
 #include <mono/metadata/metadata.h>
 #include <mono/metadata/class.h>
+#include <mono/metadata/object.h>
 
 typedef struct {
        char *name;
@@ -13,37 +14,6 @@ typedef struct {
        guint32 offset; /* from start of metadata */
 } MonoDynamicStream;
 
-typedef struct {
-       char *name;
-       char *fname;
-       GList *types;
-       guint32 table_idx;
-} MonoModuleBuilder;
-
-typedef struct {
-       char *name;
-       char *nspace;
-       int attrs;
-       int has_default_ctor;
-       guint32 table_idx;
-       MonoType *base;
-       GList *methods;
-       GList *fields;
-       GList *properties;
-} MonoTypeBuilder;
-
-typedef struct {
-       char *name;
-       guint32 attrs;
-       guint32 callconv;
-       guint32 nparams;
-       guint32 table_idx;
-       MonoType *ret;
-       MonoType **params;
-       char *code;
-       guint32 code_size;
-} MonoMethodBuilder;
-
 typedef struct {
        guint32 rows;
        guint32 row_size; /*  calculated later with column_sizes */
@@ -61,14 +31,49 @@ typedef struct {
        guint32 offset; /* from start of metadata */
 } MonoStringHeap;
 
+/*
+ * The followinbg structure must match the C# implementation in our corlib.
+ */
+
+typedef struct {
+       MonoObject object;
+       MonoType  *type;
+} MonoReflectionType;
+
+typedef struct {
+       MonoObject object;
+       MonoArray *code;
+       MonoObject *mbuilder;
+       gint32 code_len;
+       gint32 max_stack;
+       gint32 cur_stack;
+       MonoArray *locals;
+} MonoReflectionILGen;
+
+typedef struct {
+       MonoObject object;
+       MonoReflectionType *type;
+       MonoString *name;
+} MonoReflectionLocalBuilder;
+
+typedef struct {
+       MonoObject object;
+       MonoMethod *impl;
+       MonoReflectionType *rtype;
+       MonoArray *parameters;
+       guint32 attrs;
+       MonoString *name;
+       guint32 table_idx;
+       MonoArray *code;
+       MonoReflectionILGen *ilgen;
+       MonoObject *type;
+} MonoReflectionMethodBuilder;
+
 typedef struct {
        MonoAssembly assembly;
-       char *name;
-       GList *modules;
        guint32 meta_size;
        guint32 text_rva;
        guint32 metadata_rva;
-       MonoMethodBuilder *entry_point;
        GHashTable *typeref;
        MonoStringHeap sheap;
        MonoDynamicStream code; /* used to store method headers and bytecode */
@@ -79,7 +84,70 @@ typedef struct {
        MonoDynamicTable tables [64];
 } MonoDynamicAssembly;
 
-int           mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize);
+typedef struct {
+       MonoObject object;
+       MonoAssembly *assembly;
+} MonoReflectionAssembly;
+
+typedef struct {
+       MonoReflectionAssembly assembly;
+       MonoDynamicAssembly *dynamic_assembly;
+       MonoReflectionMethodBuilder *entry_point;
+       MonoArray *modules;
+       MonoString *name;
+} MonoReflectionAssemblyBuilder;
+
+typedef struct {
+       MonoObject object;
+       guint32 attrs;
+       MonoReflectionType *type;
+       MonoString *name;
+       MonoObject *def_value;
+       gint32 offset;
+       gint32 table_idx;
+} MonoReflectionFieldBuilder;
+
+typedef struct {
+       MonoObject object;
+       guint32 attrs;
+       MonoString *name;
+       MonoReflectionType *type;
+       MonoArray *parameters;
+       MonoObject *def_value;
+       MonoReflectionMethodBuilder *set_method;
+       MonoReflectionMethodBuilder *get_method;
+       gint32 table_idx;
+} MonoReflectionPropertyBuilder;
+
+typedef struct {
+       MonoReflectionType type;
+       MonoString *name;
+       MonoString *nspace;
+       MonoReflectionType *parent;
+       MonoArray *interfaces;
+       MonoArray *methods;
+       MonoArray *properties;
+       MonoArray *fields;
+       guint32 attrs;
+       guint32 table_idx;
+} MonoReflectionTypeBuilder;
+
+typedef struct {
+       MonoObject      obj;
+       MonoImage  *image;
+       MonoObject *assembly;
+       MonoString *fqname;
+       MonoString *name;
+       MonoString *scopename;
+} MonoReflectionModule;
+
+typedef struct {
+       MonoReflectionModule module;
+       MonoArray *types;
+       guint32    table_idx;
+} MonoReflectionModuleBuilder;
+
+int           mono_image_get_header (MonoReflectionAssemblyBuilder *assembly, char *buffer, int maxsize);
 
 #endif /* __METADATA_REFLECTION_H__ */
 
index d8624c74d52960cd95f7ef70351b143fec5fc587..76f02358a3ec3ac66ff0908a21151afc18a5fe6f 100644 (file)
@@ -8,12 +8,14 @@ class CGen {
                AssemblyBuilder abuilder;
                ModuleBuilder mbuilder;
                TypeBuilder tbuilder;
+               FieldBuilder fbuilder;
+               PropertyBuilder pbuilder;
                AssemblyName an;
                String name = "tcgen.exe";
-               MethodBuilder method;
+               MethodBuilder method, get_method;
                TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.Class;
                MethodAttributes mattrs = MethodAttributes.Public | MethodAttributes.Static;
-               byte[] body = {0x2a}; // ret
+               byte[] body = {0x16, 0x2a}; // ldc.i4.0 ret
 
                an = new AssemblyName ();
                an.Name = name;
@@ -23,9 +25,17 @@ class CGen {
 
                tbuilder = mbuilder.DefineType ("Test.CodeGen", attrs);
                Type result = typeof(int);
-               Type[] param = new Type[] {};
+               Type[] param = new Type[] {typeof (String[])};
                method = tbuilder.DefineMethod("Main", mattrs, result, param);
                method.CreateMethodBody (body, body.Length);
+
+               fbuilder = tbuilder.DefineField ("int_field", typeof(int), FieldAttributes.Private);
+               fbuilder = tbuilder.DefineField ("string_field", typeof(string), FieldAttributes.Public);
+               /*pbuilder = tbuilder.DefineProperty ("FieldI", PropertyAttributes.None, typeof(int), null);
+               get_method = tbuilder.DefineMethod("get_FieldI", MethodAttributes.Public, result, null);
+               get_method.CreateMethodBody (body, body.Length);
+               pbuilder.SetGetMethod (get_method);*/
+
                Type t = tbuilder.CreateType ();
                abuilder.SetEntryPoint (method);
                abuilder.Save (name);
diff --git a/mono/tests/codegen2.cs b/mono/tests/codegen2.cs
new file mode 100644 (file)
index 0000000..5e4e981
--- /dev/null
@@ -0,0 +1,61 @@
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+
+class CGen {
+
+       public static int Main() {
+               AssemblyBuilder abuilder;
+               ModuleBuilder mbuilder;
+               TypeBuilder tbuilder, tb2;
+               FieldBuilder fbuilder;
+               PropertyBuilder pbuilder;
+               ILGenerator ilg;
+               AssemblyName an;
+               String name = "tcgen.exe";
+               MethodBuilder get_method, entryp;
+               TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.Class;
+               MethodAttributes mattrs = MethodAttributes.Public | MethodAttributes.Static;
+
+               an = new AssemblyName ();
+               an.Name = name;
+               abuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save);
+
+               mbuilder = abuilder.DefineDynamicModule (name, name);
+
+               tbuilder = mbuilder.DefineType ("Test.CodeGen", attrs);
+               Type result = typeof(int);
+               Type[] param = new Type[] {typeof (String[])};
+               entryp = tbuilder.DefineMethod("Main", mattrs, result, param);
+               ilg = entryp.GetILGenerator (128);
+               ilg.DeclareLocal (typeof(int));
+               Label fail = ilg.DefineLabel ();
+               ilg.Emit (OpCodes.Ldc_I4_2);
+               ilg.Emit (OpCodes.Dup);
+               ilg.Emit (OpCodes.Add);
+               ilg.Emit (OpCodes.Stloc_0);
+               ilg.Emit (OpCodes.Ldc_I4_4);
+               ilg.Emit (OpCodes.Ldloc_0);
+               ilg.Emit (OpCodes.Sub);
+               ilg.Emit (OpCodes.Brfalse, fail);
+                       ilg.Emit (OpCodes.Ldc_I4_1);
+                       ilg.Emit (OpCodes.Ret);
+               ilg.MarkLabel (fail);
+               ilg.Emit (OpCodes.Ldc_I4_0);
+               ilg.Emit (OpCodes.Ret);
+               
+
+               fbuilder = tbuilder.DefineField ("int_field", typeof(int), FieldAttributes.Private);
+               /*pbuilder = tbuilder.DefineProperty ("FieldI", PropertyAttributes.None, typeof(int), null);
+               get_method = tbuilder.DefineMethod("get_FieldI", MethodAttributes.Public, result, null);
+               ilg = get_method.GetILGenerator (128);
+               ilg.Emit (OpCodes.Ldloc_0);
+               ilg.Emit (OpCodes.Ret);
+               pbuilder.SetGetMethod (get_method);*/
+
+               Type t = tbuilder.CreateType ();
+               abuilder.SetEntryPoint (entryp);
+               abuilder.Save (name);
+               return 0;
+       }
+}
index cc8a06fb933fb870581aa9c8fb6bf58d6c41b2fe..db2f11f569be7cab3f2e10bc4300c438d1d90aa3 100755 (executable)
@@ -13,7 +13,7 @@ public class Test {
                Thread thr=new Thread(new ThreadStart(test.Thread_func));
                thr.Start();
                Console.WriteLine("In the main line!");
-               
+               thr.Join ();
                return 0;
        }
 }