#include "mono/metadata/tabledefs.h"
#include "mono/metadata/tokentype.h"
#include "mono/metadata/appdomain.h"
+#include "mono/metadata/opcodes.h"
#include <stdio.h>
#include <glib.h>
#include <errno.h>
#include "rawbuffer.h"
#include "mono-endian.h"
#include "private.h"
+#if HAVE_BOEHM_GC
+#include <gc/gc.h>
+#endif
#define TEXT_OFFSET 512
#define CLI_H_SIZE 136
}
static guint32
-string_heap_insert (MonoStringHeap *sh, const char *str)
+string_heap_insert (MonoDynamicStream *sh, const char *str)
{
guint32 idx;
guint32 len;
}
static void
-string_heap_init (MonoStringHeap *sh)
+string_heap_init (MonoDynamicStream *sh)
{
sh->index = 0;
sh->alloc_size = 4096;
}
static void
-string_heap_free (MonoStringHeap *sh)
+string_heap_free (MonoDynamicStream *sh)
{
g_free (sh->data);
g_hash_table_foreach (sh->hash, (GHFunc)g_free, NULL);
}
static guint32
-mono_image_add_stream_data (MonoDynamicStream *stream, char *data, guint32 len)
+mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
{
guint32 idx;
if (stream->alloc_size < stream->index + len) {
mono_metadata_encode_value (type->type, p, &p);
break;
case MONO_TYPE_PTR:
+ g_print ("encode pointer\n");
case MONO_TYPE_SZARRAY:
mono_metadata_encode_value (type->type, p, &p);
encode_type (assembly, type->data.type, p, &p);
for (i = 0; i < nparams; ++i)
encode_type (assembly, sig->params [i], p, &p);
/* store length */
+ g_assert (p - buf < size);
mono_metadata_encode_value (p-buf, b, &b);
idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
mono_image_add_stream_data (&assembly->blob, buf, p-buf);
encode_reflection_type (assembly, pt, p, &p);
}
/* store length */
+ g_assert (p - buf < size);
mono_metadata_encode_value (p-buf, b, &b);
idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
mono_image_add_stream_data (&assembly->blob, buf, p-buf);
MonoDynamicTable *table;
guint32 *values;
char *p;
- guint32 idx, sig_idx;
+ guint32 idx, sig_idx, size;
guint nl = mono_array_length (ilgen->locals);
char *buf;
char blob_size [6];
char *b = blob_size;
int i;
- p = buf = g_malloc (10 + nl * 10);
+ size = 10 + nl * 10;
+ p = buf = g_malloc (size);
table = &assembly->tables [MONO_TABLE_STANDALONESIG];
idx = table->next_idx ++;
table->rows ++;
MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
encode_reflection_type (assembly, lb->type, p, &p);
}
+ g_assert (p - buf < size);
mono_metadata_encode_value (p-buf, b, &b);
sig_idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
mono_image_add_stream_data (&assembly->blob, buf, p-buf);
idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
/* add to the fixup todo list */
if (mb->ilgen && mb->ilgen->num_token_fixups)
- g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 1));
+ mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 1));
mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
return assembly->text_rva + idx + CLI_H_SIZE;
}
idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
/* add to the fixup todo list */
if (mb->ilgen && mb->ilgen->num_token_fixups)
- g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 12));
+ mono_g_hash_table_insert (assembly->token_fixups, mb->ilgen, GUINT_TO_POINTER (idx + 12));
mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
if (num_exception) {
}
static guint32
-find_index_in_table (MonoDynamicAssembly *assembly, int table_idx, int col, guint32 index)
+find_index_in_table (MonoDynamicAssembly *assembly, int table_idx, int col, guint32 token)
{
int i;
MonoDynamicTable *table;
values = table->values + table->columns;
for (i = 1; i <= table->rows; ++i) {
- if (values [col] == index)
+ if (values [col] == token)
return i;
}
return 0;
}
/*
- * index is the table index of the object
+ * idx is the table index of the object
* type is one of CUSTOM_ATTR_*
*/
static void
-mono_image_add_cattrs (MonoDynamicAssembly *assembly, guint32 index, guint32 type, MonoArray *cattrs)
+mono_image_add_cattrs (MonoDynamicAssembly *assembly, guint32 idx, guint32 type, MonoArray *cattrs)
{
MonoDynamicTable *table;
MonoReflectionCustomAttr *cattr;
table->rows += count;
alloc_table (table, table->rows);
values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
- index <<= CUSTOM_ATTR_BITS;
- index |= type;
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= type;
for (i = 0; i < count; ++i) {
cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
- values [MONO_CUSTOM_ATTR_PARENT] = index;
+ values [MONO_CUSTOM_ATTR_PARENT] = idx;
token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor);
type = mono_metadata_token_index (token);
type <<= CUSTOM_ATTR_TYPE_BITS;
}
}
+/*
+ * Fill in the MethodDef and ParamDef tables for a method.
+ * This is used for both normal methods and constructors.
+ */
static void
mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicAssembly *assembly)
{
goto handle_enum;
} else
g_error ("we can't encode valuetypes");
- case MONO_TYPE_STRING:
+ case MONO_TYPE_STRING: {
+ MonoString *str = (MonoString*)val;
+ /* there is no signature */
+ len = str->length * 2;
+ mono_metadata_encode_value (len, b, &b);
+ idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
+ /* FIXME: ENOENDIAN */
+ mono_image_add_stream_data (&assembly->blob, (const char*)mono_string_chars (str), len);
+
+ g_free (buf);
+ return idx;
+ }
default:
g_error ("we don't encode constant type 0x%02x yet", *ret_type);
}
char *b = blob_size;
guint32 nparams = 0;
MonoReflectionMethodBuilder *mb = fb->get_method;
- guint32 idx, i;
+ guint32 idx, i, size;
if (mb && mb->parameters)
nparams = mono_array_length (mb->parameters);
- buf = p = g_malloc (24 + nparams * 10);
+ size = 24 + nparams * 10;
+ buf = p = g_malloc (size);
*p = 0x08;
p++;
mono_metadata_encode_value (nparams, p, &p);
*p++ = 1; /* void: a property should probably not be allowed without a getter */
}
/* store length */
+ g_assert (p - buf < size);
mono_metadata_encode_value (p-buf, b, &b);
idx = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
mono_image_add_stream_data (&assembly->blob, buf, p-buf);
table->rows ++;
alloc_table (table, table->rows);
values = table->values + token * MONO_ASSEMBLYREF_SIZE;
- values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
+ if (strcmp ("corlib", image->assembly_name) == 0)
+ values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, "mscorlib");
+ else
+ values [MONO_ASSEMBLYREF_NAME] = string_heap_insert (&assembly->sheap, image->assembly_name);
values [MONO_ASSEMBLYREF_MAJOR_VERSION] = cols [MONO_ASSEMBLY_MAJOR_VERSION];
values [MONO_ASSEMBLYREF_MINOR_VERSION] = cols [MONO_ASSEMBLY_MINOR_VERSION];
values [MONO_ASSEMBLYREF_BUILD_NUMBER] = cols [MONO_ASSEMBLY_BUILD_NUMBER];
return token;
}
+/*
+ * Insert a memberef row into the metadata: the token that point to the memberref
+ * is returned. Caching is done in the caller (mono_image_get_methodref_token() or
+ * mono_image_get_fieldref_token()).
+ * The sig param is an index to an already built signature.
+ */
static guint32
mono_image_get_memberref_token (MonoDynamicAssembly *assembly, MonoClass *klass, const char *name, guint32 sig)
{
return token;
}
+/*
+ * Insert into the metadata tables all the info about the TypeBuilder tb.
+ * Data in the tables is inserted in a predefined order, since some tables need to be sorted.
+ */
static void
mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, MonoDynamicAssembly *assembly)
{
alloc_table (table, table->rows);
values = table->values + (i + 1) * MONO_INTERFACEIMPL_SIZE;
for (i = 0; i < mono_array_length (tb->interfaces); ++i) {
- MonoReflectionType* interface = (MonoReflectionType*) mono_array_get (tb->interfaces, gpointer, i);
+ MonoReflectionType* iface = (MonoReflectionType*) mono_array_get (tb->interfaces, gpointer, i);
values [MONO_INTERFACEIMPL_CLASS] = tb->table_idx;
- values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, interface->type);
+ values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, iface->type);
values += MONO_INTERFACEIMPL_SIZE;
}
}
(p) += 4 - (__diff & 3);\
} while (0)
+/*
+ * build_compressed_metadata() fills in the blob of data that represents the
+ * raw metadata as it will be saved in the PE file. The five streams are output
+ * and the metadata tables are comnpressed from the guint32 array representation,
+ * to the compressed on-disk format.
+ */
static void
build_compressed_metadata (MonoDynamicAssembly *assembly)
{
int i;
guint64 valid_mask = 0;
+ guint64 sorted_mask;
guint32 heapt_size = 0;
guint32 meta_size = 256; /* allow for header and other stuff */
guint32 table_offset;
guint16 *int16val;
MonoImage *meta;
unsigned char *p;
- char *version = "mono" VERSION;
+ const char *version = "mono" VERSION;
+ struct StreamDesc {
+ const char *name;
+ MonoDynamicStream *stream;
+ } stream_desc [] = {
+ {"#~", &assembly->tstream},
+ {"#Strings", &assembly->sheap},
+ {"#US", &assembly->us},
+ {"#Blob", &assembly->blob},
+ {"#GUID", &assembly->guid},
+ };
+
+ /* tables that are sorted */
+ sorted_mask = ((guint64)1 << MONO_TABLE_CONSTANT) | ((guint64)1 << MONO_TABLE_FIELDMARSHAL)
+ | ((guint64)1 << MONO_TABLE_METHODSEMANTICS) | ((guint64)1 << MONO_TABLE_CLASSLAYOUT)
+ | ((guint64)1 << MONO_TABLE_FIELDLAYOUT) | ((guint64)1 << MONO_TABLE_FIELDRVA)
+ | ((guint64)1 << MONO_TABLE_IMPLMAP) | ((guint64)1 << MONO_TABLE_NESTEDCLASS)
+ | ((guint64)1 << MONO_TABLE_METHODIMPL) | ((guint64)1 << MONO_TABLE_CUSTOMATTRIBUTE)
+ | ((guint64)1 << MONO_TABLE_DECLSECURITY);
/* Compute table sizes */
- meta = assembly->assembly.image = g_new0 (MonoImage, 1);
+ /* the MonoImage has already been created in mono_image_basic_init() */
+ meta = assembly->assembly.image;
/* Setup the info used by compute_sizes () */
meta->idx_blob_wide = assembly->blob.index >= 65536 ? 1 : 0;
*/
table_offset = (p - (unsigned char*)meta->raw_metadata) + 5 * 8 + 40; /* room needed for stream headers */
table_offset += 3; table_offset &= ~3;
-
- int32val = (guint32*)p;
- *int32val++ = assembly->tstream.offset = table_offset;
- *int32val = heapt_size;
- table_offset += *int32val;
- table_offset += 3; table_offset &= ~3;
- p += 8;
- strcpy (p, "#~");
- p += 3;
- align_pointer (meta->raw_metadata, p);
-
- int32val = (guint32*)p;
- *int32val++ = assembly->sheap.offset = table_offset;
- *int32val = assembly->sheap.index;
- table_offset += *int32val;
- table_offset += 3; table_offset &= ~3;
- p += 8;
- strcpy (p, "#Strings");
- p += 9;
- align_pointer (meta->raw_metadata, p);
-
- int32val = (guint32*)p;
- *int32val++ = assembly->us.offset = table_offset;
- *int32val = assembly->us.index;
- table_offset += *int32val;
- table_offset += 3; table_offset &= ~3;
- p += 8;
- strcpy (p, "#US");
- p += 4;
- align_pointer (meta->raw_metadata, p);
-
- int32val = (guint32*)p;
- *int32val++ = assembly->blob.offset = table_offset;
- *int32val = assembly->blob.index;
- table_offset += *int32val;
- table_offset += 3; table_offset &= ~3;
- p += 8;
- strcpy (p, "#Blob");
- p += 6;
- align_pointer (meta->raw_metadata, p);
-
- int32val = (guint32*)p;
- *int32val++ = assembly->guid.offset = table_offset;
- *int32val = assembly->guid.index;
- table_offset += *int32val;
- table_offset += 3; table_offset &= ~3;
- p += 8;
- strcpy (p, "#GUID");
- p += 6;
- align_pointer (meta->raw_metadata, p);
+ assembly->tstream.index = heapt_size;
+ for (i = 0; i < 5; ++i) {
+ int32val = (guint32*)p;
+ *int32val++ = stream_desc [i].stream->offset = table_offset;
+ *int32val = stream_desc [i].stream->index;
+ table_offset += *int32val;
+ table_offset += 3; table_offset &= ~3;
+ p += 8;
+ strcpy (p, stream_desc [i].name);
+ p += strlen (stream_desc [i].name) + 1;
+ align_pointer (meta->raw_metadata, p);
+ }
/*
* now copy the data, the table stream header and contents goes first.
*/
*p++ = 0; /* reserved */
int64val = (guint64*)p;
*int64val++ = valid_mask;
- *int64val++ = 0; /* bitvector of sorted tables, set to 0 for now */
+ *int64val++ = valid_mask & sorted_mask; /* bitvector of sorted tables */
p += 16;
int32val = (guint32*)p;
for (i = 0; i < 64; i++){
}
}
}
- g_assert ((p - (unsigned char*)meta->tables [i].base) == (meta->tables [i].rows * meta->tables [i].row_size));
+ g_assert ((p - (const unsigned char*)meta->tables [i].base) == (meta->tables [i].rows * meta->tables [i].row_size));
}
g_assert (assembly->guid.offset + assembly->guid.index < meta_size);
assembly->meta_size = assembly->guid.offset + assembly->guid.index;
}
+/*
+ * Some tables in metadata need to be sorted according to some criteria, but
+ * when methods and fields are first created with reflection, they may be assigned a token
+ * that doesn't correspond to the final token they will get assigned after the sorting.
+ * ILGenerator.cs keeps a fixup table that maps the position of tokens in the IL code stream
+ * with the reflection objects that represent them. Once all the tables are set up, the
+ * reflection objects will contains the correct table index. fixup_method() will fixup the
+ * tokens for the method with ILGenerator @ilgen.
+ */
static void
fixup_method (MonoReflectionILGen *ilgen, gpointer value, MonoDynamicAssembly *assembly) {
guint32 code_idx = GPOINTER_TO_UINT (value);
MonoReflectionFieldBuilder *field;
MonoReflectionCtorBuilder *ctor;
MonoReflectionMethodBuilder *method;
- guint32 i, index;
+ guint32 i, idx;
unsigned char *target;
for (i = 0; i < ilgen->num_token_fixups; ++i) {
if (strcmp (iltoken->member->vtable->klass->name, "FieldBuilder"))
g_assert_not_reached ();
field = (MonoReflectionFieldBuilder *)iltoken->member;
- index = field->table_idx;
+ idx = field->table_idx;
break;
case MONO_TABLE_METHOD:
if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
method = (MonoReflectionMethodBuilder *)iltoken->member;
- index = method->table_idx;
+ idx = method->table_idx;
} else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
ctor = (MonoReflectionCtorBuilder *)iltoken->member;
- index = ctor->table_idx;
+ idx = ctor->table_idx;
} else {
g_assert_not_reached ();
}
default:
g_error ("got unexpected table 0x%02x in fixup", target [3]);
}
- target [0] = index & 0xff;
- target [1] = (index >> 8) & 0xff;
- target [2] = (index >> 16) & 0xff;
+ target [0] = idx & 0xff;
+ target [1] = (idx >> 8) & 0xff;
+ target [2] = (idx >> 16) & 0xff;
}
}
+/*
+ * mono_image_build_metadata() will fill the info in all the needed metadata tables
+ * for the AssemblyBuilder @assemblyb: it iterates over the assembly modules
+ * and recursively outputs the info for a module. Each module will output all the info
+ * about it's types etc.
+ * At the end of the process, method and field tokens are fixed up and the on-disk
+ * compressed metadata representation is created.
+ */
static void
mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb)
{
values [MONO_TYPEDEF_METHOD_LIST] = 1;
/* fixup tokens */
- g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
+ mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
build_compressed_metadata (assembly);
}
guint32
mono_image_insert_string (MonoReflectionAssemblyBuilder *assembly, MonoString *str)
{
- guint32 index;
+ guint32 idx;
char buf [16];
char *b = buf;
if (!assembly->dynamic_assembly)
mono_image_basic_init (assembly);
mono_metadata_encode_value (1 | (str->length * 2), b, &b);
- index = mono_image_add_stream_data (&assembly->dynamic_assembly->us, buf, b-buf);
+ idx = mono_image_add_stream_data (&assembly->dynamic_assembly->us, buf, b-buf);
/* FIXME: ENOENDIAN */
- mono_image_add_stream_data (&assembly->dynamic_assembly->us, (char*)mono_string_chars (str), str->length * 2);
+ mono_image_add_stream_data (&assembly->dynamic_assembly->us, (const char*)mono_string_chars (str), str->length * 2);
mono_image_add_stream_data (&assembly->dynamic_assembly->us, "", 1);
- return MONO_TOKEN_STRING | index;
+ return MONO_TOKEN_STRING | idx;
}
/*
guint32
mono_image_create_token (MonoDynamicAssembly *assembly, MonoObject *obj)
{
- MonoClass *klass = obj->vtable->klass;
+ MonoClass *klass;
guint32 token;
+ if (!obj)
+ g_error ("System.Array methods not yet supported");
+
+ klass = obj->vtable->klass;
if (strcmp (klass->name, "MethodBuilder") == 0) {
MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
return 0;
}
+/*
+ * Create the MonoImage that represents the assembly builder and setup some
+ * of the helper hash table and the basic metadata streams.
+ */
void
mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
{
if (assemblyb->dynamic_assembly)
return;
+#if HAVE_BOEHM_GC
+ assembly = assemblyb->dynamic_assembly = GC_malloc (sizeof (MonoDynamicAssembly));
+#else
assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
+#endif
- assembly->token_fixups = g_hash_table_new (g_direct_hash, g_direct_equal);
+ assembly->token_fixups = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
assembly->typeref = g_hash_table_new (g_direct_hash, g_direct_equal);
string_heap_init (&assembly->sheap);
}
+/*
+ * When we need to save an assembly, we first call this function that ensures the metadata
+ * tables are built for all the modules in the assembly. This function creates the PE-COFF
+ * header, the image sections, the CLI header etc. The header is written in @buffer
+ * and the length of the data written is returned.
+ */
int
mono_image_get_header (MonoReflectionAssemblyBuilder *assemblyb, char *buffer, int maxsize)
{
header->nt.pe_os_minor = 0;
header->nt.pe_subsys_major = 4;
/* need to set pe_image_size, pe_header_size */
+ header->nt.pe_header_size = 0x200;
+ header->nt.pe_image_size = 0x00008000;
header->nt.pe_subsys_required = 3; /* 3 -> cmdline app, 2 -> GUI app */
header->nt.pe_stack_reserve = 0x00100000;
header->nt.pe_stack_commit = 0x00001000;
pe_reloc_table
pe_iat
#endif
- header->datadir.pe_cli_header.size = CLI_H_SIZE;
+ header->datadir.pe_cli_header.size = 72;
header->datadir.pe_cli_header.rva = assembly->text_rva; /* we put it always at the beginning */
/* Write section tables */
* Write the MonoCLIHeader header
*/
cli_header = (MonoCLIHeader*)(buffer + TEXT_OFFSET);
- cli_header->ch_size = CLI_H_SIZE;
+ cli_header->ch_size = 72;
cli_header->ch_runtime_major = 2;
cli_header->ch_flags = CLI_FLAGS_ILONLY;
if (assemblyb->entry_point)
* We need to return always the same object for MethodInfo, FieldInfo etc..
* type uses a different hash, since it uses custom hash/equal functions.
*/
-static GHashTable *object_cache = NULL;
-static GHashTable *type_cache = NULL;
+static MonoGHashTable *object_cache = NULL;
+static MonoGHashTable *type_cache = NULL;
#define CHECK_OBJECT(t,p) \
do { \
t _obj; \
if (!object_cache) \
- object_cache = g_hash_table_new (g_direct_hash, g_direct_equal); \
- if ((_obj = g_hash_table_lookup (object_cache, (p)))) \
+ object_cache = mono_g_hash_table_new (g_direct_hash, g_direct_equal); \
+ if ((_obj = mono_g_hash_table_lookup (object_cache, (p)))) \
return _obj; \
} while (0)
#define CACHE_OBJECT(p,o) \
do { \
- g_hash_table_insert (object_cache, p,o); \
+ mono_g_hash_table_insert (object_cache, p,o); \
} while (0)
MonoReflectionAssembly*
MonoClass *klass = mono_class_from_mono_type (type);
if (!type_cache)
- type_cache = g_hash_table_new ((GHashFunc)mymono_metadata_type_hash,
+ type_cache = mono_g_hash_table_new ((GHashFunc)mymono_metadata_type_hash,
(GCompareFunc)mymono_metadata_type_equal);
- if ((res = g_hash_table_lookup (type_cache, type)))
+ if ((res = mono_g_hash_table_lookup (type_cache, type)))
return res;
if (klass->reflection_info) {
/* should this be considered an error condition? */
mono_class_init (klass);
res = (MonoReflectionType *)mono_object_new (domain, mono_defaults.monotype_class);
res->type = type;
- g_hash_table_insert (type_cache, type, res);
+ mono_g_hash_table_insert (type_cache, type, res);
return res;
}
* We use the same C representation for methods and constructors, but the type
* name in C# is different.
*/
- char *cname;
+ const char *cname;
MonoClass *klass;
MonoReflectionMethod *ret;
*/
CHECK_OBJECT (MonoReflectionParameter**, &(method->signature));
oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "ParameterInfo");
+#if HAVE_BOEHM_GC
+ res = GC_malloc (sizeof (MonoReflectionParameter*) * method->signature->param_count);
+#else
res = g_new0 (MonoReflectionParameter*, method->signature->param_count);
+#endif
for (i = 0; i < method->signature->param_count; ++i) {
res [i] = (MonoReflectionParameter *)mono_object_new (domain, oklass);
res [i]->ClassImpl = mono_type_get_object (domain, method->signature->params [i]);
MonoArray*
mono_reflection_get_custom_attrs (MonoObject *obj)
{
- guint32 index, mtoken, i;
+ guint32 idx, mtoken, i, len;
guint32 cols [MONO_CUSTOM_ATTR_SIZE];
MonoClass *klass;
MonoImage *image;
if (klass == mono_defaults.monotype_class) {
MonoReflectionType *rtype = (MonoReflectionType*)obj;
klass = mono_class_from_mono_type (rtype->type);
- index = mono_metadata_token_index (klass->type_token);
- index <<= CUSTOM_ATTR_BITS;
- index |= CUSTOM_ATTR_TYPEDEF;
+ idx = mono_metadata_token_index (klass->type_token);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_TYPEDEF;
image = klass->image;
} else if (strcmp ("Assembly", klass->name) == 0) {
MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
- index = 1; /* there is only one assembly */
- index <<= CUSTOM_ATTR_BITS;
- index |= CUSTOM_ATTR_ASSEMBLY;
+ idx = 1; /* there is only one assembly */
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_ASSEMBLY;
image = rassembly->assembly->image;
} else if (strcmp ("MonoProperty", klass->name) == 0) {
MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
- index = find_property_index (rprop->klass, rprop->property);
- index <<= CUSTOM_ATTR_BITS;
- index |= CUSTOM_ATTR_PROPERTY;
+ idx = find_property_index (rprop->klass, rprop->property);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_PROPERTY;
image = rprop->klass->image;
} else if (strcmp ("MonoEvent", klass->name) == 0) {
MonoReflectionEvent *revent = (MonoReflectionEvent*)obj;
- index = find_event_index (revent->klass, revent->event);
- index <<= CUSTOM_ATTR_BITS;
- index |= CUSTOM_ATTR_EVENT;
+ idx = find_event_index (revent->klass, revent->event);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_EVENT;
image = revent->klass->image;
} else if (strcmp ("MonoField", klass->name) == 0) {
MonoReflectionField *rfield = (MonoReflectionField*)obj;
- index = find_field_index (rfield->klass, rfield->field);
- index <<= CUSTOM_ATTR_BITS;
- index |= CUSTOM_ATTR_FIELDDEF;
+ idx = find_field_index (rfield->klass, rfield->field);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_FIELDDEF;
image = rfield->klass->image;
} else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
- index = find_method_index (rmethod->method);
- index <<= CUSTOM_ATTR_BITS;
- index |= CUSTOM_ATTR_METHODDEF;
+ idx = find_method_index (rmethod->method);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_METHODDEF;
image = method->klass->image;
} else if (strcmp ("ParameterInfo", klass->name) == 0) {
MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
}
if (!found)
return mono_array_new (mono_domain_get (), mono_defaults.object_class, 0);
- index = i;
- index <<= CUSTOM_ATTR_BITS;
- index |= CUSTOM_ATTR_PARAMDEF;
+ idx = i;
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_PARAMDEF;
} else { /* handle other types here... */
g_error ("get custom attrs not yet supported for %s", klass->name);
}
/* the table is not sorted */
for (i = 0; i < ca->rows; ++i) {
mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
- if (cols [MONO_CUSTOM_ATTR_PARENT] != index)
+ if (cols [MONO_CUSTOM_ATTR_PARENT] != idx)
continue;
mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS;
switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) {
g_free (params);
}
- index = g_list_length (list);
+ len = g_list_length (list);
/*
* The return type is really object[], but System/Attribute.cs does a cast
* to (Attribute []) and that is not allowed: I'm lazy for now, but we should
* probably fix that.
*/
klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
- result = mono_array_new (mono_domain_get (), klass, index);
- for (i = 0; i < index; ++i) {
+ result = mono_array_new (mono_domain_get (), klass, len);
+ for (i = 0; i < len; ++i) {
mono_array_set (result, gpointer, i, list->data);
list = list->next;
}
/*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
}
+MonoArray *
+mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
+{
+ MonoDynamicAssembly *assembly = sig->module->assemblyb->dynamic_assembly;
+ guint32 na = mono_array_length (sig->arguments);
+ guint32 buflen, i;
+ MonoArray *result;
+ char *buf, *p;
+
+ p = buf = g_malloc (10 + na * 10);
+
+ mono_metadata_encode_value (0x07, p, &p);
+ mono_metadata_encode_value (na, p, &p);
+ for (i = 0; i < na; ++i) {
+ MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType *, i);
+ encode_reflection_type (assembly, type, p, &p);
+ }
+
+ buflen = p - buf;
+ result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, buflen);
+ p = mono_array_addr (result, char, 0);
+ memcpy (p, buf, buflen);
+ g_free (buf);
+
+ return result;
+}
+
+MonoArray *
+mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig)
+{
+ MonoDynamicAssembly *assembly = sig->module->assemblyb->dynamic_assembly;
+ guint32 na = mono_array_length (sig->arguments);
+ guint32 buflen, i;
+ MonoArray *result;
+ char *buf, *p;
+
+ p = buf = g_malloc (10 + na * 10);
+
+ mono_metadata_encode_value (0x06, p, &p);
+ for (i = 0; i < na; ++i) {
+ MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType *, i);
+ encode_reflection_type (assembly, type, p, &p);
+ }
+
+ buflen = p - buf;
+ result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, buflen);
+ p = mono_array_addr (result, char, 0);
+ memcpy (p, buf, buflen);
+ g_free (buf);
+
+ return result;
+}