* interp.c: hanlde field refs. Throw an exception on NULL references.
Check consistency of corlib types with the C struct representation.
Fri Nov 2 19:37:51 CET 2001 Paolo Molaro <lupus@ximian.com>
* class.h, class.c: include name in MonoClassField.
* class.c: fix fundamental type of System.Object and System.String.
Set the right fundamental type for SZARRAY, too. Handle TypeSpec
tokens in ldtoken.
* icall.c: remove internalcalls for the Reflection stuff that is now
done in C# code.
* loader.c: mono_field_from_memberref () implementation.
* mono-endian.c: thinko (s/struct/union/g).
* object.c, object.h: make the mono_string_* prototypes actually use
MonoString instead of MonoObject.
* reflection.c, reflection.h: updates for changes in the reflection
code in corlib: we use C structures that map to the actual C# classes.
Handle SZARRAYs when encoding types. Handle locals in methods. Use a
fat method header if needed and use the info from the ILGenerator for
methods. Handle fields in types. Misc fixes.
svn path=/trunk/mono/; revision=1262
+
+Fri Nov 2 19:06:54 CET 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: hanlde field refs. Throw an exception on NULL references.
+ Check consistency of corlib types with the C struct representation.
+
2001-10-25 Dietmar Maurer <dietmar@ximian.com>
* interp.c (ves_exec_method): use relative numbering for runtime
#include <mono/metadata/tokentype.h>
#include <mono/metadata/loader.h>
#include <mono/metadata/threads.h>
+#include <mono/metadata/reflection.h>
#include <mono/arch/x86/x86-codegen.h>
/*#include <mono/cli/types.h>*/
#include "interp.h"
case VAL_I64: printf ("[%lld] ", s->data.l); break;
case VAL_DOUBLE: printf ("[%0.5f] ", s->data.f); break;
case VAL_VALUET: printf ("[vt: %p] ", s->data.vt.vt); break;
+#if 0
+ case VAL_OBJ: {
+ MonoObject *obj = s->data.p;
+ if (obj && obj->klass == mono_defaults.string_class) {
+ char *str = mono_string_to_utf8 ((MonoString*)obj);
+ printf ("\"%s\" ", str);
+ g_free (str);
+ break;
+ }
+ }
+#endif
default: printf ("[%p] ", s->data.p); break;
}
++s;
if (csignature->hasthis) {
g_assert (sp >= frame->stack);
--sp;
- g_assert (sp->type == VAL_OBJ || sp->type == VAL_VALUETA);
+ /*
+ * It may also be a TP from LD(S)FLDA
+ * g_assert (sp->type == VAL_OBJ || sp->type == VAL_VALUETA);
+ */
if (sp->type == VAL_OBJ && child_frame.method->klass->valuetype) /* unbox it */
child_frame.obj = (char*)sp->data.p + sizeof (MonoObject);
else
index = mono_metadata_token_index (read32 (ip));
ip += 4;
- o = mono_ldstr (image, index);
+ o = (MonoObject*)mono_ldstr (image, index);
sp->type = VAL_OBJ;
sp->data.p = o;
sp->data.vt.klass = NULL;
ip += 4;
/* need to handle fieldrefs */
- klass = mono_class_get (image,
- MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
- if (!klass->inited)
- init_class (klass);
- field = mono_class_get_field (klass, token);
+ if (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF) {
+ field = mono_field_from_memberref (image, token, &klass);
+ if (!klass->inited)
+ init_class (klass);
+ } else {
+ klass = mono_class_get (image,
+ MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
+ if (!klass->inited)
+ init_class (klass);
+ field = mono_class_get_field (klass, token);
+ }
g_assert (field);
if (load_addr) {
sp->type = VAL_TP;
g_assert (sp [-1].type == VAL_OBJ);
o = sp [-1].data.p;
- g_assert (o != NULL);
+ if (!o)
+ THROW_EX (get_exception_null_reference (), ip - 1);
g_assert (MONO_CLASS_IS_ARRAY (o->obj.klass));
}
#endif
+typedef struct {
+ char *name;
+ gulong offset;
+} FieldDesc;
+
+typedef struct {
+ char *name;
+ FieldDesc *fields;
+} ClassDesc;
+
+static FieldDesc
+typebuilder_fields[] = {
+ {"name", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, name)},
+ {"nspace", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, nspace)},
+ {"parent", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, parent)},
+ {"interfaces", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, interfaces)},
+ {"methods", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, methods)},
+ {"properties", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, properties)},
+ {"fields", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, fields)},
+ {"attrs", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, attrs)},
+ {"table_idx", G_STRUCT_OFFSET (MonoReflectionTypeBuilder, table_idx)},
+ {NULL, 0}
+};
+
+static FieldDesc
+modulebuilder_fields[] = {
+ {"types", G_STRUCT_OFFSET (MonoReflectionModuleBuilder, types)},
+ {"table_idx", G_STRUCT_OFFSET (MonoReflectionModuleBuilder, table_idx)},
+ {NULL, 0}
+};
+
+static FieldDesc
+assemblybuilder_fields[] = {
+ {"entry_point", G_STRUCT_OFFSET (MonoReflectionAssemblyBuilder, entry_point)},
+ {"modules", G_STRUCT_OFFSET (MonoReflectionAssemblyBuilder, modules)},
+ {"name", G_STRUCT_OFFSET (MonoReflectionAssemblyBuilder, name)},
+ {NULL, 0}
+};
+
+static FieldDesc
+methodbuilder_fields[] = {
+ {"rtype", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, rtype)},
+ {"parameters", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, parameters)},
+ {"attrs", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, attrs)},
+ {"name", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, name)},
+ {"table_idx", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, table_idx)},
+ {"code", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, code)},
+ {NULL, 0}
+};
+
+static FieldDesc
+fieldbuilder_fields[] = {
+ {"attrs", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, attrs)},
+ {"type", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, type)},
+ {"name", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, name)},
+ {"def_value", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, def_value)},
+ {"offset", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, offset)},
+ {"table_idx", G_STRUCT_OFFSET (MonoReflectionFieldBuilder, table_idx)},
+ {NULL, 0}
+};
+
+static FieldDesc
+propertybuilder_fields[] = {
+ {"attrs", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, attrs)},
+ {"name", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, name)},
+ {"type", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, type)},
+ {"parameters", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, parameters)},
+ {"def_value", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, def_value)},
+ {"set_method", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, set_method)},
+ {"get_method", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, get_method)},
+ {"table_idx", G_STRUCT_OFFSET (MonoReflectionPropertyBuilder, table_idx)},
+ {NULL, 0}
+};
+
+static ClassDesc
+classes_to_check [] = {
+ {"TypeBuilder", typebuilder_fields},
+ {"ModuleBuilder", modulebuilder_fields},
+ {"AssemblyBuilder", assemblybuilder_fields},
+ {"MethodBuilder", methodbuilder_fields},
+ {"FieldBuilder", fieldbuilder_fields},
+ {"PropertyBuilder", propertybuilder_fields},
+ {NULL, NULL}
+};
+
+static void
+check_corlib (MonoImage *corlib)
+{
+ MonoClass *klass;
+ MonoClassField *field;
+ FieldDesc *fdesc;
+ ClassDesc *cdesc;
+ const char *refl = "System.Reflection.Emit";
+
+ for (cdesc = classes_to_check; cdesc->name; ++cdesc) {
+ klass = mono_class_from_name (corlib, refl, cdesc->name);
+ if (!klass)
+ g_error ("Cannot find class %s", cdesc->name);
+ mono_class_metadata_init (klass);
+ for (fdesc = cdesc->fields; fdesc->name; ++fdesc) {
+ field = mono_class_get_field_from_name (klass, fdesc->name);
+ if (!field || (field->offset != fdesc->offset))
+ g_error ("filed %s mismatch in class %s (%d != %d)", fdesc->name, cdesc->name, fdesc->offset, field?field->offset:-1);
+ }
+ }
+}
+
int
main (int argc, char *argv [])
{
#ifdef RUN_TEST
test_load_class (assembly->image);
#else
+ check_corlib (mono_defaults.corlib);
/*
* skip the program name from the args.
*/
+
+Fri Nov 2 19:37:51 CET 2001 Paolo Molaro <lupus@ximian.com>
+
+ * class.h, class.c: include name in MonoClassField.
+ * class.c: fix fundamental type of System.Object and System.String.
+ Set the right fundamental type for SZARRAY, too. Handle TypeSpec
+ tokens in ldtoken.
+ * icall.c: remove internalcalls for the Reflection stuff that is now
+ done in C# code.
+ * loader.c: mono_field_from_memberref () implementation.
+ * mono-endian.c: thinko (s/struct/union/g).
+ * object.c, object.h: make the mono_string_* prototypes actually use
+ MonoString instead of MonoObject.
+ * reflection.c, reflection.h: updates for changes in the reflection
+ code in corlib: we use C structures that map to the actual C# classes.
+ Handle SZARRAYs when encoding types. Handle locals in methods. Use a
+ fat method header if needed and use the info from the ILGenerator for
+ methods. Handle fields in types. Misc fixes.
+
2001-10-17 Dietmar Maurer <dietmar@ximian.com>
* class.c (mono_class_metadata_init): bug fix: always allocate
*/
for (i = 0; i < top; i++){
const char *sig;
- guint32 cols [3];
+ guint32 cols [MONO_FIELD_SIZE];
int idx = class->field.first + i;
mono_metadata_decode_row (t, idx, cols, CSIZE (cols));
- sig = mono_metadata_blob_heap (m, cols [2]);
+ /* The name is needed for fieldrefs */
+ class->fields [i].name = mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]);
+ sig = mono_metadata_blob_heap (m, cols [MONO_FIELD_SIGNATURE]);
mono_metadata_decode_value (sig, &sig);
/* FIELD signature == 0x06 */
g_assert (*sig == 0x06);
} else if (!strcmp (name, "Enum")) {
class->valuetype = 1;
class->enumtype = 1;
+ } else if (!strcmp (name, "Object")) {
+ class->this_arg.type = class->byval_arg.type = MONO_TYPE_OBJECT;
+ } else if (!strcmp (name, "String")) {
+ class->this_arg.type = class->byval_arg.type = MONO_TYPE_STRING;
}
}
t = MONO_TYPE_I;
}
break;
- case 'O':
- if (!strcmp (name, "Object")) {
- t = MONO_TYPE_OBJECT;
- }
- break;
case 'S':
if (!strcmp (name, "Single")) {
t = MONO_TYPE_R4;
- } else if (!strcmp(name, "String")) {
- t = MONO_TYPE_STRING;
} else if (!strcmp(name, "SByte")) {
t = MONO_TYPE_I1;
}
class->rank = rank;
class->element_class = eclass;
+ if (rank > 1) {
+ class->byval_arg.type = MONO_TYPE_ARRAY;
+ /* FIXME: complete.... */
+ } else {
+ class->byval_arg.type = MONO_TYPE_SZARRAY;
+ class->byval_arg.data.type = &eclass->byval_arg;
+ }
+ class->this_arg = class->byval_arg;
+ class->this_arg.byref = 1;
g_hash_table_insert (image->array_cache, GUINT_TO_POINTER (key), class);
return class;
/* We return a MonoType* as handle */
return &class->byval_arg;
}
+ case MONO_TOKEN_TYPE_SPEC: {
+ MonoClass *class;
+ if (handle_class)
+ *handle_class = mono_defaults.typehandle_class;
+ if ((class = g_hash_table_lookup (image->class_cache,
+ GUINT_TO_POINTER (token))))
+ return &class->byval_arg;
+ class = mono_class_create_from_typespec (image, token);
+ return &class->byval_arg;
+ break;
+ }
case MONO_TOKEN_METHOD_DEF:
case MONO_TOKEN_FIELD_DEF:
case MONO_TOKEN_MEMBER_REF:
default:
+ g_warning ("Unknown token 0x%08x in ldtoken", token);
break;
}
return NULL;
typedef struct {
MonoType *type;
int offset;
+ char *name;
} MonoClassField;
struct _MonoClass {
MonoClass *
mono_class_from_name (MonoImage *image, const char* name_space, const char *name);
+MonoClassField*
+mono_field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass);
+
MonoClass *
mono_array_class_get (MonoClass *eclass, guint32 rank);
return res;
}
-static gpointer
-object_field_pointer (MonoObject *obj, char *name)
-{
- MonoClassField *field;
- gpointer *slot;
-
- field = mono_class_get_field_from_name (obj->klass, name);
- slot = (gpointer*)((char*)obj + field->offset);
- return *slot;
-}
-
-static gpointer
-object_impl_pointer (MonoObject *obj)
-{
- return object_field_pointer (obj, "_impl");
-}
-
-static MonoObject *
-ves_icall_app_define_assembly (MonoObject *appdomain, MonoObject *assembly_name, int access)
-{
- MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "AssemblyBuilder");
- MonoDynamicAssembly *ass = g_new0 (MonoDynamicAssembly, 1);
- MonoClassField *field;
- MonoObject *name;
-
- field = mono_class_get_field_from_name (assembly_name->klass, "name");
- name = *(MonoObject**)((char*)assembly_name + field->offset);
-
- ass->name = mono_string_to_utf8 (name);
-
- return my_mono_new_object (klass, ass);
-}
-
static gint32
-ves_icall_get_data_chunk (MonoObject *assb, gint32 type, MonoArray *buf)
+ves_icall_get_data_chunk (MonoReflectionAssemblyBuilder *assb, gint32 type, MonoArray *buf)
{
- MonoDynamicAssembly *ass = object_impl_pointer (assb);
- MonoObject *ep;
int count;
- /*
- * get some info from the object
- */
- ep = object_field_pointer (assb, "entry_point");
- if (ep)
- ass->entry_point = object_impl_pointer (ep);
- else
- ass->entry_point = 0;
if (type == 0) { /* get the header */
- count = mono_image_get_header (ass, buf->vector, buf->bounds->length);
+ count = mono_image_get_header (assb, buf->vector, buf->bounds->length);
if (count != -1)
return count;
} else {
+ MonoDynamicAssembly *ass = assb->dynamic_assembly;
count = ass->code.index + ass->meta_size;
if (count > buf->bounds->length)
return 0;
return 0;
}
-static MonoObject *
-ves_icall_define_module (MonoObject *assb, MonoObject *name, MonoObject *fname)
-{
- MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "ModuleBuilder");
- MonoModuleBuilder *mb = g_new0 (MonoModuleBuilder, 1);
- MonoDynamicAssembly *ass = object_impl_pointer (assb);
- ass->modules = g_list_prepend (ass->modules, mb);
-
- mb->name = mono_string_to_utf8 (name);
- mb->fname = mono_string_to_utf8 (fname);
-
- return my_mono_new_object (klass, mb);
-}
-
-static MonoObject *
-ves_icall_define_type (MonoObject *moduleb, MonoObject *name, int attrs)
-{
- MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "TypeBuilder");
- MonoTypeBuilder *tb = g_new0 (MonoTypeBuilder, 1);
- MonoModuleBuilder *mb = object_impl_pointer (moduleb);
- char *nspace = mono_string_to_utf8 (name);
- char *tname = strrchr (nspace, '.');
-
- if (tname) {
- *tname = 0;
- tname++;
- } else {
- nspace = "";
- }
-
- tb->name = tname;
- tb->nspace = nspace;
- tb->attrs = attrs;
- mb->types = g_list_prepend (mb->types, tb);
-
- return my_mono_new_object (klass, tb);
-}
-
-static MonoObject *
-ves_icall_define_method (MonoObject *typeb, MonoObject *name, int attrs, int callconv, MonoObject *rettype, MonoArray *paramtypes)
-{
- MonoClass *klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "MethodBuilder");
- MonoMethodBuilder *mb = g_new0 (MonoMethodBuilder, 1);
- MonoTypeBuilder *tb = object_impl_pointer (typeb);
-
- mb->name = mono_string_to_utf8 (name);
- mb->attrs = attrs;
- mb->callconv = callconv;
- mb->ret = object_impl_pointer (rettype);
- /* ignore params ... */
-
- if (!tb->has_default_ctor) {
- if (strcmp (".ctor", mb->name) == 0 && paramtypes->bounds->length == 0)
- tb->has_default_ctor = 1;
- }
-
- tb->methods = g_list_prepend (tb->methods, mb);
-
- return my_mono_new_object (klass, mb);
-}
-
-static void
-ves_icall_set_method_body (MonoObject *methodb, MonoArray *code, gint32 count)
-{
- MonoMethodBuilder *mb = object_impl_pointer (methodb);
- if (code->bounds->length < count) {
- g_warning ("code len is less than count");
- return;
- }
- g_free (mb->code);
- mb->code = g_malloc (count);
- mb->code_size = count;
- memcpy (mb->code, code->vector, count);
-}
-
static MonoObject*
ves_icall_type_from_name (MonoObject *name)
{
* System.AppDomain
*/
"System.AppDomain::getCurDomain", ves_icall_app_get_cur_domain,
- "System.AppDomain::defineAssembly", ves_icall_app_define_assembly,
/*
* ModuleBuilder
*/
- "System.Reflection.Emit.ModuleBuilder::defineType", ves_icall_define_type,
/*
* AssemblyBuilder
*/
- "System.Reflection.Emit.AssemblyBuilder::defineModule", ves_icall_define_module,
"System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_get_data_chunk,
/*
* TypeBuilder
*/
- "System.Reflection.Emit.TypeBuilder::defineMethod", ves_icall_define_method,
/*
* MethodBuilder
*/
- "System.Reflection.Emit.MethodBuilder::set_method_body", ves_icall_set_method_body,
/*
* System.Type
return res;
}
+MonoClassField*
+mono_field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass)
+{
+ MonoImage *mimage;
+ MonoClass *klass;
+ MonoTableInfo *tables = image->tables;
+ guint32 cols[6];
+ guint32 nindex, class, i;
+ const char *fname, *name, *nspace;
+ const char *ptr;
+ guint32 index = mono_metadata_token_index (token);
+
+ mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], index-1, cols, MONO_MEMBERREF_SIZE);
+ nindex = cols [MONO_MEMBERREF_CLASS] >> MEMBERREF_PARENT_BITS;
+ class = cols [MONO_MEMBERREF_CLASS] & MEMBERREF_PARENT_MASK;
+
+ fname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
+
+ ptr = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
+ mono_metadata_decode_blob_size (ptr, &ptr);
+ /* we may want to check the signature here... */
+
+ switch (class) {
+ case MEMBERREF_PARENT_TYPEREF: {
+ guint32 scopeindex, scopetable;
+
+ mono_metadata_decode_row (&tables [MONO_TABLE_TYPEREF], nindex-1, cols, MONO_TYPEREF_SIZE);
+ scopeindex = cols [MONO_TYPEREF_SCOPE] >> RESOLTION_SCOPE_BITS;
+ scopetable = cols [MONO_TYPEREF_SCOPE] & RESOLTION_SCOPE_MASK;
+ /*g_print ("typeref: 0x%x 0x%x %s.%s\n", scopetable, scopeindex,
+ mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]),
+ mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]));*/
+ switch (scopetable) {
+ case RESOLTION_SCOPE_ASSEMBLYREF:
+ /*
+ * To find the field we have the following info:
+ * *) name and namespace of the class from the TYPEREF table
+ * *) name and signature of the field from the MEMBERREF table
+ */
+ nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
+ name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
+
+ /* this will triggered by references to mscorlib */
+ if (image->references [scopeindex-1] == NULL)
+ g_error ("Reference to mscorlib? Probably need to implement %s.%s::%s in corlib", nspace, name, fname);
+
+ mimage = image->references [scopeindex-1]->image;
+
+ klass = mono_class_from_name (mimage, nspace, name);
+ mono_class_metadata_init (klass);
+
+ /* mostly dumb search for now */
+ for (i = 0; i < klass->field.count; ++i) {
+ MonoClassField *f = &klass->fields [i];
+ if (!strcmp (fname, f->name)) {
+ if (retklass)
+ *retklass = klass;
+ return f;
+ }
+ }
+ g_warning ("Missing field %s.%s::%s", nspace, name, fname);
+ return NULL;
+ default:
+ return NULL;
+ }
+ break;
+ }
+ default:
+ return NULL;
+ }
+}
+
static MonoMethod *
method_from_memberref (MonoImage *image, guint32 index)
{
#if NO_UNALIGNED_ACCESS
-typedef struct {
+typedef union {
char c [2];
guint16 i;
} mono_rint16;
-typedef struct {
+typedef union {
char c [4];
guint32 i;
} mono_rint32;
-typedef struct {
+typedef union {
char c [8];
guint64 i;
} mono_rint64;
*
* Returns: A newly created string object which contains @text.
*/
-MonoObject *
+MonoString *
mono_string_new_utf16 (const guint16 *text, gint32 len)
{
- MonoObject *s;
+ MonoString *s;
MonoArray *ca;
- s = mono_object_new (mono_defaults.string_class);
+ s = (MonoString*)mono_object_new (mono_defaults.string_class);
g_assert (s != NULL);
ca = (MonoArray *)mono_array_new (mono_defaults.string_class, len);
g_assert (ca != NULL);
- ((MonoString *)s)->c_str = ca;
- ((MonoString *)s)->length = len;
+ s->c_str = ca;
+ s->length = len;
memcpy (ca->vector, text, len * 2);
*
* Returns: A newly created string object which contains @text.
*/
-MonoObject *
+MonoString*
mono_string_new (const char *text)
{
- MonoObject *o;
+ MonoString *o;
guint16 *ut;
int i, l;
}
typedef struct {
- MonoObject *obj;
- MonoObject *found;
+ MonoString *obj;
+ MonoString *found;
} InternCheck;
static void
-check_interned (gpointer key, MonoObject *value, InternCheck *check)
+check_interned (gpointer key, MonoString *value, InternCheck *check)
{
if (value == check->obj)
check->found = value;
}
-MonoObject*
-mono_string_is_interned (MonoObject *o)
+MonoString*
+mono_string_is_interned (MonoString *o)
{
InternCheck check;
check.obj = o;
return check.found;
}
-MonoObject*
-mono_string_intern (MonoObject *o)
+MonoString*
+mono_string_intern (MonoString *str)
{
- MonoObject *res;
- MonoString *str = (MonoString*) o;
+ MonoString *res;
char *ins = g_malloc (4 + str->length * 2);
char *p;
return res;
}
g_hash_table_insert (ldstr_table, ins, str);
- return (MonoObject*)str;
+ return str;
}
-MonoObject*
+MonoString*
mono_ldstr (MonoImage *image, guint32 index)
{
const char *str, *sig;
- MonoObject *o;
+ MonoString *o;
guint len;
if (!ldstr_table)
}
char *
-mono_string_to_utf8 (MonoObject *o)
+mono_string_to_utf8 (MonoString *s)
{
- MonoString *s = (MonoString *)o;
char *as, *vector;
int i;
- g_assert (o != NULL);
+ g_assert (s != NULL);
- if (!s->length)
+ if (!s->length || !s->c_str)
return g_strdup ("");
vector = s->c_str->vector;
MonoObject *
mono_array_new (MonoClass *eclass, guint32 n);
-MonoObject *
+MonoString*
mono_string_new_utf16 (const guint16 *text, gint32 len);
-MonoObject*
+MonoString*
mono_ldstr (MonoImage *image, guint32 index);
-MonoObject*
-mono_string_is_interned (MonoObject *o);
+MonoString*
+mono_string_is_interned (MonoString *str);
-MonoObject*
-mono_string_intern (MonoObject *o);
+MonoString*
+mono_string_intern (MonoString *str);
-MonoObject *
+MonoString*
mono_string_new (const char *text);
char *
-mono_string_to_utf8 (MonoObject *string_obj);
+mono_string_to_utf8 (MonoString *string_obj);
void
mono_object_free (MonoObject *o);
string_heap_free (MonoStringHeap *sh)
{
g_free (sh->data);
- g_hash_table_foreach (sh->hash, g_free, NULL);
+ g_hash_table_foreach (sh->hash, (GHFunc)g_free, NULL);
g_hash_table_destroy (sh->hash);
}
case MONO_TYPE_TYPEDBYREF:
mono_metadata_encode_value (type->type, p, endbuf);
break;
+ case MONO_TYPE_SZARRAY:
+ mono_metadata_encode_value (type->type, p, endbuf);
+ encode_type (type->data.type, p, endbuf);
+ break;
+ case MONO_TYPE_CLASS:
+ mono_metadata_encode_value (type->type, p, endbuf);
+ g_warning ("need to encode class %s", type->data.klass->name);
+ break;
default:
- g_error ("need to encode type %d", type->type);
+ g_error ("need to encode type %x", type->type);
}
}
static guint32
-method_encode_signature (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
+method_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionMethodBuilder *mb)
{
char *buf;
char *p;
int i;
- guint32 size = 10 + mb->nparams * 10;
+ guint32 nparams = mb->parameters ? mono_array_length (mb->parameters): 0;
+ guint32 size = 10 + nparams * 10;
guint32 idx;
char blob_size [6];
char *b = blob_size;
* FIXME: set also call convention and explict_this if needed.
*/
p++;
- mono_metadata_encode_value (mb->nparams, p, &p);
- encode_type (mb->ret, p, &p);
- for (i = 0; i < mb->nparams; ++i) {
- encode_type (mb->params [i], p, &p);
+ mono_metadata_encode_value (nparams, p, &p);
+ encode_type (mb->rtype->type, p, &p);
+ for (i = 0; i < nparams; ++i) {
+ MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
+ encode_type (pt->type, p, &p);
}
/* store length */
mono_metadata_encode_value (p-buf, b, &b);
}
static guint32
-method_encode_code (MonoDynamicAssembly *assembly, MonoMethodBuilder *mb)
+encode_locals (MonoDynamicAssembly *assembly, MonoReflectionILGen *ilgen)
+{
+ MonoDynamicTable *table;
+ guint32 *values;
+ char *name, *p;
+ guint32 idx, sig_idx;
+ 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);
+ table = &assembly->tables [MONO_TABLE_STANDALONESIG];
+ idx = table->next_idx ++;
+ table->rows ++;
+ alloc_table (table, table->rows);
+ values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
+
+ mono_metadata_encode_value (0x07, p, &p);
+ mono_metadata_encode_value (nl, p, &p);
+ for (i = 0; i < nl; ++i) {
+ MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
+ encode_type (lb->type->type, p, &p);
+ }
+ 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);
+ g_free (buf);
+
+ values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
+
+ return idx;
+}
+
+static guint32
+method_encode_code (MonoDynamicAssembly *assembly, MonoReflectionMethodBuilder *mb)
{
/* we use only tiny formats now: need to implement ILGenerator */
char flags = 0;
guint32 idx;
- /* check for exceptions, maxstack, locals */
- if (mb->code_size < 64 && !(mb->code_size & 1)) {
- flags = (mb->code_size << 2) | 0x2;
- } else if (mb->code_size < 32 && (mb->code_size & 1)) {
- flags = (mb->code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
+ guint32 code_size;
+ gint32 max_stack;
+ gint32 num_locals = 0;
+ gint32 num_exception = 0;
+ gint maybe_small;
+ guint32 fat_flags;
+ char fat_header [12];
+ guint32 *intp;
+ guint16 *shortp;
+ guint32 local_sig = 0;
+ MonoArray *code;
+
+ if (mb->ilgen) {
+ code = mb->ilgen->code;
+ code_size = mb->ilgen->code_len;
+ max_stack = mb->ilgen->max_stack;
+ num_locals = mb->ilgen->locals ? mono_array_length (mb->ilgen->locals) : 0;
} else {
- g_error ("fat method headers not yet supported");
+ code = mb->code;
+ code_size = mono_array_length (code);
+ max_stack = 8; /* we probably need to run a verifier on the code... */
}
- idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
- mono_image_add_stream_data (&assembly->code, mb->code, mb->code_size);
+
+ /* check for exceptions, maxstack, locals */
+ maybe_small = (max_stack <= 8) && (!num_locals) && (!num_exception);
+ if (maybe_small) {
+ if (code_size < 64 && !(code_size & 1)) {
+ flags = (code_size << 2) | 0x2;
+ } else if (code_size < 32 && (code_size & 1)) {
+ flags = (code_size << 2) | 0x6; /* LAMESPEC: see metadata.c */
+ } else {
+ goto fat_header;
+ }
+ idx = mono_image_add_stream_data (&assembly->code, &flags, 1);
+ mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
+ return assembly->text_rva + idx + CLI_H_SIZE;
+ }
+fat_header:
+ if (num_locals)
+ local_sig = encode_locals (assembly, mb->ilgen);
+ /*
+ * FIXME: need to set also the header size in fat_flags.
+ * (and more sects and init locals flags)
+ */
+ fat_flags = 0x03;
+ shortp = (guint16*)(fat_header);
+ *shortp = fat_flags;
+ shortp = (guint16*)(fat_header + 2);
+ *shortp = max_stack;
+ intp = (guint32*)(fat_header + 4);
+ *intp = code_size;
+ intp = (guint32*)(fat_header + 8);
+ *intp = local_sig;
+ idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
+ mono_image_add_stream_data (&assembly->code, mono_array_addr (code, char, 0), code_size);
return assembly->text_rva + idx + CLI_H_SIZE;
}
static void
-mono_image_get_method_info (MonoMethodBuilder *mb, MonoDynamicAssembly *assembly)
+mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicAssembly *assembly)
{
MonoDynamicTable *table;
guint32 *values;
+ char *name;
table = &assembly->tables [MONO_TABLE_METHOD];
mb->table_idx = table->next_idx ++;
values = table->values + mb->table_idx * MONO_METHOD_SIZE;
- values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, mb->name);
+ name = mono_string_to_utf8 (mb->name);
+ values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, name);
+ g_free (name);
values [MONO_METHOD_FLAGS] = mb->attrs;
values [MONO_METHOD_IMPLFLAGS] = 0;
values [MONO_METHOD_SIGNATURE] = method_encode_signature (assembly, mb);
- values [MONO_METHOD_PARAMLIST] = 1; /* FIXME: add support later */
+ values [MONO_METHOD_PARAMLIST] = 0; /* FIXME: add support later */
values [MONO_METHOD_RVA] = method_encode_code (assembly, mb);
}
+static guint32
+field_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionFieldBuilder *fb)
+{
+ char blob_size [64];
+ char *b = blob_size;
+ char *p;
+ char* buf;
+ guint32 idx;
+
+ p = buf = g_malloc (64);
+
+ mono_metadata_encode_value (0x06, p, &p);
+ /* encode custom attributes before the type */
+ encode_type (fb->type->type, p, &p);
+ g_assert (p-buf < 64);
+ 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);
+ g_free (buf);
+ return idx;
+}
+
+static void
+mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicAssembly *assembly)
+{
+ MonoDynamicTable *table;
+ guint32 *values;
+ char *name;
+
+ table = &assembly->tables [MONO_TABLE_FIELD];
+ fb->table_idx = table->next_idx ++;
+ values = table->values + fb->table_idx * MONO_FIELD_SIZE;
+ name = mono_string_to_utf8 (fb->name);
+ values [MONO_FIELD_NAME] = string_heap_insert (&assembly->sheap, name);
+ g_free (name);
+ values [MONO_FIELD_FLAGS] = fb->attrs;
+ values [MONO_FIELD_SIGNATURE] = field_encode_signature (assembly, fb);
+}
+
+static guint32
+property_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionPropertyBuilder *fb)
+{
+ /*
+ * FIXME: fill me in
+ */
+ return 0;
+}
+
+static void
+mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicAssembly *assembly)
+{
+ MonoDynamicTable *table;
+ guint32 *values;
+ char *name;
+ guint num_methods = 0;
+ guint32 semaidx;
+
+ /*
+ * we need to set things in the following tables:
+ * PROPERTYMAP (info already filled in _get_type_info ())
+ * PROPERTY (rows already preallocated in _get_type_info ())
+ * METHOD
+ * METHODSEMANTICS
+ */
+ table = &assembly->tables [MONO_TABLE_PROPERTY];
+ pb->table_idx = table->next_idx ++;
+ values = table->values + pb->table_idx * MONO_FIELD_SIZE;
+ name = mono_string_to_utf8 (pb->name);
+ values [MONO_PROPERTY_NAME] = string_heap_insert (&assembly->sheap, name);
+ g_free (name);
+ values [MONO_PROPERTY_FLAGS] = pb->attrs;
+ values [MONO_PROPERTY_TYPE] = property_encode_signature (assembly, pb);
+
+ /* alloc room for the methods (we still don't handle 'other' methods) */
+ if (pb->get_method) num_methods ++;
+ if (pb->set_method) num_methods ++;
+ table = &assembly->tables [MONO_TABLE_METHOD];
+ table->rows += num_methods;
+ alloc_table (table, table->rows);
+
+ table = &assembly->tables [MONO_TABLE_METHODSEMANTICS];
+ table->rows += num_methods;
+ alloc_table (table, table->rows);
+
+ if (pb->get_method) {
+ mono_image_get_method_info (pb->get_method, assembly);
+ semaidx = table->next_idx ++;
+ values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
+ values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_GETTER;
+ values [MONO_METHOD_SEMA_METHOD] = pb->get_method->table_idx;
+ values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << 1) | 1;
+ }
+ if (pb->set_method) {
+ mono_image_get_method_info (pb->set_method, assembly);
+ semaidx = table->next_idx ++;
+ values = table->values + semaidx * MONO_METHOD_SEMA_SIZE;
+ values [MONO_METHOD_SEMA_SEMANTICS] = METHOD_SEMANTIC_SETTER;
+ values [MONO_METHOD_SEMA_METHOD] = pb->set_method->table_idx;
+ values [MONO_METHOD_SEMA_ASSOCIATION] = (pb->table_idx << 1) | 0;
+ }
+}
+
static guint32
mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoClass *klass)
{
}
static void
-mono_image_get_type_info (MonoTypeBuilder *tb, MonoDynamicAssembly *assembly)
+mono_image_get_type_info (MonoReflectionTypeBuilder *tb, MonoDynamicAssembly *assembly)
{
MonoDynamicTable *table;
guint *values;
+ int i;
+ char *n;
table = &assembly->tables [MONO_TABLE_TYPEDEF];
tb->table_idx = table->next_idx ++;
values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
values [MONO_TYPEDEF_FLAGS] = tb->attrs;
- /* use tb->base later */
+ /* FIXME: use tb->base later */
values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, mono_defaults.object_class);
- values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, tb->name);
- values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, tb->nspace);
+ n = mono_string_to_utf8 (tb->name);
+ values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, n);
+ g_free (n);
+ n = mono_string_to_utf8 (tb->nspace);
+ values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, n);
+ g_free (n);
values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;
- table = &assembly->tables [MONO_TABLE_METHOD];
- table->rows += g_list_length (tb->methods);
- /*if (!tb->has_default_ctor)
- table->rows++;*/
- alloc_table (table, table->rows);
- g_list_foreach (tb->methods, mono_image_get_method_info, assembly);
+ /* handle methods */
+ if (tb->methods) {
+ table = &assembly->tables [MONO_TABLE_METHOD];
+ table->rows += mono_array_length (tb->methods);
+ alloc_table (table, table->rows);
+ for (i = 0; i < mono_array_length (tb->methods); ++i)
+ mono_image_get_method_info (
+ mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), assembly);
+ }
+
+ /* handle fields */
+ if (tb->fields) {
+ table = &assembly->tables [MONO_TABLE_FIELD];
+ table->rows += mono_array_length (tb->fields);
+ alloc_table (table, table->rows);
+ for (i = 0; i < mono_array_length (tb->fields); ++i)
+ mono_image_get_field_info (
+ mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i), assembly);
+ }
- /* Do the same with fields, properties etc.. */
+ /* Do the same with properties etc.. */
+ if (tb->properties && mono_array_length (tb->properties)) {
+ table = &assembly->tables [MONO_TABLE_PROPERTY];
+ table->rows += mono_array_length (tb->properties);
+ alloc_table (table, table->rows);
+ table = &assembly->tables [MONO_TABLE_PROPERTYMAP];
+ table->rows ++;
+ alloc_table (table, table->rows);
+ values = table->values + (table->rows - 1) * MONO_PROPERTY_MAP_SIZE;
+ values [MONO_PROPERTY_MAP_PARENT] = tb->table_idx;
+ values [MONO_PROPERTY_MAP_PROPERTY_LIST] = assembly->tables [MONO_TABLE_PROPERTY].next_idx ++;
+ for (i = 0; i < mono_array_length (tb->properties); ++i)
+ mono_image_get_property_info (
+ mono_array_get (tb->fields, MonoReflectionPropertyBuilder*, i), assembly);
+ }
}
static void
-mono_image_fill_module_table (MonoModuleBuilder *mb, MonoDynamicAssembly *assembly)
+mono_image_fill_module_table (MonoReflectionModuleBuilder *mb, MonoDynamicAssembly *assembly)
{
MonoDynamicTable *table;
+ int i;
+ char *name;
table = &assembly->tables [MONO_TABLE_MODULE];
mb->table_idx = table->next_idx ++;
- table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, mb->name);
+ name = mono_string_to_utf8 (mb->module.name);
+ table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, name);
+ g_free (name);
/* need to set mvid? */
/*
* fill-in info in other tables as well.
*/
table = &assembly->tables [MONO_TABLE_TYPEDEF];
- table->rows += g_list_length (mb->types);
+ table->rows += mono_array_length (mb->types);
alloc_table (table, table->rows);
- g_list_foreach (mb->types, mono_image_get_type_info, assembly);
+ for (i = 0; i < mono_array_length (mb->types); ++i)
+ mono_image_get_type_info (mono_array_get (mb->types, MonoReflectionTypeBuilder*, i), assembly);
}
static void
}
static void
-mono_image_build_metadata (MonoDynamicAssembly *assembly)
+mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb)
{
char *meta;
MonoDynamicTable *table;
+ MonoDynamicAssembly *assembly = assemblyb->dynamic_assembly;
GList *type;
guint32 len;
guint32 *values;
+ char *name;
int i;
/*
alloc_table (table, 1);
values = table->values + MONO_ASSEMBLY_SIZE;
values [MONO_ASSEMBLY_HASH_ALG] = 0x8004;
- values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, assembly->name);
+ name = mono_string_to_utf8 (assemblyb->name);
+ values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, name);
+ g_free (name);
values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, "");
assembly->tables [MONO_TABLE_TYPEDEF].rows = 1; /* .<Module> */
assembly->tables [MONO_TABLE_TYPEDEF].next_idx++;
- len = g_list_length (assembly->modules);
+ len = mono_array_length (assemblyb->modules);
table = &assembly->tables [MONO_TABLE_MODULE];
alloc_table (table, len);
- g_list_foreach (assembly->modules, mono_image_fill_module_table, assembly);
+ for (i = 0; i < len; ++i)
+ mono_image_fill_module_table (mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i), assembly);
table = &assembly->tables [MONO_TABLE_TYPEDEF];
/*
}
int
-mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize)
+mono_image_get_header (MonoReflectionAssemblyBuilder *assemblyb, char *buffer, int maxsize)
{
MonoMSDOSHeader *msdos;
MonoDotNetHeader *header;
MonoSectionTable *section;
MonoCLIHeader *cli_header;
guint32 header_size = TEXT_OFFSET + CLI_H_SIZE;
+ MonoDynamicAssembly *assembly;
static const unsigned char msheader[] = {
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
if (maxsize < header_size)
return -1;
- mono_image_build_metadata (assembly);
+ assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
+ mono_image_build_metadata (assemblyb);
memset (buffer, 0, header_size);
memcpy (buffer, msheader, sizeof (MonoMSDOSHeader));
cli_header->ch_size = CLI_H_SIZE;
cli_header->ch_runtime_major = 2;
cli_header->ch_flags = CLI_FLAGS_ILONLY;
- if (assembly->entry_point)
- cli_header->ch_entry_point = assembly->entry_point->table_idx | MONO_TOKEN_METHOD_DEF;
+ if (assemblyb->entry_point)
+ cli_header->ch_entry_point = assemblyb->entry_point->table_idx | MONO_TOKEN_METHOD_DEF;
else
cli_header->ch_entry_point = 0;
cli_header->ch_metadata.rva = assembly->text_rva + assembly->code.index + CLI_H_SIZE;
#include <mono/metadata/image.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/class.h>
+#include <mono/metadata/object.h>
typedef struct {
char *name;
guint32 offset; /* from start of metadata */
} MonoDynamicStream;
-typedef struct {
- char *name;
- char *fname;
- GList *types;
- guint32 table_idx;
-} MonoModuleBuilder;
-
-typedef struct {
- char *name;
- char *nspace;
- int attrs;
- int has_default_ctor;
- guint32 table_idx;
- MonoType *base;
- GList *methods;
- GList *fields;
- GList *properties;
-} MonoTypeBuilder;
-
-typedef struct {
- char *name;
- guint32 attrs;
- guint32 callconv;
- guint32 nparams;
- guint32 table_idx;
- MonoType *ret;
- MonoType **params;
- char *code;
- guint32 code_size;
-} MonoMethodBuilder;
-
typedef struct {
guint32 rows;
guint32 row_size; /* calculated later with column_sizes */
guint32 offset; /* from start of metadata */
} MonoStringHeap;
+/*
+ * The followinbg structure must match the C# implementation in our corlib.
+ */
+
+typedef struct {
+ MonoObject object;
+ MonoType *type;
+} MonoReflectionType;
+
+typedef struct {
+ MonoObject object;
+ MonoArray *code;
+ MonoObject *mbuilder;
+ gint32 code_len;
+ gint32 max_stack;
+ gint32 cur_stack;
+ MonoArray *locals;
+} MonoReflectionILGen;
+
+typedef struct {
+ MonoObject object;
+ MonoReflectionType *type;
+ MonoString *name;
+} MonoReflectionLocalBuilder;
+
+typedef struct {
+ MonoObject object;
+ MonoMethod *impl;
+ MonoReflectionType *rtype;
+ MonoArray *parameters;
+ guint32 attrs;
+ MonoString *name;
+ guint32 table_idx;
+ MonoArray *code;
+ MonoReflectionILGen *ilgen;
+ MonoObject *type;
+} MonoReflectionMethodBuilder;
+
typedef struct {
MonoAssembly assembly;
- char *name;
- GList *modules;
guint32 meta_size;
guint32 text_rva;
guint32 metadata_rva;
- MonoMethodBuilder *entry_point;
GHashTable *typeref;
MonoStringHeap sheap;
MonoDynamicStream code; /* used to store method headers and bytecode */
MonoDynamicTable tables [64];
} MonoDynamicAssembly;
-int mono_image_get_header (MonoDynamicAssembly *assembly, char *buffer, int maxsize);
+typedef struct {
+ MonoObject object;
+ MonoAssembly *assembly;
+} MonoReflectionAssembly;
+
+typedef struct {
+ MonoReflectionAssembly assembly;
+ MonoDynamicAssembly *dynamic_assembly;
+ MonoReflectionMethodBuilder *entry_point;
+ MonoArray *modules;
+ MonoString *name;
+} MonoReflectionAssemblyBuilder;
+
+typedef struct {
+ MonoObject object;
+ guint32 attrs;
+ MonoReflectionType *type;
+ MonoString *name;
+ MonoObject *def_value;
+ gint32 offset;
+ gint32 table_idx;
+} MonoReflectionFieldBuilder;
+
+typedef struct {
+ MonoObject object;
+ guint32 attrs;
+ MonoString *name;
+ MonoReflectionType *type;
+ MonoArray *parameters;
+ MonoObject *def_value;
+ MonoReflectionMethodBuilder *set_method;
+ MonoReflectionMethodBuilder *get_method;
+ gint32 table_idx;
+} MonoReflectionPropertyBuilder;
+
+typedef struct {
+ MonoReflectionType type;
+ MonoString *name;
+ MonoString *nspace;
+ MonoReflectionType *parent;
+ MonoArray *interfaces;
+ MonoArray *methods;
+ MonoArray *properties;
+ MonoArray *fields;
+ guint32 attrs;
+ guint32 table_idx;
+} MonoReflectionTypeBuilder;
+
+typedef struct {
+ MonoObject obj;
+ MonoImage *image;
+ MonoObject *assembly;
+ MonoString *fqname;
+ MonoString *name;
+ MonoString *scopename;
+} MonoReflectionModule;
+
+typedef struct {
+ MonoReflectionModule module;
+ MonoArray *types;
+ guint32 table_idx;
+} MonoReflectionModuleBuilder;
+
+int mono_image_get_header (MonoReflectionAssemblyBuilder *assembly, char *buffer, int maxsize);
#endif /* __METADATA_REFLECTION_H__ */
AssemblyBuilder abuilder;
ModuleBuilder mbuilder;
TypeBuilder tbuilder;
+ FieldBuilder fbuilder;
+ PropertyBuilder pbuilder;
AssemblyName an;
String name = "tcgen.exe";
- MethodBuilder method;
+ MethodBuilder method, get_method;
TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.Class;
MethodAttributes mattrs = MethodAttributes.Public | MethodAttributes.Static;
- byte[] body = {0x2a}; // ret
+ byte[] body = {0x16, 0x2a}; // ldc.i4.0 ret
an = new AssemblyName ();
an.Name = name;
tbuilder = mbuilder.DefineType ("Test.CodeGen", attrs);
Type result = typeof(int);
- Type[] param = new Type[] {};
+ Type[] param = new Type[] {typeof (String[])};
method = tbuilder.DefineMethod("Main", mattrs, result, param);
method.CreateMethodBody (body, body.Length);
+
+ fbuilder = tbuilder.DefineField ("int_field", typeof(int), FieldAttributes.Private);
+ fbuilder = tbuilder.DefineField ("string_field", typeof(string), FieldAttributes.Public);
+ /*pbuilder = tbuilder.DefineProperty ("FieldI", PropertyAttributes.None, typeof(int), null);
+ get_method = tbuilder.DefineMethod("get_FieldI", MethodAttributes.Public, result, null);
+ get_method.CreateMethodBody (body, body.Length);
+ pbuilder.SetGetMethod (get_method);*/
+
Type t = tbuilder.CreateType ();
abuilder.SetEntryPoint (method);
abuilder.Save (name);
--- /dev/null
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+
+class CGen {
+
+ public static int Main() {
+ AssemblyBuilder abuilder;
+ ModuleBuilder mbuilder;
+ TypeBuilder tbuilder, tb2;
+ FieldBuilder fbuilder;
+ PropertyBuilder pbuilder;
+ ILGenerator ilg;
+ AssemblyName an;
+ String name = "tcgen.exe";
+ MethodBuilder get_method, entryp;
+ TypeAttributes attrs = TypeAttributes.Public | TypeAttributes.Class;
+ MethodAttributes mattrs = MethodAttributes.Public | MethodAttributes.Static;
+
+ an = new AssemblyName ();
+ an.Name = name;
+ abuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save);
+
+ mbuilder = abuilder.DefineDynamicModule (name, name);
+
+ tbuilder = mbuilder.DefineType ("Test.CodeGen", attrs);
+ Type result = typeof(int);
+ Type[] param = new Type[] {typeof (String[])};
+ entryp = tbuilder.DefineMethod("Main", mattrs, result, param);
+ ilg = entryp.GetILGenerator (128);
+ ilg.DeclareLocal (typeof(int));
+ Label fail = ilg.DefineLabel ();
+ ilg.Emit (OpCodes.Ldc_I4_2);
+ ilg.Emit (OpCodes.Dup);
+ ilg.Emit (OpCodes.Add);
+ ilg.Emit (OpCodes.Stloc_0);
+ ilg.Emit (OpCodes.Ldc_I4_4);
+ ilg.Emit (OpCodes.Ldloc_0);
+ ilg.Emit (OpCodes.Sub);
+ ilg.Emit (OpCodes.Brfalse, fail);
+ ilg.Emit (OpCodes.Ldc_I4_1);
+ ilg.Emit (OpCodes.Ret);
+ ilg.MarkLabel (fail);
+ ilg.Emit (OpCodes.Ldc_I4_0);
+ ilg.Emit (OpCodes.Ret);
+
+
+ fbuilder = tbuilder.DefineField ("int_field", typeof(int), FieldAttributes.Private);
+ /*pbuilder = tbuilder.DefineProperty ("FieldI", PropertyAttributes.None, typeof(int), null);
+ get_method = tbuilder.DefineMethod("get_FieldI", MethodAttributes.Public, result, null);
+ ilg = get_method.GetILGenerator (128);
+ ilg.Emit (OpCodes.Ldloc_0);
+ ilg.Emit (OpCodes.Ret);
+ pbuilder.SetGetMethod (get_method);*/
+
+ Type t = tbuilder.CreateType ();
+ abuilder.SetEntryPoint (entryp);
+ abuilder.Save (name);
+ return 0;
+ }
+}
Thread thr=new Thread(new ThreadStart(test.Thread_func));
thr.Start();
Console.WriteLine("In the main line!");
-
+ thr.Join ();
return 0;
}
}