/* * 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; }
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); }
/* * 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); }
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); }
/** * 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; }
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; }