Wed Nov 14 19:21:26 CET 2001 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Wed, 14 Nov 2001 15:18:56 +0000 (15:18 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Wed, 14 Nov 2001 15:18:56 +0000 (15:18 -0000)
* x86/tramp.c: handle boolean as a return value.
* x96/x86-codegen.c: x86_widen_memindex() added.

Wed Nov 14 19:23:00 CET 2001 Paolo Molaro <lupus@ximian.com>

* interp.c: move the stack frame dumping code to a function so it can
be called from the debugger. Fix virtual method lookup for interfaces.
Throw exceptions instead of aborting in more places.
Print also the message in an exception. Updates for field renames in
corlib.

Wed Nov 14 19:26:06 CET 2001 Paolo Molaro <lupus@ximian.com>

* class.h, class.c: add a max_interface_id to MonoClass.
* icall.c: rename my_mono_new_object() to my_mono_new_mono_type()
since it's used to do that. Added mono_type_type_from_obj().
Make GetType() return NULL instead of segfaulting if the type was not
found. Handle simple arrays in assQualifiedName.
* object.h: add a struct to represent an Exception.
* reflection.c: output call convention in method signature.
Add code to support P/Invoke methods and fixed offsets for fields.

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

20 files changed:
mono/arch/ChangeLog
mono/arch/x86/test.c
mono/arch/x86/tramp.c
mono/arch/x86/x86-codegen.h
mono/interpreter/ChangeLog
mono/interpreter/interp.c
mono/interpreter/interp.h
mono/metadata/ChangeLog
mono/metadata/class.c
mono/metadata/class.h
mono/metadata/icall.c
mono/metadata/object.c
mono/metadata/object.h
mono/metadata/reflection.c
mono/metadata/reflection.h
mono/tests/Makefile.am
mono/tests/arraylist.cs [new file with mode: 0644]
mono/tests/hash-table.cs [new file with mode: 0644]
mono/tests/string.cs [new file with mode: 0755]
mono/tests/stringbuilder.cs [new file with mode: 0644]

index 10f43c66dffcba7f09fae0f80bdcda9219ce52ad..e6213803371a66c31fd220e4bddef7d13f13ba34 100644 (file)
@@ -1,3 +1,9 @@
+
+Wed Nov 14 19:21:26 CET 2001 Paolo Molaro <lupus@ximian.com>
+
+       * x86/tramp.c: handle boolean as a return value.
+       * x96/x86-codegen.c: x86_widen_memindex() added.
+
 2001-11-07  Miguel de Icaza  <miguel@ximian.com>
 
        * x86/tramp.c: Include stdlib to kill warning.
index 45fb5780278035cc773a3324929c1e861d10b4ae..a9695dc2a97f94fef1d97a954e1bdda8f71f8bf5 100644 (file)
@@ -126,6 +126,7 @@ int main() {
 
        x86_lea_mem (p, X86_EDX, mem_addr);
        /* test widen */
+       x86_widen_memindex (p, X86_EDX, X86_ECX, 0, X86_EBX, 2, 1, 0);
        
        x86_cdq (p);
        x86_wait (p);
index 0f1e01428fd5e484423c235bc820dcc632e7c595..879021958b473f2207d05f832e69fb6745a28b68 100644 (file)
@@ -406,6 +406,9 @@ mono_create_method_pointer (MonoMethod *method)
                switch (sig->ret->type) {
                case MONO_TYPE_VOID:
                        break;
+               case MONO_TYPE_BOOLEAN:
+                       x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 1);
+                       break;
                case MONO_TYPE_I4:
                case MONO_TYPE_U4:
                case MONO_TYPE_I:
index 6f65e173f89433852b3d4f417642ddec9e13ab92..2b9b1e1e50937f23bda214a47f5b8550e50600a9 100644 (file)
@@ -1,7 +1,7 @@
 /* Copyright (C)  2000 Intel Corporation.  All rights reserved.
    Copyright (C)  2001 Ximian, Inc. 
 //
-// $Header: /home/miguel/third-conversion/public/mono/mono/arch/x86/x86-codegen.h,v 1.15 2001/11/09 13:40:43 dietmar Exp $
+// $Header: /home/miguel/third-conversion/public/mono/mono/arch/x86/x86-codegen.h,v 1.16 2001/11/14 15:18:55 lupus Exp $
 */
 
 #ifndef X86_H
@@ -846,6 +846,16 @@ typedef union {
                x86_membase_emit ((inst), (dreg), (basereg), (disp));   \
        } while (0)
 
+#define x86_widen_memindex(inst,dreg,basereg,disp,indexreg,shift,is_signed,is_half)    \
+       do {    \
+               unsigned char op = 0xb6;        \
+               *(inst)++ = (unsigned char)0x0f;        \
+               if ((is_signed)) op += 0x08;    \
+               if ((is_half)) op += 0x01;      \
+               *(inst)++ = op; \
+               x86_memindex_emit ((inst), (dreg), (basereg), (disp), (indexreg), (shift));     \
+       } while (0)
+
 #define x86_cdq(inst)  do { *(inst)++ = (unsigned char)0x99; } while (0)
 #define x86_wait(inst) do { *(inst)++ = (unsigned char)0x9b; } while (0)
 
index 87a8b7aad2af790ab3c8def2802d9dae1937a54f..70c542e627794a2338285ba7042049996fae6997 100644 (file)
@@ -1,3 +1,12 @@
+
+Wed Nov 14 19:23:00 CET 2001 Paolo Molaro <lupus@ximian.com>
+
+       * interp.c: move the stack frame dumping code to a function so it can
+       be called from the debugger. Fix virtual method lookup for interfaces.
+       Throw exceptions instead of aborting in more places.
+       Print also the message in an exception. Updates for field renames in
+       corlib.
+
 2001-11-09  Dick Porter  <dick@ximian.com>
 
        * Makefile.am (mint_LDADD): Don't need THREAD_LIBS any more
index 6d155d34b47b3006b475e19c32d8360a18fdda46..3c62405d09032427804910568d535b6f394284c1 100644 (file)
@@ -595,7 +595,7 @@ ves_runtime_method (MonoInvocation *frame)
        if (!target_offset) {
                MonoClassField *field;
 
-               field = mono_class_get_field_from_name (mono_defaults.delegate_class, "target");
+               field = mono_class_get_field_from_name (mono_defaults.delegate_class, "m_target");
                target_offset = field->offset;
                field = mono_class_get_field_from_name (mono_defaults.delegate_class, "method_ptr");
                method_offset = field->offset;
@@ -655,6 +655,20 @@ dump_stack (stackval *stack, stackval *sp)
        }
 }
 
+static void
+dump_frame (MonoInvocation *inv)
+{
+       int i;
+       for (i = 0; inv; inv = inv->parent, ++i) {
+               MonoClass *k = inv->method->klass;
+               MonoMethodHeader *hd = ((MonoMethodNormal *)inv->method)->header;
+               g_print ("#%d: 0x%05x in %s.%s::%s (", i, inv->ip - hd->code, 
+                                               k->name_space, k->name, inv->method->name);
+               dump_stack (inv->stack_args, inv->stack_args + inv->method->signature->param_count);
+               g_print (")\n");
+       }
+}
+
 #define DEBUG_INTERP 1
 #if DEBUG_INTERP
 
@@ -718,7 +732,7 @@ db_match_method (gpointer data, gpointer user_data)
 #define THROW_EX(exception,ex_ip)      \
                do {\
                        frame->ip = (ex_ip);            \
-                       frame->ex = (exception);        \
+                       frame->ex = (MonoException*)(exception);        \
                        goto handle_exception;  \
                } while (0)
 
@@ -792,7 +806,7 @@ ves_exec_method (MonoInvocation *frame)
 
        if (frame->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
                if (!frame->method->addr) {
-                       frame->ex = get_exception_missing_method ();
+                       frame->ex = (MonoException*)get_exception_missing_method ();
                        DEBUG_LEAVE ();
                        return;
                }
@@ -808,7 +822,7 @@ ves_exec_method (MonoInvocation *frame)
 
        if (frame->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
                if (!frame->method->addr) {
-                       frame->ex = get_exception_missing_method ();
+                       frame->ex = (MonoException*)get_exception_missing_method ();
                        DEBUG_LEAVE ();
                        return;
                }
@@ -2116,10 +2130,9 @@ array_constructed:
                                oclass = o->klass;
 
                                if (c->flags & TYPE_ATTRIBUTE_INTERFACE) {
-                                       if ((c->interface_id < oclass->interface_count) &&
+                                       if ((c->interface_id <= oclass->max_interface_id) &&
                                            oclass->interface_offsets [c->interface_id])
                                                found = TRUE;
-                                       g_error ("fixme: dont know if this works");
                                } else {
                                        if ((oclass->baseval - c->baseval) <= c->diffval) {
                                                sp [-1].data.vt.klass = c;
@@ -2169,8 +2182,11 @@ array_constructed:
                        c = mono_class_get (image, token);
                        
                        o = sp [-1].data.p;
+                       if (!o)
+                               THROW_EX (get_exception_null_reference(), ip - 1);
 
-                       g_assert (o->klass->type_token == c->type_token);
+                       if (o->klass->type_token != c->type_token)
+                               THROW_EX (get_exception_invalid_cast (), ip - 1);
 
                        sp [-1].type = VAL_MP;
                        sp [-1].data.p = (char *)o + sizeof (MonoObject);
@@ -3156,6 +3172,8 @@ array_constructed:
                MonoInvocation *inv;
                MonoMethodHeader *hd;
                MonoExceptionClause *clause;
+               char *message;
+               MonoObject *ex_obj;
                
                for (inv = frame; inv; inv = inv->parent) {
                        hd = ((MonoMethodNormal*)inv->method)->header;
@@ -3164,7 +3182,7 @@ array_constructed:
                                clause = &hd->clauses [i];
                                if (clause->flags <= 1 && OFFSET_IN_CLAUSE (clause, ip_offset)) {
                                        if (!clause->flags) {
-                                                       if (mono_object_isinst (frame->ex, mono_class_get (inv->method->klass->image, clause->token_or_filter))) {
+                                                       if (mono_object_isinst ((MonoObject*)frame->ex, mono_class_get (inv->method->klass->image, clause->token_or_filter))) {
                                                                /* 
                                                                 * OK, we found an handler, now we need to execute the finally
                                                                 * and fault blocks before branching to the handler code.
@@ -3189,15 +3207,12 @@ array_constructed:
                /*
                 * If we get here, no handler was found: print a stack trace.
                 */
-               g_print ("Unhandled exception %s.%s.\n", frame->ex->klass->name_space, frame->ex->klass->name);
-               for (inv = frame, i = 0; inv; inv = inv->parent, ++i) {
-                       MonoClass *k = inv->method->klass;
-                       MonoMethodHeader *hd = ((MonoMethodNormal *)inv->method)->header;
-                       g_print ("#%d: 0x%05x in %s.%s::%s (", i, inv->ip - hd->code, 
-                                                       k->name_space, k->name, inv->method->name);
-                       dump_stack (inv->stack_args, inv->stack_args + inv->method->signature->param_count);
-                       g_print (")\n");
-               }
+               ex_obj = (MonoObject*)frame->ex;
+               message = frame->ex->message? mono_string_to_utf8 (frame->ex->message): NULL;
+               g_print ("Unhandled exception %s.%s %s.\n", ex_obj->klass->name_space, ex_obj->klass->name,
+                               message?message:"");
+               g_free (message);
+               dump_frame (frame);
                exit (1);
        }
        handle_finally:
@@ -3334,7 +3349,7 @@ typedef struct {
 
 static FieldDesc 
 typebuilder_fields[] = {
-       {"name", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, name)},
+       {"tname", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, name)},
        {"nspace", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, nspace)},
        {"parent", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, parent)},
        {"interfaces", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, interfaces)},
index d42c0e7483d1eee490358500a19363afb93ff8dc..f3f89fb45133169e2b0c7a4e3c7b04046e4a4656 100644 (file)
@@ -59,7 +59,7 @@ struct _MonoInvocation {
        stackval       *stack;
        /* exception info */
        const unsigned char  *ip;
-       MonoObject     *ex;
+       MonoException     *ex;
        MonoExceptionClause *ex_handler;
 };
 
index ebacd3c8a10a61d22e36cbb7f112221a169b5a81..dc734efb3909c4869c4b8d141c655c4a831c3cef 100644 (file)
@@ -1,4 +1,15 @@
 
+Wed Nov 14 19:26:06 CET 2001 Paolo Molaro <lupus@ximian.com>
+
+       * class.h, class.c: add a max_interface_id to MonoClass.
+       * icall.c: rename my_mono_new_object() to my_mono_new_mono_type()
+       since it's used to do that. Added mono_type_type_from_obj().
+       Make GetType() return NULL instead of segfaulting if the type was not
+       found. Handle simple arrays in assQualifiedName.
+       * object.h: add a struct to represent an Exception.
+       * reflection.c: output call convention in method signature.
+       Add code to support P/Invoke methods and fixed offsets for fields.
+
 Mon Nov 12 12:41:32 CET 2001 Paolo Molaro <lupus@ximian.com>
 
        * decimal.c, decimal.h: mono_double2decimal() get the sign bit from
index 69aa7907995a6abb4a2b0879845eb3247dc464aa..b4cc95329d53f0ed38061f0dce4c18aa1bfaac75 100644 (file)
@@ -224,7 +224,8 @@ mono_class_metadata_init (MonoClass *class)
                                max_iid = ic->interface_id;
                }
        }
-
+       
+       class->max_interface_id = max_iid;
        /* compute vtable offset for interfaces */
        class->interface_offsets = g_malloc (sizeof (gpointer) * (max_iid + 1));
 
@@ -292,6 +293,8 @@ mono_class_metadata_init (MonoClass *class)
                                MonoMethod *im = ic->methods [l];                                               
                                MonoClass *k1;
 
+                               g_assert (io <= class->vtable_size);
+
                                if (tmp_vtable [io + l] || vtable [io + l])
                                        continue;
                                        
index dbfc88d61d8edc4580bdd3e123c9f75b3a3b2e0a..c03716a9d7de8cb5429331d2ca120b0f87ad692f 100644 (file)
@@ -34,6 +34,7 @@ struct _MonoClass {
        const char *name_space;
        
        guint       interface_id; /* unique inderface id (for interfaces) */
+       guint       max_interface_id;
        gpointer   *interface_offsets;
        guint       interface_count;
        MonoClass **interfaces;
index ff91d19d16cd623d9c6f2b86f61c281b1cd7bbcd..d2f704bbc445fa96f68fd0a9cfef357fa2769e64 100644 (file)
@@ -143,15 +143,20 @@ ves_icall_app_get_cur_domain ()
 }
 
 static MonoReflectionType *
-my_mono_new_object (MonoClass *klass, gpointer data)
+my_mono_new_mono_type (MonoType *type)
 {
-       MonoReflectionType *res = (MonoReflectionType *)mono_object_new (klass);
-
-       res->type = (MonoType *)data;
+       MonoReflectionType *res = (MonoReflectionType *)mono_object_new (mono_defaults.monotype_class);
 
+       res->type = type;
        return res;
 }
 
+static void
+mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
+{
+       mtype->type = &obj->klass->byval_arg;
+}
+
 static gint32
 ves_icall_get_data_chunk (MonoReflectionAssemblyBuilder *assb, gint32 type, MonoArray *buf)
 {
@@ -182,9 +187,9 @@ ves_icall_type_from_name (MonoObject *name)
 }
 
 static MonoReflectionType*
-ves_icall_type_from_handle (gpointer handle)
+ves_icall_type_from_handle (MonoType *handle)
 {
-       return my_mono_new_object (mono_defaults.monotype_class, handle);
+       return my_mono_new_mono_type (handle);
 }
 
 static gpointer
@@ -242,13 +247,14 @@ ves_icall_System_Reflection_Assembly_GetType (MonoReflectionAssembly *assembly,
        g_strfreev (parts);
 
        klass = mono_class_from_name (assembly->assembly->image, namespace, name);
-       if (!klass->metadata_inited)
-               mono_class_metadata_init (klass);
-
        g_free (name);
        g_free (namespace);
+       if (!klass)
+               return NULL;
+       if (!klass->metadata_inited)
+               mono_class_metadata_init (klass);
 
-       return my_mono_new_object (mono_defaults.monotype_class, &klass->byval_arg);
+       return my_mono_new_mono_type (&klass->byval_arg);
 }
 
 static MonoString *
@@ -256,18 +262,25 @@ ves_icall_System_MonoType_assQualifiedName (MonoReflectionType *object)
 {
        /* FIXME : real rules are more complicated (internal classes,
          reference types, array types, etc. */
-
-
        MonoString *res;
        gchar *fullname;
        MonoClass *klass;
-
-       klass = object->type->data.klass;
+       char *append = NULL;
+
+       switch (object->type->type) {
+       case MONO_TYPE_SZARRAY:
+               klass = object->type->data.type->data.klass;
+               append = "[]";
+               break;
+       default:
+               klass = object->type->data.klass;
+               break;
+       }
 
        fullname = g_strconcat (klass->name_space, ".",
                                   klass->name, ",",
-                                  klass->image->assembly_name);
-  res = mono_string_new (fullname);
+                                  klass->image->assembly_name, append, NULL);
+       res = mono_string_new (fullname);
        g_free (fullname);
 
        return res;
@@ -385,7 +398,11 @@ static gpointer icall_map [] = {
        "System.Reflection.Assembly::LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom,
        "System.Reflection.Assembly::GetType", ves_icall_System_Reflection_Assembly_GetType,
 
+       /*
+        * System.MonoType.
+        */
        "System.MonoType::assQualifiedName", ves_icall_System_MonoType_assQualifiedName,
+       "System.MonoType::type_from_obj", mono_type_type_from_obj,
 
        "System.PAL.OpSys::GetCurrentDirectory", ves_icall_System_PAL_GetCurrentDirectory,
        /*
index c81d66508bebd46980bcd40fdc09623d56195574..0c9d54d804e60bdec21c2c497207ba1cc42ec37e 100644 (file)
@@ -101,6 +101,7 @@ mono_object_clone (MonoObject *obj)
        
        size = obj->klass->instance_size;
        o = mono_object_allocate (size);
+       /* FIXME: handle arrays... */
        
        memcpy (o, obj, size);
 
@@ -134,6 +135,8 @@ mono_array_new_full (MonoClass *array_class, guint32 *lengths, guint32 *lower_bo
         * they need to be kept in sync.
         */
        o = mono_object_allocate (sizeof (MonoArray) + byte_len);
+       if (!o)
+               G_BREAKPOINT ();
        o->klass = array_class;
        mono_threads_synchronisation_init (&o->synchronisation);
 
index 4e721b4f3033925f39bf38216d4175c8e7130847..795210330af3782afaf24add925a46f160db191a 100644 (file)
@@ -27,6 +27,12 @@ typedef struct {
        gint32 length;
 } MonoString;
 
+typedef struct {
+       MonoObject object;
+       MonoObject *inner_ex;
+       MonoString *message;
+} MonoException;
+
 #define mono_array_length(array) ((array)->bounds->length)
 #define mono_array_addr(array,type,index) ( ((char*)(array)->vector) + sizeof (type) * (index) )
 #define mono_array_addr_with_size(array,size,index) ( ((char*)(array)->vector) + (size) * (index) )
index f05c4c005b430c5e572b63245fa17583a9c1f5a1..ee3a0d6b3576c55526bdb281b729e1322e9c8129 100644 (file)
@@ -194,12 +194,12 @@ method_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionMethodBuil
        char *b = blob_size;
        
        p = buf = g_malloc (size);
-       *p = 0;
+       /* LAMESPEC: all the call conv spec is foobared */
+       *p = mb->call_conv & 0x60; /* has-this, explicit-this */
+       if (mb->call_conv & 2)
+               *p |= 0x5; /* vararg */
        if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
                *p |= 0x20; /* hasthis */
-       /* 
-        * FIXME: set also call convention and explict_this if needed.
-        */
        p++;
        mono_metadata_encode_value (nparams, p, &p);
        encode_type (mb->rtype->type, p, &p);
@@ -315,6 +315,25 @@ fat_header:
        return assembly->text_rva + idx + CLI_H_SIZE;
 }
 
+static guint32
+find_index_in_table (MonoDynamicAssembly *assembly, int table_idx, int col, guint32 index)
+{
+       int i;
+       MonoDynamicTable *table;
+       guint32 *values;
+       
+       table = &assembly->tables [table_idx];
+
+       g_assert (col < table->columns);
+
+       values = table->values + table->columns;
+       for (i = 1; i <= table->rows; ++i) {
+               if (values [col] == index)
+                       return i;
+       }
+       return 0;
+}
+
 static void
 mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicAssembly *assembly)
 {
@@ -333,6 +352,29 @@ mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicAssembly
        values [MONO_METHOD_SIGNATURE] = method_encode_signature (assembly, mb);
        values [MONO_METHOD_PARAMLIST] = 0; /* FIXME: add support later */
        values [MONO_METHOD_RVA] = method_encode_code (assembly, mb);
+
+       if (mb->dll) { /* It's a P/Invoke method */
+               guint32 moduleref;
+               table = &assembly->tables [MONO_TABLE_IMPLMAP];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_IMPLMAP_SIZE;
+               values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | mb->charset;
+               values [MONO_IMPLMAP_MEMBER] = (mb->table_idx << 1) | 1; /* memberforwarded: method */
+               name = mono_string_to_utf8 (mb->dllentry);
+               values [MONO_IMPLMAP_NAME] = string_heap_insert (&assembly->sheap, name);
+               g_free (name);
+               name = mono_string_to_utf8 (mb->dll);
+               moduleref = string_heap_insert (&assembly->sheap, name);
+               g_free (name);
+               if (!(values [MONO_IMPLMAP_SCOPE] = find_index_in_table (assembly, MONO_TABLE_MODULEREF, MONO_MODULEREF_NAME, moduleref))) {
+                       table = &assembly->tables [MONO_TABLE_MODULEREF];
+                       table->rows ++;
+                       alloc_table (table, table->rows);
+                       table->values [table->rows * MONO_MODULEREF_SIZE + MONO_MODULEREF_NAME] = moduleref;
+                       values [MONO_IMPLMAP_SCOPE] = table->rows;
+               }
+       }
 }
 
 static guint32
@@ -372,6 +414,15 @@ mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicAssembly *
        g_free (name);
        values [MONO_FIELD_FLAGS] = fb->attrs;
        values [MONO_FIELD_SIGNATURE] = field_encode_signature (assembly, fb);
+
+       if (fb->offset != -1) {
+               table = &assembly->tables [MONO_TABLE_FIELDLAYOUT];
+               table->rows ++;
+               alloc_table (table, table->rows);
+               values = table->values + table->rows * MONO_FIELD_LAYOUT_SIZE;
+               values [MONO_FIELD_LAYOUT_FIELD] = fb->table_idx;
+               values [MONO_FIELD_LAYOUT_OFFSET] = fb->offset;
+       }
 }
 
 static guint32
@@ -457,18 +508,20 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicAsse
 }
 
 static guint32
-mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoClass *klass)
+mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type)
 {
        MonoDynamicTable *table;
        guint32 *values;
        guint32 token;
+       MonoClass *klass;
 
        if (!assembly->typeref)
                assembly->typeref = g_hash_table_new (g_direct_hash, g_direct_equal);
        
-       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, klass));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
        if (token)
                return token;
