#include <mono/metadata/object.h>
#include <mono/metadata/threads.h>
+#include <mono/metadata/threads-types.h>
#include <mono/metadata/threadpool.h>
#include <mono/metadata/monitor.h>
#include <mono/metadata/reflection.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/tokentype.h>
#include <mono/metadata/unicode.h>
-#include <mono/metadata/appdomain.h>
+#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/metadata-internals.h>
+#include <mono/metadata/class-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/rand.h>
#include <mono/metadata/char-conversions.h>
#include <mono/metadata/security.h>
#include <mono/metadata/mono-config.h>
+#include <mono/metadata/cil-coff.h>
#include <mono/io-layer/io-layer.h>
#include <mono/utils/strtod.h>
#include <mono/utils/monobitset.h>
return this->bounds [dimension].lower_bound;
}
+static void
+ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
+{
+ int sz = mono_array_element_size (mono_object_class (arr));
+ memset (mono_array_addr_with_size (arr, idx, sz), 0, length * sz);
+}
+
static gboolean
ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
{
{
MONO_ARCH_SAVE_REGS;
- return mono_image_create_token (mb->dynamic_image, obj);
+ return mono_image_create_token (mb->dynamic_image, obj, TRUE);
}
static gint32
MonoType *type = NULL;
MonoAssembly *assembly;
MonoTypeNameParse info;
+ char *temp_str = g_strdup (str);
+ gboolean type_resolve = FALSE;
MONO_ARCH_SAVE_REGS;
- if (!mono_reflection_parse_type (str, &info)) {
+ /* mono_reflection_parse_type() mangles the string */
+ if (!mono_reflection_parse_type (temp_str, &info)) {
g_list_free (info.modifiers);
g_list_free (info.nested);
+ g_free (temp_str);
return NULL;
}
}
if (assembly)
- type = mono_reflection_get_type (assembly->image, &info, ignoreCase);
+ type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
if (!info.assembly.name && !type) /* try mscorlib */
- type = mono_reflection_get_type (NULL, &info, ignoreCase);
+ type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
g_list_free (info.modifiers);
g_list_free (info.nested);
+ g_free (temp_str);
+
if (!type)
return NULL;
return mono_type_get_object (mono_domain_get (), type);
}
+#ifdef UNUSED
MonoReflectionType *
mono_type_get (const char *str)
{
g_free (copy);
return type;
}
+#endif
static MonoReflectionType*
ves_icall_type_from_name (MonoString *name,
return klass->flags;
}
+static MonoReflectionMarshal*
+ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
+{
+ MonoClass *klass = field->field->parent;
+ MonoMarshalType *info;
+ int i;
+
+ if (klass->generic_container ||
+ (klass->generic_inst && klass->generic_inst->is_open))
+ return NULL;
+
+ info = mono_marshal_load_type_info (klass);
+
+ for (i = 0; i < info->num_fields; ++i) {
+ if (info->fields [i].field == field->field) {
+ if (!info->fields [i].mspec)
+ return NULL;
+ else
+ return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
+ }
+ }
+
+ return NULL;
+}
+
static MonoReflectionField*
ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
{
info->implattrs = method->iflags;
if (method->signature->call_convention == MONO_CALL_DEFAULT)
info->callconv = 1;
- else
+ else {
if (method->signature->call_convention == MONO_CALL_VARARG)
info->callconv = 2;
else
info->callconv = 0;
+ }
info->callconv |= (method->signature->hasthis << 5) | (method->signature->explicit_this << 6);
}
return mono_param_get_objects (domain, method);
}
+static gint32
+ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
+{
+ return field->field->offset - sizeof (MonoObject);
+}
+
static MonoReflectionType*
ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
{
info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
+
+ if (event->event->other) {
+ int i, n = 0;
+ while (event->event->other [n])
+ n++;
+ info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
+
+ for (i = 0; i < n; i++)
+ mono_array_set (info->other_methods, gpointer, i,
+ mono_method_get_object (domain, event->event->other [i], NULL));
+ }
}
static MonoArray*
{
MonoDomain *domain = mono_object_domain (type);
MonoArray *intf;
- int ninterf, i;
+ GPtrArray *ifaces = NULL;
+ int i;
MonoClass *class = mono_class_from_mono_type (type->type);
MonoClass *parent;
MonoBitSet *slots = mono_bitset_new (class->max_interface_id + 1, 0);
return mono_array_new (domain, mono_defaults.monotype_class, 0);
}
- ninterf = 0;
for (parent = class; parent; parent = parent->parent) {
- for (i = 0; i < parent->interface_count; ++i) {
- if (mono_bitset_test (slots, parent->interfaces [i]->interface_id))
- continue;
+ GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
+ if (tmp_ifaces) {
+ for (i = 0; i < tmp_ifaces->len; ++i) {
+ MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
- mono_bitset_set (slots, parent->interfaces [i]->interface_id);
- ++ninterf;
+ if (mono_bitset_test (slots, ic->interface_id))
+ continue;
+
+ mono_bitset_set (slots, ic->interface_id);
+ if (ifaces == NULL)
+ ifaces = g_ptr_array_new ();
+ g_ptr_array_add (ifaces, ic);
+ }
+ g_ptr_array_free (tmp_ifaces, TRUE);
}
}
+ mono_bitset_free (slots);
- intf = mono_array_new (domain, mono_defaults.monotype_class, ninterf);
- ninterf = 0;
- for (parent = class; parent; parent = parent->parent) {
- for (i = 0; i < parent->interface_count; ++i) {
- if (!mono_bitset_test (slots, parent->interfaces [i]->interface_id))
- continue;
-
- mono_bitset_clear (slots, parent->interfaces [i]->interface_id);
- mono_array_set (intf, gpointer, ninterf,
- mono_type_get_object (domain, &parent->interfaces [i]->byval_arg));
- ++ninterf;
- }
+ if (!ifaces)
+ return mono_array_new (domain, mono_defaults.monotype_class, 0);
+
+ intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
+ for (i = 0; i < ifaces->len; ++i) {
+ MonoClass *ic = g_ptr_array_index (ifaces, i);
+
+ mono_array_set (intf, gpointer, i,
+ mono_type_get_object (domain, &ic->byval_arg));
}
+ g_ptr_array_free (ifaces, TRUE);
- mono_bitset_free (slots);
return intf;
}
}
}
+static void
+ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
+{
+ MonoClass *klass = mono_class_from_mono_type (type->type);
+
+ g_assert (!klass->image->dynamic);
+
+ mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
+}
+
static MonoReflectionType*
ves_icall_MonoType_GetElementType (MonoReflectionType *type)
{
MONO_ARCH_SAVE_REGS;
+ // GelElementType should only return a type for:
+ // Array Pointer PassedByRef
if (type->type->byref)
return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
- else if (class->element_class)
+ else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
+ return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
+ else if (class->element_class && type->type->type == MONO_TYPE_PTR)
return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
else
return NULL;
while (class->nested_in)
class = class->nested_in;
- return mono_string_new (domain, class->name_space);
+ if (class->name_space [0] == '\0')
+ return NULL;
+ else
+ return mono_string_new (domain, class->name_space);
}
static gint32
if (type->type->byref) {
res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
- } else if (klass->gen_params) {
- res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, klass->num_gen_params);
- for (i = 0; i < klass->num_gen_params; ++i) {
- pklass = mono_class_from_generic_parameter (&klass->gen_params [i], klass->image, FALSE);
+ } else if (klass->generic_container) {
+ MonoGenericContainer *container = klass->generic_container;
+ res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
+ for (i = 0; i < container->type_argc; ++i) {
+ pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
mono_array_set (res, gpointer, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
}
} else if (klass->generic_inst) {
return FALSE;
klass = mono_class_from_mono_type (type->type);
- return klass->gen_params != NULL;
+ return klass->generic_container != NULL;
}
static MonoReflectionType*
if (type->type->byref)
return NULL;
klass = mono_class_from_mono_type (type->type);
- if (klass->gen_params) {
+ if (klass->generic_container) {
return type; /* check this one */
}
if (klass->generic_inst) {
return -1;
}
+static GenericParameterAttributes
+ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
+{
+ MONO_ARCH_SAVE_REGS;
+ return type->type->data.generic_param->flags;
+}
+
+static MonoArray *
+ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
+{
+ MonoGenericParam *param;
+ MonoDomain *domain;
+ MonoClass **ptr;
+ MonoArray *res;
+ int i, count;
+
+ MONO_ARCH_SAVE_REGS;
+
+ domain = mono_object_domain (type);
+ param = type->type->data.generic_param;
+ for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
+ ;
+
+ res = mono_array_new (domain, mono_defaults.monotype_class, count);
+ for (i = 0; i < count; i++)
+ mono_array_set (res, gpointer, i,
+ mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
+
+
+ return res;
+}
+
static MonoBoolean
ves_icall_MonoType_get_HasGenericArguments (MonoReflectionType *type)
{
if (type->type->byref)
return FALSE;
klass = mono_class_from_mono_type (type->type);
- if (klass->gen_params || klass->generic_inst)
+ if (klass->generic_container || klass->generic_inst)
return TRUE;
return FALSE;
}
return FALSE;
}
+static void
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
+ MonoReflectionType *t)
+{
+ enumtype->type = t->type;
+}
+
static MonoReflectionType*
ves_icall_MonoGenericInst_GetParentType (MonoReflectionGenericInst *type)
{
return NULL;
klass = mono_class_from_mono_type (ginst->parent);
- if (!klass->generic_inst && !klass->gen_params)
+ if (!klass->generic_inst && !klass->generic_container)
return NULL;
return mono_type_get_object (mono_object_domain (type), ginst->parent);
return mono_method_get_object (mono_object_domain (type), method, klass);
}
+static MonoReflectionDllImportAttribute*
+ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
+{
+ static MonoClass *DllImportAttributeClass = NULL;
+ MonoDomain *domain = mono_domain_get ();
+ MonoReflectionDllImportAttribute *attr;
+ MonoImage *image = method->klass->image;
+ MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
+ MonoTableInfo *tables = image->tables;
+ MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
+ MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
+ guint32 im_cols [MONO_IMPLMAP_SIZE];
+ guint32 scope_token;
+ const char *import = NULL;
+ const char *scope = NULL;
+ guint32 flags;
+
+ if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+ return NULL;
+
+ if (!DllImportAttributeClass) {
+ DllImportAttributeClass =
+ mono_class_from_name (mono_defaults.corlib,
+ "System.Runtime.InteropServices", "DllImportAttribute");
+ g_assert (DllImportAttributeClass);
+ }
+
+ if (method->klass->image->dynamic) {
+ MonoReflectionMethodAux *method_aux =
+ mono_g_hash_table_lookup (
+ ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ if (method_aux) {
+ import = method_aux->dllentry;
+ scope = method_aux->dll;
+ }
+ }
+ else {
+ if (piinfo->implmap_idx) {
+ mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
+
+ piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
+ import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
+ scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
+ scope = mono_metadata_string_heap (image, scope_token);
+ }
+ }
+ flags = piinfo->piflags;
+
+ attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
+
+ attr->dll = mono_string_new (domain, scope);
+ attr->entry_point = mono_string_new (domain, import);
+ attr->call_conv = (flags & 0x700) >> 8;
+ attr->charset = ((flags & 0x6) >> 1) + 1;
+ if (attr->charset == 1)
+ attr->charset = 2;
+ attr->exact_spelling = (flags & 0x1) != 0;
+ attr->set_last_error = (flags & 0x4) != 0;
+ attr->best_fit_mapping = (flags & 0x10) != 0;
+ attr->throw_on_unmappable = (flags & 0x1000) != 0;
+ attr->preserve_sig = FALSE;
+
+ return attr;
+}
+
static MonoReflectionMethod *
ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
{
res = mono_array_new (domain, mono_defaults.monotype_class, count);
for (i = 0; i < count; i++) {
- MonoGenericParam *param = &mn->header->gen_params [i];
+ MonoGenericParam *param = &mn->generic_container->type_params [i];
MonoClass *pklass = mono_class_from_generic_parameter (
param, method->method->klass->image, TRUE);
mono_array_set (res, gpointer, i,
*/
MonoMethod *m = method->method;
int pcount;
+ void *obj = this;
MONO_ARCH_SAVE_REGS;
if (!mono_object_isinst (this, m->klass))
mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
m = mono_object_get_virtual_method (this, m);
+ /* must pass the pointer to the value for valuetype methods */
+ if (m->klass->valuetype)
+ obj = mono_object_unbox (this);
} else if (!(m->flags & METHOD_ATTRIBUTE_STATIC) && strcmp (m->name, ".ctor") && !m->wrapper_type)
mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
if (pcount != m->signature->param_count)
mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
+ if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
+ mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
+
if (m->klass->rank && !strcmp (m->name, ".ctor")) {
int i;
guint32 *lengths;
return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
}
- return mono_runtime_invoke_array (m, this, params, NULL);
+ return mono_runtime_invoke_array (m, obj, params, NULL);
}
static MonoObject *
if (!strcmp (m->name, "FieldGetter")) {
MonoClass *k = this->vtable->klass;
+
+ /* If this is a proxy, then it must be a CBO */
+ if (k == mono_defaults.transparent_proxy_class) {
+ MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
+ this = tp->rp->unwrapped_server;
+ g_assert (this);
+ k = this->vtable->klass;
+ }
+
MonoString *name = mono_array_get (params, MonoString *, 1);
char *str;
str = mono_string_to_utf8 (name);
- for (i = 0; i < k->field.count; i++) {
- if (!strcmp (k->fields [i].name, str)) {
- MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
- if (field_klass->valuetype)
- result = mono_value_box (domain, field_klass,
- (char *)this + k->fields [i].offset);
- else
- result = *((gpointer *)((char *)this + k->fields [i].offset));
-
- g_assert (result);
- out_args = mono_array_new (domain, mono_defaults.object_class, 1);
- *outArgs = out_args;
- mono_array_set (out_args, gpointer, 0, result);
- g_free (str);
- return NULL;
+ do {
+ for (i = 0; i < k->field.count; i++) {
+ if (!strcmp (k->fields [i].name, str)) {
+ MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
+ if (field_klass->valuetype)
+ result = mono_value_box (domain, field_klass,
+ (char *)this + k->fields [i].offset);
+ else
+ result = *((gpointer *)((char *)this + k->fields [i].offset));
+
+ g_assert (result);
+ out_args = mono_array_new (domain, mono_defaults.object_class, 1);
+ *outArgs = out_args;
+ mono_array_set (out_args, gpointer, 0, result);
+ g_free (str);
+ return NULL;
+ }
}
- }
+ k = k->parent;
+ }
+ while (k != NULL);
g_free (str);
g_assert_not_reached ();
} else if (!strcmp (m->name, "FieldSetter")) {
MonoClass *k = this->vtable->klass;
+
+ /* If this is a proxy, then it must be a CBO */
+ if (k == mono_defaults.transparent_proxy_class) {
+ MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
+ this = tp->rp->unwrapped_server;
+ g_assert (this);
+ k = this->vtable->klass;
+ }
+
MonoString *name = mono_array_get (params, MonoString *, 1);
int size, align;
char *str;
str = mono_string_to_utf8 (name);
- for (i = 0; i < k->field.count; i++) {
- if (!strcmp (k->fields [i].name, str)) {
- MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
- MonoObject *val = mono_array_get (params, gpointer, 2);
-
- if (field_klass->valuetype) {
- size = mono_type_size (k->fields [i].type, &align);
- memcpy ((char *)this + k->fields [i].offset,
- ((char *)val) + sizeof (MonoObject), size);
- } else
- *(MonoObject**)((char *)this + k->fields [i].offset) = val;
-
- out_args = mono_array_new (domain, mono_defaults.object_class, 0);
- *outArgs = out_args;
-
- g_free (str);
- return NULL;
+ do {
+ for (i = 0; i < k->field.count; i++) {
+ if (!strcmp (k->fields [i].name, str)) {
+ MonoClass *field_klass = mono_class_from_mono_type (k->fields [i].type);
+ MonoObject *val = mono_array_get (params, gpointer, 2);
+
+ if (field_klass->valuetype) {
+ size = mono_type_size (k->fields [i].type, &align);
+ memcpy ((char *)this + k->fields [i].offset,
+ ((char *)val) + sizeof (MonoObject), size);
+ } else
+ *(MonoObject**)((char *)this + k->fields [i].offset) = val;
+
+ out_args = mono_array_new (domain, mono_defaults.object_class, 0);
+ *outArgs = out_args;
+
+ g_free (str);
+ return NULL;
+ }
}
- }
+ k = k->parent;
+ }
+ while (k != NULL);
g_free (str);
g_assert_not_reached ();
out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
- /* fixme: handle constructors? */
+ /* handle constructors only for objects already allocated */
if (!strcmp (method->method->name, ".ctor"))
- g_assert_not_reached ();
+ g_assert (this);
+ /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
+ g_assert (!method->method->klass->valuetype);
result = mono_runtime_invoke_array (method->method, this, params, NULL);
for (i = 0, j = 0; i < mono_array_length (params); i++) {
if (mono_field_is_deleted (field))
continue;
mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
- if (!field->def_value) {
- field->def_value = g_new0 (MonoConstant, 1);
+
+ if (!field->data) {
crow = mono_metadata_get_constant_index (enumc->image, MONO_TOKEN_FIELD_DEF | (i+enumc->field.first+1), crow + 1);
- field->def_value->type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
+ field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
- field->def_value->value = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
+ field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
}
- p = field->def_value->value;
+ p = field->data;
len = mono_metadata_decode_blob_size (p, &p);
switch (enumc->enum_basetype->type) {
case MONO_TYPE_U1:
gchar *str;
MonoType *type = NULL;
MonoTypeNameParse info;
+ gboolean type_resolve = FALSE;
MONO_ARCH_SAVE_REGS;
if (module != NULL) {
if (module->image)
- type = mono_reflection_get_type (module->image, &info, ignoreCase);
+ type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
else
type = NULL;
}
if (abuilder->modules) {
for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
- type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase);
+ type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
if (type)
break;
}
if (!type && abuilder->loaded_modules) {
for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
- type = mono_reflection_get_type (mod->image, &info, ignoreCase);
+ type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
if (type)
break;
}
}
}
else
- type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase);
+ type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
g_free (str);
g_list_free (info.modifiers);
g_list_free (info.nested);
{
MonoDomain *domain = mono_object_domain (assembly);
MonoString *res;
- char *name = g_build_filename (
- assembly->assembly->basedir,
- assembly->assembly->image->module_name, NULL);
MONO_ARCH_SAVE_REGS;
- res = mono_string_new (domain, name);
- g_free (name);
+ res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
+
return res;
}
return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
}
+static MonoReflectionModule*
+ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
+{
+ return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
+}
+
static MonoArray*
ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
{
{
static MonoClass *System_Reflection_AssemblyName;
MonoArray *result;
- MonoAssembly **ptr;
MonoDomain *domain = mono_object_domain (assembly);
int i, count = 0;
+ static MonoMethod *create_culture = NULL;
+ MonoTableInfo *t;
MONO_ARCH_SAVE_REGS;
System_Reflection_AssemblyName = mono_class_from_name (
mono_defaults.corlib, "System.Reflection", "AssemblyName");
- for (ptr = assembly->assembly->image->references; ptr && *ptr; ptr++)
- count++;
+ t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
+ count = t->rows;
+
+ result = mono_array_new (domain, System_Reflection_AssemblyName, count);
- result = mono_array_new (mono_object_domain (assembly), System_Reflection_AssemblyName, count);
+ if (count > 0) {
+ MonoMethodDesc *desc = mono_method_desc_new (
+ "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
+ create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
+ g_assert (create_culture);
+ mono_method_desc_free (desc);
+ }
for (i = 0; i < count; i++) {
- MonoAssembly *assem = assembly->assembly->image->references [i];
+ MonoAssembly *assem;
MonoReflectionAssemblyName *aname;
char *codebase, *absolute;
+ /* FIXME: There is no need to load the assemblies themselves */
+ mono_assembly_load_reference (assembly->assembly->image, i);
+
+ assem = assembly->assembly->image->references [i];
+ if (assem == (gpointer)-1) {
+ char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i, assembly->assembly->image->name);
+ MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
+ g_free (msg);
+ mono_raise_exception (ex);
+ }
+
aname = (MonoReflectionAssemblyName *) mono_object_new (
domain, System_Reflection_AssemblyName);
aname->minor = assem->aname.minor;
aname->build = assem->aname.build;
aname->revision = assem->aname.revision;
+ aname->revision = assem->aname.revision;
+ aname->hashalg = assem->aname.hash_alg;
+ aname->flags = assem->aname.flags;
+
+ if (create_culture) {
+ gpointer args [1];
+ args [0] = mono_string_new (domain, assem->aname.culture);
+ aname->cultureInfo = mono_runtime_invoke (create_culture, NULL, args, NULL);
+ }
+
+ if (assem->aname.public_key) {
+ guint32 pkey_len;
+ const char *pkey_ptr = assem->aname.public_key;
+ pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
+
+ aname->publicKey = mono_array_new (domain, mono_defaults.byte_class, pkey_len);
+ memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
+ }
+
+ /* public key token isn't copied - the class library will
+ automatically generate it from the public key if required */
absolute = g_build_filename (assem->basedir, assem->image->module_name, NULL);
codebase = g_filename_to_uri (absolute, NULL, NULL);
* this code should only be called after obtaining the
* ResourceInfo and handling the other cases.
*/
- g_assert ((impl & IMPLEMENTATION_MASK) == IMPLEMENTATION_FILE);
- file_idx = impl >> IMPLEMENTATION_BITS;
+ g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
+ file_idx = impl >> MONO_IMPLEMENTATION_BITS;
module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
if (!module)
info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
}
else {
- switch (cols [MONO_MANIFEST_IMPLEMENTATION] & IMPLEMENTATION_MASK) {
- case IMPLEMENTATION_FILE:
- i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
+ switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
+ case MONO_IMPLEMENTATION_FILE:
+ i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
info->location = RESOURCE_LOCATION_EMBEDDED;
break;
- case IMPLEMENTATION_ASSEMBLYREF:
- i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
+ case MONO_IMPLEMENTATION_ASSEMBLYREF:
+ i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
+ mono_assembly_load_reference (assembly->assembly->image, i - 1);
+ if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
+ char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
+ MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
+ g_free (msg);
+ mono_raise_exception (ex);
+ }
info->assembly = mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]);
/* Obtain info recursively */
info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
break;
- case IMPLEMENTATION_EXP_TYPE:
+ case MONO_IMPLEMENTATION_EXP_TYPE:
g_assert_not_reached ();
break;
}
MonoDomain *domain = mono_domain_get();
MonoArray *res;
MonoClass *klass;
- int i, module_count = 0, file_count = 0;
- MonoImage **modules = assembly->assembly->image->modules;
+ int i, j, file_count = 0;
+ MonoImage **modules;
+ guint32 module_count, real_module_count;
MonoTableInfo *table;
- if (modules) {
- while (modules[module_count])
- ++module_count;
- }
+ g_assert (assembly->assembly->image != NULL);
table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
file_count = table->rows;
- g_assert( assembly->assembly->image != NULL);
- ++module_count;
+ modules = assembly->assembly->image->modules;
+ module_count = assembly->assembly->image->module_count;
+
+ real_module_count = 0;
+ for (i = 0; i < module_count; ++i)
+ if (modules [i])
+ real_module_count ++;
- klass = mono_class_from_name ( mono_defaults.corlib, "System.Reflection", "Module");
- res = mono_array_new (domain, klass, module_count + file_count);
+ klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
+ res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
mono_array_set (res, gpointer, 0, mono_module_get_object (domain, assembly->assembly->image));
- for ( i = 1; i < module_count; ++i )
- mono_array_set (res, gpointer, i, mono_module_get_object (domain, modules[i]));
+ j = 1;
+ for (i = 0; i < module_count; ++i)
+ if (modules [i]) {
+ mono_array_set (res, gpointer, j, mono_module_get_object (domain, modules[i]));
+ ++j;
+ }
- for (i = 0; i < table->rows; ++i)
- mono_array_set (res, gpointer, module_count + i, mono_module_file_get_object (domain, assembly->assembly->image, i));
+ for (i = 0; i < file_count; ++i, ++j)
+ mono_array_set (res, gpointer, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
return res;
}
return mono_method_get_object (mono_domain_get (), m, NULL);
}
+static MonoReflectionMethod*
+ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
+{
+ return mono_method_get_object (mono_domain_get (), method, NULL);
+}
+
+static MonoReflectionMethodBody*
+ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
+{
+ return mono_method_body_get_object (mono_domain_get (), method);
+}
+
static MonoReflectionAssembly*
ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
{
MONO_ARCH_SAVE_REGS;
if (!domain->entry_assembly)
- domain = mono_root_domain;
+ domain = mono_get_root_domain ();
return mono_assembly_get_object (domain, domain->entry_assembly);
}
MONO_ARCH_SAVE_REGS;
- mono_stack_walk (get_caller, &dest);
+ mono_stack_walk_no_il (get_caller, &dest);
if (!dest)
dest = m;
return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
}
static MonoString *
-ves_icall_System_MonoType_getFullName (MonoReflectionType *object)
+ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name)
{
MonoDomain *domain = mono_object_domain (object);
MonoString *res;
MONO_ARCH_SAVE_REGS;
- name = mono_type_get_name (object->type);
+ if (full_name)
+ name = mono_type_get_full_name (object->type);
+ else
+ name = mono_type_get_name (object->type);
res = mono_string_new (domain, name);
g_free (name);
static MonoArray*
ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
{
- MonoArray *res;
- MonoImage *image = assembly->assembly->image;
- MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
+ MonoArray *res = NULL;
+ MonoImage *image = NULL;
+ MonoTableInfo *table = NULL;
MonoDomain *domain;
int i;
MONO_ARCH_SAVE_REGS;
domain = mono_object_domain (assembly);
+
+ if (assembly->assembly->dynamic) {
+ MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
+ if (abuilder->modules) {
+ for (i = 0; i < mono_array_length(abuilder->modules); i++) {
+ MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
+ if (res == NULL)
+ res = mb->types;
+ else {
+ MonoArray *append = mb->types;
+ if (mono_array_length (append) > 0) {
+ guint32 len1, len2;
+ MonoArray *new;
+ len1 = mono_array_length (res);
+ len2 = mono_array_length (append);
+ new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
+ memcpy (mono_array_addr (new, MonoReflectionType*, 0),
+ mono_array_addr (res, MonoReflectionType*, 0),
+ len1 * sizeof (MonoReflectionType*));
+ memcpy (mono_array_addr (new, MonoReflectionType*, len1),
+ mono_array_addr (append, MonoReflectionType*, 0),
+ len2 * sizeof (MonoReflectionType*));
+ res = new;
+ }
+ }
+ }
+
+ /*
+ * Replace TypeBuilders with the created types to be compatible
+ * with MS.NET.
+ */
+ if (res) {
+ for (i = 0; i < mono_array_length (res); ++i) {
+ MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
+ if (tb->created)
+ mono_array_set (res, MonoReflectionType*, i, tb->created);
+ }
+ }
+ }
+
+ if (abuilder->loaded_modules)
+ for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
+ MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
+ if (res == NULL)
+ res = mono_module_get_types (domain, rm->image, exportedOnly);
+ else {
+ MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
+ if (mono_array_length (append) > 0) {
+ guint32 len1, len2;
+ MonoArray *new;
+ len1 = mono_array_length (res);
+ len2 = mono_array_length (append);
+ new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
+ memcpy (mono_array_addr (new, MonoReflectionType*, 0),
+ mono_array_addr (res, MonoReflectionType*, 0),
+ len1 * sizeof (MonoReflectionType*));
+ memcpy (mono_array_addr (new, MonoReflectionType*, len1),
+ mono_array_addr (append, MonoReflectionType*, 0),
+ len2 * sizeof (MonoReflectionType*));
+ res = new;
+ }
+ }
+ }
+ return res;
+ }
+ image = assembly->assembly->image;
+ table = &image->tables [MONO_TABLE_FILE];
res = mono_module_get_types (domain, image, exportedOnly);
/* Append data from all modules in the assembly */
}
}
}
-
return res;
}
MONO_ARCH_SAVE_REGS;
g_assert (module->image);
+
+ if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
+ /* These images do not have a global type */
+ return NULL;
+
klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
return mono_type_get_object (domain, &klass->byval_arg);
}
return mono_string_new (domain, module->image->guid);
}
+static void
+ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
+{
+ if (image->dynamic) {
+ MonoDynamicImage *dyn = (MonoDynamicImage*)image;
+ *pe_kind = dyn->pe_kind;
+ *machine = dyn->machine;
+ }
+ else {
+ *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
+ *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
+ }
+}
+
static MonoArray*
ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
{
return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
}
+static gboolean
+mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
+{
+ guint32 cols [MONO_MEMBERREF_SIZE];
+ const char *sig;
+ mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
+ sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
+ mono_metadata_decode_blob_size (sig, &sig);
+ return (*sig != 0x6);
+}
+
+static MonoType*
+ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+{
+ MonoClass *klass;
+ int table = mono_metadata_token_table (token);
+ int index = mono_metadata_token_index (token);
+
+ *error = ResolveTokenError_Other;
+
+ /* Validate token */
+ if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
+ (table != MONO_TABLE_TYPESPEC)) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ if (image->dynamic)
+ return mono_lookup_dynamic_token (image, token);
+
+ if ((index <= 0) || (index > image->tables [table].rows)) {
+ *error = ResolveTokenError_OutOfRange;
+ return NULL;
+ }
+
+ klass = mono_class_get (image, token);
+ if (klass)
+ return &klass->byval_arg;
+ else
+ return NULL;
+}
+
+static MonoMethod*
+ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+{
+ int table = mono_metadata_token_table (token);
+ int index = mono_metadata_token_index (token);
+
+ *error = ResolveTokenError_Other;
+
+ /* Validate token */
+ if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
+ (table != MONO_TABLE_MEMBERREF)) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ if (image->dynamic)
+ /* FIXME: validate memberref token type */
+ return mono_lookup_dynamic_token (image, token);
+
+ if ((index <= 0) || (index > image->tables [table].rows)) {
+ *error = ResolveTokenError_OutOfRange;
+ return NULL;
+ }
+ if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ return mono_get_method (image, token, NULL);
+}
+
+static MonoString*
+ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+{
+ int index = mono_metadata_token_index (token);
+
+ *error = ResolveTokenError_Other;
+
+ /* Validate token */
+ if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ if (image->dynamic)
+ return mono_lookup_dynamic_token (image, token);
+
+ if ((index <= 0) || (index >= image->heap_us.size)) {
+ *error = ResolveTokenError_OutOfRange;
+ return NULL;
+ }
+
+ /* FIXME: What to do if the index points into the middle of a string ? */
+
+ return mono_ldstr (mono_domain_get (), image, index);
+}
+
+static MonoClassField*
+ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+{
+ MonoClass *klass;
+ int table = mono_metadata_token_table (token);
+ int index = mono_metadata_token_index (token);
+
+ *error = ResolveTokenError_Other;
+
+ /* Validate token */
+ if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ if (image->dynamic)
+ /* FIXME: validate memberref token type */
+ return mono_lookup_dynamic_token (image, token);
+
+ if ((index <= 0) || (index > image->tables [table].rows)) {
+ *error = ResolveTokenError_OutOfRange;
+ return NULL;
+ }
+ if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
+ *error = ResolveTokenError_BadTable;
+ return NULL;
+ }
+
+ return mono_field_from_token (image, token, &klass, NULL);
+}
+
+
+static MonoObject*
+ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
+{
+ int table = mono_metadata_token_table (token);
+
+ *error = ResolveTokenError_Other;
+
+ switch (table) {
+ case MONO_TABLE_TYPEDEF:
+ case MONO_TABLE_TYPEREF:
+ case MONO_TABLE_TYPESPEC: {
+ MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
+ if (t)
+ return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
+ else
+ return NULL;
+ }
+ case MONO_TABLE_METHOD:
+ case MONO_TABLE_METHODSPEC: {
+ MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
+ if (m)
+ return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
+ else
+ return NULL;
+ }
+ case MONO_TABLE_FIELD: {
+ MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
+ if (f)
+ return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
+ else
+ return NULL;
+ }
+ case MONO_TABLE_MEMBERREF:
+ if (mono_metadata_memberref_is_method (image, token)) {
+ MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
+ if (m)
+ return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
+ else
+ return NULL;
+ }
+ else {
+ MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
+ if (f)
+ return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
+ else
+ return NULL;
+ }
+ break;
+
+ default:
+ *error = ResolveTokenError_BadTable;
+ }
+
+ return NULL;
+}
+
static MonoReflectionType*
ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
{
return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
}
+static MonoReflectionType *
+ves_icall_Type_MakePointerType (MonoReflectionType *type)
+{
+ MonoClass *pklass;
+
+ MONO_ARCH_SAVE_REGS;
+
+ pklass = mono_ptr_class_get (type->type);
+
+ return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
+}
+
static MonoObject *
ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
MonoReflectionMethod *info)
return delegate;
}
+static void
+ves_icall_System_Delegate_FreeTrampoline (MonoDelegate *this)
+{
+ mono_delegate_free_ftnptr (this);
+}
+
/*
* Magic number to convert a time which is relative to
* Jan 1, 1970 into a value which is relative to Jan 1, 0001.
t1 += 60;
tt1 = *localtime (&t1);
} while (gmt_offset (&tt1, t1) == gmtoff);
-
+ t1+=gmtoff;
strftime (tzone, sizeof (tzone), "%Z", &tt);
/* Write data, if we're already in daylight saving, we're done. */
return result;
}
+static MonoString *
+ves_icall_System_Environment_InternalGetHome (void)
+{
+ MONO_ARCH_SAVE_REGS;
+
+ return mono_string_new (mono_domain_get (), g_get_home_dir ());
+}
+
static const char *encodings [] = {
(char *) 1,
"ascii", "us_ascii", "us", "ansi_x3.4_1968",
ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
{
const char *cset;
- char *p;
+ const char *p;
+ char *c;
char *codepage = NULL;
int code;
int want_name = *int_code_page;
MONO_ARCH_SAVE_REGS;
g_get_charset (&cset);
- p = codepage = strdup (cset);
- for (p = codepage; *p; p++){
- if (isascii (*p) && isalpha (*p))
- *p = tolower (*p);
- if (*p == '-')
- *p = '_';
+ c = codepage = strdup (cset);
+ for (c = codepage; *c; c++){
+ if (isascii (*c) && isalpha (*c))
+ *c = tolower (*c);
+ if (*c == '-')
+ *c = '_';
}
/* g_print ("charset: %s\n", cset); */
p = encodings [0];
code = 0;
for (i = 0; p != 0; ){
- if ((int) p < 7){
- code = (int) p;
+ if ((gssize) p < 7){
+ code = (gssize) p;
p = encodings [++i];
continue;
}
MONO_ARCH_SAVE_REGS;
- path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", "machine.config", NULL);
+ path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_framework_version (), "machine.config", NULL);
#if defined (PLATFORM_WIN32)
/* Avoid mixing '/' and '\\' */
iter->args = (char*)iter->args + arg_size;
iter->next_arg++;
- //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
+ /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
return res;
}
arg_size = mono_type_stack_size (res.type, &align);
iter->args = (char*)iter->args + arg_size;
iter->next_arg++;
- //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
+ /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
return res;
}
- //g_print ("arg type 0x%02x not found\n", res.type->type);
+ /* g_print ("arg type 0x%02x not found\n", res.type->type); */
res.type = NULL;
res.value = NULL;
prelink_method (klass->methods [i]);
}
+/* These parameters are "readonly" in corlib/System/Char.cs */
static void
-ves_icall_System_Char_GetDataTablePointers (guint8 **category_data, guint8 **numeric_data,
- gdouble **numeric_data_values, guint16 **to_lower_data_low,
- guint16 **to_lower_data_high, guint16 **to_upper_data_low,
- guint16 **to_upper_data_high)
+ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
+ guint8 const **numeric_data,
+ gdouble const **numeric_data_values,
+ guint16 const **to_lower_data_low,
+ guint16 const **to_lower_data_high,
+ guint16 const **to_upper_data_low,
+ guint16 const **to_upper_data_high)
{
*category_data = CategoryData;
*numeric_data = NumericData;
*to_upper_data_high = ToUpperDataHigh;
}
+static MonoString *
+ves_icall_MonoDebugger_check_runtime_version (MonoString *fname)
+{
+ gchar *filename, *error = NULL;
+
+ MONO_ARCH_SAVE_REGS;
+
+ filename = mono_string_to_utf8 (fname);
+ error = mono_debugger_check_runtime_version (filename);
+ g_free (filename);
+
+ if (error)
+ return mono_string_new (mono_domain_get (), error);
+ else
+ return NULL;
+}
+
/* icall map */
typedef struct {
const char *method;
{"SetData", ves_icall_System_AppDomain_SetData},
{"createDomain", ves_icall_System_AppDomain_createDomain},
{"getCurDomain", ves_icall_System_AppDomain_getCurDomain},
+ {"getDomainByID", ves_icall_System_AppDomain_getDomainByID},
{"getFriendlyName", ves_icall_System_AppDomain_getFriendlyName},
{"getSetup", ves_icall_System_AppDomain_getSetup}
};
};
static const IcallEntry array_icalls [] = {
+ {"ClearInternal", ves_icall_System_Array_ClearInternal},
{"Clone", mono_array_clone},
{"CreateInstanceImpl", ves_icall_System_Array_CreateInstanceImpl},
{"FastCopy", ves_icall_System_Array_FastCopy},
};
static const IcallEntry delegate_icalls [] = {
- {"CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal}
+ {"CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal},
+ {"FreeTrampoline", ves_icall_System_Delegate_FreeTrampoline}
};
static const IcallEntry tracelist_icalls [] = {
{"get_TickCount", ves_icall_System_Environment_get_TickCount},
{"get_UserName", ves_icall_System_Environment_get_UserName},
{"internalGetGacPath", ves_icall_System_Environment_GetGacPath},
+ {"internalGetHome", ves_icall_System_Environment_InternalGetHome},
{"set_ExitCode", mono_environment_exitcode_set}
};
};
static const IcallEntry customattrs_icalls [] = {
- {"GetCustomAttributes", mono_reflection_get_custom_attrs}
+ {"GetCustomAttributesInternal", mono_reflection_get_custom_attrs}
};
static const IcallEntry enuminfo_icalls [] = {
};
static const IcallEntry fieldinfo_icalls [] = {
+ {"GetUnmanagedMarshal", ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal},
{"internal_from_handle", ves_icall_System_Reflection_FieldInfo_internal_from_handle}
};
+static const IcallEntry memberinfo_icalls [] = {
+ {"get_MetadataToken", mono_reflection_get_token}
+};
+
static const IcallEntry monotype_icalls [] = {
{"GetArrayRank", ves_icall_MonoType_GetArrayRank},
{"GetConstructors", ves_icall_Type_GetConstructors_internal},
/*
* Private icalls for the Mono Debugger
*/
+ {"MonoDebugger_CheckRuntimeVersion", ves_icall_MonoDebugger_check_runtime_version},
{"MonoDebugger_GetLocalTypeFromSignature", ves_icall_MonoDebugger_GetLocalTypeFromSignature},
{"MonoDebugger_GetMethod", ves_icall_MonoDebugger_GetMethod},
{"MonoDebugger_GetMethodToken", ves_icall_MonoDebugger_GetMethodToken},
{"MonoDebugger_GetType", ves_icall_MonoDebugger_GetType},
+
/* normal icalls again */
{"get_EntryPoint", ves_icall_System_Reflection_Assembly_get_EntryPoint},
+ {"get_ManifestModule", ves_icall_System_Reflection_Assembly_get_ManifestModule},
+ {"get_MetadataToken", mono_reflection_get_token},
{"get_code_base", ves_icall_System_Reflection_Assembly_get_code_base},
{"get_global_assembly_cache", ves_icall_System_Reflection_Assembly_get_global_assembly_cache},
{"get_location", ves_icall_System_Reflection_Assembly_get_location},
};
static const IcallEntry methodbase_icalls [] = {
- {"GetCurrentMethod", ves_icall_GetCurrentMethod}
+ {"GetCurrentMethod", ves_icall_GetCurrentMethod},
+ {"GetMethodBodyInternal", ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal},
+ {"GetMethodFromHandleInternal", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal}
};
static const IcallEntry module_icalls [] = {
{"Close", ves_icall_System_Reflection_Module_Close},
{"GetGlobalType", ves_icall_System_Reflection_Module_GetGlobalType},
{"GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal},
- {"InternalGetTypes", ves_icall_System_Reflection_Module_InternalGetTypes}
+ {"GetPEKind", ves_icall_System_Reflection_Module_GetPEKind},
+ {"InternalGetTypes", ves_icall_System_Reflection_Module_InternalGetTypes},
+ {"ResolveFieldToken", ves_icall_System_Reflection_Module_ResolveFieldToken},
+ {"ResolveMemberToken", ves_icall_System_Reflection_Module_ResolveMemberToken},
+ {"ResolveMethodToken", ves_icall_System_Reflection_Module_ResolveMethodToken},
+ {"ResolveStringToken", ves_icall_System_Reflection_Module_ResolveStringToken},
+ {"ResolveTypeToken", ves_icall_System_Reflection_Module_ResolveTypeToken},
+ {"get_MetadataToken", mono_reflection_get_token}
};
static const IcallEntry monocmethod_icalls [] = {
};
static const IcallEntry monofield_icalls [] = {
+ {"GetFieldOffset", ves_icall_MonoField_GetFieldOffset},
{"GetParentType", ves_icall_MonoField_GetParentType},
{"GetValueInternal", ves_icall_MonoField_GetValueInternal},
{"Mono_GetGenericFieldDefinition", ves_icall_MonoField_Mono_GetGenericFieldDefinition},
static const IcallEntry monomethod_icalls [] = {
{"BindGenericParameters", mono_reflection_bind_generic_method_parameters},
+ {"GetDllImportAttribute", ves_icall_MonoMethod_GetDllImportAttribute},
{"GetGenericArguments", ves_icall_MonoMethod_GetGenericArguments},
{"GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition},
{"InternalInvoke", ves_icall_InternalInvoke},
{"get_property_info", ves_icall_get_property_info}
};
+static const IcallEntry parameterinfo_icalls [] = {
+ {"get_MetadataToken", mono_reflection_get_token}
+};
+
static const IcallEntry dns_icalls [] = {
{"GetHostByAddr_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByAddr_internal},
{"GetHostByName_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByName_internal},
};
static const IcallEntry typebuilder_icalls [] = {
+ {"create_generic_class", mono_reflection_create_generic_class},
{"create_internal_class", mono_reflection_create_internal_class},
{"create_runtime_class", mono_reflection_create_runtime_class},
{"get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter},
{"setup_internal_class", mono_reflection_setup_internal_class}
};
+static const IcallEntry enumbuilder_icalls [] = {
+ {"setup_enum_type", ves_icall_EnumBuilder_setup_enum_type}
+};
+
static const IcallEntry runtimehelpers_icalls [] = {
{"GetObjectValue", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue},
+ /* REMOVEME: no longer needed, just so we dont break things when not needed */
{"GetOffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData},
{"InitializeArray", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray},
- {"RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor}
+ {"RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor},
+ {"get_OffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData}
};
static const IcallEntry gchandle_icalls [] = {
static const IcallEntry marshal_icalls [] = {
{"AllocCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem},
- {"AllocHGlobal", mono_marshal_alloc},
+ {"AllocHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal},
{"DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure},
{"FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem},
- {"FreeHGlobal", mono_marshal_free},
+ {"FreeHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal},
+ {"GetDelegateForFunctionPointerInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal},
+ {"GetFunctionPointerForDelegateInternal", mono_delegate_to_ftnptr},
{"GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error},
{"OffsetOf", ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf},
{"Prelink", ves_icall_System_Runtime_InteropServices_Marshal_Prelink},
};
static const IcallEntry mutex_icalls [] = {
- {"CreateMutex_internal", ves_icall_System_Threading_Mutex_CreateMutex_internal},
- {"ReleaseMutex_internal", ves_icall_System_Threading_Mutex_ReleaseMutex_internal}
+ {"CreateMutex_internal(bool,string,bool&)", ves_icall_System_Threading_Mutex_CreateMutex_internal},
+ {"ReleaseMutex_internal(intptr)", ves_icall_System_Threading_Mutex_ReleaseMutex_internal}
};
static const IcallEntry nativeevents_icalls [] = {
{"Suspend_internal", ves_icall_System_Threading_Thread_Suspend},
{"Thread_free_internal", ves_icall_System_Threading_Thread_Thread_free_internal},
{"Thread_internal", ves_icall_System_Threading_Thread_Thread_internal},
- {"VolatileRead(IntPtr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
- {"VolatileRead(UIntPtr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
{"VolatileRead(byte&)", ves_icall_System_Threading_Thread_VolatileRead1},
{"VolatileRead(double&)", ves_icall_System_Threading_Thread_VolatileRead8},
- {"VolatileRead(float&)", ves_icall_System_Threading_Thread_VolatileRead4},
{"VolatileRead(int&)", ves_icall_System_Threading_Thread_VolatileRead4},
+ {"VolatileRead(int16&)", ves_icall_System_Threading_Thread_VolatileRead2},
+ {"VolatileRead(intptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
{"VolatileRead(long&)", ves_icall_System_Threading_Thread_VolatileRead8},
{"VolatileRead(object&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
{"VolatileRead(sbyte&)", ves_icall_System_Threading_Thread_VolatileRead1},
- {"VolatileRead(short&)", ves_icall_System_Threading_Thread_VolatileRead2},
+ {"VolatileRead(single&)", ves_icall_System_Threading_Thread_VolatileRead4},
{"VolatileRead(uint&)", ves_icall_System_Threading_Thread_VolatileRead2},
+ {"VolatileRead(uint16&)", ves_icall_System_Threading_Thread_VolatileRead2},
+ {"VolatileRead(uintptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
{"VolatileRead(ulong&)", ves_icall_System_Threading_Thread_VolatileRead8},
- {"VolatileRead(ushort&)", ves_icall_System_Threading_Thread_VolatileRead2},
- {"VolatileWrite(IntPtr&,IntPtr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
- {"VolatileWrite(UIntPtr&,UIntPtr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
{"VolatileWrite(byte&,byte)", ves_icall_System_Threading_Thread_VolatileWrite1},
{"VolatileWrite(double&,double)", ves_icall_System_Threading_Thread_VolatileWrite8},
- {"VolatileWrite(float&,float)", ves_icall_System_Threading_Thread_VolatileWrite4},
{"VolatileWrite(int&,int)", ves_icall_System_Threading_Thread_VolatileWrite4},
+ {"VolatileWrite(int16&,int16)", ves_icall_System_Threading_Thread_VolatileWrite2},
+ {"VolatileWrite(intptr&,intptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
{"VolatileWrite(long&,long)", ves_icall_System_Threading_Thread_VolatileWrite8},
{"VolatileWrite(object&,object)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
{"VolatileWrite(sbyte&,sbyte)", ves_icall_System_Threading_Thread_VolatileWrite1},
- {"VolatileWrite(short&,short)", ves_icall_System_Threading_Thread_VolatileWrite2},
+ {"VolatileWrite(single&,single)", ves_icall_System_Threading_Thread_VolatileWrite4},
{"VolatileWrite(uint&,uint)", ves_icall_System_Threading_Thread_VolatileWrite2},
+ {"VolatileWrite(uint16&,uint16)", ves_icall_System_Threading_Thread_VolatileWrite2},
+ {"VolatileWrite(uintptr&,uintptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
{"VolatileWrite(ulong&,ulong)", ves_icall_System_Threading_Thread_VolatileWrite8},
- {"VolatileWrite(ushort&,ushort)", ves_icall_System_Threading_Thread_VolatileWrite2},
{"current_lcid()", ves_icall_System_Threading_Thread_current_lcid}
};
static const IcallEntry type_icalls [] = {
{"BindGenericParameters", ves_icall_Type_BindGenericParameters},
{"Equals", ves_icall_type_Equals},
+ {"GetGenericParameterAttributes", ves_icall_Type_GetGenericParameterAttributes},
+ {"GetGenericParameterConstraints_impl", ves_icall_Type_GetGenericParameterConstraints},
{"GetGenericParameterPosition", ves_icall_Type_GetGenericParameterPosition},
{"GetGenericTypeDefinition_impl", ves_icall_Type_GetGenericTypeDefinition_impl},
{"GetInterfaceMapData", ves_icall_Type_GetInterfaceMapData},
+ {"GetPacking", ves_icall_Type_GetPacking},
{"GetTypeCode", ves_icall_type_GetTypeCode},
{"IsArrayImpl", ves_icall_Type_IsArrayImpl},
{"IsInstanceOfType", ves_icall_type_IsInstanceOfType},
+ {"MakePointerType", ves_icall_Type_MakePointerType},
{"get_IsGenericInstance", ves_icall_Type_get_IsGenericInstance},
{"get_IsGenericTypeDefinition", ves_icall_Type_get_IsGenericTypeDefinition},
{"internal_from_handle", ves_icall_type_from_handle},
{"System.Reflection.Emit.AssemblyBuilder", assemblybuilder_icalls, G_N_ELEMENTS (assemblybuilder_icalls)},
{"System.Reflection.Emit.CustomAttributeBuilder", customattrbuilder_icalls, G_N_ELEMENTS (customattrbuilder_icalls)},
{"System.Reflection.Emit.DynamicMethod", dynamicmethod_icalls, G_N_ELEMENTS (dynamicmethod_icalls)},
+ {"System.Reflection.Emit.EnumBuilder", enumbuilder_icalls, G_N_ELEMENTS (enumbuilder_icalls)},
{"System.Reflection.Emit.GenericTypeParameterBuilder", generictypeparambuilder_icalls, G_N_ELEMENTS (generictypeparambuilder_icalls)},
{"System.Reflection.Emit.MethodBuilder", methodbuilder_icalls, G_N_ELEMENTS (methodbuilder_icalls)},
{"System.Reflection.Emit.ModuleBuilder", modulebuilder_icalls, G_N_ELEMENTS (modulebuilder_icalls)},
{"System.Reflection.Emit.SignatureHelper", signaturehelper_icalls, G_N_ELEMENTS (signaturehelper_icalls)},
{"System.Reflection.Emit.TypeBuilder", typebuilder_icalls, G_N_ELEMENTS (typebuilder_icalls)},
{"System.Reflection.FieldInfo", fieldinfo_icalls, G_N_ELEMENTS (fieldinfo_icalls)},
+ {"System.Reflection.MemberInfo", memberinfo_icalls, G_N_ELEMENTS (memberinfo_icalls)},
{"System.Reflection.MethodBase", methodbase_icalls, G_N_ELEMENTS (methodbase_icalls)},
{"System.Reflection.Module", module_icalls, G_N_ELEMENTS (module_icalls)},
{"System.Reflection.MonoCMethod", monocmethod_icalls, G_N_ELEMENTS (monocmethod_icalls)},
{"System.Reflection.MonoMethod", monomethod_icalls, G_N_ELEMENTS (monomethod_icalls)},
{"System.Reflection.MonoMethodInfo", monomethodinfo_icalls, G_N_ELEMENTS (monomethodinfo_icalls)},
{"System.Reflection.MonoPropertyInfo", monopropertyinfo_icalls, G_N_ELEMENTS (monopropertyinfo_icalls)},
+ {"System.Reflection.ParameterInfo", parameterinfo_icalls, G_N_ELEMENTS (parameterinfo_icalls)},
{"System.Runtime.CompilerServices.RuntimeHelpers", runtimehelpers_icalls, G_N_ELEMENTS (runtimehelpers_icalls)},
{"System.Runtime.InteropServices.GCHandle", gchandle_icalls, G_N_ELEMENTS (gchandle_icalls)},
{"System.Runtime.InteropServices.Marshal", marshal_icalls, G_N_ELEMENTS (marshal_icalls)},
};
static GHashTable *icall_hash = NULL;
+static GHashTable *jit_icall_hash_name = NULL;
+static GHashTable *jit_icall_hash_addr = NULL;
void
mono_init_icall (void)
return NULL;
}
+static MonoType*
+type_from_typename (char *typename)
+{
+ MonoClass *klass = NULL; /* assignment to shut GCC warning up */
+
+ if (!strcmp (typename, "int"))
+ klass = mono_defaults.int_class;
+ else if (!strcmp (typename, "ptr"))
+ klass = mono_defaults.int_class;
+ else if (!strcmp (typename, "void"))
+ klass = mono_defaults.void_class;
+ else if (!strcmp (typename, "int32"))
+ klass = mono_defaults.int32_class;
+ else if (!strcmp (typename, "uint32"))
+ klass = mono_defaults.uint32_class;
+ else if (!strcmp (typename, "long"))
+ klass = mono_defaults.int64_class;
+ else if (!strcmp (typename, "ulong"))
+ klass = mono_defaults.uint64_class;
+ else if (!strcmp (typename, "float"))
+ klass = mono_defaults.single_class;
+ else if (!strcmp (typename, "double"))
+ klass = mono_defaults.double_class;
+ else if (!strcmp (typename, "object"))
+ klass = mono_defaults.object_class;
+ else if (!strcmp (typename, "obj"))
+ klass = mono_defaults.object_class;
+ else {
+ g_error (typename);
+ g_assert_not_reached ();
+ }
+ return &klass->byval_arg;
+}
+
+MonoMethodSignature*
+mono_create_icall_signature (const char *sigstr)
+{
+ gchar **parts;
+ int i, len;
+ gchar **tmp;
+ MonoMethodSignature *res;
+
+ mono_loader_lock ();
+ res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
+ if (res) {
+ mono_loader_unlock ();
+ return res;
+ }
+
+ parts = g_strsplit (sigstr, " ", 256);
+
+ tmp = parts;
+ len = 0;
+ while (*tmp) {
+ len ++;
+ tmp ++;
+ }
+
+ res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
+ res->pinvoke = 1;
+
+#ifdef PLATFORM_WIN32
+ /*
+ * Under windows, the default pinvoke calling convention is STDCALL but
+ * we need CDECL.
+ */
+ res->call_convention = MONO_CALL_C;
+#endif
+
+ res->ret = type_from_typename (parts [0]);
+ for (i = 1; i < len; ++i) {
+ res->params [i - 1] = type_from_typename (parts [i]);
+ }
+
+ g_strfreev (parts);
+
+ g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
+
+ mono_loader_unlock ();
+
+ return res;
+}
+
+MonoJitICallInfo *
+mono_find_jit_icall_by_name (const char *name)
+{
+ MonoJitICallInfo *info;
+ g_assert (jit_icall_hash_name);
+
+ mono_loader_lock ();
+ info = g_hash_table_lookup (jit_icall_hash_name, name);
+ mono_loader_unlock ();
+ return info;
+}
+
+MonoJitICallInfo *
+mono_find_jit_icall_by_addr (gconstpointer addr)
+{
+ MonoJitICallInfo *info;
+ g_assert (jit_icall_hash_addr);
+
+ mono_loader_lock ();
+ info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
+ mono_loader_unlock ();
+
+ return info;
+}
+
+void
+mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
+{
+ mono_loader_lock ();
+ g_hash_table_insert (jit_icall_hash_addr, (gpointer)info->wrapper, info);
+ mono_loader_unlock ();
+}
+
+MonoJitICallInfo *
+mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
+{
+ MonoJitICallInfo *info;
+
+ g_assert (func);
+ g_assert (name);
+
+ mono_loader_lock ();
+
+ if (!jit_icall_hash_name) {
+ jit_icall_hash_name = g_hash_table_new (g_str_hash, g_str_equal);
+ jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
+ }
+
+ if (g_hash_table_lookup (jit_icall_hash_name, name)) {
+ g_warning ("jit icall already defined \"%s\"\n", name);
+ g_assert_not_reached ();
+ }
+
+ info = g_new (MonoJitICallInfo, 1);
+
+ info->name = name;
+ info->func = func;
+ info->sig = sig;
+
+ if (is_save) {
+ info->wrapper = func;
+ } else {
+ info->wrapper = NULL;
+ }
+
+ g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
+ g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
+
+ mono_loader_unlock ();
+ return info;
+}