// Get string from a Mono exception char* PyNet_ExceptionToString(MonoObject *e) { MonoMethodDesc* mdesc = mono_method_desc_new(":ToString()", FALSE); MonoMethod* mmethod = mono_method_desc_search_in_class(mdesc, mono_get_object_class()); mono_method_desc_free(mdesc); mmethod = mono_object_get_virtual_method(e, mmethod); MonoString* monoString = (MonoString*) mono_runtime_invoke(mmethod, e, NULL, NULL); mono_runtime_invoke(mmethod, e, NULL, NULL); return mono_string_to_utf8(monoString); }
MonoObject* MonoMethod::invokeVirtual(MonoObject* instance, void** params) { ::MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, mMethod); MonoObject* exception = nullptr; MonoObject* retVal = mono_runtime_invoke(virtualMethod, instance, params, &exception); MonoUtil::throwIfException(exception); return retVal; }
static guint64 debugger_get_virtual_method (guint64 object_arg, guint64 method_arg) { MonoObject *object = (MonoObject *) GUINT_TO_POINTER ((gsize) object_arg); MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg); if (mono_class_is_valuetype (mono_method_get_class (method))) return method_arg; return (guint64) (gsize) mono_object_get_virtual_method (object, method); }
/** * common_call_trampoline: * * The code to handle normal, virtual, and interface method calls and jumps, both * from JITted and LLVM compiled code. */ static gpointer common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tramp, MonoVTable *vt, gpointer *vtable_slot, gboolean need_rgctx_tramp) { gpointer addr, compiled_method; gboolean generic_shared = FALSE; MonoMethod *declaring = NULL; MonoMethod *generic_virtual = NULL, *variant_iface = NULL, *orig_method = NULL; int context_used; gboolean virtual, variance_used = FALSE; gpointer *orig_vtable_slot, *vtable_slot_to_patch = NULL; MonoJitInfo *ji = NULL; virtual = (gpointer)vtable_slot > (gpointer)vt; orig_vtable_slot = vtable_slot; vtable_slot_to_patch = vtable_slot; #ifdef MONO_ARCH_HAVE_IMT /* IMT call */ if (vt && (gpointer)vtable_slot < (gpointer)vt) { MonoMethod *impl_method = NULL; MonoObject *this_arg; /* we get the interface method because mono_convert_imt_slot_to_vtable_slot () * needs the signature to be able to find the this argument */ m = mono_arch_find_imt_method (regs, code); vtable_slot = orig_vtable_slot; g_assert (vtable_slot); orig_method = m; this_arg = mono_arch_get_this_arg_from_call (regs, code); if (mono_object_is_transparent_proxy (this_arg)) { /* Use the slow path for now */ m = mono_object_get_virtual_method (this_arg, m); vtable_slot_to_patch = NULL; } else { addr = NULL; vtable_slot = mono_convert_imt_slot_to_vtable_slot (vtable_slot, regs, code, m, &impl_method, &need_rgctx_tramp, &variance_used, &addr); /* This is the vcall slot which gets called through the IMT thunk */ vtable_slot_to_patch = vtable_slot; /* mono_convert_imt_slot_to_vtable_slot () also gives us the method that is supposed * to be called, so we compile it and go ahead as usual. */ /*g_print ("imt found method %p (%s) at %p\n", impl_method, impl_method->name, code);*/ if (m->is_inflated && ((MonoMethodInflated*)m)->context.method_inst) { /* Generic virtual method */ generic_virtual = m; need_rgctx_tramp = TRUE; } else if (variance_used && mono_class_has_variant_generic_params (m->klass)) { variant_iface = m; } if (addr && !generic_virtual && !variant_iface) { /* * We found AOT compiled code for the method, skip the rest. */ if (mono_domain_owns_vtable_slot (mono_domain_get (), vtable_slot)) *vtable_slot = addr; return mono_create_ftnptr (mono_domain_get (), addr); } m = impl_method; } } #endif /* * The virtual check is needed because is_generic_method_definition (m) could * return TRUE for methods used in IMT calls too. */ if (virtual && is_generic_method_definition (m)) { MonoGenericContext context = { NULL, NULL }; MonoMethod *declaring; if (m->is_inflated) declaring = mono_method_get_declaring_generic_method (m); else declaring = m; if (m->klass->generic_class) context.class_inst = m->klass->generic_class->context.class_inst; else g_assert (!m->klass->generic_container); #ifdef MONO_ARCH_HAVE_IMT generic_virtual = mono_arch_find_imt_method (regs, code); #endif if (generic_virtual) { g_assert (generic_virtual->is_inflated); context.method_inst = ((MonoMethodInflated*)generic_virtual)->context.method_inst; } m = mono_class_inflate_generic_method (declaring, &context); /* FIXME: only do this if the method is sharable */ need_rgctx_tramp = TRUE; } else if ((context_used = mono_method_check_context_used (m))) {