+ m = mono_marshal_method_from_wrapper (method);
+ g_assert (m);
+ g_assert (m != method);
+ success = success && append_mangled_method (s, m);
+ break;
+ }
+ case MONO_WRAPPER_MANAGED_TO_MANAGED: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+
+ if (info->subtype == WRAPPER_SUBTYPE_ELEMENT_ADDR) {
+ g_string_append_printf (s, "%d_", info->d.element_addr.rank);
+ g_string_append_printf (s, "%d_", info->d.element_addr.elem_size);
+ } else if (info->subtype == WRAPPER_SUBTYPE_STRING_CTOR) {
+ success = success && append_mangled_method (s, info->d.string_ctor.method);
+ } else {
+ g_assert_not_reached ();
+ }
+ break;
+ }
+ case MONO_WRAPPER_CASTCLASS: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+ break;
+ }
+ case MONO_WRAPPER_RUNTIME_INVOKE: {
+ append_mangled_wrapper_subtype (s, info->subtype);
+ if (info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT || info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL)
+ success = success && append_mangled_method (s, info->d.runtime_invoke.method);
+ else if (info->subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_NORMAL)
+ success = success && append_mangled_signature (s, info->d.runtime_invoke.sig);
+ break;
+ }
+ case MONO_WRAPPER_DELEGATE_INVOKE:
+ case MONO_WRAPPER_DELEGATE_BEGIN_INVOKE:
+ case MONO_WRAPPER_DELEGATE_END_INVOKE: {
+ if (method->is_inflated) {
+ /* These wrappers are identified by their class */
+ g_string_append_printf (s, "i_");
+ success = success && append_mangled_klass (s, method->klass);
+ } else {
+ WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+
+ g_string_append_printf (s, "u_");
+ if (method->wrapper_type == MONO_WRAPPER_DELEGATE_INVOKE)
+ append_mangled_wrapper_subtype (s, info->subtype);
+ g_string_append_printf (s, "u_sigstart");
+ }
+ break;
+ }
+ case MONO_WRAPPER_NATIVE_TO_MANAGED: {
+ g_assert (info);
+ success = success && append_mangled_method (s, info->d.native_to_managed.method);
+ success = success && append_mangled_klass (s, method->klass);
+ break;
+ }
+ default:
+ g_assert_not_reached ();
+ }
+ return success && append_mangled_signature (s, mono_method_signature (method));
+}
+
+static void
+append_mangled_context (GString *str, MonoGenericContext *context)
+{
+ GString *res = g_string_new ("");
+
+ g_string_append_printf (res, "gens_");
+ g_string_append (res, "00");
+
+ gboolean good = context->class_inst && context->class_inst->type_argc > 0;
+ good = good || (context->method_inst && context->method_inst->type_argc > 0);
+ g_assert (good);
+
+ if (context->class_inst)
+ mono_ginst_get_desc (res, context->class_inst);
+ if (context->method_inst) {
+ if (context->class_inst)
+ g_string_append (res, "11");
+ mono_ginst_get_desc (res, context->method_inst);
+ }
+ g_string_append_printf (str, "gens_%s", res->str);
+}
+
+static gboolean
+append_mangled_method (GString *s, MonoMethod *method)
+{
+ if (method->wrapper_type)
+ return append_mangled_wrapper (s, method);
+
+ g_string_append_printf (s, "%s_", method->klass->image->assembly->aname.name);
+
+ if (method->is_inflated) {
+ g_string_append_printf (s, "inflated_");
+ MonoMethodInflated *imethod = (MonoMethodInflated*) method;
+ g_assert (imethod->context.class_inst != NULL || imethod->context.method_inst != NULL);
+
+ append_mangled_context (s, &imethod->context);
+ g_string_append_printf (s, "_declared_by_");
+ append_mangled_method (s, imethod->declaring);
+ } else if (method->is_generic) {
+ g_string_append_printf (s, "generic_");
+ append_mangled_klass (s, method->klass);
+ g_string_append_printf (s, "_%s_", method->name);
+
+ MonoGenericContainer *container = mono_method_get_generic_container (method);
+ g_string_append_printf (s, "_%s");
+ append_mangled_context (s, &container->context);
+
+ return append_mangled_signature (s, mono_method_signature (method));
+ } else {
+ g_string_append_printf (s, "_");
+ append_mangled_klass (s, method->klass);
+ g_string_append_printf (s, "_%s_", method->name);
+ if (!append_mangled_signature (s, mono_method_signature (method))) {
+ g_string_free (s, TRUE);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/*
+ * mono_aot_get_mangled_method_name:
+ *
+ * Return a unique mangled name for METHOD, or NULL.
+ */
+char*
+mono_aot_get_mangled_method_name (MonoMethod *method)
+{
+ GString *s = g_string_new ("aot_");
+ if (!append_mangled_method (s, method)) {