for (i = csignature->param_count - 1; i >= 0; --i)
store_arg (td, i + csignature->hasthis);
- if (csignature->hasthis) {
- g_error ("STTHIS removal");
- // ADD_CODE(td, MINT_STTHIS);
- --td->sp;
- }
ADD_CODE(td, MINT_BR_S);
offset = body_start_offset - ((td->new_ip - 1) - td->new_code);
ADD_CODE(td, offset);
td.new_ip = td.new_code;
td.last_new_ip = NULL;
- td.stack = g_malloc0(header->max_stack * sizeof(td.stack[0]));
+ td.stack = g_malloc0 ((header->max_stack + 1) * sizeof (td.stack [0]));
td.sp = td.stack;
td.max_stack_height = 0;
unsigned short *next_new_ip;
++td.ip;
n = read32 (td.ip);
- ADD_CODE(&td, MINT_SWITCH);
- ADD_CODE(&td, * (unsigned short *)(&n));
- ADD_CODE(&td, * ((unsigned short *)&n + 1));
+ ADD_CODE (&td, MINT_SWITCH);
+ WRITE32 (&td, &n);
td.ip += 4;
next_ip = td.ip + n * 4;
next_new_ip = td.new_ip + n * 2;
+ --td.sp;
+ int stack_height = td.sp - td.stack;
for (i = 0; i < n; i++) {
offset = read32 (td.ip);
target = next_ip - td.il_code + offset;
- if (offset < 0)
+ if (offset < 0) {
+#if DEBUG_INTERP
+ if (stack_height > 0 && stack_height != td.stack_height [target])
+ g_warning ("SWITCH with back branch and non-empty stack");
+#endif
target = td.in_offsets [target] - (next_new_ip - td.new_code);
- else {
+ } else {
+ td.stack_height [target] = stack_height;
+ td.vt_stack_size [target] = td.vt_sp;
+ if (stack_height > 0)
+ td.stack_state [target] = g_memdup (td.stack, stack_height * sizeof (td.stack [0]));
int prev = td.forward_refs [target];
td.forward_refs [td.ip - td.il_code] = prev;
td.forward_refs [target] = td.ip - td.il_code;
td.in_offsets [td.ip - td.il_code] = - (base_ip - td.il_code);
}
- ADD_CODE(&td, * (unsigned short *)(&target));
- ADD_CODE(&td, * ((unsigned short *)&target + 1));
+ WRITE32 (&td, &target);
td.ip += 4;
}
- --td.sp;
break;
}
case CEE_LDIND_I1:
klass = mono_class_get_full (image, token, generic_context);
if (mini_type_is_reference (&klass->byval_arg)) {
- g_error ("unbox_any: generic class is reference type");
+ ADD_CODE (&td, MINT_CASTCLASS);
+ ADD_CODE (&td, get_data_item_index (&td, klass));
+ SET_TYPE (td.sp - 1, stack_type [mt], klass);
+ td.ip += 5;
} else if (mono_class_is_nullable (klass)) {
MonoMethod *target_method = mono_class_get_method_from_name (klass, "Unbox", 1);
/* td.ip is incremented by interp_transform_call */
ADD_CODE (&td, MINT_LDSFLDA);
ADD_CODE (&td, get_data_item_index (&td, field));
} else {
- ADD_CODE (&td, MINT_LDFLDA);
+ if ((td.sp - 1)->type == STACK_TYPE_O) {
+ ADD_CODE (&td, MINT_LDFLDA);
+ } else {
+ g_assert ((td.sp -1)->type == STACK_TYPE_MP);
+ ADD_CODE (&td, MINT_LDFLDA_UNSAFE);
+ }
ADD_CODE (&td, klass->valuetype ? field->offset - sizeof (MonoObject) : field->offset);
}
td.ip += 5;
ADD_CODE(&td, MINT_CONV_OVF_I8_UN_R8);
break;
case STACK_TYPE_I8:
+ if (*td.ip == CEE_CONV_OVF_I8_UN)
+ ADD_CODE (&td, MINT_CONV_OVF_I8_U8);
break;
case STACK_TYPE_I4:
ADD_CODE(&td, MINT_CONV_I8_U4);
token = read32 (td.ip + 1);
klass = mono_class_get_full (image, token, generic_context);
switch (mint_type (&klass->byval_arg)) {
+ case MINT_TYPE_U1:
+ SIMPLE_OP (td, MINT_STELEM_U1);
+ break;
case MINT_TYPE_I4:
SIMPLE_OP (td, MINT_STELEM_I4);
break;
+ case MINT_TYPE_I8:
+ SIMPLE_OP (td, MINT_STELEM_I8);
+ break;
case MINT_TYPE_O:
SIMPLE_OP (td, MINT_STELEM_REF);
break;
ADD_CODE(&td, MINT_CONV_OVF_I4_U4);
break;
case STACK_TYPE_I8:
- ADD_CODE(&td, MINT_CONV_OVF_I4_I8);
+ if (*td.ip == CEE_CONV_OVF_I4_UN)
+ ADD_CODE (&td, MINT_CONV_OVF_I4_U8);
+ else
+ ADD_CODE (&td, MINT_CONV_OVF_I4_I8);
break;
default:
g_assert_not_reached ();
ADD_CODE(&td, MINT_CONV_OVF_U8_I4);
break;
case STACK_TYPE_I8:
+ ADD_CODE (&td, MINT_CONV_OVF_U8_I8);
break;
default:
g_assert_not_reached ();
printf("\n");
}
}
+ g_assert (td.max_stack_height <= (header->max_stack + 1));
rtm->clauses = mono_mempool_alloc (domain->mp, header->num_clauses * sizeof(MonoExceptionClause));
memcpy (rtm->clauses, header->clauses, header->num_clauses * sizeof(MonoExceptionClause));
g_free (td.stack_height);
g_free (td.vt_stack_size);
g_free (td.data_items);
+ g_free (td.stack);
g_hash_table_destroy (td.data_hash);
}
// g_printerr ("TRANSFORM(0x%016lx): begin %s::%s\n", mono_thread_current (), method->klass->name, method->name);
method_class_vt = mono_class_vtable (domain, runtime_method->method->klass);
if (!method_class_vt->initialized) {
+ MonoError error;
jmp_buf env;
MonoInvocation *last_env_frame = context->env_frame;
jmp_buf *old_env = context->current_env;
+ error_init (&error);
if (setjmp(env)) {
MonoException *failed = context->env_frame->ex;
}
context->env_frame = context->current_frame;
context->current_env = &env;
- mono_runtime_class_init (method_class_vt);
+ mono_runtime_class_init_full (method_class_vt, &error);
+ if (!mono_error_ok (&error)) {
+ return mono_error_convert_to_exception (&error);
+ }
context->env_frame = last_env_frame;
context->current_env = old_env;
}