Console.WriteLine ();
}
- [Category ("!INTERPRETER")]
[Category ("!BITCODE")]
public static int test_0_rethrow_stacktrace () {
// Check that rethrowing an exception preserves the original stack trace
int transformed;
guint32 *arg_offsets;
guint32 *local_offsets;
+ guint32 *exvar_offsets;
unsigned int param_count;
unsigned int hasthis;
gpointer jit_wrapper;
#define FILL_IN_TRACE(exception, frame) fill_in_trace(exception, frame)
-#define THROW_EX(exception,ex_ip) \
+#define THROW_EX_GENERAL(exception,ex_ip,rethrow) \
do {\
frame->ip = (ex_ip); \
frame->ex = (MonoException*)(exception); \
- FILL_IN_TRACE(frame->ex, frame); \
+ if (!rethrow) { \
+ FILL_IN_TRACE(frame->ex, frame); \
+ } \
goto handle_exception; \
} while (0)
+#define THROW_EX(exception,ex_ip) THROW_EX_GENERAL ((exception), (ex_ip), FALSE)
+
static MonoObject*
ves_array_create (MonoInvocation *frame, MonoDomain *domain, MonoClass *klass, MonoMethodSignature *sig, stackval *values)
{
ip += 2;
MINT_IN_BREAK;
#endif
- MINT_IN_CASE(MINT_RETHROW)
+ MINT_IN_CASE(MINT_RETHROW) {
/*
* need to clarify what this should actually do:
* start the search from the last found handler in
* We need to NULL frame->ex_handler for the later code to
* actually run the new found handler.
*/
+ int exvar_offset = *(guint16*)(ip + 1);
frame->ex_handler = NULL;
- THROW_EX (frame->ex, ip - 1);
+ THROW_EX_GENERAL (*(MonoException**)(frame->locals + exvar_offset), ip - 1, TRUE);
MINT_IN_BREAK;
+ }
MINT_IN_DEFAULT
g_print ("Unimplemented opcode: %04x %s at 0x%x\n", *ip, mono_interp_opname[*ip], ip-rtm->code);
THROW_EX (mono_get_exception_execution_engine ("Unimplemented opcode"), ip);
g_print ("* Matched Filter at '%s'\n", method->name);
#endif
inv->ex_handler = clause;
+ *(MonoException**)(inv->locals + inv->runtime_method->exvar_offsets [i]) = frame->ex;
goto handle_finally;
}
} else if (clause->flags == MONO_EXCEPTION_CLAUSE_NONE) {
g_print ("* Found handler at '%s'\n", method->name);
#endif
inv->ex_handler = clause;
+ *(MonoException**)(inv->locals + inv->runtime_method->exvar_offsets [i]) = frame->ex;
goto handle_finally;
}
}
OPDEF(MINT_LEAVE_S, "leave.s", 2, MintOpShortBranch)
OPDEF(MINT_THROW, "throw", 1, MintOpNoArgs)
-OPDEF(MINT_RETHROW, "rethrow", 1, MintOpNoArgs)
+OPDEF(MINT_RETHROW, "rethrow", 2, MintOpUShortInt)
OPDEF(MINT_ENDFINALLY, "endfinally", 2, MintOpNoArgs)
OPDEF(MINT_BRFALSE_I4, "brfalse.i4", 3, MintOpBranch)
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;
}
}
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);
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;
}
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;