コード例 #1
0
ファイル: exception.c プロジェクト: vargaz/mono
MonoExceptionHandle
mono_get_exception_runtime_wrapped_handle (MonoObjectHandle wrapped_exception, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoClass *klass;
	MonoMethod *method;

	klass = mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");

	MonoObjectHandle o = mono_object_new_handle (mono_domain_get (), klass, error);
	mono_error_assert_ok (error);
	g_assert (!MONO_HANDLE_IS_NULL (o));

	method = mono_class_get_method_from_name_checked (klass, ".ctor", 1, 0, error);
	mono_error_assert_ok (error);
	g_assert (method);

	gpointer args [ ] = { MONO_HANDLE_RAW (wrapped_exception) };

	mono_runtime_invoke_handle (method, o, args, error);
	goto_if_nok (error, return_null);
	goto exit;
return_null:
	o = mono_new_null ();
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, o));
}
コード例 #2
0
ファイル: exception.c プロジェクト: vargaz/mono
/**
 * mono_exception_new_by_name_domain:
 * \param domain Domain where the return object will be created.
 * \param image the Mono image where to look for the class
 * \param name_space the namespace for the class
 * \param name class name
 *
 * Creates an exception object of the given namespace/name class on
 * the given domain.
 *
 * \returns the initialized exception instance.
 */
static MonoExceptionHandle
mono_exception_new_by_name_domain (MonoDomain *domain, MonoImage *image,
				 const char* name_space, const char *name, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoDomain * const caller_domain = mono_domain_get ();

	MonoClass * const klass = mono_class_load_from_name (image, name_space, name);

	MonoObjectHandle o = mono_object_new_handle (domain, klass, error);
	goto_if_nok (error, return_null);

	if (domain != caller_domain)
		mono_domain_set_internal (domain);

	mono_runtime_object_init_handle (o, error);
	mono_error_assert_ok (error);

	// Restore domain in success and error path.
	if (domain != caller_domain)
		mono_domain_set_internal (caller_domain);

	goto_if_ok (error, exit);
return_null:
	MONO_HANDLE_ASSIGN (o, NULL_HANDLE);
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, o));
}
コード例 #3
0
ファイル: exception.c プロジェクト: vargaz/mono
/**
 * mono_exception_new_by_name_msg:
 * \param image the Mono image where to look for the class
 * \param name_space the namespace for the class
 * \param name class name
 * \param msg the message to embed inside the exception
 *
 * Creates an exception and initializes its message field.
 *
 * \returns the initialized exception instance.
 */
MonoExceptionHandle
mono_exception_new_by_name_msg (MonoImage *image, const char *name_space,
			      const char *name, const char *msg, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoExceptionHandle ex = mono_exception_new_by_name (image, name_space, name, error);
	goto_if_nok (error, return_null);

	if (msg) {
		MonoStringHandle msg_str = mono_string_new_handle (MONO_HANDLE_DOMAIN (ex), msg, error);
		// FIXME? Maybe just ignore this error, the exception is close to correct.
		goto_if_nok (error, return_null);
		// ex->message = msg_str;
		MONO_HANDLE_SET (ex, message, msg_str);
	}
	goto exit;
return_null:
	MONO_HANDLE_ASSIGN (ex, NULL_HANDLE);
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, ex)
}
コード例 #4
0
ファイル: exception.c プロジェクト: vargaz/mono
MonoExceptionHandle
mono_corlib_exception_new_with_args (const char *name_space, const char *name, const char *arg_0, const char *arg_1, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoStringHandle str_0 = NULL_HANDLE_STRING;
	MonoStringHandle str_1 = NULL_HANDLE_STRING;
	MonoExceptionHandle ex = MONO_HANDLE_CAST (MonoException, NULL_HANDLE);
	MonoDomain * const domain = mono_domain_get ();

	str_0 = arg_0 ? mono_string_new_handle (domain, arg_0, error) : NULL_HANDLE_STRING;
	goto_if_nok (error, return_null);

	str_1 = arg_1 ? mono_string_new_handle (domain, arg_1, error) : NULL_HANDLE_STRING;
	goto_if_nok (error, return_null);

	ex = mono_exception_from_name_two_strings_checked (mono_defaults.corlib, name_space, name, str_0, str_1, error);
	goto exit;
return_null:
	ex = MONO_HANDLE_CAST (MonoException, mono_new_null ());
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, ex);
}
コード例 #5
0
ファイル: exception.c プロジェクト: vargaz/mono
MonoExceptionHandle
mono_get_exception_type_initialization_handle (const gchar *type_name, MonoExceptionHandle inner, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoClass *klass;
	MonoMethod *method;
	gpointer iter;

	error_init (error);

	klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException");

	mono_class_init_internal (klass);

	iter = NULL;
	while ((method = mono_class_get_methods (klass, &iter))) {
		if (!strcmp (".ctor", mono_method_get_name (method))) {
			MonoMethodSignature *sig = mono_method_signature_internal (method);

			if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type_internal (sig->params [1]) == mono_defaults.exception_class)
				break;
		}
		method = NULL;
	}
	g_assert (method);

	MonoDomain * const domain = mono_domain_get ();
	MonoStringHandle type_name_str = mono_string_new_handle (domain, type_name, error);
	mono_error_assert_ok (error);
	gpointer args [ ] = { MONO_HANDLE_RAW (type_name_str), MONO_HANDLE_RAW (inner) };

	MonoObjectHandle exc = mono_object_new_handle (domain, klass, error);
	mono_error_assert_ok (error);

	mono_runtime_invoke_handle (method, exc, args, error);
	goto_if_nok (error, return_null);
	goto exit;
