}
static void
-interp_ex_obj_init(MonoObject *obj, MonoClass *klass)
+runtime_object_init (MonoObject *obj)
{
int i;
MonoInvocation call;
MonoMethod *method = NULL;
-
+ MonoClass *klass = obj->klass;
+
for (i = 0; i < klass->method.count; ++i) {
if (!strcmp (".ctor", klass->methods [i]->name) &&
klass->methods [i]->signature->param_count == 0) {
#define ves_abort() do {ves_real_abort(__LINE__, frame->method, ip, frame->stack, sp); THROW_EX (get_exception_execution_engine (), ip);} while (0);
/*
- * init_class:
+ * runtime_class_init:
* @klass: klass that needs to be initialized
*
- * This routine calls the class constructor for @class if it needs it.
+ * This routine calls the class constructor for @class.
*/
static void
-init_class (MonoClass *klass)
+runtime_class_init (MonoClass *klass)
{
MonoMethod *method;
MonoInvocation call;
int i;
- if (!klass->metadata_inited)
- mono_class_metadata_init (klass);
-
- if (klass->inited)
- return;
-
- if (klass->parent && !klass->parent->inited)
- init_class (klass->parent);
-
- klass->inited = 1;
-
for (i = 0; i < klass->method.count; ++i) {
method = klass->methods [i];
- if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && (strcmp (".cctor", method->name) == 0)) {
+ if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) &&
+ (strcmp (".cctor", method->name) == 0)) {
INIT_FRAME (&call, NULL, NULL, NULL, NULL, method);
-
ves_exec_method (&call);
return;
}
if ((m->flags & METHOD_ATTRIBUTE_FINAL) || !(m->flags & METHOD_ATTRIBUTE_VIRTUAL))
return m;
- g_assert (m->klass->metadata_inited);
+ g_assert (m->klass->inited);
obj = objs->data.p;
klass = obj->klass;
return vtable [m->slot];
}
-static MonoObject*
-get_exception_divide_by_zero ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "DivideByZeroException");
- return ex;
-}
-
-static MonoObject*
-get_exception_security ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "SecurityException");
- return ex;
-}
-
-static MonoObject*
-get_exception_arithmetic ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "ArithmeticException");
- return ex;
-}
-
-static MonoObject*
-get_exception_overflow ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "OverflowException");
- return ex;
-}
-
-static MonoObject*
-get_exception_null_reference ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "NullReferenceException");
- return ex;
-}
-
-static MonoObject*
-get_exception_execution_engine ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "ExecutionEngineException");
- return ex;
-}
-
-static MonoObject*
-get_exception_invalid_cast ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "InvalidCastException");
- return ex;
-}
-
-static MonoObject*
-get_exception_index_out_of_range ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "IndexOutOfRangeException");
- return ex;
-}
-
-static MonoObject*
-get_exception_array_type_mismatch ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "ArrayTypeMismatchException");
- return ex;
-}
-
-static MonoObject*
-get_exception_missing_method ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = mono_exception_from_name (mono_defaults.corlib, "System",
- "MissingMethodException");
- return ex;
-}
-
void inline
stackval_from_data (MonoType *type, stackval *result, const char *data)
{
MonoObject *obj = (MonoObject*)frame->obj;
MonoDelegate *delegate = (MonoDelegate*)frame->obj;
- init_class(mono_defaults.delegate_class);
+ mono_class_init (mono_defaults.delegate_class);
if (*name == '.' && (strcmp (name, ".ctor") == 0) && obj &&
mono_object_isinst (obj, mono_defaults.delegate_class)) {
vtallocation *vtalloc = NULL;
GOTO_LABEL_VARS;
- if (!frame->method->klass->inited)
- init_class (frame->method->klass);
+ mono_class_init (frame->method->klass);
DEBUG_ENTER ();
token = read32 (ip);
c = mono_class_get (image, token);
- if (!c->inited)
- init_class (c);
+ mono_class_init (c);
g_assert (sp [-1].type == VAL_OBJ);
/* need to handle fieldrefs */
if (mono_metadata_token_table (token) == MONO_TABLE_MEMBERREF) {
field = mono_field_from_memberref (image, token, &klass);
- if (!klass->inited)
- init_class (klass);
+ mono_class_init (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);
+ mono_class_init (klass);
field = mono_class_get_field (klass, token);
}
g_assert (field);
/* 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);
+ mono_class_init (klass);
field = mono_class_get_field (klass, token);
g_assert (field);
stackval_to_data (field->type, sp, (char*)MONO_CLASS_STATIC_FIELDS_BASE(klass) + field->offset);
for (i = 1; i <= t->rows; ++i) {
klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);
- mono_class_metadata_init (klass);
+ mono_class_init (klass);
}
}
#endif
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);
+ mono_class_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))
mono_init ();
mono_init_icall ();
+
+ mono_install_runtime_class_init (runtime_class_init);
+ mono_install_runtime_object_init (runtime_object_init);
+
mono_install_handler (interp_ex_handler);
- mono_exception_install_handlers(init_class, interp_ex_obj_init);
+
+ //mono_exception_install_handlers(init_class, interp_ex_obj_init);
mono_add_internal_call ("__array_Set", ves_array_set);
mono_add_internal_call ("__array_Get", ves_array_get);
+2001-11-30 Dietmar Maurer <dietmar@ximian.com>
+
+ * emit-x86.c (tree_preallocate_regs): improved register allocation
+
+ * x86.brg: impl. ISINST, CASTCLASS
Fri Nov 30 12:02:24 CET 2001 Paolo Molaro <lupus@ximian.com>
+* impl. marshalling attributes for pinvoke
+* raise exceptions everywhere
+* implement all those CONV and CONV_OVF opcodes
+* impl. value type: simple thing works already
* exceptions: handle exceptions inside unmanaged code
* exceptions: save/restore floating point state
-* implementet all floating point instruction in x86.brg, we also need to check
+* implement all floating point instruction in x86.brg, we also need to check
the floating branch instruction - some of them seems to be wrong, we need to
write better tests for that.
-* implement exceptions
* correctly align value types on the stack and in arrays
* enum types can have several base types (not only int32)
* document the functions and variables in the JIT
for (i = 0; name [i]; ++i)
if (name [i] == '.') name [i] = '_';
- mono_class_metadata_init (klass);
+ mono_class_init (klass);
/*
* Find the method index in the image.
*/
char buf [64];
AssemblyDebugInfo* info = mono_debug_open_ass (debug, klass->image);
- mono_class_metadata_init (klass);
+ mono_class_init (klass);
/* output enums ...*/
if (klass->enumtype) {
case MONO_TYPE_I8:
printf ("%lld, ", *((gint64 *)(ebp)));
break;
+ case MONO_TYPE_R4:
+ printf ("%f, ", *((float *)(ebp)));
+ break;
case MONO_TYPE_R8:
printf ("%f, ", *((double *)(ebp)));
break;
{
gint64 l;
+ printf ("LEAVE: %s.%s::%s ", method->klass->name_space,
+ method->klass->name, method->name);
+
switch (method->signature->ret->type) {
case MONO_TYPE_VOID:
- printf ("LEAVE: %s.%s::%s\n", method->klass->name_space,
- method->klass->name, method->name);
break;
case MONO_TYPE_BOOLEAN:
+ if (eax)
+ printf ("TRUE:%d", eax);
+ else
+ printf ("FALSE");
+
+ break;
case MONO_TYPE_CHAR:
case MONO_TYPE_I1:
case MONO_TYPE_U1:
case MONO_TYPE_U4:
case MONO_TYPE_I:
case MONO_TYPE_U:
- printf ("LEAVE: %s.%s::%s EAX=%d\n", method->klass->name_space,
- method->klass->name, method->name, eax);
+ printf ("EAX=%d", eax);
break;
case MONO_TYPE_STRING:
- printf ("LEAVE: %s.%s::%s [STRING:%s], ", method->klass->name_space,
- method->klass->name, method->name,
- mono_string_to_utf8 ((MonoString *)(eax)));
+ printf ("[STRING:%s]", mono_string_to_utf8 ((MonoString *)(eax)));
break;
case MONO_TYPE_OBJECT: {
- MonoObject *o = (MonoClass *)eax;
+ MonoObject *o = (MonoObject *)eax;
- printf ("LEAVE: %s.%s::%s ", method->klass->name_space,
- method->klass->name, method->name);
-
if (o->klass == mono_defaults.boolean_class) {
- printf ("[BOOLEAN:%p:%d]\n", o, *((guint8 *)o + sizeof (MonoObject)));
+ printf ("[BOOLEAN:%p:%d]", o, *((guint8 *)o + sizeof (MonoObject)));
+ } else if (o->klass == mono_defaults.int32_class) {
+ printf ("[INT32:%p:%d]", o, *((gint32 *)((gpointer)o + sizeof (MonoObject))));
} else {
if (o)
- printf ("[%s.%s:%p]\n", o->klass->name_space, o->klass->name, o);
+ printf ("[%s.%s:%p]", o->klass->name_space, o->klass->name, o);
else
- printf ("EAX=%p\n", (gpointer)eax);
+ printf ("[OBJECT:%p]", (gpointer)eax);
}
break;
}
case MONO_TYPE_FNPTR:
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
- printf ("LEAVE: %s.%s::%s EAX=%p\n", method->klass->name_space,
- method->klass->name, method->name, (gpointer)eax);
+ printf ("EAX=%p", (gpointer)eax);
break;
case MONO_TYPE_I8:
*((gint32 *)&l) = eax;
*((gint32 *)&l + 1) = edx;
- printf ("LEAVE: %s.%s::%s EAX/EDX=%lld\n", method->klass->name_space,
- method->klass->name, method->name, l);
+ printf ("EAX/EDX=%lld", l);
break;
case MONO_TYPE_R8:
- printf ("LEAVE: %s.%s::%s FP=%f\n", method->klass->name_space,
- method->klass->name, method->name, test);
+ printf ("FP=%f\n", test);
break;
default:
- printf ("LEAVE: %s.%s::%s (unknown return type)\n", method->klass->name_space,
- method->klass->name, method->name);
+ printf ("(unknown return type)");
}
+
+ printf ("\n");
}
/**
}
static void
-tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs)
+tree_preallocate_regs (MBTree *tree, int goal, MonoRegSet *rs)
{
- MBTree *kids[10];
- int ern = mono_burg_rule (tree->state, goal);
- guint16 *nts = mono_burg_nts [ern];
- int i;
-
- mono_burg_kids (tree, ern, kids);
+ switch (tree->op) {
+ case MB_TERM_CALL_I4:
+ case MB_TERM_CALL_I8:
+ case MB_TERM_CALL_R8:
+// case MB_TERM_CALL_VOID :
+ tree->reg1 = mono_regset_alloc_reg (rs, X86_EAX, tree->exclude_mask);
+ tree->reg2 = mono_regset_alloc_reg (rs, X86_EDX, tree->exclude_mask);
+ tree->reg3 = mono_regset_alloc_reg (rs, X86_ECX, tree->exclude_mask);
+ break;
+ }
switch (goal) {
case MB_NTERM_reg:
tree->exclude_mask |= (1 << X86_ECX);
tree->left->exclude_mask |= (1 << X86_ECX);
break;
- case MB_TERM_CALL_I4:
- tree->reg1 = X86_EAX;
- break;
- case MB_TERM_CALL_I8:
- tree->reg1 = X86_EAX;
- tree->reg2 = X86_EDX;
- break;
case MB_TERM_DIV:
case MB_TERM_DIV_UN:
case MB_TERM_REM:
case MB_TERM_REM_UN:
- tree->reg1 = X86_EAX;
- tree->reg2 = X86_EDX;
+ tree->reg1 = mono_regset_alloc_reg (rs, X86_EAX, tree->exclude_mask);
+ tree->reg2 = mono_regset_alloc_reg (rs, X86_EDX, tree->exclude_mask);
if (goal == MB_NTERM_reg) {
tree->left->exclude_mask |= (1 << X86_EDX);
tree->right->exclude_mask |= (1 << X86_EDX);
default:
break;
}
+ break;
}
default:
break;
}
+}
+
+static void
+tree_allocate_regs (MBTree *tree, int goal, MonoRegSet *rs)
+{
+ MBTree *kids[10];
+ int ern = mono_burg_rule (tree->state, goal);
+ guint16 *nts = mono_burg_nts [ern];
+ int i;
+
+ mono_burg_kids (tree, ern, kids);
//printf ("RALLOC START %d %p %d\n", tree->op, rs->free_mask, goal);
return;
}
+ for (i = 0; nts [i]; i++)
+ tree_preallocate_regs (kids [i], nts [i], rs);
+
for (i = 0; nts [i]; i++)
tree_allocate_regs (kids [i], nts [i], rs);
for (i = 0; nts [i]; i++) {
mono_regset_free_reg (rs, kids [i]->reg1);
mono_regset_free_reg (rs, kids [i]->reg2);
+ mono_regset_free_reg (rs, kids [i]->reg3);
}
switch (goal) {
case MB_NTERM_reg:
- if ((tree->reg1 =
- mono_regset_alloc_reg (rs, tree->reg1, tree->exclude_mask)) == -1) {
- g_warning ("register allocation failed %d 0x%08x 0x%08x\n", tree->reg1, rs->free_mask, tree->exclude_mask);
- g_assert_not_reached ();
+ if (tree->reg1 < 0) {
+ tree->reg1 = mono_regset_alloc_reg (rs, -1, tree->exclude_mask);
+ g_assert (tree->reg1 != -1);
}
break;
case MB_NTERM_lreg:
- if ((tree->reg1 =
- mono_regset_alloc_reg (rs, tree->reg1, tree->exclude_mask)) == -1 ||
- (tree->reg2 =
- mono_regset_alloc_reg (rs, tree->reg2, tree->exclude_mask)) == -1) {
- g_warning ("register allocation failed\n");
- g_assert_not_reached ();
+ if (tree->reg1 < 0) {
+ tree->reg1 = mono_regset_alloc_reg (rs, -1, tree->exclude_mask);
+ g_assert (tree->reg1 != -1);
+ }
+ if (tree->reg2 < 0) {
+ tree->reg2 = mono_regset_alloc_reg (rs, -1, tree->exclude_mask);
+ g_assert (tree->reg2 != -1);
}
break;
tree->reg1 = mono_regset_alloc_reg (rs, tree->left->reg1, tree->exclude_mask);
tree->reg2 = mono_regset_alloc_reg (rs, tree->right->reg1, tree->exclude_mask);
}
- //if (tree->op == MB_TERM_CALL_I4) {
- //tree->reg1 = mono_regset_alloc_reg (rs, tree->left->reg1, tree->exclude_mask);
- //}
break;
case MB_NTERM_base:
delegate = TRUE;
if (!target_offset) {
- mono_jit_init_class (mono_defaults.delegate_class);
+ mono_class_init (mono_defaults.delegate_class);
field = mono_class_get_field_from_name (mono_defaults.delegate_class, "m_target");
target_offset = field->offset;
}
/**
- * mono_jit_init_class:
+ * runtime_class_init:
* @klass: the class to initialise
*
- * Initialise the class @klass by calling the class
- * constructor.
+ * Initialise the class @klass by calling the class constructor.
*/
-void
-mono_jit_init_class (MonoClass *klass)
+static void
+runtime_class_init (MonoClass *klass)
{
MonoCCtor cctor;
MonoMethod *method;
int i;
- if (!klass->metadata_inited)
- mono_class_metadata_init (klass);
-
- if (klass->inited)
- return;
-
- if (klass->parent && !klass->parent->inited)
- mono_jit_init_class (klass->parent);
-
- klass->inited = 1;
-
if (mono_debug_handle)
mono_debug_add_type (mono_debug_handle, klass);
g_assert (class->valuetype);
- if (!class->inited)
- mono_jit_init_class (class);
+ mono_class_init (class);
if (class == mono_defaults.double_class)
return MB_TERM_STIND_R8;
return MB_TERM_STIND_OBJ;
}
+static int
+map_stvaluearg_type (MonoClass *class)
+{
+ int size;
+
+ g_assert (class->valuetype);
+
+ mono_class_init (class);
+
+ if (class == mono_defaults.double_class)
+ return MB_TERM_STIND_R8;
+
+ if (class == mono_defaults.single_class)
+ return MB_TERM_STIND_R4;
+
+ size = class->instance_size - sizeof (MonoObject);
+
+ switch (size) {
+ case 4:
+ case 2:
+ case 1:
+ return MB_TERM_STIND_I4;
+ }
+ return MB_TERM_STIND_OBJ;
+}
+
+static int
+map_argvalue_type (MonoClass *class)
+{
+ int size;
+
+ g_assert (class->valuetype);
+
+ mono_class_init (class);
+
+ if (class == mono_defaults.double_class)
+ return MB_TERM_ARG_R8;
+
+ if (class == mono_defaults.single_class)
+ return MB_TERM_ARG_R4;
+
+ size = class->instance_size - sizeof (MonoObject);
+
+ switch (size) {
+ case 4:
+ case 2:
+ case 1:
+ return MB_TERM_ARG_I4;
+ }
+ return MB_TERM_ARG_OBJ;
+}
+
/**
* map_stind_type:
* @type: the type to map
return -1;
}
+static int
+map_starg_type (MonoType *type)
+{
+ if (type->byref)
+ return MB_TERM_STIND_I4;
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ return MB_TERM_STIND_I4;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ return MB_TERM_STIND_I8;
+ case MONO_TYPE_R4:
+ return MB_TERM_STIND_R4;
+ case MONO_TYPE_R8:
+ return MB_TERM_STIND_R8;
+ case MONO_TYPE_VALUETYPE:
+ return map_stvaluearg_type (type->data.klass);
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
+static int
+map_arg_type (MonoType *type, gboolean pinvoke)
+{
+ if (type->byref)
+ return MB_TERM_ARG_I4;
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ return MB_TERM_ARG_I4;
+ case MONO_TYPE_STRING:
+ if (pinvoke)
+ return MB_TERM_ARG_STRING;
+ return MB_TERM_ARG_I4;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ return MB_TERM_ARG_I8;
+ case MONO_TYPE_R4:
+ return MB_TERM_ARG_R4;
+ case MONO_TYPE_R8:
+ return MB_TERM_ARG_R8;
+ case MONO_TYPE_VALUETYPE:
+ return map_argvalue_type (type->data.klass);
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
/**
* map_ldind_type:
* @type: the type to map
return -1;
}
+static int
+map_ldarg_type (MonoType *type, MonoValueType *svt)
+{
+ if (type->byref) {
+ *svt = VAL_POINTER;
+ return MB_TERM_LDIND_I4;
+ }
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_U4;
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
+ *svt = VAL_POINTER;
+ return MB_TERM_LDIND_U4;
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ *svt = VAL_I64;
+ return MB_TERM_LDIND_I8;
+ case MONO_TYPE_R4:
+ *svt = VAL_DOUBLE;
+ return MB_TERM_LDIND_R4;
+ case MONO_TYPE_R8:
+ *svt = VAL_DOUBLE;
+ return MB_TERM_LDIND_R8;
+ case MONO_TYPE_VALUETYPE: {
+ int size, align;
+ size = mono_type_size (type, &align);
+
+ switch (size) {
+ case 4:
+ case 2:
+ case 1:
+ *svt = VAL_I32;
+ return MB_TERM_LDIND_U1;
+ default:
+ g_assert_not_reached ();
+ }
+ }
+ default:
+ g_warning ("unknown type %02x", type->type);
+ g_assert_not_reached ();
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
/**
* map_call_type:
* @type: the type to map
* Creates a tree to load the value at address @addr.
*/
inline static MBTree *
-ctree_create_load (MonoFlowGraph *cfg, MonoType *type, MBTree *addr, MonoValueType *svt)
+ctree_create_load (MonoFlowGraph *cfg, MonoType *type, MBTree *addr, MonoValueType *svt, gboolean arg)
{
MonoMemPool *mp = cfg->mp;
int ldind, size, align, vnum;
}
}
- ldind = map_ldind_type (type, svt);
+ if (arg)
+ ldind = map_ldarg_type (type, svt);
+ else
+ ldind = map_ldind_type (type, svt);
+
t = mono_ctree_new (mp, ldind, addr, NULL);
return t;
* Creates a tree to store the value @s at address @addr.
*/
inline static MBTree *
-ctree_create_store (MonoFlowGraph *cfg, int addr_type, MBTree *s, MonoType *type, gpointer addr)
+ctree_create_store (MonoFlowGraph *cfg, int addr_type, MBTree *s, MonoType *type, gpointer addr, gboolean arg)
{
MonoMemPool *mp = cfg->mp;
- int stind = map_stind_type (type);
+ int stind;
MBTree *t;
-
+
+ if (arg)
+ stind = map_starg_type (type);
+ else
+ stind = map_stind_type (type);
t = mono_ctree_new_leaf (mp, addr_type);
t->data.p = addr;
}
-static MonoObject*
-get_named_exception (const char *name)
+static void
+runtime_object_init (MonoObject *obj)
{
- MonoClass *klass;
+ MonoClass *klass = obj->klass;
MonoMethod *method = NULL;
- MonoObject *o;
void (*ctor) (gpointer this);
int i;
- klass = mono_class_from_name (mono_defaults.corlib, "System", name);
-
- o = mono_object_new (klass);
- g_assert (o != NULL);
-
- if (!klass->inited)
- mono_jit_init_class (klass);
-
for (i = 0; i < klass->method.count; ++i) {
if (!strcmp (".ctor", klass->methods [i]->name) &&
klass->methods [i]->signature->param_count == 0) {
g_assert (method);
ctor = arch_compile_method (method);
- ctor (o);
-
- return o;
-}
-
-static MonoObject*
-get_exception_divide_by_zero ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = get_named_exception ("DivideByZeroException");
- return ex;
-}
-
-static MonoObject*
-get_exception_execution_engine ()
-{
- static MonoObject *ex = NULL;
- if (ex)
- return ex;
- ex = get_named_exception ("ExecutionEngineException");
- return ex;
+ ctor (obj);
}
static MonoBBlock *
c = mono_class_get (image, token);
g_assert (c->valuetype);
- t1 = ctree_create_load (cfg, &c->byval_arg, *sp, &svt);
+ t1 = ctree_create_load (cfg, &c->byval_arg, *sp, &svt, FALSE);
PUSH_TREE (t1, svt);
break;
}
klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF |
mono_metadata_typedef_from_field (image, token & 0xffffff));
- if (!klass->inited)
- mono_jit_init_class (klass);
+ mono_class_init (klass);
field = mono_class_get_field (klass, token);
g_assert (field);
} else {
t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
t1->data.p = addr;
- t1 = ctree_create_load (cfg, field->type, t1, &svt);
+ t1 = ctree_create_load (cfg, field->type, t1, &svt, FALSE);
}
PUSH_TREE (t1, svt);
klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF |
mono_metadata_typedef_from_field (image, token & 0xffffff));
- if (!klass->inited)
- mono_jit_init_class (klass);
+ mono_class_init (klass);
field = mono_class_get_field (klass, token);
g_assert (field);
klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF |
mono_metadata_typedef_from_field (image, token & 0xffffff));
- if (!klass->inited)
- mono_jit_init_class (klass);
-
+ mono_class_init (klass);
+
field = mono_class_get_field (klass, token);
g_assert (field);
addr = MONO_CLASS_STATIC_FIELDS_BASE (klass) + field->offset;
- t1 = ctree_create_store (cfg, MB_TERM_ADDR_G, *sp, field->type, addr);
+ t1 = ctree_create_store (cfg, MB_TERM_ADDR_G, *sp, field->type, addr, FALSE);
ADD_TREE (t1, cli_addr);
break;
klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF |
mono_metadata_typedef_from_field (image, token & 0xffffff));
- if (!klass->inited)
- mono_jit_init_class (klass);
+ mono_class_init (klass);
field = mono_class_get_field (klass, token);
g_assert (field);
class = mono_class_get (image, token);
- if (!class->inited)
- mono_jit_init_class (class);
+ mono_class_init (class);
esize = mono_class_instance_size (class);
if (class->valuetype)
}
for (i = csig->param_count - 1; i >= 0; i--) {
- t1 = mono_ctree_new (mp, MB_TERM_ARG, arg_sp [i], NULL);
+ MonoType *type = cm->signature->params [i];
+ t1 = mono_ctree_new (mp, map_arg_type (type, FALSE), arg_sp [i], NULL);
ADD_TREE (t1, cli_addr);
- size = mono_type_size (cm->signature->params [i], &align);
+ size = mono_type_size (type, &align);
args_size += (size + 3) & ~3;
}
}
for (i = nargs - 1; i >= 0; i--) {
- if (pinvoke && cm->signature->params [i]->type == MONO_TYPE_STRING) {
- t1 = mono_ctree_new (mp, MB_TERM_STRING_ARG, arg_sp [i], NULL);
- } else {
- t1 = mono_ctree_new (mp, MB_TERM_ARG, arg_sp [i], NULL);
- }
+ MonoType *type = cm->signature->params [i];
+ t1 = mono_ctree_new (mp, map_arg_type (type, pinvoke), arg_sp [i], NULL);
ADD_TREE (t1, cli_addr);
- size = mono_type_size (cm->signature->params [i], &align);
+ size = mono_type_size (type, &align);
args_size += (size + 3) & ~3;
// fixme: align value type arguments to 8 byte boundary on the stack
} else {
if (virtual) {
- if (!cm->klass->metadata_inited)
- mono_class_metadata_init (cm->klass);
+ mono_class_init (cm->klass);
if (cm->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
t2 = mono_ctree_new_leaf (mp, MB_TERM_INTF_ADDR);
break;
}
- case CEE_ISINST:
+ case CEE_ISINST: {
+ MonoClass *c;
+ guint32 token;
+ ++ip;
+ token = read32 (ip);
+ --sp;
+
+ c = mono_class_get (image, token);
+
+ t1 = mono_ctree_new (mp, MB_TERM_ISINST, *sp, NULL);
+ t1->data.klass = c;
+
+ PUSH_TREE (t1, VAL_I32);
+
+ ip += 4;
+ break;
+ }
case CEE_CASTCLASS: {
+ MonoClass *c;
guint32 token;
++ip;
token = read32 (ip);
+ --sp;
+
+ c = mono_class_get (image, token);
+
+ t1 = mono_ctree_new (mp, MB_TERM_CASTCLASS, *sp, NULL);
+ t1->data.klass = c;
- /* fixme: do something */
+ PUSH_TREE (t1, VAL_I32);
ip += 4;
break;
t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
t1->data.i = LOCAL_POS (n);
- t1 = ctree_create_load (cfg, LOCAL_TYPE (n), t1, &svt);
+ t1 = ctree_create_load (cfg, LOCAL_TYPE (n), t1, &svt, FALSE);
PUSH_TREE (t1, svt);
break;
t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
t1->data.i = LOCAL_POS (*ip);
- t1 = ctree_create_load (cfg, LOCAL_TYPE (*ip), t1, &svt);
+ t1 = ctree_create_load (cfg, LOCAL_TYPE (*ip), t1, &svt, FALSE);
++ip;
PUSH_TREE (t1, svt);
--sp;
t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (n),
- (gpointer)LOCAL_POS (n));
+ (gpointer)LOCAL_POS (n), FALSE);
ADD_TREE (t1, cli_addr);
break;
--sp;
t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, LOCAL_TYPE (*ip),
- (gpointer)LOCAL_POS (*ip));
+ (gpointer)LOCAL_POS (*ip), FALSE);
++ip;
ADD_TREE (t1, cli_addr);
t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
t1->data.i = ARG_POS (n);
- t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt);
+ t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt, TRUE);
PUSH_TREE (t1, svt);
break;
}
t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
t1->data.i = ARG_POS (*ip);
- t1 = ctree_create_load (cfg, ARG_TYPE (*ip), t1, &svt);
+ t1 = ctree_create_load (cfg, ARG_TYPE (*ip), t1, &svt, TRUE);
PUSH_TREE (t1, svt);
++ip;
break;
--sp;
t1 = ctree_create_store (cfg, MB_TERM_ADDR_L, *sp, ARG_TYPE (*ip),
- (gpointer)ARG_POS (*ip));
+ (gpointer)ARG_POS (*ip), TRUE);
++ip;
ADD_TREE (t1, cli_addr);
t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
t1->data.i = ARG_POS (n);
- t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt);
+ t1 = ctree_create_load (cfg, ARG_TYPE (n), t1, &svt, TRUE);
PUSH_TREE (t1, svt);
break;
}
mono_jit_info_table = mono_jit_info_table_new ();
+ mono_install_runtime_class_init (runtime_class_init);
+ mono_install_runtime_object_init (runtime_object_init);
+
/*
* This doesn't seem to work... :-(
if (mono_debug_handle)
void
mono_disassemble_code (guint8 *code, int size);
-void
-mono_jit_init_class (MonoClass *klass);
-
gpointer
arch_compile_method (MonoMethod *method);
void
mono_print_forest (GPtrArray *forest);
-
#endif
#include <mono/metadata/metadata.h>
#include <mono/metadata/loader.h>
#include <mono/metadata/object.h>
+#include <mono/metadata/tabledefs.h>
#include <mono/arch/x86/x86-codegen.h>
#include "regset.h"
gint8 reg1;
gint8 reg2;
+ gint8 reg3;
MonoValueType svt;
MonoBBlock *bb;
MonoMethod *m;
MethodCallInfo *ci;
+ MonoClass *klass;
X86AddressInfo ainfo;
} data;
};
guint64 mono_lldiv_un (guint64 a, guint64 b);
guint64 mono_llrem_un (guint64 a, guint64 b);
-gpointer get_throw_exception (void);
+gpointer
+get_throw_exception (void);
+
+gpointer
+get_mono_object_isinst (void);
#define MB_OPT_LEVEL 1
%term LDIND_I1 LDIND_U1 LDIND_I2 LDIND_U2 LDIND_I4 LDIND_I8 LDIND_R4 LDIND_R8
%term LDIND_U4 LDIND_OBJ
%term STIND_I1 STIND_I2 STIND_I4 STIND_I8 STIND_R4 STIND_R8 STIND_OBJ
-%term ADDR_L ADDR_G ARG STRING_ARG CALL_I4 CALL_I8 CALL_R8 CALL_VOID
+%term ADDR_L ADDR_G ARG_I4 ARG_I8 ARG_R4 ARG_R8 ARG_OBJ ARG_STRING CALL_I4 CALL_I8 CALL_R8 CALL_VOID
%term BREAK SWITCH BR RET RETV ENDFINALLY
%term ADD SUB MUL DIV DIV_UN REM REM_UN AND OR XOR SHL SHR SHR_UN NEG NOT
%term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN BLE BLE_UN BGT BGT_UN
%term CEQ CLT
%term CONV_I4 CONV_I1 CONV_I2 CONV_I8 CONV_U8 CONV_R4 CONV_R8
-%term INTF_ADDR VFUNC_ADDR NOP NEWARR NEWOBJ CPOBJ POP INITOBJ VTYPE
-%term EXCEPTION THROW RETHROW HANDLER
+%term INTF_ADDR VFUNC_ADDR NOP NEWARR NEWOBJ CPOBJ POP INITOBJ VTYPE ISINST CASTCLASS
+%term EXCEPTION THROW RETHROW HANDLER
%term LDLEN
#
stmt: HANDLER {
gint32 addr = tree->data.bb->addr - tree->addr - 5;
tree->is_jump = 1;
-
x86_call_imm (s->code, addr);
}
}
}
+reg: CASTCLASS (reg) {
+ guint8 *start = s->code, *l1, *l2, *l3, *l4, *le;
+ int i;
+
+ tree->is_jump = TRUE;
+ l1 = l2 = l3 = l4 = le = NULL;
+
+ for (i = 0; i < 2; i++) {
+ s->code = start;
+
+ if (tree->reg1 != X86_EAX)
+ x86_push_reg (s->code, X86_EAX);
+
+ x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 0);
+ x86_branch8 (s->code, X86_CC_EQ, le - l2, FALSE);
+ l2 = s->code;
+ x86_push_reg (s->code, X86_ECX);
+ x86_push_reg (s->code, X86_EDX);
+
+ x86_push_imm (s->code, tree->data.klass);
+ x86_push_reg (s->code, tree->left->reg1);
+ x86_call_code (s->code, mono_object_isinst);
+ x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 8);
+ x86_pop_reg (s->code, X86_EDX);
+ x86_pop_reg (s->code, X86_ECX);
+
+ x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0);
+ x86_branch8 (s->code, X86_CC_NE, le - l3, FALSE);
+ l3 = s->code;
+
+ x86_mov_reg_imm (s->code, X86_ECX, get_exception_invalid_cast ());
+ x86_call_code (s->code, get_throw_exception ());
+
+ le = s->code;
+
+ }
+}
+
+reg: ISINST (reg) {
+ if (tree->reg1 != X86_EAX)
+ x86_push_reg (s->code, X86_EAX);
+ x86_push_reg (s->code, X86_ECX);
+ x86_push_reg (s->code, X86_EDX);
+
+ x86_push_imm (s->code, tree->data.klass);
+ x86_push_reg (s->code, tree->left->reg1);
+ x86_call_code (s->code, mono_object_isinst);
+ x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 8);
+
+ x86_pop_reg (s->code, X86_EDX);
+ x86_pop_reg (s->code, X86_ECX);
+ if (tree->reg1 != X86_EAX) {
+ x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
+ x86_pop_reg (s->code, X86_EAX);
+ }
+
+}
+
+#reg: ISINST (reg) {
+# guint8 *start = s->code, *l1, *l2, *l3, *l4, *le;
+# MonoClass *k = tree->data.klass;
+# int treg = tree->reg1;
+# gint32 i;
+#
+# tree->is_jump = TRUE;
+# l1 = l2 = l3 = l4 = le = NULL;
+#
+# for (i = 0; i < 2; i++) {
+# s->code = start;
+#
+# x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, 0);
+# x86_branch8 (s->code, X86_CC_EQ, le - l1, FALSE);
+# l1 = s->code;
+#
+# x86_push_reg (s->code, tree->left->reg1);
+#
+# if (k->flags & TYPE_ATTRIBUTE_INTERFACE) {
+# x86_mov_reg_membase (s->code, treg, treg, 0, 4); // treg = o->klass
+# x86_mov_reg_membase (s->code, treg, treg, G_STRUCT_OFFSET (MonoClass, max_interface_id), 4);
+# x86_alu_reg_imm (s->code, X86_CMP, treg, k->interface_id);
+# x86_branch8 (s->code, X86_CC_GE, l3 - l2, FALSE);
+# l2 = s->code;
+# x86_pop_reg (s->code, treg);
+# x86_alu_reg_reg (s->code, X86_XOR, treg, treg);
+# x86_jump8 (s->code, le - l3);
+# l3 = s->code;
+# x86_mov_reg_membase (s->code, treg, X86_ESP, 0, 4); // treg = o
+# x86_mov_reg_membase (s->code, treg, treg, 0, 4); // treg = o->klass
+# x86_mov_reg_membase (s->code, treg, treg, G_STRUCT_OFFSET (MonoClass, interface_offsets), 4);
+# x86_mov_reg_membase (s->code, treg, treg, (k->interface_id << 2), 4);
+# x86_alu_reg_imm (s->code, X86_CMP, treg, 0);
+# x86_pop_reg (s->code, treg);
+# x86_branch8 (s->code, X86_CC_NE, le - l4, FALSE);
+# l4 = s->code;
+# x86_alu_reg_reg (s->code, X86_XOR, treg, treg);
+# } else {
+# x86_mov_reg_membase (s->code, treg, treg, 0, 4); // treg = o->klass
+# x86_mov_reg_membase (s->code, treg, treg, G_STRUCT_OFFSET (MonoClass, baseval), 4);
+# x86_alu_reg_imm (s->code, X86_SUB, treg, k->baseval);
+# x86_alu_reg_imm (s->code, X86_CMP, treg, k->diffval);
+# x86_pop_reg (s->code, treg);
+# x86_branch8 (s->code, X86_CC_LE, le - l2, FALSE);
+# l2 = s->code;
+# x86_alu_reg_reg (s->code, X86_XOR, treg, treg);
+# }
+#
+# le = s->code;
+# //x86_breakpoint (s->code);
+# }
+#}
+
stmt: INITOBJ (reg) {
int i, j;
}
}
-stmt: ARG (reg) {
+stmt: ARG_I4 (reg) {
x86_push_reg (s->code, tree->left->reg1);
}
# fixme: we must free the allocated strings somewhere
-stmt: STRING_ARG (reg) {
+stmt: ARG_STRING (reg) {
x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
x86_push_reg (s->code, X86_EAX);
x86_push_reg (s->code, X86_ECX);
x86_pop_reg (s->code, X86_EAX);
}
-stmt: ARG (ADDR_G) {
+stmt: ARG_I4 (ADDR_G) {
x86_push_imm (s->code, tree->left->data.p);
}
-stmt: ARG (CONST_I4) "MB_USE_OPT1(0)" {
+stmt: ARG_I4 (CONST_I4) "MB_USE_OPT1(0)" {
x86_push_imm (s->code, tree->left->data.i);
}
}
-stmt: ARG (lreg) {
+stmt: ARG_I8 (lreg) {
x86_push_reg (s->code, tree->left->reg2);
x86_push_reg (s->code, tree->left->reg1);
}
# x86_fist_pop_membase (s->code, X86_EBP, tree->data.i, FALSE);
#}
+reg: CONV_I4 (freg) {
+ x86_push_reg (s->code, X86_EAX); // SP = SP - 4
+ x86_fist_pop_membase (s->code, X86_ESP, 0, FALSE);
+ x86_pop_reg (s->code, tree->reg1);
+}
+
freg: CONV_R8 (freg) {
/* nothing to do */
}
x86_fld (s->code, tree->data.p, TRUE);
}
-freg: LDIND_R4 (locaddr) {
- x86_fld_membase (s->code, X86_EBP, tree->left->data.i, FALSE);
+freg: LDIND_R4 (reg) {
+ x86_fld_membase (s->code, tree->left->reg1, 0, FALSE);
}
-freg: LDIND_R8 (locaddr) {
- x86_fld_membase (s->code, X86_EBP, tree->left->data.i, TRUE);
+freg: LDIND_R8 (reg) {
+ x86_fld_membase (s->code, tree->left->reg1, 0, TRUE);
}
freg: LDIND_R8 (reg) {
stmt: POP (freg)
-stmt: STIND_R4 (locaddr, freg) {
- x86_fst_membase (s->code, X86_EBP, tree->left->data.i, FALSE, TRUE);
-}
-
-stmt: STIND_R8 (locaddr, freg) {
- x86_fst_membase (s->code, X86_EBP, tree->left->data.i, TRUE, TRUE);
+stmt: STIND_R4 (reg, freg) {
+ x86_fst_membase (s->code, tree->left->reg1, 0, FALSE, TRUE);
}
stmt: STIND_R8 (reg, freg) {
x86_fst_membase (s->code, tree->left->reg1, 0, TRUE, TRUE);
}
-stmt: ARG (freg) {
+stmt: ARG_R4 (freg) {
+ x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 4);
+ x86_fst_membase (s->code, X86_ESP, 0, FALSE, TRUE);
+}
+
+stmt: ARG_R8 (freg) {
x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 8);
x86_fst_membase (s->code, X86_ESP, 0, TRUE, TRUE);
}
x86_pop_reg (s->code, X86_EAX);
}
-stmt: ARG (vtype) {
+stmt: ARG_OBJ (vtype) {
int treg = X86_EAX;
int offset = g_array_index (s->varinfo, MonoVarInfo, tree->left->data.i).offset;
int size = g_array_index (s->varinfo, MonoVarInfo, tree->left->data.i).size;
t->right = right;
t->reg1 = -1;
t->reg2 = -1;
+ t->reg3 = -1;
t->svt = VAL_UNKNOWN;
t->cli_addr = -1;
return t;
return start;
}
-
#ifdef DEBUG
void *
MEMCOPY (void *dest, const void *src, size_t n)
return memcpy (dest, src, n);
}
#endif
+
+2001-11-30 Dietmar Maurer <dietmar@ximian.com>
+
+ * class.c (mono_install_runtime_class_init): impl.
+ (mono_class_init): renamed mono_class_metadata_init to
+ mono_class_init, also removed the metadata_inited flag
+
+ * object.c (mono_object_isinst): use faster algorithm
+
2001-11-30 Radek Doulik <rodo@ximian.com>
* mono-endian.h: reverted last change
return method;
}
+static void
+default_runtime_class_init (MonoClass *klass)
+{
+ return;
+}
+
static MonoTrampoline arch_create_jit_trampoline = default_trampoline;
+static MonoRuntimeClassInit mono_runtime_class_init = default_runtime_class_init;
void
-mono_install_trampoline (MonoTrampoline func) {
+mono_install_trampoline (MonoTrampoline func)
+{
arch_create_jit_trampoline = func? func: default_trampoline;
}
+void
+mono_install_runtime_class_init (MonoRuntimeClassInit func)
+{
+ mono_runtime_class_init = func? func: default_runtime_class_init;
+}
+
static MonoClass *
mono_class_create_from_typeref (MonoImage *image, guint32 type_token)
{
}
void
-mono_class_metadata_init (MonoClass *class)
+mono_class_init (MonoClass *class)
{
MonoClass *k, *ic;
MonoMethod **tmp_vtable, **vtable = (MonoMethod **)class->vtable;
g_assert (class);
- if (class->metadata_inited)
+ if (class->inited)
return;
- class->metadata_inited = 1;
+ class->inited = 1;
if (class->parent) {
- if (!class->parent->metadata_inited)
- mono_class_metadata_init (class->parent);
+ if (!class->parent->inited)
+ mono_class_init (class->parent);
class->instance_size += class->parent->instance_size;
class->class_size += class->parent->class_size;
class->min_align = class->parent->min_align;
for (i = 0; i < k->interface_count; i++) {
ic = k->interfaces [i];
- if (!ic->metadata_inited)
- mono_class_metadata_init (ic);
+ if (!ic->inited)
+ mono_class_init (ic);
if (max_iid < ic->interface_id)
max_iid = ic->interface_id;
vtable [cm->slot] = arch_create_jit_trampoline (cm);
}
+ mono_runtime_class_init (class);
+
/*
for (i = 0; i < class->vtable_size; ++i) {
MonoMethod *cm;
if (!parent)
parent = mono_defaults.array_class;
- if (!parent->metadata_inited)
- mono_class_metadata_init (parent);
+ if (!parent->inited)
+ mono_class_init (parent);
image = eclass->image;
mono_class_instance_size (MonoClass *klass)
{
- if (!klass->metadata_inited)
- mono_class_metadata_init (klass);
+ if (!klass->inited)
+ mono_class_init (klass);
return klass->instance_size;
}
mono_class_data_size (MonoClass *klass)
{
- if (!klass->metadata_inited)
- mono_class_metadata_init (klass);
+ if (!klass->inited)
+ mono_class_init (klass);
return klass->class_size;
}
MonoClass *class;
guint32 type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token));
class = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type);
- mono_class_metadata_init (class);
+ mono_class_init (class);
if (handle_class)
*handle_class = mono_class_from_name (mono_defaults.corlib, "System", "RuntimeFieldHandle");
return mono_class_get_field (class, token);
guint dummy : 1; /* temorary hack */
guint inited : 1;
- guint metadata_inited : 1;
guint valuetype : 1; /* derives from System.ValueType */
guint enumtype : 1; /* derives from System.Enum */
guint min_align : 4;
gpointer vtable [0];
};
+typedef gpointer (*MonoTrampoline) (MonoMethod *method);
+typedef void (*MonoRuntimeClassInit) (MonoClass *klass);
+
MonoClass *
mono_class_get (MonoImage *image, guint32 type_token);
void
-mono_class_metadata_init (MonoClass *klass);
+mono_class_init (MonoClass *klass);
MonoClass *
mono_class_from_name (MonoImage *image, const char* name_space, const char *name);
gpointer
mono_ldtoken (MonoImage *image, guint32 token, MonoClass **retclass);
-typedef gpointer (*MonoTrampoline) (MonoMethod *method);
-
void
mono_install_trampoline (MonoTrampoline func);
+void
+mono_install_runtime_class_init (MonoRuntimeClassInit func);
+
#endif /* _MONO_CLI_CLASS_H_ */
#include <mono/metadata/exception.h>
#include <mono/metadata/class.h>
-static MonoExceptionClassInitFunc ex_init_class = NULL;
-static MonoExceptionObjectInitFunc ex_init_obj = NULL;
-
-void
-mono_exception_install_handlers(MonoExceptionClassInitFunc class_init,
- MonoExceptionObjectInitFunc obj_init)
-{
- ex_init_class = class_init;
- ex_init_obj = obj_init;
-}
-
MonoObject*
mono_exception_from_name (MonoImage *image, const char *name_space,
const char *name)
o = mono_object_new (klass);
g_assert (o != NULL);
-
- if(!klass->inited && ex_init_class) {
- ex_init_class(klass);
- }
- if(ex_init_obj) {
- ex_init_obj(o, klass);
- }
+ mono_runtime_object_init (o);
return o;
}
+
+MonoObject*
+get_exception_divide_by_zero ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "DivideByZeroException");
+ return ex;
+}
+
+MonoObject*
+get_exception_security ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "SecurityException");
+ return ex;
+}
+
+MonoObject*
+get_exception_arithmetic ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "ArithmeticException");
+ return ex;
+}
+
+MonoObject*
+get_exception_overflow ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "OverflowException");
+ return ex;
+}
+
+MonoObject*
+get_exception_null_reference ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "NullReferenceException");
+ return ex;
+}
+
+MonoObject*
+get_exception_execution_engine ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "ExecutionEngineException");
+ return ex;
+}
+
+MonoObject*
+get_exception_invalid_cast ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "InvalidCastException");
+ return ex;
+}
+
+MonoObject*
+get_exception_index_out_of_range ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "IndexOutOfRangeException");
+ return ex;
+}
+
+MonoObject*
+get_exception_array_type_mismatch ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "ArrayTypeMismatchException");
+ return ex;
+}
+
+MonoObject*
+get_exception_missing_method ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = mono_exception_from_name (mono_defaults.corlib, "System",
+ "MissingMethodException");
+ return ex;
+}
+
g_free (namespace);
if (!klass)
return NULL;
- if (!klass->metadata_inited)
- mono_class_metadata_init (klass);
+ if (!klass->inited)
+ mono_class_init (klass);
return my_mono_new_mono_type (&klass->byval_arg);
}
mimage = image->references [scopeindex-1]->image;
klass = mono_class_from_name (mimage, nspace, name);
- mono_class_metadata_init (klass);
+ mono_class_init (klass);
/* mostly dumb search for now */
for (i = 0; i < klass->field.count; ++i) {
mimage = image->references [scopeindex-1]->image;
klass = mono_class_from_name (mimage, nspace, name);
- mono_class_metadata_init (klass);
+ mono_class_init (klass);
/*
* FIXME: this is a workaround for the different signatures
for (i = 0; i < method->signature->param_count; ++i)
names [i] = "";
- mono_class_metadata_init (klass);
+ mono_class_init (klass);
if (!klass->methods)
return;
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <mono/metadata/tabledefs.h>
#include <mono/metadata/loader.h>
#include <mono/metadata/object.h>
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
#endif
#endif
+static void
+default_runtime_object_init (MonoObject *o)
+{
+ return;
+}
+
+MonoRuntimeObjectInit mono_runtime_object_init = default_runtime_object_init;
+
+void
+mono_install_runtime_object_init (MonoRuntimeObjectInit func)
+{
+ mono_runtime_object_init = func? func: default_runtime_object_init;
+}
+
/**
* mono_object_allocate:
* @size: number of bytes to allocate
{
MonoObject *o;
- if (!klass->metadata_inited)
- mono_class_metadata_init (klass);
+ if (!klass->inited)
+ mono_class_init (klass);
o = mono_object_allocate (klass->instance_size);
o->klass = klass;
MonoArrayBounds *bounds;
int i;
- if (!array_class->metadata_inited)
- mono_class_metadata_init (array_class);
+ if (!array_class->inited)
+ mono_class_init (array_class);
byte_len = mono_array_element_size (array_class);
bounds = g_malloc0 (sizeof (MonoArrayBounds) * array_class->rank);
* @obj: an object
* @klass: a pointer to a class
*
- * Returns: #TRUE if @obj is derived from @klass
+ * Returns: @obj if @obj is derived from @klass
*/
-gboolean
+MonoObject *
mono_object_isinst (MonoObject *obj, MonoClass *klass)
{
- MonoClass *oklass = obj->klass;
+ MonoClass *oklass;
+
+ if (!obj)
+ return NULL;
- while (oklass) {
- if (oklass == klass)
- return TRUE;
- oklass = oklass->parent;
+ oklass = obj->klass;
+
+ if (!klass->inited)
+ mono_class_init (klass);
+
+ if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
+ if ((klass->interface_id <= oklass->max_interface_id) &&
+ oklass->interface_offsets [klass->interface_id])
+ return obj;
+ } else {
+ if ((oklass->baseval - klass->baseval) <= klass->diffval)
+ return obj;
}
- return FALSE;
+
+ return NULL;
}
static GHashTable *ldstr_table = NULL;
gpointer method_ptr;
} MonoDelegate;
+typedef void (*MonoRuntimeObjectInit) (MonoObject *o);
+
+extern MonoRuntimeObjectInit mono_runtime_object_init;
+
#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) )
MonoObject *
mono_object_clone (MonoObject *obj);
-gboolean
+MonoObject *
mono_object_isinst (MonoObject *obj, MonoClass *klass);
typedef void (*MonoExceptionFunc) (MonoException *ex);
void
mono_raise_exception (MonoException *ex);
+void
+mono_install_runtime_object_init (MonoRuntimeObjectInit func);
+
+MonoObject*
+get_exception_divide_by_zero (void);
+
+MonoObject*
+get_exception_security (void);
+
+MonoObject*
+get_exception_arithmetic (void);
+
+MonoObject*
+get_exception_overflow (void);
+
+MonoObject*
+get_exception_null_reference (void);
+
+MonoObject*
+get_exception_execution_engine (void);
+
+MonoObject*
+get_exception_invalid_cast (void);
+
+MonoObject*
+get_exception_index_out_of_range (void);
+
+MonoObject*
+get_exception_array_type_mismatch (void);
+
+MonoObject*
+get_exception_missing_method (void);
+
#endif