* 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)
+ * 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"
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);
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);
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;
image = mb->method->klass->image;
- mono_loader_lock ();
+#ifndef DISABLE_JIT
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;
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;
if (mb->no_dup_name)
method->name = mb->name;
else
method->name = mono_image_strdup (image, mb->name);
- ((MonoMethodNormal *)method)->header = header = (MonoMethodHeader *)
- mono_image_alloc0 (image, sizeof (MonoMethodHeader) + mb->locals * sizeof (MonoType *));
+#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;
- mw = (MonoMethodWrapper*) mb->method;
- i = g_list_length (mw->method_data);
+ method->skip_visibility = mb->skip_visibility;
+#endif
+
+ 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;
}
g_list_free (l);
- ((MonoMethodWrapper*)method)->method_data = data;
+ mw->method_data = data;
}
+
+#ifndef DISABLE_JIT
/*{
static int total_code = 0;
static int total_alloc = 0;
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;
}
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
{
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;
{
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;
}
}
+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)
{
{
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);
}
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;
+}
+
+/*
+ * 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 */