X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmethod-builder.c;h=ccff8c91a0c1573cf2f0d38174f62fb5ae5a252b;hb=56b3c007f428d93b7f230d58744393ad69e4ca63;hp=3b04c246494af2d77121e5cbbb55fbade2bb2d3b;hpb=3e947106f2236c6c5a2c24510269c62d11d11426;p=mono.git diff --git a/mono/metadata/method-builder.c b/mono/metadata/method-builder.c index 3b04c246494..ccff8c91a0c 100644 --- a/mono/metadata/method-builder.c +++ b/mono/metadata/method-builder.c @@ -1,11 +1,13 @@ -/* - * method-builder.c: Functions for creating IL methods at runtime. +/** + * \file + * Functions for creating IL methods at runtime. * * Author: * Paolo Molaro (lupus@ximian.com) * * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" @@ -65,7 +67,7 @@ mono_mb_new_base (MonoClass *klass, MonoWrapperType type) m->inline_info = 1; m->wrapper_type = type; -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN mb->code_size = 40; mb->code = (unsigned char *)g_malloc (mb->code_size); mb->init_locals = TRUE; @@ -85,6 +87,9 @@ mono_mb_new_no_dup_name (MonoClass *klass, const char *name, MonoWrapperType typ return mb; } +/** + * mono_mb_new: + */ MonoMethodBuilder * mono_mb_new (MonoClass *klass, const char *name, MonoWrapperType type) { @@ -93,10 +98,19 @@ mono_mb_new (MonoClass *klass, const char *name, MonoWrapperType type) return mb; } +/** + * mono_mb_free: + */ void mono_mb_free (MonoMethodBuilder *mb) { -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN + GList *l; + + for (l = mb->locals_list; l; l = l->next) { + /* Allocated in mono_mb_add_local () */ + g_free (l->data); + } g_list_free (mb->locals_list); if (!mb->dynamic) { g_free (mb->method); @@ -114,15 +128,13 @@ mono_mb_free (MonoMethodBuilder *mb) /** * mono_mb_create_method: - * - * Create a MonoMethod from this method builder. - * Returns: the newly created method. - * + * Create a \c MonoMethod from this method builder. + * \returns the newly created method. */ MonoMethod * mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack) { -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN MonoMethodHeader *header; #endif MonoMethodWrapper *mw; @@ -135,7 +147,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in image = mb->method->klass->image; -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN if (mb->dynamic) { method = mb->method; mw = (MonoMethodWrapper*)method; @@ -149,7 +161,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in header->code = mb->code; for (i = 0, l = mb->locals_list; l; l = l->next, i++) { - header->locals [i] = mono_metadata_type_dup (NULL, (MonoType*)l->data); + header->locals [i] = (MonoType*)l->data; } } else #endif @@ -165,7 +177,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in else method->name = mono_image_strdup (image, mb->name); -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN mw->header = header = (MonoMethodHeader *) mono_image_alloc0 (image, MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *)); @@ -173,16 +185,22 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in memcpy ((char*)header->code, mb->code, mb->pos); for (i = 0, l = mb->locals_list; l; l = l->next, i++) { - header->locals [i] = mono_metadata_type_dup (NULL, (MonoType*)l->data); + header->locals [i] = (MonoType*)l->data; } #endif } +#ifdef ENABLE_ILGEN + /* Free the locals list so mono_mb_free () doesn't free the types twice */ + g_list_free (mb->locals_list); + mb->locals_list = NULL; +#endif + method->signature = signature; if (!signature->hasthis) method->flags |= METHOD_ATTRIBUTE_STATIC; -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN if (max_stack < 8) max_stack = 8; @@ -218,7 +236,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in mw->method_data = data; } -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN /*{ static int total_code = 0; static int total_alloc = 0; @@ -248,6 +266,9 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in return method; } +/** + * mono_mb_add_data: + */ guint32 mono_mb_add_data (MonoMethodBuilder *mb, gpointer data) { @@ -263,23 +284,36 @@ mono_mb_add_data (MonoMethodBuilder *mb, gpointer data) return g_list_length ((GList *)mw->method_data); } -#ifndef DISABLE_JIT +#ifdef ENABLE_ILGEN +/** + * mono_mb_add_local: + */ int mono_mb_add_local (MonoMethodBuilder *mb, MonoType *type) { int res; + MonoType *t; + + /* + * Have to make a copy early since type might be sig->ret, + * which is transient, see mono_metadata_signature_dup_internal_with_padding (). + */ + t = mono_metadata_type_dup (NULL, type); g_assert (mb != NULL); g_assert (type != NULL); res = mb->locals; - mb->locals_list = g_list_append (mb->locals_list, type); + mb->locals_list = g_list_append (mb->locals_list, t); mb->locals++; return res; } +/** + * mono_mb_patch_addr: + */ void mono_mb_patch_addr (MonoMethodBuilder *mb, int pos, int value) { @@ -289,12 +323,18 @@ mono_mb_patch_addr (MonoMethodBuilder *mb, int pos, int value) mb->code [pos + 3] = (value >> 24) & 0xff; } +/** + * mono_mb_patch_addr_s: + */ void mono_mb_patch_addr_s (MonoMethodBuilder *mb, int pos, gint8 value) { *((gint8 *)(&mb->code [pos])) = value; } +/** + * mono_mb_emit_byte: + */ void mono_mb_emit_byte (MonoMethodBuilder *mb, guint8 op) { @@ -306,6 +346,9 @@ mono_mb_emit_byte (MonoMethodBuilder *mb, guint8 op) mb->code [mb->pos++] = op; } +/** + * mono_mb_emit_ldflda: + */ void mono_mb_emit_ldflda (MonoMethodBuilder *mb, gint32 offset) { @@ -318,6 +361,9 @@ mono_mb_emit_ldflda (MonoMethodBuilder *mb, gint32 offset) } } +/** + * mono_mb_emit_i4: + */ void mono_mb_emit_i4 (MonoMethodBuilder *mb, gint32 data) { @@ -343,6 +389,9 @@ mono_mb_emit_i8 (MonoMethodBuilder *mb, gint64 data) mb->pos += 8; } +/** + * mono_mb_emit_i2: + */ void mono_mb_emit_i2 (MonoMethodBuilder *mb, gint16 data) { @@ -363,12 +412,18 @@ mono_mb_emit_op (MonoMethodBuilder *mb, guint8 op, gpointer data) mono_mb_emit_i4 (mb, mono_mb_add_data (mb, data)); } +/** + * mono_mb_emit_ldstr: + */ void mono_mb_emit_ldstr (MonoMethodBuilder *mb, char *str) { mono_mb_emit_op (mb, CEE_LDSTR, str); } +/** + * mono_mb_emit_ldarg: + */ void mono_mb_emit_ldarg (MonoMethodBuilder *mb, guint argnum) { @@ -384,6 +439,9 @@ mono_mb_emit_ldarg (MonoMethodBuilder *mb, guint argnum) } } +/** + * mono_mb_emit_ldarg_addr: + */ void mono_mb_emit_ldarg_addr (MonoMethodBuilder *mb, guint argnum) { @@ -397,6 +455,9 @@ mono_mb_emit_ldarg_addr (MonoMethodBuilder *mb, guint argnum) } } +/** + * mono_mb_emit_ldloc_addr: + */ void mono_mb_emit_ldloc_addr (MonoMethodBuilder *mb, guint locnum) { @@ -410,6 +471,9 @@ mono_mb_emit_ldloc_addr (MonoMethodBuilder *mb, guint locnum) } } +/** + * mono_mb_emit_ldloc: + */ void mono_mb_emit_ldloc (MonoMethodBuilder *mb, guint num) { @@ -425,6 +489,9 @@ mono_mb_emit_ldloc (MonoMethodBuilder *mb, guint num) } } +/** + * mono_mb_emit_stloc: + */ void mono_mb_emit_stloc (MonoMethodBuilder *mb, guint num) { @@ -440,6 +507,9 @@ mono_mb_emit_stloc (MonoMethodBuilder *mb, guint num) } } +/** + * mono_mb_emit_icon: + */ void mono_mb_emit_icon (MonoMethodBuilder *mb, gint32 value) { @@ -473,6 +543,9 @@ mono_mb_get_pos (MonoMethodBuilder *mb) return mb->pos; } +/** + * mono_mb_emit_branch: + */ guint32 mono_mb_emit_branch (MonoMethodBuilder *mb, guint8 op) { @@ -526,12 +599,18 @@ mono_mb_emit_calli (MonoMethodBuilder *mb, MonoMethodSignature *sig) mono_mb_emit_op (mb, CEE_CALLI, sig); } +/** + * mono_mb_emit_managed_call: + */ void mono_mb_emit_managed_call (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *opt_sig) { mono_mb_emit_op (mb, CEE_CALL, method); } +/** + * mono_mb_emit_native_call: + */ void mono_mb_emit_native_call (MonoMethodBuilder *mb, MonoMethodSignature *sig, gpointer func) { @@ -565,12 +644,32 @@ mono_mb_emit_exception_full (MonoMethodBuilder *mb, const char *exc_nspace, cons mono_mb_emit_byte (mb, CEE_THROW); } +/** + * mono_mb_emit_exception: + */ void mono_mb_emit_exception (MonoMethodBuilder *mb, const char *exc_name, const char *msg) { mono_mb_emit_exception_full (mb, "System", exc_name, msg); } +/** + * mono_mb_emit_exception_for_error: + */ +void +mono_mb_emit_exception_for_error (MonoMethodBuilder *mb, MonoError *error) +{ + /* + * If at some point there is need to support other types of errors, + * the behaviour should conform with mono_error_prepare_exception(). + */ + g_assert (mono_error_get_error_code (error) == MONO_ERROR_GENERIC && "Unsupported error code."); + mono_mb_emit_exception_full (mb, "System", mono_error_get_exception_name (error), mono_error_get_message (error)); +} + +/** + * mono_mb_emit_add_to_local: + */ void mono_mb_emit_add_to_local (MonoMethodBuilder *mb, guint16 local, gint32 incr) {