From cb9f0675532eaadf52e86967dba77dc96cf21d1a Mon Sep 17 00:00:00 2001 From: Paolo Molaro Date: Mon, 19 Nov 2001 06:52:53 +0000 Subject: [PATCH] Mon Nov 19 11:37:14 CET 2001 Paolo Molaro * class.c, class.h: add mono_install_trampoline() so that the runtime can register a function to create a trampoline: removes the ugly requirement that a runtime needed to export arch_create_jit_trampoline. * object.h, object.c: added mono_install_handler() so that the runtime can install an handler for exceptions generated in C code (with mono_raise_exception()). Added C struct for System.Delegate. * pedump.c: removed arch_create_jit_trampoline. * reflection.c: some cleanups to allow registering user strings and later getting a token for methodrefs and fieldrefs before the assembly is built. * row-indexes.h: updates and fixes from the new ECMA specs. Mon Nov 19 11:36:22 CET 2001 Paolo Molaro * jit.c: use mono_install_trampoline (), instead of exporting a function to a lower-level library. Mon Nov 19 11:33:00 CET 2001 Paolo Molaro * interp.c: start adding support for handling exceptions across managed/unmanaged boundaries. Cleanup Delegate method invocation. Pass the correct target object in Delegate::Invoke and use the correct 'this' pointer in ldvirtftn (bugs pointed out by Dietmar). Mon Nov 19 11:32:28 CET 2001 Paolo Molaro * main.c: remove arch_create_jit_trampoline(). svn path=/trunk/mono/; revision=1380 --- mono/arch/ChangeLog | 4 + mono/arch/x86/tramp.c | 28 ++++-- mono/dis/ChangeLog | 11 ++ mono/dis/dump.c | 11 +- mono/dis/get.c | 24 ++--- mono/dis/main.c | 20 ++-- mono/interpreter/ChangeLog | 12 +++ mono/interpreter/Makefile.am | 1 + mono/interpreter/interp.c | 188 ++++++++++++++++++++++------------- mono/jit/ChangeLog | 6 ++ mono/jit/jit.c | 2 + mono/metadata/ChangeLog | 24 +++++ mono/metadata/class.c | 17 +++- mono/metadata/class.h | 9 +- mono/metadata/icall.c | 1 + mono/metadata/metadata.c | 43 ++++++++ mono/metadata/metadata.h | 2 + mono/metadata/object.c | 21 ++++ mono/metadata/object.h | 16 +++ mono/metadata/pedump.c | 8 -- mono/metadata/reflection.c | 170 ++++++++++++++++++++++++++----- mono/metadata/reflection.h | 18 +++- mono/metadata/row-indexes.h | 24 ++--- mono/tests/Makefile.am | 9 +- mono/tests/ackermann.cs | 19 ++++ mono/tests/enum.cs | 20 ++++ mono/tests/sieve.cs | 32 ++++++ mono/tests/tight-loop.cs | 9 ++ 28 files changed, 595 insertions(+), 154 deletions(-) create mode 100644 mono/tests/ackermann.cs create mode 100644 mono/tests/sieve.cs create mode 100644 mono/tests/tight-loop.cs diff --git a/mono/arch/ChangeLog b/mono/arch/ChangeLog index e6213803371..6eb7c170489 100644 --- a/mono/arch/ChangeLog +++ b/mono/arch/ChangeLog @@ -1,4 +1,8 @@ +Thu Nov 15 17:41:01 CET 2001 Paolo Molaro + + * x86/tramp.c: handle enums with underlying type different from int32. + Wed Nov 14 19:21:26 CET 2001 Paolo Molaro * x86/tramp.c: handle boolean as a return value. diff --git a/mono/arch/x86/tramp.c b/mono/arch/x86/tramp.c index 879021958b4..51213fbc094 100644 --- a/mono/arch/x86/tramp.c +++ b/mono/arch/x86/tramp.c @@ -32,7 +32,7 @@ mono_create_trampoline (MonoMethod *method) MonoMethodSignature *sig; unsigned char *p, *code_buffer; guint32 local_size = 0, stack_size = 0, code_size = 30; - guint32 arg_pos; + guint32 arg_pos, simpletype; int i, stringp; sig = method->signature; @@ -48,7 +48,9 @@ mono_create_trampoline (MonoMethod *method) code_size += i < 10 ? 5 : 8; continue; } - switch (sig->params [i]->type) { + simpletype = sig->params [i]->type; +enum_calc_size: + switch (simpletype) { case MONO_TYPE_BOOLEAN: case MONO_TYPE_CHAR: case MONO_TYPE_I1: @@ -68,7 +70,11 @@ mono_create_trampoline (MonoMethod *method) code_size += i < 10 ? 5 : 8; break; case MONO_TYPE_VALUETYPE: - if (!sig->params [i]->data.klass->enumtype && (mono_class_value_size (sig->params [i]->data.klass, NULL) != 4)) + if (sig->params [i]->data.klass->enumtype) { + simpletype = sig->params [i]->data.klass->enum_basetype->type; + goto enum_calc_size; + } + if (mono_class_value_size (sig->params [i]->data.klass, NULL) != 4) g_error ("can only marshal enums, not generic structures (size: %d)", mono_class_value_size (sig->params [i]->data.klass, NULL)); stack_size += 4; code_size += i < 10 ? 5 : 8; @@ -129,7 +135,9 @@ mono_create_trampoline (MonoMethod *method) x86_push_membase (p, X86_EDX, arg_pos); continue; } - switch (sig->params [i - 1]->type) { + simpletype = sig->params [i - 1]->type; +enum_marshal: + switch (simpletype) { case MONO_TYPE_BOOLEAN: case MONO_TYPE_I1: case MONO_TYPE_U1: @@ -154,7 +162,8 @@ mono_create_trampoline (MonoMethod *method) x86_push_regp (p, X86_EAX); } else { /* it's an enum value */ - x86_push_membase (p, X86_EDX, arg_pos); + simpletype = sig->params [i - 1]->data.klass->enum_basetype->type; + goto enum_marshal; } break; case MONO_TYPE_R8: @@ -222,7 +231,9 @@ mono_create_trampoline (MonoMethod *method) x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); } else { - switch (sig->ret->type) { + simpletype = sig->ret->type; +enum_retvalue: + switch (simpletype) { case MONO_TYPE_BOOLEAN: case MONO_TYPE_I1: case MONO_TYPE_U1: @@ -252,6 +263,11 @@ mono_create_trampoline (MonoMethod *method) x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); x86_mov_membase_reg (p, X86_ECX, 4, X86_EDX, 4); break; + case MONO_TYPE_VALUETYPE: + if (sig->ret->data.klass->enumtype) { + simpletype = sig->ret->data.klass->enum_basetype->type; + goto enum_retvalue; + } case MONO_TYPE_VOID: break; default: diff --git a/mono/dis/ChangeLog b/mono/dis/ChangeLog index e1b3b590af4..c72f7651235 100644 --- a/mono/dis/ChangeLog +++ b/mono/dis/ChangeLog @@ -1,3 +1,14 @@ + +Mon Nov 19 11:32:28 CET 2001 Paolo Molaro + + * main.c: remove arch_create_jit_trampoline(). + +Thu Nov 15 17:42:03 CET 2001 Paolo Molaro + + * dump.c: decode more info in the constant table. + * get.c: show literals the same way ildasm does. + * main.c: decode literal values for fields. + Fri Nov 2 19:04:21 CET 2001 Paolo Molaro * main.c, dump, dump.c: decode the customattr table. diff --git a/mono/dis/dump.c b/mono/dis/dump.c index 3e3da13830c..07542a850c7 100644 --- a/mono/dis/dump.c +++ b/mono/dis/dump.c @@ -277,15 +277,22 @@ dump_table_constant (MonoMetadata *m) { MonoTableInfo *t = &m->tables [MONO_TABLE_CONSTANT]; int i; + const char *desc [] = { + "Field", + "Param", + "Property", + "" + }; fprintf (output, "Constant Table (0..%d)\n", t->rows); for (i = 0; i < t->rows; i++){ guint32 cols [MONO_CONSTANT_SIZE]; + char *parent = desc [cols [MONO_CONSTANT_PARENT] & HASCOSTANT_MASK]; mono_metadata_decode_row (t, i, cols, MONO_CONSTANT_SIZE); - fprintf (output, "%d: Parent=0x%08x %s\n", - i, cols [MONO_CONSTANT_PARENT], + fprintf (output, "%d: Parent= %s: %d %s\n", + i, parent, cols [MONO_CONSTANT_PARENT] >> HASCOSTANT_BITS, get_constant (m, (MonoTypeEnum) cols [MONO_CONSTANT_TYPE], cols [MONO_CONSTANT_VALUE])); } diff --git a/mono/dis/get.c b/mono/dis/get.c index 4d1eff5626b..ea002d2d169 100644 --- a/mono/dis/get.c +++ b/mono/dis/get.c @@ -1040,22 +1040,26 @@ get_constant (MonoMetadata *m, MonoTypeEnum t, guint32 blob_index) return g_strdup_printf ("%s", *ptr ? "true" : "false"); case MONO_TYPE_CHAR: - return g_strdup_printf ("%c", *ptr); + return g_strdup_printf ("%c", *ptr); /* FIXME: unicode char */ case MONO_TYPE_U1: - return g_strdup_printf ("0x%02x", (int) (*ptr)); + case MONO_TYPE_I1: + return g_strdup_printf ("int8(0x%02x)", (int) (*ptr)); break; + case MONO_TYPE_U2: case MONO_TYPE_I2: - return g_strdup_printf ("%d", (int) read16 (ptr)); + return g_strdup_printf ("int16(0x%08x)", (int) read16 (ptr)); + case MONO_TYPE_U4: case MONO_TYPE_I4: - return g_strdup_printf ("%d", read32 (ptr)); + return g_strdup_printf ("int32(%d)", read32 (ptr)); case MONO_TYPE_I8: /* * FIXME: This is not endian portable, does only * matter for debugging, but still. + * Need also to fix unaligned access. */ return g_strdup_printf ("0x%08x%08x", *(guint32 *) ptr, *(guint32 *) (ptr + 4)); @@ -1109,18 +1113,6 @@ get_constant (MonoMetadata *m, MonoTypeEnum t, guint32 blob_index) case MONO_TYPE_CLASS: return g_strdup ("CLASS CONSTANT. MUST BE ZERO"); - /* - * These are non CLS compliant: - */ - case MONO_TYPE_I1: - return g_strdup_printf ("%d", (int) *ptr); - - case MONO_TYPE_U2: - return g_strdup_printf ("0x%04x", (unsigned int) read16 (ptr)); - - case MONO_TYPE_U4: - return g_strdup_printf ("0x%04x", (unsigned int) read32 (ptr)); - default: g_error ("Unknown MONO_TYPE (%d) on constant at Blob index (0x%08x)\n", (int) *ptr, blob_index); diff --git a/mono/dis/main.c b/mono/dis/main.c index 3bd574b8320..fb2adc624f0 100644 --- a/mono/dis/main.c +++ b/mono/dis/main.c @@ -32,14 +32,6 @@ gboolean dump_header_data_p = FALSE; int dump_table = -1; -gpointer arch_create_jit_trampoline (MonoMethod *method); - -gpointer -arch_create_jit_trampoline (MonoMethod *method) -{ - return method; -} - static void dump_header_data (MonoImage *img) { @@ -190,12 +182,16 @@ dis_field_list (MonoMetadata *m, guint32 start, guint32 end) flags = field_flags (cols [MONO_FIELD_FLAGS]); if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_LITERAL){ - MonoTypeEnum type; char *lit; + guint32 const_cols [MONO_CONSTANT_SIZE]; + guint32 crow; - type = get_field_literal_type (m, cols [MONO_FIELD_SIGNATURE]); - lit = g_strdup ("FIXME:Do-not-know-how-to-get-this-from-the-constants-table"); - /* get_constant (m, type, cols [2]); */ + if ((crow = mono_metadata_get_constant_index (m, MONO_TOKEN_FIELD_DEF | (i+1)))) { + mono_metadata_decode_row (&m->tables [MONO_TABLE_CONSTANT], crow-1, const_cols, MONO_CONSTANT_SIZE); + lit = get_constant (m, const_cols [MONO_CONSTANT_TYPE], const_cols [MONO_CONSTANT_VALUE]); + } else { + lit = g_strdup ("not found"); + } fprintf (output, " .field %s %s %s = ", flags, sig, diff --git a/mono/interpreter/ChangeLog b/mono/interpreter/ChangeLog index 70c542e6277..f3f28c8e08c 100644 --- a/mono/interpreter/ChangeLog +++ b/mono/interpreter/ChangeLog @@ -1,4 +1,16 @@ +Mon Nov 19 11:33:00 CET 2001 Paolo Molaro + + * interp.c: start adding support for handling exceptions across + managed/unmanaged boundaries. Cleanup Delegate method invocation. + Pass the correct target object in Delegate::Invoke and use the correct + 'this' pointer in ldvirtftn (bugs pointed out by Dietmar). + +Thu Nov 15 17:40:24 CET 2001 Paolo Molaro + + * interp.c: handle enums with underlying type different from int32. + More checks for C structs <-> C# objects consistency. + Wed Nov 14 19:23:00 CET 2001 Paolo Molaro * interp.c: move the stack frame dumping code to a function so it can diff --git a/mono/interpreter/Makefile.am b/mono/interpreter/Makefile.am index b1a2df58a93..b43f9588190 100644 --- a/mono/interpreter/Makefile.am +++ b/mono/interpreter/Makefile.am @@ -13,6 +13,7 @@ mint_SOURCES = \ mint_LDADD = \ ../arch/libmonoarch.la \ ../metadata/libmetadata.a \ + ../io-layer/libwapi.a \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ -lm diff --git a/mono/interpreter/interp.c b/mono/interpreter/interp.c index 3c62405d090..b182b1855d8 100644 --- a/mono/interpreter/interp.c +++ b/mono/interpreter/interp.c @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef HAVE_ALLOCA_H # include @@ -37,6 +38,7 @@ #include #include #include +#include /*#include */ #include "interp.h" #include "hacks.h" @@ -87,12 +89,13 @@ void ves_exec_method (MonoInvocation *frame); typedef void (*ICallMethod) (MonoInvocation *frame); -gpointer arch_create_jit_trampoline (MonoMethod *method); +static guint32 frame_thread_id = 0; -gpointer -arch_create_jit_trampoline (MonoMethod *method) -{ - return method; +static void +interp_ex_handler (MonoException *ex) { + MonoInvocation *frame = TlsGetValue (frame_thread_id); + frame->ex = ex; + longjmp (*(jmp_buf*)frame->locals, 1); } static void @@ -378,9 +381,7 @@ stackval_from_data (MonoType *type, stackval *result, const char *data) return; case MONO_TYPE_VALUETYPE: if (type->data.klass->enumtype) { - result->type = VAL_I32; - result->data.i = *(guint32*)data; - result->data.vt.klass = mono_class_from_mono_type (type); + return stackval_from_data (type->data.klass->enum_basetype, result, data); } else { result->type = VAL_VALUET; result->data.vt.klass = type->data.klass; @@ -462,8 +463,7 @@ stackval_to_data (MonoType *type, stackval *val, char *data) } case MONO_TYPE_VALUETYPE: if (type->data.klass->enumtype) { - gint32 *p = (gint32*)data; - *p = val->data.i; + return stackval_to_data (type->data.klass->enum_basetype, val, data); } else { memcpy (data, val->data.vt.vt, mono_class_value_size (type->data.klass, NULL)); } @@ -564,20 +564,28 @@ ves_array_get (MonoInvocation *frame) static void ves_pinvoke_method (MonoInvocation *frame) { - MonoPIFunc func = mono_create_trampoline (frame->method); + jmp_buf env; + volatile MonoPIFunc func = mono_create_trampoline (frame->method); + if (setjmp(env)) { + g_free ((void*)func); + return; + } + /* + * frame->locals and args are unused for P/Invoke methods, so we reuse them. + * locals will point to the jmp_buf, while args will point to the previous + * MonoInvocation frame: this is needed to make exception searching work across + * managed/unmanaged boundaries. + */ + frame->locals = (char*)&env; + frame->args = (char*)TlsGetValue (frame_thread_id); + TlsSetValue (frame_thread_id, frame); + func ((MonoFunc)frame->method->addr, &frame->retval->data.p, frame->obj, frame->stack_args); stackval_from_data (frame->method->signature->ret, frame->retval, (const char*)&frame->retval->data.p); g_free ((void*)func); } /* - * This is a hack, you don't want to see the code in this function. Go away. - * - * We need a way to easily find the offset in an object of a field we may be - * interested in: it's needed here and in several other code where the C# - * implementation is highly tied to the internals (Array and String are other good - * examples). - * * From the spec: * runtime specifies that the implementation of the method is automatically * provided by the runtime and is primarily used for the methods of delegates. @@ -586,35 +594,22 @@ static void ves_runtime_method (MonoInvocation *frame) { const char *name = frame->method->name; - MonoObject *obj = frame->obj; - static guint target_offset = 0; - static guint method_offset = 0; + MonoObject *obj = (MonoObject*)frame->obj; + MonoDelegate *delegate = (MonoDelegate*)frame->obj; init_class(mono_defaults.delegate_class); - if (!target_offset) { - MonoClassField *field; - - field = mono_class_get_field_from_name (mono_defaults.delegate_class, "m_target"); - target_offset = field->offset; - field = mono_class_get_field_from_name (mono_defaults.delegate_class, "method_ptr"); - method_offset = field->offset; - } - if (*name == '.' && (strcmp (name, ".ctor") == 0) && obj && mono_object_isinst (obj, mono_defaults.delegate_class)) { - gpointer *p; - p = (gpointer*)(((char*)obj) + target_offset); - *p = frame->stack_args[0].data.p; - p = (gpointer*)(((char*)obj) + method_offset); - *p = frame->stack_args[1].data.p; + delegate->target = frame->stack_args[0].data.p; + delegate->method_ptr = frame->stack_args[1].data.p; return; } if (*name == 'I' && (strcmp (name, "Invoke") == 0) && obj && mono_object_isinst (obj, mono_defaults.delegate_class)) { MonoPIFunc func = mono_create_trampoline (frame->method); - void* faddr = *(gpointer*)(((char*)obj) + method_offset); - func ((MonoFunc)faddr, &frame->retval->data.p, frame->obj, frame->stack_args); + /* FIXME: need to handle exceptions across managed/unmanaged boundaries */ + func ((MonoFunc)delegate->method_ptr, &frame->retval->data.p, delegate->target, frame->stack_args); stackval_from_data (frame->method->signature->ret, frame->retval, (const char*)&frame->retval->data.p); g_free ((void*)func); return; @@ -2205,10 +2200,13 @@ array_constructed: guint32 token, offset; int load_addr = *ip == CEE_LDFLDA; + if (!sp [-1].data.p) + THROW_EX (get_exception_null_reference (), ip); + ++ip; token = read32 (ip); ip += 4; - + if (sp [-1].type == VAL_OBJ) { obj = sp [-1].data.p; field = mono_class_get_field (obj->klass, token); @@ -2968,10 +2966,10 @@ array_constructed: if (!m) THROW_EX (get_exception_missing_method (), ip - 5); if (virtual) { - stackval *objs = &sp [-m->signature->param_count - 1]; - if (!objs->data.p) + --sp; + if (!sp->data.p) THROW_EX (get_exception_null_reference (), ip - 5); - m = get_virtual_method (m, objs); + m = get_virtual_method (m, sp); } sp->type = VAL_NATI; sp->data.p = mono_create_method_pointer (m); @@ -3182,21 +3180,21 @@ array_constructed: clause = &hd->clauses [i]; if (clause->flags <= 1 && OFFSET_IN_CLAUSE (clause, ip_offset)) { if (!clause->flags) { - if (mono_object_isinst ((MonoObject*)frame->ex, mono_class_get (inv->method->klass->image, clause->token_or_filter))) { - /* - * OK, we found an handler, now we need to execute the finally - * and fault blocks before branching to the handler code. - */ - inv->ex_handler = clause; - /* - * It seems that if the catch handler is found in the same method, - * it gets executed before the finally handler. - */ - if (inv == frame) - goto handle_fault; - else - goto handle_finally; - } + if (mono_object_isinst ((MonoObject*)frame->ex, mono_class_get (inv->method->klass->image, clause->token_or_filter))) { + /* + * OK, we found an handler, now we need to execute the finally + * and fault blocks before branching to the handler code. + */ + inv->ex_handler = clause; + /* + * It seems that if the catch handler is found in the same method, + * it gets executed before the finally handler. + */ + if (inv == frame) + goto handle_fault; + else + goto handle_finally; + } } else { /* FIXME: handle filter clauses */ g_assert (0); @@ -3376,14 +3374,36 @@ assemblybuilder_fields[] = { {NULL, 0} }; +static FieldDesc +ctorbuilder_fields[] = { + {"ilgen", G_STRUCT_OFFSET (MonoReflectionCtorBuilder, ilgen)}, + {"parameters", G_STRUCT_OFFSET (MonoReflectionCtorBuilder, parameters)}, + {"attrs", G_STRUCT_OFFSET (MonoReflectionCtorBuilder, attrs)}, + {"iattrs", G_STRUCT_OFFSET (MonoReflectionCtorBuilder, iattrs)}, + {"table_idx", G_STRUCT_OFFSET (MonoReflectionCtorBuilder, table_idx)}, + {"call_conv", G_STRUCT_OFFSET (MonoReflectionCtorBuilder, call_conv)}, + {"type", G_STRUCT_OFFSET (MonoReflectionCtorBuilder, type)}, + {NULL, 0} +}; + static FieldDesc methodbuilder_fields[] = { + {"mhandle", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, mhandle)}, {"rtype", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, rtype)}, {"parameters", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, parameters)}, {"attrs", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, attrs)}, + {"iattrs", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, iattrs)}, {"name", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, name)}, {"table_idx", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, table_idx)}, {"code", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, code)}, + {"ilgen", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, ilgen)}, + {"type", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, type)}, + {"pinfo", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, pinfo)}, + {"pi_dll", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, dll)}, + {"pi_entry", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, dllentry)}, + {"ncharset", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, charset)}, + {"native_cc", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, native_cc)}, + {"call_conv", G_STRUCT_OFFSET (MonoReflectionMethodBuilder, call_conv)}, {NULL, 0} }; @@ -3412,16 +3432,44 @@ propertybuilder_fields[] = { }; static ClassDesc -classes_to_check [] = { +emit_classes_to_check [] = { {"TypeBuilder", typebuilder_fields}, {"ModuleBuilder", modulebuilder_fields}, {"AssemblyBuilder", assemblybuilder_fields}, + {"ConstructorBuilder", ctorbuilder_fields}, {"MethodBuilder", methodbuilder_fields}, {"FieldBuilder", fieldbuilder_fields}, {"PropertyBuilder", propertybuilder_fields}, {NULL, NULL} }; +static FieldDesc +delegate_fields[] = { + {"target_type", G_STRUCT_OFFSET (MonoDelegate, target_type)}, + {"m_target", G_STRUCT_OFFSET (MonoDelegate, target)}, + {"method", G_STRUCT_OFFSET (MonoDelegate, method)}, + {"method_ptr", G_STRUCT_OFFSET (MonoDelegate, method_ptr)}, + {NULL, 0} +}; + +static ClassDesc +system_classes_to_check [] = { + {"Delegate", delegate_fields}, + {NULL, NULL} +}; + +typedef struct { + char *name; + ClassDesc *types; +} NameSpaceDesc; + +static NameSpaceDesc +namespaces_to_check[] = { + {"System.Reflection.Emit", emit_classes_to_check}, + {"System", system_classes_to_check}, + {NULL, NULL} +}; + static void check_corlib (MonoImage *corlib) { @@ -3429,17 +3477,19 @@ check_corlib (MonoImage *corlib) MonoClassField *field; FieldDesc *fdesc; ClassDesc *cdesc; - const char *refl = "System.Reflection.Emit"; + NameSpaceDesc *ndesc; - 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 (%ld != %ld)", fdesc->name, cdesc->name, (long) fdesc->offset, (long) (field?field->offset:-1)); + for (ndesc = namespaces_to_check; ndesc->name; ++ndesc) { + for (cdesc = ndesc->types; cdesc->name; ++cdesc) { + klass = mono_class_from_name (corlib, ndesc->name, 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 ("field %s mismatch in class %s (%ld != %ld)", fdesc->name, cdesc->name, (long) fdesc->offset, (long) (field?field->offset:-1)); + } } } } @@ -3474,6 +3524,7 @@ main (int argc, char *argv []) mono_init (); mono_init_icall (); + mono_install_handler (interp_ex_handler); mono_add_internal_call ("__array_Set", ves_array_set); mono_add_internal_call ("__array_Get", ves_array_get); @@ -3486,6 +3537,9 @@ main (int argc, char *argv []) mono_thread_init(); + frame_thread_id = TlsAlloc (); + TlsSetValue (frame_thread_id, NULL); + #ifdef RUN_TEST test_load_class (assembly->image); #else diff --git a/mono/jit/ChangeLog b/mono/jit/ChangeLog index ea61fdd3bd1..34cada0ca09 100644 --- a/mono/jit/ChangeLog +++ b/mono/jit/ChangeLog @@ -1,3 +1,9 @@ + +Mon Nov 19 11:36:22 CET 2001 Paolo Molaro + + * jit.c: use mono_install_trampoline (), instead of exporting + a function to a lower-level library. + 2001-11-16 Dietmar Maurer * x86.brg (STRING_ARG): impl. a way to marshal strings. This diff --git a/mono/jit/jit.c b/mono/jit/jit.c index 62e9541afca..c14a6f2e62f 100644 --- a/mono/jit/jit.c +++ b/mono/jit/jit.c @@ -2644,6 +2644,8 @@ main (int argc, char *argv []) mono_add_internal_call ("__array_Set", ves_array_set); mono_add_internal_call ("__array_Get", ves_array_get); + mono_install_trampoline (arch_create_jit_trampoline); + assembly = mono_assembly_open (file, NULL, NULL); if (!assembly){ fprintf (stderr, "Can not open image %s\n", file); diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index dc734efb390..e7fdfac72bb 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,4 +1,28 @@ +Mon Nov 19 11:37:14 CET 2001 Paolo Molaro + + * class.c, class.h: add mono_install_trampoline() so that the runtime + can register a function to create a trampoline: removes the ugly + requirement that a runtime needed to export arch_create_jit_trampoline. + * object.h, object.c: added mono_install_handler() so that the runtime + can install an handler for exceptions generated in C code (with + mono_raise_exception()). Added C struct for System.Delegate. + * pedump.c: removed arch_create_jit_trampoline. + * reflection.c: some cleanups to allow registering user strings and + later getting a token for methodrefs and fieldrefs before the assembly + is built. + * row-indexes.h: updates and fixes from the new ECMA specs. + +Thu Nov 15 17:44:49 CET 2001 Paolo Molaro + + * class.h, class.c: add enum_basetype field to MonoClass. + * metadata.h, metadata.c: add mono_metadata_get_constant_index() + to get index in the constant table reated to a field, param or + property. + * reflection.h, reflection.c: handle constructors. Set public-key and + version number of the built assembly to 0. + * row-indexes.h: update from new ECMA spec. + Wed Nov 14 19:26:06 CET 2001 Paolo Molaro * class.h, class.c: add a max_interface_id to MonoClass. diff --git a/mono/metadata/class.c b/mono/metadata/class.c index b57a318c789..92a544140ab 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -28,7 +28,18 @@ #define CSIZE(x) (sizeof (x) / 4) -gpointer arch_create_jit_trampoline (MonoMethod *method); +static gpointer +default_trampoline (MonoMethod *method) +{ + return method; +} + +static MonoTrampoline arch_create_jit_trampoline = default_trampoline; + +void +mono_install_trampoline (MonoTrampoline func) { + arch_create_jit_trampoline = func? func: default_trampoline; +} static MonoClass * mono_class_create_from_typeref (MonoImage *image, guint32 type_token) @@ -48,7 +59,7 @@ mono_class_create_from_typeref (MonoImage *image, guint32 type_token) * detected a reference to mscorlib, we simply return a reference to a dummy * until we have a better solution. */ - fprintf(stderr, "Sending dummy where %s expected\n", mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME])); + fprintf(stderr, "Sending dummy where %s.%s expected\n", mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]), mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME])); res = mono_class_from_name (image, "System", "MonoDummy"); /* prevent method loading */ res->dummy = 1; @@ -107,6 +118,8 @@ class_compute_field_layout (MonoClass *class) if (!class->fields [i].data) g_warning ("field %s in %s should have RVA data, but hasn't", class->fields [i].name, class->name); } + if (class->enumtype && !(cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_STATIC)) + class->enum_basetype = class->fields [i].type; } /* * Compute field layout and total size. diff --git a/mono/metadata/class.h b/mono/metadata/class.h index c03716a9d7d..6cdff29d5ec 100644 --- a/mono/metadata/class.h +++ b/mono/metadata/class.h @@ -47,7 +47,7 @@ struct _MonoClass { int vtable_size; /* number of slots */ /* - * relartive numbering for fast type checking + * relative numbering for fast type checking */ unsigned int baseval; unsigned int diffval; @@ -68,6 +68,8 @@ struct _MonoClass { MonoMethod **methods; + /* The underlying type of the enum */ + MonoType *enum_basetype; /* for arrays */ MonoClass *element_class; /* element class */ guint32 rank; /* array dimension */ @@ -120,4 +122,9 @@ mono_class_from_mono_type (MonoType *type); gpointer mono_ldtoken (MonoImage *image, guint32 token, MonoClass **retclass); +typedef gpointer (*MonoTrampoline) (MonoMethod *method); + +void +mono_install_trampoline (MonoTrampoline func); + #endif /* _MONO_CLI_CLASS_H_ */ diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index d2f704bbc44..decdbea238f 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -349,6 +349,7 @@ static gpointer icall_map [] = { * AssemblyBuilder */ "System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_get_data_chunk, + "System.Reflection.Emit.AssemblyBuilder::getUSIndex", mono_image_insert_string, /* * TypeBuilder diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index c58a7d8d0bf..a6fc432671e 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -1972,3 +1972,46 @@ mono_metadata_field_info (MonoMetadata *meta, guint32 index, guint32 *offset, co } } + +/* + * mono_metadata_get_constant_index: + * @meta: the Image the field is defined in + * @index: the token that may have a row defined in the constants table + * + * @token must be a FieldDef, ParamDef or PropertyDef token. + * + * Returns: the index into the Constsnts table or 0 if not found. + */ +guint32 +mono_metadata_get_constant_index (MonoMetadata *meta, guint32 token) +{ + MonoTableInfo *tdef; + locator_t loc; + guint32 index = mono_metadata_token_index (token); + + tdef = &meta->tables [MONO_TABLE_CONSTANT]; + index <<= HASCOSTANT_BITS; + switch (mono_metadata_token_table (token)) { + case MONO_TABLE_FIELD: + index |= HASCOSTANT_FIEDDEF; + break; + case MONO_TABLE_PARAM: + index |= HASCOSTANT_PARAM; + break; + case MONO_TABLE_PROPERTY: + index |= HASCOSTANT_PROPERTY; + break; + default: + g_warning ("Not a valid token for the constant table: 0x%08x", token); + return 0; + } + loc.idx = index; + loc.col_idx = MONO_CONSTANT_PARENT; + loc.t = tdef; + + if (tdef->base && bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator)) { + return loc.result + 1; + } + return 0; +} + diff --git a/mono/metadata/metadata.h b/mono/metadata/metadata.h index 72f2743fe86..47521f2b375 100644 --- a/mono/metadata/metadata.h +++ b/mono/metadata/metadata.h @@ -120,6 +120,8 @@ void mono_metadata_field_info (MonoMetadata *meta, const char **rva, const char **marshal_info); +guint32 mono_metadata_get_constant_index (MonoMetadata *meta, guint32 token); + /* * Functions to extract information from the Blobs */ diff --git a/mono/metadata/object.c b/mono/metadata/object.c index 0c9d54d804e..3fad7f11516 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -389,3 +389,24 @@ mono_string_to_utf8 (MonoString *s) return as; } +static void +default_ex_handler (MonoException *ex) +{ + MonoObject *o = (MonoObject*)ex; + g_error ("Exception %s.%s raised in C code", o->klass->name_space, o->klass->name); +} + +static MonoExceptionFunc ex_handler = default_ex_handler; + +void +mono_install_handler (MonoExceptionFunc func) +{ + ex_handler = func? func: default_ex_handler; +} + +void +mono_raise_exception (MonoException *ex) +{ + ex_handler (ex); +} + diff --git a/mono/metadata/object.h b/mono/metadata/object.h index 795210330af..1af32a8ae68 100644 --- a/mono/metadata/object.h +++ b/mono/metadata/object.h @@ -33,6 +33,14 @@ typedef struct { MonoString *message; } MonoException; +typedef struct { + MonoObject object; + MonoObject *target_type; + MonoObject *target; + MonoString *method; + gpointer method_ptr; +} MonoDelegate; + #define mono_array_length(array) ((array)->bounds->length) #define mono_array_addr(array,type,index) ( ((char*)(array)->vector) + sizeof (type) * (index) ) #define mono_array_addr_with_size(array,size,index) ( ((char*)(array)->vector) + (size) * (index) ) @@ -87,5 +95,13 @@ mono_object_clone (MonoObject *obj); gboolean mono_object_isinst (MonoObject *obj, MonoClass *klass); +typedef void (*MonoExceptionFunc) (MonoException *ex); + +void +mono_install_handler (MonoExceptionFunc func); + +void +mono_raise_exception (MonoException *ex); + #endif diff --git a/mono/metadata/pedump.c b/mono/metadata/pedump.c index 0d49fccb8c4..e57c5dcab09 100644 --- a/mono/metadata/pedump.c +++ b/mono/metadata/pedump.c @@ -20,14 +20,6 @@ gboolean dump_data = TRUE; gboolean dump_tables = FALSE; -gpointer arch_create_jit_trampoline (MonoMethod *method); - -gpointer -arch_create_jit_trampoline (MonoMethod *method) -{ - return method; -} - static void hex_dump (char *buffer, int base, int count) { diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index ee3a0d6b357..1890cf2a7e4 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -27,6 +27,19 @@ #define CLI_H_SIZE 136 #define FILE_ALIGN 512 +typedef struct { + MonoReflectionILGen *ilgen; + MonoReflectionType *rtype; + MonoArray *parameters; + guint32 attrs; + guint32 iattrs; + guint32 call_conv; + guint32 *table_idx; /* note: it's a pointer */ + MonoArray *code; + MonoObject *type; + MonoString *name; +} ReflectionMethodBuilder; + const unsigned char table_sizes [64] = { MONO_MODULE_SIZE, MONO_TYPEREF_SIZE, @@ -147,6 +160,11 @@ mono_image_add_stream_data (MonoDynamicStream *stream, char *data, guint32 len) static void encode_type (MonoType *type, char *p, char **endbuf) { + if (!type) { + mono_metadata_encode_value (MONO_TYPE_VOID, p, endbuf); + return; + } + switch (type->type){ case MONO_TYPE_VOID: case MONO_TYPE_BOOLEAN: @@ -182,7 +200,7 @@ encode_type (MonoType *type, char *p, char **endbuf) } static guint32 -method_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionMethodBuilder *mb) +method_encode_signature (MonoDynamicAssembly *assembly, ReflectionMethodBuilder *mb) { char *buf; char *p; @@ -252,7 +270,7 @@ encode_locals (MonoDynamicAssembly *assembly, MonoReflectionILGen *ilgen) } static guint32 -method_encode_code (MonoDynamicAssembly *assembly, MonoReflectionMethodBuilder *mb) +method_encode_code (MonoDynamicAssembly *assembly, ReflectionMethodBuilder *mb) { /* we use only tiny formats now: need to implement ILGenerator */ char flags = 0; @@ -335,23 +353,49 @@ find_index_in_table (MonoDynamicAssembly *assembly, int table_idx, int col, guin } static void -mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicAssembly *assembly) +mono_image_basic_method (ReflectionMethodBuilder *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; - name = mono_string_to_utf8 (mb->name); - values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, name); - g_free (name); + *mb->table_idx = table->next_idx ++; + values = table->values + *mb->table_idx * MONO_METHOD_SIZE; + if (mb->name) { + name = mono_string_to_utf8 (mb->name); + values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, name); + g_free (name); + } else { /* a constructor */ + values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, mb->attrs & METHOD_ATTRIBUTE_STATIC? ".cctor": ".ctor"); + } values [MONO_METHOD_FLAGS] = mb->attrs; - values [MONO_METHOD_IMPLFLAGS] = 0; + values [MONO_METHOD_IMPLFLAGS] = mb->iattrs; values [MONO_METHOD_SIGNATURE] = method_encode_signature (assembly, mb); values [MONO_METHOD_PARAMLIST] = 0; /* FIXME: add support later */ values [MONO_METHOD_RVA] = method_encode_code (assembly, mb); +} + +static void +mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicAssembly *assembly) +{ + MonoDynamicTable *table; + guint32 *values; + char *name; + ReflectionMethodBuilder rmb; + + rmb.ilgen = mb->ilgen; + rmb.rtype = mb->rtype; + rmb.parameters = mb->parameters; + rmb.attrs = mb->attrs; + rmb.iattrs = mb->iattrs; + rmb.call_conv = mb->call_conv; + rmb.code = mb->code; + rmb.type = mb->type; + rmb.name = mb->name; + rmb.table_idx = &mb->table_idx; + + mono_image_basic_method (&rmb, assembly); if (mb->dll) { /* It's a P/Invoke method */ guint32 moduleref; @@ -377,6 +421,26 @@ mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicAssembly } } +static void +mono_image_get_ctor_info (MonoReflectionCtorBuilder *mb, MonoDynamicAssembly *assembly) +{ + ReflectionMethodBuilder rmb; + + rmb.ilgen = mb->ilgen; + rmb.rtype = NULL; + rmb.parameters = mb->parameters; + rmb.attrs = mb->attrs; + rmb.iattrs = mb->iattrs; + rmb.call_conv = mb->call_conv; + rmb.code = NULL; + rmb.type = mb->type; + rmb.name = NULL; + rmb.table_idx = &mb->table_idx; + + mono_image_basic_method (&rmb, assembly); + +} + static guint32 field_encode_signature (MonoDynamicAssembly *assembly, MonoReflectionFieldBuilder *fb) { @@ -507,6 +571,15 @@ mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicAsse } } +static guint32 +resolution_scope_from_image (MonoDynamicAssembly *assembly, MonoImage *image) +{ + if (image != mono_defaults.corlib) + g_error ("multiple assemblyref not yet supported"); + /* first row in assemblyref */ + return (1 << RESOLTION_SCOPE_BITS) | RESOLTION_SCOPE_ASSEMBLYREF; +} + static guint32 mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type) { @@ -522,16 +595,18 @@ mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type) if (token) return token; klass = type->data.klass; - if (klass->image != mono_defaults.corlib) - g_error ("multiple assemblyref not yet supported"); + /* + * If it's in the same module: + * return TYPEDEFORREF_TYPEDEF | ((klass->token & 0xffffff) << TYPEDEFORREF_BITS) + */ table = &assembly->tables [MONO_TABLE_TYPEREF]; alloc_table (table, table->rows + 1); values = table->values + table->next_idx * MONO_TYPEREF_SIZE; - values [MONO_TYPEREF_SCOPE] = (1 << 2) | 2; /* first row in assemblyref LAMESPEC, see get.c */ + values [MONO_TYPEREF_SCOPE] = resolution_scope_from_image (assembly, klass->image); values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name); values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space); - token = 1 | (table->next_idx << 2); /* typeref */ + token = TYPEDEFORREF_TYPEREF | (table->next_idx << TYPEDEFORREF_BITS); /* typeref */ g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token)); table->next_idx ++; return token; @@ -569,6 +644,16 @@ mono_image_get_type_info (MonoReflectionTypeBuilder *tb, MonoDynamicAssembly *as mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), assembly); } + /* handle constructors */ + if (tb->ctors) { + table = &assembly->tables [MONO_TABLE_METHOD]; + table->rows += mono_array_length (tb->ctors); + alloc_table (table, table->rows); + for (i = 0; i < mono_array_length (tb->ctors); ++i) + mono_image_get_ctor_info ( + mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), assembly); + } + /* handle fields */ if (tb->fields) { table = &assembly->tables [MONO_TABLE_FIELD]; @@ -825,20 +910,8 @@ mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb) char *name; int i; - /* - * FIXME: check if metadata was already built. - */ - string_heap_init (&assembly->sheap); - mono_image_add_stream_data (&assembly->us, "", 1); - mono_image_add_stream_data (&assembly->blob, "", 1); - assembly->text_rva = 0x00002000; - for (i=0; i < 64; ++i) { - assembly->tables [i].next_idx = 1; - assembly->tables [i].columns = table_sizes [i]; - } - table = &assembly->tables [MONO_TABLE_ASSEMBLY]; alloc_table (table, 1); values = table->values + MONO_ASSEMBLY_SIZE; @@ -847,6 +920,11 @@ mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb) values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, name); g_free (name); values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, ""); + values [MONO_ASSEMBLY_PUBLIC_KEY] = 0; + values [MONO_ASSEMBLY_MAJOR_VERSION] = 0; + values [MONO_ASSEMBLY_MINOR_VERSION] = 0; + values [MONO_ASSEMBLY_REV_NUMBER] = 0; + values [MONO_ASSEMBLY_BUILD_NUMBER] = 0; assembly->tables [MONO_TABLE_TYPEDEF].rows = 1; /* . */ assembly->tables [MONO_TABLE_TYPEDEF].next_idx++; @@ -882,6 +960,44 @@ mono_image_build_metadata (MonoReflectionAssemblyBuilder *assemblyb) build_compressed_metadata (assembly); } +guint32 +mono_image_insert_string (MonoReflectionAssemblyBuilder *assembly, MonoString *str) +{ + guint32 index; + char buf [16]; + char *b = buf; + + if (!assembly->dynamic_assembly) + mono_image_basic_init (assembly); + mono_metadata_encode_value (str->length, b, &b); + index = 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); + return index; +} + +void +mono_image_basic_init (MonoReflectionAssemblyBuilder *assemblyb) +{ + MonoDynamicAssembly *assembly; + int i; + + if (assemblyb->dynamic_assembly) + return; + + assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1); + + string_heap_init (&assembly->sheap); + mono_image_add_stream_data (&assembly->us, "", 1); + mono_image_add_stream_data (&assembly->blob, "", 1); + + for (i=0; i < 64; ++i) { + assembly->tables [i].next_idx = 1; + assembly->tables [i].columns = table_sizes [i]; + } + +} + int mono_image_get_header (MonoReflectionAssemblyBuilder *assemblyb, char *buffer, int maxsize) { @@ -906,7 +1022,9 @@ mono_image_get_header (MonoReflectionAssemblyBuilder *assemblyb, char *buffer, i if (maxsize < header_size) return -1; - assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1); + mono_image_basic_init (assemblyb); + assembly = assemblyb->dynamic_assembly; + mono_image_build_metadata (assemblyb); memset (buffer, 0, header_size); diff --git a/mono/metadata/reflection.h b/mono/metadata/reflection.h index bf129e6cbdd..7a55adffee2 100644 --- a/mono/metadata/reflection.h +++ b/mono/metadata/reflection.h @@ -58,10 +58,22 @@ typedef struct { typedef struct { MonoObject object; - MonoMethod *impl; + MonoReflectionILGen *ilgen; + MonoArray *parameters; + guint32 attrs; + guint32 iattrs; + guint32 table_idx; + guint32 call_conv; + MonoObject *type; +} MonoReflectionCtorBuilder; + +typedef struct { + MonoObject object; + MonoMethod *mhandle; MonoReflectionType *rtype; MonoArray *parameters; guint32 attrs; + guint32 iattrs; MonoString *name; guint32 table_idx; MonoArray *code; @@ -147,6 +159,7 @@ typedef struct { MonoReflectionType *parent; MonoArray *interfaces; MonoArray *methods; + MonoArray *ctors; MonoArray *properties; MonoArray *fields; guint32 attrs; @@ -155,6 +168,9 @@ typedef struct { } MonoReflectionTypeBuilder; int mono_image_get_header (MonoReflectionAssemblyBuilder *assembly, char *buffer, int maxsize); +void mono_image_basic_init (MonoReflectionAssemblyBuilder *assembly); +guint32 mono_image_insert_string (MonoReflectionAssemblyBuilder *assembly, MonoString *str); + #endif /* __METADATA_REFLECTION_H__ */ diff --git a/mono/metadata/row-indexes.h b/mono/metadata/row-indexes.h index abd8984f205..07bfdf201f2 100644 --- a/mono/metadata/row-indexes.h +++ b/mono/metadata/row-indexes.h @@ -270,7 +270,7 @@ enum { enum { TYPEDEFORREF_TYPEDEF, - TYPEDEFORREF_PARAMDEF, + TYPEDEFORREF_TYPEREF, TYPEDEFORREF_TYPESPEC, TYPEDEFORREF_BITS = 2, TYPEDEFORREF_MASK = 3 @@ -278,7 +278,7 @@ enum { enum { HASCOSTANT_FIEDDEF, - HASCOSTANT_FIEDREF, /* typo in spec? LAMESPEC */ + HASCOSTANT_PARAM, HASCOSTANT_PROPERTY, HASCOSTANT_BITS = 2, HASCOSTANT_MASK = 3 @@ -319,12 +319,12 @@ enum { HAS_DECL_SECURITY_TYPEDEF, HAS_DECL_SECURITY_METHODDEF, HAS_DECL_SECURITY_ASSEMBLY, - HAS_DECL_SECURITY_BITS = 1, - HAS_DECL_SECURITY_MASK = 1 + HAS_DECL_SECURITY_BITS = 2, + HAS_DECL_SECURITY_MASK = 3 }; enum { - MEMBERREF_PARENT_TYPEDEF, + MEMBERREF_PARENT_TYPEDEF, /* not used */ MEMBERREF_PARENT_TYPEREF, MEMBERREF_PARENT_MODULEREF, MEMBERREF_PARENT_METHODDEF, @@ -363,11 +363,11 @@ enum { }; enum { - CUSTOM_ATTR_TYPE_TYPEREF, - CUSTOM_ATTR_TYPE_TYPEDEF, + CUSTOM_ATTR_TYPE_TYPEREF, /* not used */ + CUSTOM_ATTR_TYPE_TYPEDEF, /* not used */ CUSTOM_ATTR_TYPE_METHODDEF, CUSTOM_ATTR_TYPE_MEMBERREF, - CUSTOM_ATTR_TYPE_STRING, + CUSTOM_ATTR_TYPE_STRING, /* not used */ CUSTOM_ATTR_TYPE_BITS = 3, CUSTOM_ATTR_TYPE_MASK = 7 }; @@ -375,10 +375,10 @@ enum { enum { RESOLTION_SCOPE_MODULE, RESOLTION_SCOPE_MODULEREF, - RESOLTION_SCOPE_ASSEMBLYREF, /* LAMESPEC claims 3 */ - RESOLTION_SCOPE_TYPEREF, /* LAMESPEC claims 4 */ - RESOLTION_SCOPE_BITS = 2, /* LAMESPEC claims 3 */ - RESOLTION_SCOPE_MASK = 3 /* LAMESPEC claims 7 */ + RESOLTION_SCOPE_ASSEMBLYREF, + RESOLTION_SCOPE_TYPEREF, + RESOLTION_SCOPE_BITS = 2, + RESOLTION_SCOPE_MASK = 3 }; #endif /* __MONO_METADATA_ROW_INDEXES_H__ */ diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index 60a2389bdc8..3a8fef3d6b7 100644 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -4,7 +4,7 @@ JITTEST_PROG=../jit/mono CSC=csc -BENCHSRC=fib.cs random.cs nested-loops.cs +BENCHSRC=fib.cs random.cs nested-loops.cs ackermann.cs tight-loop.cs sieve.cs TESTSRC= \ array-init.cs \ @@ -70,3 +70,10 @@ testjit: $(JITTEST_PROG) $(TESTS) for i in $(TESTS); do \ ./test-driver $(JITTEST_PROG) $$i; \ done + +testjitspeed: $(JITTEST_PROG) $(TESTBS) + for i in $(TESTBS); do \ + echo $$i; \ + time $(JITTEST_PROG) $$i; \ + done + diff --git a/mono/tests/ackermann.cs b/mono/tests/ackermann.cs new file mode 100644 index 00000000000..79748a9beb9 --- /dev/null +++ b/mono/tests/ackermann.cs @@ -0,0 +1,19 @@ +// $Id: ackermann.cs,v 1.1 2001/11/19 06:52:53 lupus Exp $ +// http://www.bagley.org/~doug/shootout/ + +public class ackermann { + + public static void Main() { + int NUM = 8; + Ack(3, NUM); + return; + //System.out.print("Ack(3," + NUM + "): " + Ack(3, NUM) + "\n"); + } + + public static int Ack(int M, int N) { + if (M == 0) return( N + 1 ); + if (N == 0) return( Ack(M - 1, 1) ); + return( Ack(M - 1, Ack(M, (N - 1))) ); + } + +} diff --git a/mono/tests/enum.cs b/mono/tests/enum.cs index 9ab1080aaa7..2f8f55cd53a 100755 --- a/mono/tests/enum.cs +++ b/mono/tests/enum.cs @@ -6,11 +6,31 @@ public enum YaddaYadda { dadoom, }; +public enum byteenum : byte { + zero, + one, + two, + three +} + +public enum longenum: long { + s0 = 0, + s1 = 1 +} + +public enum sbyteenum : sbyte { + d0, + d1 +} + public class test { public static int Main () { YaddaYadda val = YaddaYadda.dadoom; + byteenum be = byteenum.one; if (val != YaddaYadda.dadoom) return 1; + if (be != (byteenum)1) + return 2; return 0; } } diff --git a/mono/tests/sieve.cs b/mono/tests/sieve.cs new file mode 100644 index 00000000000..dbcd3aa2c24 --- /dev/null +++ b/mono/tests/sieve.cs @@ -0,0 +1,32 @@ +/* -*- mode: c -*- + * $Id: sieve.cs,v 1.1 2001/11/19 06:52:53 lupus Exp $ + * http://www.bagley.org/~doug/shootout/ + */ + +class Test { +static public int Main() { + //int NUM = ((argc == 2) ? atoi(argv[1]) : 1); + int NUM = 300; + byte[] flags = new byte[8192 + 1]; + int i, k; + int count = 0; + + while (NUM-- != 0) { + count = 0; + for (i=2; i <= 8192; i++) { + flags[i] = 1; + } + for (i=2; i <= 8192; i++) { + if (flags[i] != 0) { + // remove all multiples of prime: i + for (k=i+i; k <= 8192; k+=i) { + flags[k] = 0; + } + count++; + } + } + } + //printf("Count: %d\n", count); + return(0); +} +} diff --git a/mono/tests/tight-loop.cs b/mono/tests/tight-loop.cs new file mode 100644 index 00000000000..a596f4d8d68 --- /dev/null +++ b/mono/tests/tight-loop.cs @@ -0,0 +1,9 @@ +class T { + public static int Main () { + int n = 0; + while (n < 100000000) { + ++n; + } + return 0; + } +} -- 2.25.1