コード例 #1
0
/*
 * mono_create_static_rgctx_trampoline:
 *
 *   Return a static rgctx trampoline for M which branches to ADDR which should
 * point to the compiled code of M.
 *
 *   Static rgctx trampolines are used when a shared generic method which doesn't
 * have a this argument is called indirectly, ie. from code which can't pass in
 * the rgctx argument. The trampoline sets the rgctx argument and jumps to the
 * methods code. These trampolines are similar to the unbox trampolines, they
 * perform the same task as the static rgctx wrappers, but they are smaller/faster,
 * and can be made to work with full AOT.
 * On PPC addr should be an ftnptr and the return value is an ftnptr too.
 */
gpointer
mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr)
{
	gpointer ctx;
	gpointer res;
	MonoDomain *domain;
	RgctxTrampInfo tmp_info;
	RgctxTrampInfo *info;

#ifdef PPC_USES_FUNCTION_DESCRIPTOR
	g_assert (((gpointer*)addr) [2] == 0);
#endif

	if (mini_method_get_context (m)->method_inst)
		ctx = mono_method_lookup_rgctx (mono_class_vtable (mono_domain_get (), m->klass), mini_method_get_context (m)->method_inst);
	else
		ctx = mono_class_vtable (mono_domain_get (), m->klass);

	domain = mono_domain_get ();

	/* 
	 * In the AOT case, addr might point to either the method, or to an unbox trampoline,
	 * so make the hash keyed on the m+addr pair.
	 */
	mono_domain_lock (domain);
	if (!domain_jit_info (domain)->static_rgctx_trampoline_hash)
		domain_jit_info (domain)->static_rgctx_trampoline_hash = g_hash_table_new (rgctx_tramp_info_hash, rgctx_tramp_info_equal);
	tmp_info.m = m;
	tmp_info.addr = addr;
	res = g_hash_table_lookup (domain_jit_info (domain)->static_rgctx_trampoline_hash,
							   &tmp_info);
	mono_domain_unlock (domain);
	if (res)
		return res;

	if (mono_aot_only)
		res = mono_aot_get_static_rgctx_trampoline (ctx, addr);
	else
		res = mono_arch_get_static_rgctx_trampoline (m, ctx, addr);

	mono_domain_lock (domain);
	/* Duplicates inserted while we didn't hold the lock are OK */
	info = mono_domain_alloc (domain, sizeof (RgctxTrampInfo));
	info->m = m;
	info->addr = addr;
	g_hash_table_insert (domain_jit_info (domain)->static_rgctx_trampoline_hash, info, res);
	mono_domain_unlock (domain);

	static_rgctx_trampolines ++;

	return res;
}
コード例 #2
0
static guint64
debugger_class_get_static_field_data (guint64 value)
{
	MonoClass *klass = GUINT_TO_POINTER ((gsize) value);
	MonoVTable *vtable = mono_class_vtable (mono_domain_get (), klass);
	return (guint64) (gsize) mono_vtable_get_static_field_data (vtable);
}
コード例 #3
0
ファイル: trigger.c プロジェクト: ddo88/plmono
/*
 * plmono_trigdata_get_columns
 *
 *     Get Columns property value of TriggerData class
 */
MonoObject*
plmono_trigdata_get_columns(MonoClass *trigdata)
{
	MonoVTable *vt;
	MonoProperty *prop;

	vt = mono_class_vtable(plmono_get_domain(), trigdata);
	mono_runtime_class_init(vt);
	prop = mono_class_get_property_from_name(trigdata, "Columns");
	return mono_property_get_value(prop, NULL, NULL, NULL);
}
コード例 #4
0
ファイル: PipeServer.cpp プロジェクト: Akheon23/cheat-engine
void CPipeServer::GetStaticFieldAddressFromClass(void)
{
	void *domain = (void *)ReadQword();
	void *klass = (void *)ReadQword();
	void *vtable = mono_class_vtable(domain, klass);
	if (vtable)
	{
		void *staticdata=mono_vtable_get_static_field_data(vtable);
		WriteQword((UINT_PTR)staticdata);
	}
	else
		WriteQword(0);
}
コード例 #5
0
ファイル: mono-mlist.c プロジェクト: zzz77/mono
/**
 * mono_mlist_alloc:
 * @data: object to use as data
 *
 * Allocates a new managed list node with @data as the contents.
 * A managed list node also represents a singly-linked list.
 * Managed lists are garbage collected, so there is no free routine
 * and the user is required to keep references to the managed list
 * to prevent it from being garbage collected.
 */
