#include "mono-endian.h"
#include "cil-coff.h"
#include "tokentype.h"
+#include "metadata-internals.h"
+#include "class-internals.h"
#include "private.h"
#include "class.h"
{
MonoType *type, *cached;
gboolean byref = FALSE;
+ gboolean pinned = FALSE;
+ const char *tmp_ptr;
+ int count = 0;
+ gboolean found;
/*
* According to the spec, custom modifiers should come before the byref
* Also, this type seems to be different from 'object & modopt(...)'. Maybe
* it would be better to treat byref as real type constructor instead of
* a modifier...
+ * Also, pinned should come before anything else, but some MSV++ produced
+ * assemblies violate this (#bug 61990).
*/
- if (*ptr == MONO_TYPE_BYREF) {
- byref = TRUE;
- ++ptr;
- }
- switch (mode) {
- case MONO_PARSE_MOD_TYPE:
- case MONO_PARSE_PARAM:
- case MONO_PARSE_RET:
- case MONO_PARSE_LOCAL: /* should not have modifiers according to the spec, but ms tools disagree */
- case MONO_PARSE_FIELD: {
- /* count the modifiers */
- const char *tmp_ptr = ptr;
- int count = 0;
- while (mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr))
- count++;
- if (count) {
- type = g_malloc0 (sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
- type->num_mods = count;
- if (count > 64)
- g_warning ("got more than 64 modifiers in type");
- /* save them this time */
- count = 0;
- while (mono_metadata_parse_custom_mod (m, &(type->modifiers [count]), ptr, &ptr))
- count++;
+ /* Count the modifiers first */
+ tmp_ptr = ptr;
+ found = TRUE;
+ while (found) {
+ switch (*tmp_ptr) {
+ case MONO_TYPE_PINNED:
+ case MONO_TYPE_BYREF:
+ ++tmp_ptr;
+ break;
+ case MONO_TYPE_CMOD_REQD:
+ case MONO_TYPE_CMOD_OPT:
+ count ++;
+ mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr);
break;
- } /* fall through */
+ default:
+ found = FALSE;
+ }
}
- case MONO_PARSE_TYPE:
+
+ if (count) {
+ type = g_malloc0 (sizeof (MonoType) + ((gint32)count - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod));
+ type->num_mods = count;
+ if (count > 64)
+ g_warning ("got more than 64 modifiers in type");
+ }
+ else
/*
* Later we can avoid doing this allocation.
*/
type = g_new0 (MonoType, 1);
- break;
- default:
- g_assert_not_reached ();
+
+ /* Parse pinned, byref and custom modifiers */
+ found = TRUE;
+ count = 0;
+ while (found) {
+ switch (*ptr) {
+ case MONO_TYPE_PINNED:
+ pinned = TRUE;
+ ++ptr;
+ break;
+ case MONO_TYPE_BYREF:
+ byref = TRUE;
+ ++ptr;
+ break;
+ case MONO_TYPE_CMOD_REQD:
+ case MONO_TYPE_CMOD_OPT:
+ count ++;
+ mono_metadata_parse_custom_mod (m, &(type->modifiers [count]), ptr, &ptr);
+ break;
+ default:
+ found = FALSE;
+ }
}
type->attrs = opt_attrs;
type->byref = byref;
- if (mode == MONO_PARSE_LOCAL) {
- /*
- * check for pinned flag
- */
- if (*ptr == MONO_TYPE_PINNED) {
- type->pinned = 1;
- ++ptr;
- }
- }
+ type->pinned = pinned ? 1 : 0;
+
+ do_mono_metadata_parse_type (type, m, ptr, &ptr);
- switch (*ptr) {
- case MONO_TYPE_BYREF:
- if (mode == MONO_PARSE_FIELD)
- g_warning ("A field type cannot be byref");
- type->byref = 1;
- ptr++;
- /* follow through */
- default:
- /*if (*ptr == MONO_TYPE_VOID && mode != MONO_PARSE_RET)
- g_error ("void not allowed in param");*/
- do_mono_metadata_parse_type (type, m, ptr, &ptr);
- break;
- }
if (rptr)
*rptr = ptr;
/* later we want to allocate signatures with mempools */
sig = g_malloc0 (sizeof (MonoMethodSignature) + ((gint32)nparams - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
sig->param_count = nparams;
+ sig->sentinelpos = -1;
return sig;
}
+MonoMethodSignature*
+mono_metadata_signature_dup (MonoMethodSignature *sig)
+{
+ int sigsize;
+
+ sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
+ return g_memdup (sig, sigsize);
+}
+
/*
* mono_metadata_parse_method_signature:
* @m: metadata context
method->params [i] = mono_metadata_parse_type (m, MONO_PARSE_PARAM, pattrs [i], ptr, &ptr);
}
}
+
+ if (def && (method->call_convention == MONO_CALL_VARARG))
+ method->sentinelpos = method->param_count;
+
g_free (pattrs);
if (rptr)
case MONO_TYPE_SZARRAY: {
MonoType *etype = mono_metadata_parse_type (m, MONO_PARSE_MOD_TYPE, 0, ptr, &ptr);
type->data.klass = mono_class_from_mono_type (etype);
+ mono_metadata_free_type (etype);
break;
}
case MONO_TYPE_PTR:
return sizeof (gpointer);
case MONO_TYPE_TYPEDBYREF:
*align = __alignof__(gpointer);
- return sizeof (gpointer) * 2;
+ return sizeof (gpointer) * 3;
case MONO_TYPE_R4:
*align = __alignof__(float);
return sizeof (float);
MonoType *p1 = sig1->params[i];
MonoType *p2 = sig2->params[i];
- //if (p1->attrs != p2->attrs)
- // return FALSE;
-
+ /* if (p1->attrs != p2->attrs)
+ return FALSE;
+ */
if (!mono_metadata_type_equal (p1, p2))
return FALSE;
}
{
char *p = buf;
- if (value <= 127)
+ if (value < 0x80)
*p++ = value;
- else if (value <= 16384) {
+ else if (value < 0x4000) {
p [0] = 0x80 | (value >> 8);
p [1] = value & 0xff;
p += 2;
guint32 index = mono_metadata_token_index (token);
tdef = &meta->tables [MONO_TABLE_CONSTANT];
- index <<= HASCONSTANT_BITS;
+ index <<= MONO_HASCONSTANT_BITS;
switch (mono_metadata_token_table (token)) {
case MONO_TABLE_FIELD:
- index |= HASCONSTANT_FIEDDEF;
+ index |= MONO_HASCONSTANT_FIEDDEF;
break;
case MONO_TABLE_PARAM:
- index |= HASCONSTANT_PARAM;
+ index |= MONO_HASCONSTANT_PARAM;
break;
case MONO_TABLE_PROPERTY:
- index |= HASCONSTANT_PROPERTY;
+ index |= MONO_HASCONSTANT_PROPERTY;
break;
default:
g_warning ("Not a valid token for the constant table: 0x%08x", token);
loc.t = msemt;
loc.col_idx = MONO_METHOD_SEMA_ASSOCIATION;
- loc.idx = ((index + 1) << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_EVENT; /* Method association coded index */
+ loc.idx = ((index + 1) << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_EVENT; /* Method association coded index */
if (!bsearch (&loc, msemt->base, msemt->rows, msemt->row_size, table_locator))
return 0;
loc.t = msemt;
loc.col_idx = MONO_METHOD_SEMA_ASSOCIATION;
- loc.idx = ((index + 1) << HAS_SEMANTICS_BITS) | HAS_SEMANTICS_PROPERTY; /* Method association coded index */
+ loc.idx = ((index + 1) << MONO_HAS_SEMANTICS_BITS) | MONO_HAS_SEMANTICS_PROPERTY; /* Method association coded index */
if (!bsearch (&loc, msemt->base, msemt->rows, msemt->row_size, table_locator))
return 0;
loc.t = tdef;
loc.col_idx = MONO_IMPLMAP_MEMBER;
- loc.idx = ((method_idx + 1) << MEMBERFORWD_BITS) | MEMBERFORWD_METHODDEF;
+ loc.idx = ((method_idx + 1) << MONO_MEMBERFORWD_BITS) | MONO_MEMBERFORWD_METHODDEF;
if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
return 0;
case MONO_NATIVE_IUNKNOWN:
*conv = MONO_MARSHAL_CONV_OBJECT_IUNKNOWN;
return MONO_NATIVE_IUNKNOWN;
+ case MONO_NATIVE_FUNC:
+ if (t == MONO_TYPE_CLASS && (type->data.klass == mono_defaults.multicastdelegate_class ||
+ type->data.klass == mono_defaults.delegate_class ||
+ type->data.klass->parent == mono_defaults.multicastdelegate_class)) {
+ *conv = MONO_MARSHAL_CONV_DEL_FTN;
+ return MONO_NATIVE_FUNC;
+ }
+ else
+ /* Fall through */
+ ;
default:
g_error ("cant marshal object as native type %02x", mspec->native);
}
loc.t = tdef;
loc.col_idx = MONO_FIELD_MARSHAL_PARENT;
- loc.idx = ((idx + 1) << HAS_FIELD_MARSHAL_BITS) | (is_field? HAS_FIELD_MARSHAL_FIELDSREF: HAS_FIELD_MARSHAL_PARAMDEF);
+ loc.idx = ((idx + 1) << MONO_HAS_FIELD_MARSHAL_BITS) | (is_field? MONO_HAS_FIELD_MARSHAL_FIELDSREF: MONO_HAS_FIELD_MARSHAL_PARAMDEF);
if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
return NULL;
static MonoMethod*
method_from_method_def_or_ref (MonoImage *m, guint32 tok)
{
- guint32 idx = tok >> METHODDEFORREF_BITS;
- switch (tok & METHODDEFORREF_MASK) {
- case METHODDEFORREF_METHODDEF:
+ guint32 idx = tok >> MONO_METHODDEFORREF_BITS;
+ switch (tok & MONO_METHODDEFORREF_MASK) {
+ case MONO_METHODDEFORREF_METHODDEF:
return mono_get_method (m, MONO_TOKEN_METHOD_DEF | idx, NULL);
- case METHODDEFORREF_METHODREF:
+ case MONO_METHODDEFORREF_METHODREF:
return mono_get_method (m, MONO_TOKEN_MEMBER_REF | idx, NULL);
}
g_assert_not_reached ();
return params;
}
+gboolean
+mono_type_is_byref (MonoType *type)
+{
+ return type->byref;
+}
+
+int
+mono_type_get_type (MonoType *type)
+{
+ return type->type;
+}
+
+/* For MONO_TYPE_FNPTR */
+MonoMethodSignature*
+mono_type_get_signature (MonoType *type)
+{
+ return type->data.method;
+}
+
+/* For MONO_TYPE_CLASS, VALUETYPE */
+MonoClass*
+mono_type_get_class (MonoType *type)
+{
+ return type->data.klass;
+}
+
+/* For MONO_TYPE_ARRAY */
+MonoArrayType*
+mono_type_get_array_type (MonoType *type)
+{
+ return type->data.array;
+}
+
+MonoClass*
+mono_type_get_modifiers (MonoType *type, gboolean *is_required, gpointer *iter)
+{
+ /* FIXME: implement */
+ return NULL;
+}
+
+MonoType*
+mono_signature_get_return_type (MonoMethodSignature *sig)
+{
+ return sig->ret;
+}
+
+MonoType*
+mono_signature_get_params (MonoMethodSignature *sig, gpointer *iter)
+{
+ MonoType** type;
+ if (!iter)
+ return NULL;
+ if (!*iter) {
+ /* start from the first */
+ if (sig->param_count) {
+ *iter = &sig->params [0];
+ return sig->params [0];
+ } else {
+ /* no method */
+ return NULL;
+ }
+ }
+ type = *iter;
+ type++;
+ if (type < &sig->params [sig->param_count]) {
+ *iter = type;
+ return *type;
+ }
+ return NULL;
+}
+
+guint32
+mono_signature_get_param_count (MonoMethodSignature *sig)
+{
+ return sig->param_count;
+}
+
+guint32
+mono_signature_get_call_conv (MonoMethodSignature *sig)
+{
+ return sig->call_convention;
+}
+
+int
+mono_signature_vararg_start (MonoMethodSignature *sig)
+{
+ return sig->sentinelpos;
+}
+
+gboolean
+mono_signature_is_instance (MonoMethodSignature *sig)
+{
+ return sig->hasthis;
+}
+
+gboolean
+mono_signature_explicit_this (MonoMethodSignature *sig)
+{
+ return sig->explicit_this;
+}
+