X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmethod-builder.c;h=09e6027f4a0d53b7f5c2d50eed49cc7c59b1479b;hb=5c11fe647563fa051f73d3571da839dfccd26f8e;hp=247c749bdedad87bad1932fc978dea8bb7f81eb9;hpb=b3f3ef56c81f6589870659ca6b7db13143ea4d87;p=mono.git diff --git a/mono/metadata/method-builder.c b/mono/metadata/method-builder.c index 247c749bded..09e6027f4a0 100644 --- a/mono/metadata/method-builder.c +++ b/mono/metadata/method-builder.c @@ -6,10 +6,12 @@ * * 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" #include "loader.h" +#include "mono/metadata/abi-details.h" #include "mono/metadata/method-builder.h" #include "mono/metadata/tabledefs.h" #include "mono/metadata/exception.h" @@ -64,8 +66,11 @@ mono_mb_new_base (MonoClass *klass, MonoWrapperType type) m->inline_info = 1; m->wrapper_type = type; +#ifndef DISABLE_JIT mb->code_size = 40; - mb->code = g_malloc (mb->code_size); + mb->code = (unsigned char *)g_malloc (mb->code_size); + mb->init_locals = TRUE; +#endif /* placeholder for the wrapper always at index 1 */ mono_mb_add_data (mb, NULL); @@ -92,6 +97,13 @@ mono_mb_new (MonoClass *klass, const char *name, MonoWrapperType type) void mono_mb_free (MonoMethodBuilder *mb) { +#ifndef DISABLE_JIT + 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); @@ -99,36 +111,27 @@ mono_mb_free (MonoMethodBuilder *mb) g_free (mb->name); g_free (mb->code); } +#else + g_free (mb->method); + if (!mb->no_dup_name) + g_free (mb->name); +#endif g_free (mb); } -int -mono_mb_add_local (MonoMethodBuilder *mb, MonoType *type) -{ - int res; - - g_assert (mb != NULL); - g_assert (type != NULL); - - res = mb->locals; - mb->locals_list = g_list_append (mb->locals_list, type); - mb->locals++; - - return res; -} - /** * mono_mb_create_method: * * Create a MonoMethod from this method builder. * Returns: the newly created method. * - * LOCKING: Takes the loader lock. */ MonoMethod * mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack) { +#ifndef DISABLE_JIT MonoMethodHeader *header; +#endif MonoMethodWrapper *mw; MonoImage *image; MonoMethod *method; @@ -139,7 +142,7 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in image = mb->method->klass->image; - mono_loader_lock (); /*FIXME I think this lock can go.*/ +#ifndef DISABLE_JIT if (mb->dynamic) { method = mb->method; mw = (MonoMethodWrapper*)method; @@ -153,12 +156,14 @@ 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 { + } else +#endif + { /* Realloc the method info into a mempool */ - method = mono_image_alloc0 (image, sizeof (MonoMethodWrapper)); + method = (MonoMethod *)mono_image_alloc0 (image, sizeof (MonoMethodWrapper)); memcpy (method, mb->method, sizeof (MonoMethodWrapper)); mw = (MonoMethodWrapper*) method; @@ -167,42 +172,54 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in else method->name = mono_image_strdup (image, mb->name); +#ifndef DISABLE_JIT mw->header = header = (MonoMethodHeader *) mono_image_alloc0 (image, MONO_SIZEOF_METHOD_HEADER + mb->locals * sizeof (MonoType *)); - header->code = mono_image_alloc (image, mb->pos); + header->code = (const unsigned char *)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++) { - header->locals [i] = (MonoType *)l->data; + header->locals [i] = (MonoType*)l->data; } +#endif } +#ifndef DISABLE_JIT + /* 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 if (max_stack < 8) max_stack = 8; header->max_stack = max_stack; - method->signature = signature; - header->code_size = mb->pos; header->num_locals = mb->locals; - header->init_locals = TRUE; + header->init_locals = mb->init_locals; header->num_clauses = mb->num_clauses; header->clauses = mb->clauses; method->skip_visibility = mb->skip_visibility; +#endif - i = g_list_length (mw->method_data); + i = g_list_length ((GList *)mw->method_data); if (i) { GList *tmp; void **data; - l = g_list_reverse (mw->method_data); - if (method->dynamic) - data = g_malloc (sizeof (gpointer) * (i + 1)); + l = g_list_reverse ((GList *)mw->method_data); + if (method_is_dynamic (method)) + data = (void **)g_malloc (sizeof (gpointer) * (i + 1)); else - data = mono_image_alloc (image, sizeof (gpointer) * (i + 1)); + data = (void **)mono_image_alloc (image, sizeof (gpointer) * (i + 1)); /* store the size in the first element */ data [0] = GUINT_TO_POINTER (i); i = 1; @@ -213,6 +230,8 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in mw->method_data = data; } + +#ifndef DISABLE_JIT /*{ static int total_code = 0; static int total_alloc = 0; @@ -226,7 +245,19 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in printf ("%s\n", mono_disasm_code (&marshal_dh, method, mb->code, mb->code + mb->pos)); #endif - mono_loader_unlock (); + if (mb->param_names) { + char **param_names = (char **)mono_image_alloc0 (image, signature->param_count * sizeof (gpointer)); + for (i = 0; i < signature->param_count; ++i) + param_names [i] = mono_image_strdup (image, mb->param_names [i]); + + mono_image_lock (image); + if (!image->wrapper_param_names) + image->wrapper_param_names = g_hash_table_new (NULL, NULL); + g_hash_table_insert (image->wrapper_param_names, method, param_names); + mono_image_unlock (image); + } +#endif + return method; } @@ -240,9 +271,33 @@ mono_mb_add_data (MonoMethodBuilder *mb, gpointer data) mw = (MonoMethodWrapper *)mb->method; /* one O(n) is enough */ - mw->method_data = g_list_prepend (mw->method_data, data); + mw->method_data = g_list_prepend ((GList *)mw->method_data, data); - return g_list_length (mw->method_data); + return g_list_length ((GList *)mw->method_data); +} + +#ifndef DISABLE_JIT + +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, t); + mb->locals++; + + return res; } void @@ -265,7 +320,7 @@ mono_mb_emit_byte (MonoMethodBuilder *mb, guint8 op) { if (mb->pos >= mb->code_size) { mb->code_size += mb->code_size >> 1; - mb->code = g_realloc (mb->code, mb->code_size); + mb->code = (unsigned char *)g_realloc (mb->code, mb->code_size); } mb->code [mb->pos++] = op; @@ -288,19 +343,32 @@ mono_mb_emit_i4 (MonoMethodBuilder *mb, gint32 data) { if ((mb->pos + 4) >= mb->code_size) { mb->code_size += mb->code_size >> 1; - mb->code = g_realloc (mb->code, mb->code_size); + mb->code = (unsigned char *)g_realloc (mb->code, mb->code_size); } mono_mb_patch_addr (mb, mb->pos, data); mb->pos += 4; } +void +mono_mb_emit_i8 (MonoMethodBuilder *mb, gint64 data) +{ + if ((mb->pos + 8) >= mb->code_size) { + mb->code_size += mb->code_size >> 1; + mb->code = (unsigned char *)g_realloc (mb->code, mb->code_size); + } + + mono_mb_patch_addr (mb, mb->pos, data); + mono_mb_patch_addr (mb, mb->pos + 4, data >> 32); + mb->pos += 8; +} + void mono_mb_emit_i2 (MonoMethodBuilder *mb, gint16 data) { if ((mb->pos + 2) >= mb->code_size) { mb->code_size += mb->code_size >> 1; - mb->code = g_realloc (mb->code, mb->code_size); + mb->code = (unsigned char *)g_realloc (mb->code, mb->code_size); } mb->code [mb->pos] = data & 0xff; @@ -406,6 +474,13 @@ mono_mb_emit_icon (MonoMethodBuilder *mb, gint32 value) } } +void +mono_mb_emit_icon8 (MonoMethodBuilder *mb, gint64 value) +{ + mono_mb_emit_byte (mb, CEE_LDC_I8); + mono_mb_emit_i8 (mb, value); +} + int mono_mb_get_label (MonoMethodBuilder *mb) { @@ -496,14 +571,14 @@ mono_mb_emit_exception_full (MonoMethodBuilder *mb, const char *exc_nspace, cons { MonoMethod *ctor = NULL; - MonoClass *mme = mono_class_from_name (mono_defaults.corlib, exc_nspace, exc_name); + MonoClass *mme = mono_class_load_from_name (mono_defaults.corlib, exc_nspace, exc_name); mono_class_init (mme); ctor = mono_class_get_method_from_name (mme, ".ctor", 0); g_assert (ctor); mono_mb_emit_op (mb, CEE_NEWOBJ, ctor); if (msg != NULL) { mono_mb_emit_byte (mb, CEE_DUP); - mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoException, message)); + mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoException, message)); mono_mb_emit_ldstr (mb, (char*)msg); mono_mb_emit_byte (mb, CEE_STIND_REF); } @@ -531,3 +606,17 @@ mono_mb_set_clauses (MonoMethodBuilder *mb, int num_clauses, MonoExceptionClause mb->num_clauses = num_clauses; mb->clauses = clauses; } + +/* + * mono_mb_set_param_names: + * + * PARAM_NAMES should have length equal to the sig->param_count, the caller retains + * ownership of the array, and its entries. + */ +void +mono_mb_set_param_names (MonoMethodBuilder *mb, const char **param_names) +{ + mb->param_names = param_names; +} + +#endif /* DISABLE_JIT */