#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)
{
MonoObject *retval = NULL;
MonoMethodSignature *sig = mono_method_signature (method);
MonoClass *klass = mono_class_from_mono_type (sig->ret);
- int i, type, isobject = 0;
- void *ret = NULL;
stackval result;
stackval *args;
ThreadContext context_struct;
MonoDomain *domain = mono_domain_get ();
- switch (sig->ret->type) {
- case MONO_TYPE_VOID:
- break;
- case MONO_TYPE_STRING:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- isobject = 1;
- break;
- case MONO_TYPE_VALUETYPE:
- retval = mono_object_new_checked (domain, klass, error);
- ret = mono_object_unbox (retval);
- if (!sig->ret->data.klass->enumtype)
- result.data.vt = ret;
- else
- result.data.vt = alloca (mono_class_instance_size (klass));
- break;
- case MONO_TYPE_GENERICINST:
- if (!MONO_TYPE_IS_REFERENCE (sig->ret)) {
- retval = mono_object_new_checked (domain, klass, error);
- ret = mono_object_unbox (retval);
- if (!sig->ret->data.klass->enumtype)
- result.data.vt = ret;
- else
- result.data.vt = alloca (mono_class_instance_size (klass));
- } else {
- isobject = 1;
- }
- break;
+ MonoMethod *invoke_wrapper = mono_marshal_get_runtime_invoke_full (method, FALSE, TRUE);
- case MONO_TYPE_PTR:
- retval = mono_object_new_checked (domain, mono_defaults.int_class, error);
- ret = mono_object_unbox (retval);
- break;
- default:
- retval = mono_object_new_checked (domain, klass, error);
- ret = mono_object_unbox (retval);
- break;
- }
+ //* <code>MonoObject *runtime_invoke (MonoObject *this_obj, void **params, MonoObject **exc, void* method)</code>
+
+ result.data.vt = alloca (mono_class_instance_size (klass));
+ args = alloca (sizeof (stackval) * 4);
- args = alloca (sizeof (stackval) * (sig->param_count + !!sig->hasthis));
if (sig->hasthis)
args [0].data.p = obj;
+ else
+ args [0].data.p = NULL;
+ args [1].data.p = params;
+ args [2].data.p = exc;
+ args [3].data.p = method;
- for (i = 0; i < sig->param_count; ++i) {
- int a_index = i + !!sig->hasthis;
- if (sig->params [i]->byref) {
- args [a_index].data.p = params [i];
- continue;
- }
- type = sig->params [i]->type;
-handle_enum:
- switch (type) {
- case MONO_TYPE_U1:
- case MONO_TYPE_I1:
- case MONO_TYPE_BOOLEAN:
- args [a_index].data.i = *(MonoBoolean*)params [i];
- break;
- case MONO_TYPE_U2:
- case MONO_TYPE_I2:
- case MONO_TYPE_CHAR:
- args [a_index].data.i = *(gint16*)params [i];
- break;
-#if SIZEOF_VOID_P == 4
- case MONO_TYPE_U: /* use VAL_POINTER? */
- case MONO_TYPE_I:
-#endif
- case MONO_TYPE_U4:
- case MONO_TYPE_I4:
- args [a_index].data.i = *(gint32*)params [i];
- break;
-#if SIZEOF_VOID_P == 8
- case MONO_TYPE_U:
- case MONO_TYPE_I:
-#endif
- case MONO_TYPE_U8:
- case MONO_TYPE_I8:
- args [a_index].data.l = *(gint64*)params [i];
- break;
- case MONO_TYPE_R4:
- args [a_index].data.f = *(gfloat *) params [i];
- break;
- case MONO_TYPE_R8:
- args [a_index].data.f = *(gdouble *) params [i];
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->data.klass->enumtype) {
- type = mono_class_enum_basetype (sig->params [i]->data.klass)->type;
- goto handle_enum;
- } else {
- args [a_index].data.p = params [i];
- }
- break;
- case MONO_TYPE_STRING:
- case MONO_TYPE_PTR:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_GENERICINST:
- args [a_index].data.p = params [i];
- break;
- default:
- g_error ("type 0x%x not handled in runtime invoke", sig->params [i]->type);
- }
- }
-
- if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
- method = mono_marshal_get_native_wrapper (method, FALSE, FALSE);
+ INIT_FRAME (&frame, context->current_frame, args, &result, domain, invoke_wrapper, error);
- INIT_FRAME (&frame,context->current_frame,args,&result,domain,method,error);
if (exc)
frame.invoke_trap = 1;
context->managed_code = 1;
else
printf("dropped exception...\n");
}
- if (sig->ret->type == MONO_TYPE_VOID && !method->string_ctor)
- return NULL;
- if (isobject || method->string_ctor)
- return result.data.p;
- stackval_to_data (sig->ret, &result, ret, sig->pinvoke);
- return retval;
+ return result.data.p;
}
typedef struct {
ip += 3;
MINT_IN_BREAK;
}
+ MINT_IN_CASE(MINT_MONO_MEMORY_BARRIER) {
+ ++ip;
+ mono_memory_barrier ();
+ MINT_IN_BREAK;
+ }
MINT_IN_CASE(MINT_MONO_JIT_ATTACH) {
++ip;
++ip;
mono_jit_set_domain (context->original_domain);
MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_MONO_LDDOMAIN)
+ sp->data.p = mono_domain_get ();
+ ++sp;
+ ++ip;
+ MINT_IN_BREAK;
MINT_IN_CASE(MINT_SDB_INTR_LOC)
if (G_UNLIKELY (ss_enabled)) {
static void (*ss_tramp) (void);
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;
}
}