shorten_branch = 1;
}
} else {
- offset = 0xffff;
if (td->header->code_size <= 25000) /* FIX to be precise somehow? */
shorten_branch = 1;
Reloc *reloc = mono_mempool_alloc0 (td->mempool, sizeof (Reloc));
- if (shorten_branch)
+ if (shorten_branch) {
+ offset = 0xffff;
reloc->type = RELOC_SHORT_BRANCH;
- else
+ } else {
+ offset = 0xdeadbeef;
reloc->type = RELOC_LONG_BRANCH;
+ }
reloc->offset = td->new_ip - td->new_code;
reloc->target = target;
g_ptr_array_add (td->relocs, reloc);
csignature = mono_method_signature (target_method);
}
+ if (target_method && target_method->string_ctor) {
+ /* Create the real signature */
+ MonoMethodSignature *ctor_sig = mono_metadata_signature_dup_mempool (td->mempool, csignature);
+ ctor_sig->ret = &mono_defaults.string_class->byval_arg;
+
+ csignature = ctor_sig;
+ }
+
/* Intrinsics */
if (target_method) {
if (target_method->klass == mono_defaults.string_class) {
cbb->last_seq_point = seqp;
}
+#define BARRIER_IF_VOLATILE(td) \
+ do { \
+ if (volatile_) { \
+ ADD_CODE (&td, MINT_MONO_MEMORY_BARRIER); \
+ volatile_ = FALSE; \
+ } \
+ } while (0)
+
static void
generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start, MonoGenericContext *generic_context)
{
MonoMethodHeader *header = mono_method_get_header (method);
MonoMethodSignature *signature = mono_method_signature (method);
MonoImage *image = method->klass->image;
- MonoDomain *domain = mono_domain_get ();
+ MonoDomain *domain = rtm->domain;
MonoClass *constrained_class = NULL;
MonoError error;
int offset, mt, i, i32;
gboolean readonly = FALSE;
+ gboolean volatile_ = FALSE;
MonoClass *klass;
MonoClassField *field;
const unsigned char *end;
td.stack_state [c->data.filter_offset][0].klass = NULL; /*FIX*/
}
- if ((c->flags & MONO_EXCEPTION_CLAUSE_FINALLY) || (c->flags & MONO_EXCEPTION_CLAUSE_FAULT)) {
- for (int j = c->handler_offset; j < c->handler_offset + c->handler_len; ++j) {
- if (td.clause_indexes [j] == -1)
- td.clause_indexes [j] = i;
- }
+ for (int j = c->handler_offset; j < c->handler_offset + c->handler_len; ++j) {
+ if (td.clause_indexes [j] == -1)
+ td.clause_indexes [j] = i;
}
}
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_I1);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_U1:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_U1);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_I2:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_I2);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_U2:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_U2);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_I4:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_I4);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_U4:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_U4);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_I8:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_I8);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_I:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_I);
ADD_CODE (&td, 0);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_R4:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_R4);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_R8:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_R8);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8);
+ BARRIER_IF_VOLATILE (td);
break;
case CEE_LDIND_REF:
CHECK_STACK (&td, 1);
SIMPLE_OP (td, MINT_LDIND_REF);
+ BARRIER_IF_VOLATILE (td);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_O);
break;
case CEE_STIND_REF:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_REF);
td.sp -= 2;
break;
case CEE_STIND_I1:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_I1);
td.sp -= 2;
break;
case CEE_STIND_I2:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_I2);
td.sp -= 2;
break;
case CEE_STIND_I4:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_I4);
td.sp -= 2;
break;
case CEE_STIND_I:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_I);
td.sp -= 2;
break;
case CEE_STIND_I8:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_I8);
td.sp -= 2;
break;
case CEE_STIND_R4:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_R4);
td.sp -= 2;
break;
case CEE_STIND_R8:
CHECK_STACK (&td, 2);
+ BARRIER_IF_VOLATILE (td);
SIMPLE_OP (td, MINT_STIND_R8);
td.sp -= 2;
break;
}
td.ip += 5;
SET_TYPE(td.sp - 1, stack_type[mint_type(&klass->byval_arg)], klass);
+ BARRIER_IF_VOLATILE (td);
break;
}
case CEE_LDSTR: {
MonoClass *field_klass = mono_class_from_mono_type (field->type);
mt = mint_type (&field_klass->byval_arg);
+#ifndef DISABLE_REMOTING
if (klass->marshalbyref) {
g_assert (!is_static);
ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_LDRMFLD_VT : MINT_LDRMFLD);
ADD_CODE(&td, get_data_item_index (&td, field));
- } else {
+ } else
+#endif
+ {
if (is_static) {
ADD_CODE (&td, MINT_POP);
ADD_CODE (&td, 0);
}
td.ip += 5;
SET_TYPE(td.sp - 1, stack_type [mt], field_klass);
+ BARRIER_IF_VOLATILE (td);
break;
}
case CEE_STFLD: {
mono_class_init (klass);
mt = mint_type(field->type);
+ BARRIER_IF_VOLATILE (td);
+
+#ifndef DISABLE_REMOTING
if (klass->marshalbyref) {
g_assert (!is_static);
ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_STRMFLD_VT : MINT_STRMFLD);
ADD_CODE(&td, get_data_item_index (&td, field));
- } else {
+ } else
+#endif
+ {
if (is_static) {
ADD_CODE (&td, MINT_POP);
ADD_CODE (&td, 1);
else
klass = mini_get_class (method, token, generic_context);
+ BARRIER_IF_VOLATILE (td);
ADD_CODE(&td, td.sp [-1].type == STACK_TYPE_VT ? MINT_STOBJ_VT : MINT_STOBJ);
ADD_CODE(&td, get_data_item_index (&td, klass));
if (td.sp [-1].type == STACK_TYPE_VT) {
PUSH_TYPE (&td, STACK_TYPE_MP, NULL);
++td.ip;
break;
+ case CEE_MONO_MEMORY_BARRIER:
+ ADD_CODE (&td, MINT_MONO_MEMORY_BARRIER);
+ ++td.ip;
+ break;
case CEE_MONO_JIT_ATTACH:
ADD_CODE (&td, MINT_MONO_JIT_ATTACH);
++td.ip;
break;
case CEE_VOLATILE_:
++td.ip;
- /* FIX: should do something? */;
+ volatile_ = TRUE;
break;
case CEE_TAIL_:
++td.ip;
case CEE_CPBLK:
CHECK_STACK(&td, 3);
/* FIX? convert length to I8? */
+ if (volatile_)
+ ADD_CODE (&td, MINT_MONO_MEMORY_BARRIER);
ADD_CODE(&td, MINT_CPBLK);
+ BARRIER_IF_VOLATILE (td);
td.sp -= 3;
++td.ip;
break;
break;
case CEE_INITBLK:
CHECK_STACK(&td, 3);
+ BARRIER_IF_VOLATILE (td);
ADD_CODE(&td, MINT_INITBLK);
td.sp -= 3;
td.ip += 1;
break;
-#if 0
case CEE_NO_:
/* FIXME: implement */
- ip += 2;
+ td.ip += 2;
break;
-#endif
- case CEE_RETHROW:
+ case CEE_RETHROW: {
+ int clause_index = td.clause_indexes [in_offset];
+ g_assert (clause_index != -1);
SIMPLE_OP (td, MINT_RETHROW);
+ ADD_CODE (&td, rtm->exvar_offsets [clause_index]);
generating_code = 0;
break;
+ }
case CEE_SIZEOF: {
gint32 size;
token = read32 (td.ip + 1);
g_assert (td.new_code [reloc->offset + 1] == 0xffff);
td.new_code [reloc->offset + 1] = offset;
break;
- case RELOC_LONG_BRANCH:
- g_assert_not_reached ();
+ case RELOC_LONG_BRANCH: {
+ guint16 *v = (guint16 *) &offset;
+ g_assert (td.new_code [reloc->offset + 1] == 0xbeef);
+ g_assert (td.new_code [reloc->offset + 2] == 0xdead);
+ td.new_code [reloc->offset + 1] = *(guint16 *) v;
+ td.new_code [reloc->offset + 2] = *(guint16 *) (v + 1);
break;
+ }
case RELOC_SWITCH: {
guint16 *v = (guint16*)&offset;
td.new_code [reloc->offset] = *(guint16*)v;
ei->try_start = (guint8*)(rtm->code + c->try_offset);
ei->try_end = (guint8*)(rtm->code + c->try_offset + c->try_len);
ei->handler_start = (guint8*)(rtm->code + c->handler_offset);
- if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER || ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
+ ei->exvar_offset = rtm->exvar_offsets [i];
+ if (ei->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
+ ei->data.filter = (guint8*)(rtm->code + c->data.filter_offset);
+ } else if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
} else {
ei->data.catch_class = c->data.catch_class;
}
const MonoOpcode *opcode;
MonoMethod *m;
MonoClass *class;
- MonoDomain *domain = mono_domain_get ();
unsigned char *is_bb_start;
int in;
MonoVTable *method_class_vt;
int backwards;
MonoGenericContext *generic_context = NULL;
+ MonoDomain *domain = runtime_method->domain;
// 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);
offset += size;
}
offset = (offset + 7) & ~7;
+
+ runtime_method->exvar_offsets = g_malloc (header->num_clauses * sizeof (guint32));
+ for (i = 0; i < header->num_clauses; i++) {
+ offset += sizeof (MonoObject*);
+ runtime_method->exvar_offsets [i] = offset;
+ }
+ offset = (offset + 7) & ~7;
+
runtime_method->locals_size = offset;
g_assert (runtime_method->locals_size < 65536);
offset = 0;