return_null:
	exc = mono_new_null ();
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, exc));
}
コード例 #6
0
ファイル: exception.c プロジェクト: vargaz/mono
MonoExceptionHandle
mono_get_exception_reflection_type_load_checked (MonoArrayHandle types, MonoArrayHandle exceptions, MonoError *error)
{
	HANDLE_FUNCTION_ENTER ();

	MonoClass *klass;
	MonoMethod *method;
	gpointer iter;

	error_init (error);

	klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");

	mono_class_init_internal (klass);

	/* Find the Type[], Exception[] ctor */
	iter = NULL;
	while ((method = mono_class_get_methods (klass, &iter))) {
		if (!strcmp (".ctor", mono_method_get_name (method))) {
			MonoMethodSignature *sig = mono_method_signature_internal (method);

			if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY)
				break;
		}
		method = NULL;
	}
	g_assert (method);

	MonoExceptionHandle exc = MONO_HANDLE_CAST (MonoException, MONO_HANDLE_NEW (MonoObject, mono_object_new_checked (mono_domain_get (), klass, error)));
	mono_error_assert_ok (error);

	gpointer args [ ] = { MONO_HANDLE_RAW (types), MONO_HANDLE_RAW (exceptions) };

	mono_runtime_invoke_checked (method, MONO_HANDLE_RAW (exc), args, error);
	goto_if_nok (error, return_null);
	goto exit;
return_null:
	exc = MONO_HANDLE_CAST (MonoException, mono_new_null ());
exit:
	HANDLE_FUNCTION_RETURN_REF (MonoException, exc);
}
コード例 #7
0
ファイル: gc.c プロジェクト: LogosBible/mono
/* 
 * actually, we might want to queue the finalize requests in a separate thread,
 * but we need to be careful about the execution domain of the thread...
 */
