Beispiel #1
0
// 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;
	}		
Beispiel #3
0
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);
}
Beispiel #4
0
/**
 * 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))) {