* Patrik Torstensson (patrik.torstensson@labs2.com)
*
* (C) 2001 Ximian, Inc.
+ * Copyright (C) 2002-2006 Novell, Inc.
*
* This file is used by the interpreter and the JIT engine to locate
* assemblies. Used to load AssemblyRef and later to resolve various
#include <mono/metadata/class-internals.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/reflection.h>
+#include <mono/metadata/profiler.h>
#include <mono/utils/mono-logger.h>
#include <mono/metadata/exception.h>
{
TlsFree (loader_error_thread_id);
- DeleteCriticalSection (&loader_mutex);
+ /*DeleteCriticalSection (&loader_mutex);*/
}
/*
TlsSetValue (loader_error_thread_id, error);
}
+/**
+ * mono_loader_set_error_assembly_load:
+ *
+ * Set the loader error for this thread.
+ */
+void
+mono_loader_set_error_assembly_load (const char *assembly_name, gboolean ref_only)
+{
+ MonoLoaderError *error;
+
+ if (mono_loader_get_last_error ())
+ return;
+
+ error = g_new0 (MonoLoaderError, 1);
+ error->kind = MONO_LOADER_ERROR_ASSEMBLY;
+ error->assembly_name = g_strdup (assembly_name);
+ error->ref_only = ref_only;
+
+ /*
+ * This is not strictly needed, but some (most) of the loader code still
+ * can't deal with load errors, and this message is more helpful than an
+ * assert.
+ */
+ if (ref_only)
+ g_warning ("Cannot resolve dependency to assembly '%s' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.", assembly_name);
+ else
+ g_warning ("Could not load file or assembly '%s' or one of its dependencies.", assembly_name);
+
+ set_loader_error (error);
+}
/**
* mono_loader_set_error_type_load:
{
MonoLoaderError *ex = (MonoLoaderError*)TlsGetValue (loader_error_thread_id);
+ if (ex) {
g_free (ex->class_name);
g_free (ex->assembly_name);
- g_free (ex);
+ g_free (ex);
- TlsSetValue (loader_error_thread_id, NULL);
+ TlsSetValue (loader_error_thread_id, NULL);
+ }
}
/**
MonoException *
mono_loader_error_prepare_exception (MonoLoaderError *error)
{
- MonoException *ex = NULL;
+ MonoException *ex = NULL;
- switch (error->kind) {
- case MONO_LOADER_ERROR_TYPE: {
+ switch (error->kind) {
+ case MONO_LOADER_ERROR_TYPE: {
char *cname = g_strdup (error->class_name);
char *aname = g_strdup (error->assembly_name);
MonoString *class_name;
g_free (aname);
break;
}
- case MONO_LOADER_ERROR_METHOD: {
+ case MONO_LOADER_ERROR_METHOD: {
char *cname = g_strdup (error->class_name);
char *aname = g_strdup (error->member_name);
break;
}
- case MONO_LOADER_ERROR_FIELD: {
+ case MONO_LOADER_ERROR_FIELD: {
char *cnspace = g_strdup (*error->klass->name_space ? error->klass->name_space : "");
char *cname = g_strdup (error->klass->name);
char *cmembername = g_strdup (error->member_name);
g_free (cnspace);
break;
}
- default:
- g_assert_not_reached ();
- }
+
+ case MONO_LOADER_ERROR_ASSEMBLY: {
+ char *msg;
+
+ if (error->ref_only)
+ msg = g_strdup_printf ("Cannot resolve dependency to assembly '%s' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.", error->assembly_name);
+ else
+ msg = g_strdup_printf ("Could not load file or assembly '%s' or one of its dependencies.", error->assembly_name);
+
+ ex = mono_get_exception_file_not_found2 (msg, mono_string_new (mono_domain_get (), error->assembly_name));
+ mono_loader_clear_error ();
+ g_free (msg);
+ break;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
- return ex;
+ return ex;
}
static MonoClassField*
else
result = (MonoMethod *)mono_mempool_alloc0 (image->mempool, sizeof (MonoMethodNormal));
+ mono_stats.method_count ++;
+
if (!klass) {
guint32 type = mono_metadata_typedef_from_method (image, token);
klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type);
* mono_get_method_constrained:
*
* This is used when JITing the `constrained.' opcode.
+ *
+ * This returns two values: the contrained method, which has been inflated
+ * as the function return value; And the original CIL-stream method as
+ * declared in cil_method. The later is used for verification.
*/
MonoMethod *
mono_get_method_constrained (MonoImage *image, guint32 token, MonoClass *constrained_class,
- MonoGenericContext *context)
+ MonoGenericContext *context, MonoMethod **cil_method)
{
MonoMethod *method, *result;
MonoClass *ic = NULL;
mono_loader_lock ();
- method = mono_get_method_from_token (image, token, NULL, context);
- if (!method) {
+ *cil_method = mono_get_method_from_token (image, token, NULL, context);
+ if (!*cil_method) {
mono_loader_unlock ();
return NULL;
}
mono_class_init (constrained_class);
- method = mono_get_inflated_method (method);
+ method = mono_get_inflated_method (*cil_method);
sig = mono_method_signature (method);
if (method->is_inflated && sig->generic_param_count) {
void
mono_free_method (MonoMethod *method)
{
+ if (mono_profiler_get_events () != MONO_PROFILE_NONE)
+ return;
+
if (method->signature) {
/*
* FIXME: This causes crashes because the types inside signatures and
LeaveCriticalSection (&loader_mutex);
}
+/**
+ * mono_method_signature:
+ *
+ * Return the signature of the method M. On failure, returns NULL.
+ */
MonoMethodSignature*
mono_method_signature (MonoMethod *m)
{
size = mono_metadata_decode_blob_size (sig, &sig_body);
m->signature = mono_metadata_parse_method_signature_full (img, container, idx, sig_body, NULL);
+ if (!m->signature) {
+ mono_loader_unlock ();
+ return NULL;
+ }
if (can_cache_signature)
g_hash_table_insert (img->method_signatures, (gpointer)sig, m->signature);