MonoMList*
mono_mlist_alloc (MonoObject *data)
{
	MonoError error;
	MonoMList* res;
	if (!monolist_item_vtable) {
		MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System", "MonoListItem");
		monolist_item_vtable = mono_class_vtable (mono_get_root_domain (), klass);
		g_assert (monolist_item_vtable);
	}
	res = (MonoMList*)mono_object_new_fast_checked (monolist_item_vtable, &error);
	mono_error_raise_exception (&error);
	MONO_OBJECT_SETREF (res, data, data);
	return res;
}
コード例 #6
0
MonoArray * 
ves_icall_System_String_InternalSplit (MonoString *me, MonoArray *separator, gint32 count, gint32 options)
{
	static MonoClass *String_array;
	MonoString * tmpstr;
	MonoArray * retarr;
	gunichar2 *src;
	gint32 arrsize, srcsize, splitsize;
	gint32 i, lastpos, arrpos;
	gint32 tmpstrsize;
	gint32 remempty;
	gint32 flag;
	gunichar2 *tmpstrptr;

	remempty = options & STRINGSPLITOPTIONS_REMOVE_EMPTY_ENTRIES;
	src = mono_string_chars (me);
	srcsize = mono_string_length (me);
	arrsize = mono_array_length (separator);

	if (!String_array) {
		MonoClass *klass = mono_array_class_get (mono_get_string_class (), 1);
		mono_memory_barrier ();
		String_array = klass;
	}

	splitsize = 1;
	/* Count the number of elements we will return. Note that this operation
	 * guarantees that we will return exactly splitsize elements, and we will
	 * have enough data to fill each. This allows us to skip some checks later on.
	 */
	if (remempty == 0) {
		for (i = 0; i != srcsize && splitsize < count; i++) {
			if (string_icall_is_in_array (separator, arrsize, src [i]))
				splitsize++;
		}
	} else if (count > 1) {
		/* Require pattern "Nondelim + Delim + Nondelim" to increment counter.
		 * Lastpos != 0 means first nondelim found.
		 * Flag = 0 means last char was delim.
		 * Efficient, though perhaps confusing.
		 */
		lastpos = 0;
		flag = 0;
		for (i = 0; i != srcsize && splitsize < count; i++) {
			if (string_icall_is_in_array (separator, arrsize, src [i])) {
				flag = 0;
			} else if (flag == 0) {
				if (lastpos == 1)
					splitsize++;
				flag = 1;
				lastpos = 1;
			}
		}

		/* Nothing but separators */
		if (lastpos == 0) {
			retarr = mono_array_new_specific (mono_class_vtable (mono_domain_get (), String_array), 0);
			return retarr;
		}
	}

	/* if no split chars found return the string */
	if (splitsize == 1) {
		if (remempty == 0 || count == 1) {
			/* Copy the whole string */
			retarr = mono_array_new_specific (mono_class_vtable (mono_domain_get (), String_array), 1);
			mono_array_setref (retarr, 0, me);
		} else {
			/* otherwise we have to filter out leading & trailing delims */

			/* find first non-delim char */
			for (; srcsize != 0; srcsize--, src++) {
				if (!string_icall_is_in_array (separator, arrsize, src [0]))
					break;
			}
			/* find last non-delim char */
			for (; srcsize != 0; srcsize--) {
				if (!string_icall_is_in_array (separator, arrsize, src [srcsize - 1]))
					break;
			}
			tmpstr = mono_string_new_size (mono_domain_get (), srcsize);
			tmpstrptr = mono_string_chars (tmpstr);

			memcpy (tmpstrptr, src, srcsize * sizeof (gunichar2));
			retarr = mono_array_new_specific (mono_class_vtable (mono_domain_get (), String_array), 1);
			mono_array_setref (retarr, 0, tmpstr);
		}
		return retarr;
	}

	lastpos = 0;
	arrpos = 0;
	
	retarr = mono_array_new_specific (mono_class_vtable (mono_domain_get (), String_array), splitsize);

	for (i = 0; i != srcsize && arrpos != splitsize; i++) {
		if (string_icall_is_in_array (separator, arrsize, src [i])) {
			
			if (lastpos != i || remempty == 0) {
				tmpstrsize = i - lastpos;
				tmpstr = mono_string_new_size (mono_domain_get (), tmpstrsize);
				tmpstrptr = mono_string_chars (tmpstr);

				memcpy (tmpstrptr, src + lastpos, tmpstrsize * sizeof (gunichar2));
				mono_array_setref (retarr, arrpos, tmpstr);
				arrpos++;

				if (arrpos == splitsize - 1) {
					/* Shortcut the last array element */

					lastpos = i + 1;
					if (remempty != 0) {
						/* Search for non-delim starting char (guaranteed to find one) Note that loop
						 * condition is only there for safety. It will never actually terminate the loop. */
						for (; lastpos != srcsize ; lastpos++) {
							if (!string_icall_is_in_array (separator, arrsize, src [lastpos])) 
								break;
						}
						if (count > splitsize) {
							/* Since we have fewer results than our limit, we must remove
							 * trailing delimiters as well. 
							 */
							for (; srcsize != lastpos + 1 ; srcsize--) {
								if (!string_icall_is_in_array (separator, arrsize, src [srcsize - 1])) 
									break;
							}
						}
					}

					tmpstrsize = srcsize - lastpos;
					tmpstr = mono_string_new_size (mono_domain_get (), tmpstrsize);
					tmpstrptr = mono_string_chars (tmpstr);

					memcpy (tmpstrptr, src + lastpos, tmpstrsize * sizeof (gunichar2));
					mono_array_setref (retarr, arrpos, tmpstr);

					/* Loop will ALWAYS end here. Test criteria in the FOR loop is technically unnecessary. */
					break;
				}
			}
			lastpos = i + 1;
		}
	}

	return retarr;
}