void
mono_gc_run_finalize (void *obj, void *data)
{
	ERROR_DECL (error);
	MonoObject *exc = NULL;
	MonoObject *o;
#ifndef HAVE_SGEN_GC
	MonoObject *o2;
#endif
	MonoMethod* finalizer = NULL;
	MonoDomain *caller_domain = mono_domain_get ();
	MonoDomain *domain;

	// This function is called from the innards of the GC, so our best alternative for now is to do polling here
	mono_threads_safepoint ();

	o = (MonoObject*)((char*)obj + GPOINTER_TO_UINT (data));

	const char *o_ns = m_class_get_name_space (mono_object_class (o));
	const char *o_name = m_class_get_name (mono_object_class (o));

	if (mono_do_not_finalize) {
		if (!mono_do_not_finalize_class_names)
			return;

		size_t namespace_len = strlen (o_ns);
		for (int i = 0; mono_do_not_finalize_class_names [i]; ++i) {
			const char *name = mono_do_not_finalize_class_names [i];
			if (strncmp (name, o_ns, namespace_len))
				break;
			if (name [namespace_len] != '.')
				break;
			if (strcmp (name + namespace_len + 1, o_name))
				break;
			return;
		}
	}

	if (mono_log_finalizers)
		g_log ("mono-gc-finalizers", G_LOG_LEVEL_DEBUG, "<%s at %p> Starting finalizer checks.", o_name, o);

	if (suspend_finalizers)
		return;

	domain = o->vtable->domain;

#ifndef HAVE_SGEN_GC
	mono_domain_finalizers_lock (domain);

	o2 = (MonoObject *)g_hash_table_lookup (domain->finalizable_objects_hash, o);

	mono_domain_finalizers_unlock (domain);

	if (!o2)
		/* Already finalized somehow */
		return;
#endif

	/* make sure the finalizer is not called again if the object is resurrected */
	object_register_finalizer ((MonoObject *)obj, NULL);

	if (mono_log_finalizers)
		g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Registered finalizer as processed.", o_name, o);

	if (o->vtable->klass == mono_defaults.internal_thread_class) {
		MonoInternalThread *t = (MonoInternalThread*)o;

		if (mono_gc_is_finalizer_internal_thread (t))
			/* Avoid finalizing ourselves */
			return;
	}

	if (m_class_get_image (mono_object_class (o)) == mono_defaults.corlib && !strcmp (o_name, "DynamicMethod") && finalizing_root_domain) {
		/*
		 * These can't be finalized during unloading/shutdown, since that would
		 * free the native code which can still be referenced by other
		 * finalizers.
		 * FIXME: This is not perfect, objects dying at the same time as 
		 * dynamic methods can still reference them even when !shutdown.
		 */
		return;
	}

	if (mono_runtime_get_no_exec ())
		return;

	/* speedup later... and use a timeout */
	/* g_print ("Finalize run on %p %s.%s\n", o, mono_object_class (o)->name_space, mono_object_class (o)->name); */

	/* Use _internal here, since this thread can enter a doomed appdomain */
	mono_domain_set_internal (mono_object_domain (o));

	/* delegates that have a native function pointer allocated are
	 * registered for finalization, but they don't have a Finalize
	 * method, because in most cases it's not needed and it's just a waste.
	 */
	if (m_class_is_delegate (mono_object_class (o))) {
		MonoDelegate* del = (MonoDelegate*)o;
		if (del->delegate_trampoline)
			mono_delegate_free_ftnptr ((MonoDelegate*)o);
		mono_domain_set_internal (caller_domain);
		return;
	}

	finalizer = mono_class_get_finalizer (o->vtable->klass);

	/* If object has a CCW but has no finalizer, it was only
	 * registered for finalization in order to free the CCW.
	 * Else it needs the regular finalizer run.
	 * FIXME: what to do about ressurection and suppression
	 * of finalizer on object with CCW.
	 */
	if (mono_marshal_free_ccw (o) && !finalizer) {
		mono_domain_set_internal (caller_domain);
		return;
	}

	/* 
	 * To avoid the locking plus the other overhead of mono_runtime_invoke_checked (),
	 * create and precompile a wrapper which calls the finalize method using
	 * a CALLVIRT.
	 */
	if (mono_log_finalizers)
		g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Compiling finalizer.", o_name, o);

#ifndef HOST_WASM
	if (!domain->finalize_runtime_invoke) {
		MonoMethod *finalize_method = mono_class_get_method_from_name_checked (mono_defaults.object_class, "Finalize", 0, 0, error);
		mono_error_assert_ok (error);
		MonoMethod *invoke = mono_marshal_get_runtime_invoke (finalize_method, TRUE);

		domain->finalize_runtime_invoke = mono_compile_method_checked (invoke, error);
		mono_error_assert_ok (error); /* expect this not to fail */
	}

	RuntimeInvokeFunction runtime_invoke = (RuntimeInvokeFunction)domain->finalize_runtime_invoke;
#endif

	mono_runtime_class_init_full (o->vtable, error);
	goto_if_nok (error, unhandled_error);

	if (G_UNLIKELY (MONO_GC_FINALIZE_INVOKE_ENABLED ())) {
		MONO_GC_FINALIZE_INVOKE ((unsigned long)o, mono_object_get_size_internal (o),
				o_ns, o_name);
	}

	if (mono_log_finalizers)
		g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Calling finalizer.", o_name, o);

	MONO_PROFILER_RAISE (gc_finalizing_object, (o));

#ifdef HOST_WASM
	if (finalizer) { // null finalizers work fine when using the vcall invoke as Object has an empty one
		gpointer params [1];
		params [0] = NULL;
		mono_runtime_try_invoke (finalizer, o, params, &exc, error);
	}
#else
	runtime_invoke (o, NULL, &exc, NULL);
#endif

	MONO_PROFILER_RAISE (gc_finalized_object, (o));

	if (mono_log_finalizers)
		g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o_name, o);

unhandled_error:
	if (!is_ok (error))
		exc = (MonoObject*)mono_error_convert_to_exception (error);
	if (exc)
		mono_thread_internal_unhandled_exception (exc);

	mono_domain_set_internal (caller_domain);
}