New tests.
[mono.git] / mono / metadata / method-builder.c
index 08f43f490c6fda176faebf1cefd62f6058afd1eb..247c749bdedad87bad1932fc978dea8bb7f81eb9 100644 (file)
@@ -4,27 +4,19 @@
  * Author:
  *   Paolo Molaro (lupus@ximian.com)
  *
- * (C) 2002 Ximian, Inc.  http://www.ximian.com
- *
+ * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com)
+ * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
  */
 
 #include "config.h"
-#include "object.h"
 #include "loader.h"
-#include "metadata/marshal.h"
-#include "metadata/tabledefs.h"
-#include "metadata/exception.h"
-#include "metadata/appdomain.h"
+#include "mono/metadata/method-builder.h"
+#include "mono/metadata/tabledefs.h"
+#include "mono/metadata/exception.h"
+#include "mono/metadata/appdomain.h"
 #include "mono/metadata/debug-helpers.h"
-#include "mono/metadata/threadpool.h"
-#include "mono/metadata/threads.h"
-#include "mono/metadata/monitor.h"
 #include "mono/metadata/metadata-internals.h"
 #include "mono/metadata/domain-internals.h"
-#include "mono/metadata/gc-internal.h"
-#include "mono/metadata/threads-types.h"
-#include "mono/metadata/string-icalls.h"
-#include <mono/os/gc_wrapper.h>
 #include <string.h>
 #include <errno.h>
 
@@ -39,17 +31,6 @@ enum {
 };
 #undef OPDEF
 
-struct _MonoMethodBuilder {
-       MonoMethod *method;
-       char *name;
-       GList *locals_list;
-       int locals;
-       gboolean dynamic;
-       gboolean no_dup_name;
-       guint32 code_size, pos;
-       unsigned char *code;
-};
-
 #ifdef DEBUG_RUNTIME_CODE
 static char*
 indenter (MonoDisHelper *dh, MonoMethod *method, guint32 ip_offset)
@@ -85,7 +66,9 @@ mono_mb_new_base (MonoClass *klass, MonoWrapperType type)
 
        mb->code_size = 40;
        mb->code = g_malloc (mb->code_size);
-       
+       /* placeholder for the wrapper always at index 1 */
+       mono_mb_add_data (mb, NULL);
+
        return mb;
 }
 
@@ -147,24 +130,25 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
 {
        MonoMethodHeader *header;
        MonoMethodWrapper *mw;
-       MonoMemPool *mp;
+       MonoImage *image;
        MonoMethod *method;
        GList *l;
        int i;
 
        g_assert (mb != NULL);
 
-       mp = mb->method->klass->image->mempool;
+       image = mb->method->klass->image;
 
-       mono_loader_lock ();
+       mono_loader_lock (); /*FIXME I think this lock can go.*/
        if (mb->dynamic) {
                method = mb->method;
+               mw = (MonoMethodWrapper*)method;
 
                method->name = mb->name;
                method->dynamic = TRUE;
 
-               ((MonoMethodNormal *)method)->header = header = (MonoMethodHeader *) 
-                       g_malloc0 (sizeof (MonoMethodHeader) + mb->locals * sizeof (MonoType *));
+               mw->header = header = (MonoMethodHeader *) 
+                       g_malloc0 (MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *));
 
                header->code = mb->code;
 
@@ -174,18 +158,19 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
        } else {
                /* Realloc the method info into a mempool */
 
-               method = mono_mempool_alloc0 (mp, sizeof (MonoMethodWrapper));
+               method = mono_image_alloc0 (image, sizeof (MonoMethodWrapper));
                memcpy (method, mb->method, sizeof (MonoMethodWrapper));
+               mw = (MonoMethodWrapper*) method;
 
                if (mb->no_dup_name)
                        method->name = mb->name;
                else
-                       method->name = mono_mempool_strdup (mp, mb->name);
+                       method->name = mono_image_strdup (image, mb->name);
 
-               ((MonoMethodNormal *)method)->header = header = (MonoMethodHeader *) 
-                       mono_mempool_alloc0 (mp, sizeof (MonoMethodHeader) + mb->locals * sizeof (MonoType *));
+               mw->header = header = (MonoMethodHeader *) 
+                       mono_image_alloc0 (image, MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *));
 
-               header->code = mono_mempool_alloc (mp, mb->pos);
+               header->code = mono_image_alloc (image, mb->pos);
                memcpy ((char*)header->code, mb->code, mb->pos);
 
                for (i = 0, l = mb->locals_list; l; l = l->next, i++) {
@@ -204,7 +189,11 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
        header->num_locals = mb->locals;
        header->init_locals = TRUE;
 
-       mw = (MonoMethodWrapper*) mb->method;
+       header->num_clauses = mb->num_clauses;
+       header->clauses = mb->clauses;
+
+       method->skip_visibility = mb->skip_visibility;
+
        i = g_list_length (mw->method_data);
        if (i) {
                GList *tmp;
@@ -213,7 +202,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
                if (method->dynamic)
                        data = g_malloc (sizeof (gpointer) * (i + 1));
                else
-                       data = mono_mempool_alloc (mp, sizeof (gpointer) * (i + 1));
+                       data = mono_image_alloc (image, sizeof (gpointer) * (i + 1));
                /* store the size in the first element */
                data [0] = GUINT_TO_POINTER (i);
                i = 1;
@@ -222,7 +211,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
                }
                g_list_free (l);
 
-               ((MonoMethodWrapper*)method)->method_data = data;
+               mw->method_data = data;
        }
        /*{
                static int total_code = 0;
@@ -423,6 +412,12 @@ mono_mb_get_label (MonoMethodBuilder *mb)
        return mb->pos;
 }
 
+int
+mono_mb_get_pos (MonoMethodBuilder *mb)
+{
+       return mb->pos;
+}
+
 guint32
 mono_mb_emit_branch (MonoMethodBuilder *mb, guint8 op)
 {
@@ -444,6 +439,13 @@ mono_mb_emit_short_branch (MonoMethodBuilder *mb, guint8 op)
        return res;
 }
 
+void
+mono_mb_emit_branch_label (MonoMethodBuilder *mb, guint8 op, guint32 label)
+{
+       mono_mb_emit_byte (mb, op);
+       mono_mb_emit_i4 (mb, label - (mb->pos + 4));
+}
+
 void
 mono_mb_patch_branch (MonoMethodBuilder *mb, guint32 pos)
 {
@@ -478,12 +480,8 @@ mono_mb_emit_managed_call (MonoMethodBuilder *mb, MonoMethod *method, MonoMethod
 void
 mono_mb_emit_native_call (MonoMethodBuilder *mb, MonoMethodSignature *sig, gpointer func)
 {
-       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
-       mono_mb_emit_byte (mb, CEE_MONO_SAVE_LMF);
        mono_mb_emit_ptr (mb, func);
        mono_mb_emit_calli (mb, sig);
-       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
-       mono_mb_emit_byte (mb, CEE_MONO_RESTORE_LMF);
 }
 
 void
@@ -526,3 +524,10 @@ mono_mb_emit_add_to_local (MonoMethodBuilder *mb, guint16 local, gint32 incr)
        mono_mb_emit_byte (mb, CEE_ADD);
        mono_mb_emit_stloc (mb, local); 
 }
+
+void
+mono_mb_set_clauses (MonoMethodBuilder *mb, int num_clauses, MonoExceptionClause *clauses)
+{
+       mb->num_clauses = num_clauses;
+       mb->clauses = clauses;
+}