+       klass = type->data.klass;
        if (klass->image != mono_defaults.corlib)
                g_error ("multiple assemblyref not yet supported");
 
@@ -479,7 +532,7 @@ mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoClass *klass)
        values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
        values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
        token = 1 | (table->next_idx << 2); /* typeref */
-       g_hash_table_insert (assembly->typeref, klass, GUINT_TO_POINTER(token));
+       g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
        table->next_idx ++;
        return token;
 }
@@ -496,8 +549,7 @@ mono_image_get_type_info (MonoReflectionTypeBuilder *tb, MonoDynamicAssembly *as
        tb->table_idx = table->next_idx ++;
        values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
        values [MONO_TYPEDEF_FLAGS] = tb->attrs;
-       /* FIXME: use tb->base later */
-       values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, mono_defaults.object_class);
+       values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, tb->parent->type);
        n = mono_string_to_utf8 (tb->name);
        values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, n);
        g_free (n);
index b57dceb51d8907c8e3ecaca6965314b103c3a55d..bf129e6cbdd2558b8412226c9c375cd33a8aa75a 100644 (file)
@@ -67,6 +67,12 @@ typedef struct {
        MonoArray *code;
        MonoReflectionILGen *ilgen;
        MonoObject *type;
+       MonoArray *pinfo;
+       MonoString *dll;
+       MonoString *dllentry;
+       guint32 charset;
+       guint32 native_cc;
+       guint32 call_conv;
 } MonoReflectionMethodBuilder;
 
 typedef struct {
@@ -119,19 +125,6 @@ typedef struct {
        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;
@@ -147,6 +140,20 @@ typedef struct {
        guint32    table_idx;
 } MonoReflectionModuleBuilder;
 
+typedef struct {
+       MonoReflectionType type;
+       MonoString *name;
+       MonoString *nspace;
+       MonoReflectionType *parent;
+       MonoArray *interfaces;
+       MonoArray *methods;
+       MonoArray *properties;
+       MonoArray *fields;
+       guint32 attrs;
+       guint32 table_idx;
+       MonoReflectionModuleBuilder *module;
+} MonoReflectionTypeBuilder;
+
 int           mono_image_get_header (MonoReflectionAssemblyBuilder *assembly, char *buffer, int maxsize);
 
 #endif /* __METADATA_REFLECTION_H__ */
index 1dddb7bd25d277084a212b366a49307891eac007..1159d2cb9079bc5fd78f984913af7e19efa6262b 100644 (file)
@@ -8,9 +8,13 @@ BENCHSRC=fib.cs random.cs nested-loops.cs
 
 TESTSRC=                       \
        array-init.cs           \
+       arraylist.cs            \
        field-layout.cs         \
+       hash-table.cs           \
        test-ops.cs             \
        obj.cs                  \
+       string.cs               \
+       stringbuilder.cs        \
        switch.cs               \
        outparm.cs              \
        delegate.cs             \
diff --git a/mono/tests/arraylist.cs b/mono/tests/arraylist.cs
new file mode 100644 (file)
index 0000000..aaf8197
--- /dev/null
@@ -0,0 +1,19 @@
+using System.Collections;
+
+namespace Test {
+       public class Test {
+               public static int Main() {
+                       ArrayList a = new ArrayList (10);
+                       int i = 0;
+                       a.Add (0);
+                       a.Add (1);
+                       a.Add (2);
+                       a.Add (3);
+                       foreach (int elem in a) {
+                               if (elem != i++)
+                                       return i;
+                       }
+                       return 0;
+               }
+       }
+}
diff --git a/mono/tests/hash-table.cs b/mono/tests/hash-table.cs
new file mode 100644 (file)
index 0000000..6043aa8
--- /dev/null
@@ -0,0 +1,27 @@
+using System.Collections;
+
+namespace Test {
+       public class Test {
+               public static int Main () {
+                       string[] names = {
+                               "one", "two", "three", "four"
+                       };
+                       Hashtable hash = new Hashtable ();
+
+                       for (int i=0; i < names.Length; ++i) {
+                               hash.Add (names [i], i);
+                       }
+                       if ((int)hash ["one"] != 0)
+                               return 1;
+                       if ((int)hash ["two"] != 1)
+                               return 2;
+                       if ((int)hash ["three"] != 2)
+                               return 3;
+                       if ((int)hash ["four"] != 3)
+                               return 4;
+                       if (hash.Contains("urka"))
+                               return 5;
+                       return 0;
+               }
+       }
+}
diff --git a/mono/tests/string.cs b/mono/tests/string.cs
new file mode 100755 (executable)
index 0000000..f2e899b
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+
+public class TestString {
+
+       public static int Main() {
+               string a = "ddd";
+               string b = "ddd";
+               string c = "ddda";
+               if (a != b)
+                       return 1;
+               if (c != String.Concat(b , "a"))        
+                       return 2;
+               if (!System.Object.ReferenceEquals(a, b))
+                       return 3;
+               if (System.Object.ReferenceEquals(c, String.Concat(b, "a")))
+                       return 4;
+               return 0;
+       }
+}
diff --git a/mono/tests/stringbuilder.cs b/mono/tests/stringbuilder.cs
new file mode 100644 (file)
index 0000000..c125a50
--- /dev/null
@@ -0,0 +1,25 @@
+using System.Text;
+
+namespace test {
+       public class Test {
+               public static int Main() {
+                       StringBuilder b = new StringBuilder ();
+                       /*b.Append ('A');
+                       b.Append ('b');
+                       b.Append ('r');*/
+                       b.Append ("Abr");
+                       if (b.ToString() != "Abr") {
+                               System.Console.WriteLine ("Got: " + b.ToString());
+                               return 1;
+                       }
+                       b.Append ('a');
+                       b.Append ("cadabra");
+                       if (b.ToString() != "Abracadabra") {
+                               System.Console.WriteLine ("Got: " + b.ToString());
+                               return 2;
+                       }
+                       return 0;
+                       
+               }
+       }
+}