#define ARG_SIZE sizeof (stackval)
MonoPIFunc
-mono_create_trampoline (MonoMethod *method)
+mono_create_trampoline (MonoMethod *method, int runtime)
{
MonoMethodSignature *sig;
unsigned char *p, *code_buffer;
* If it is an internalcall we assume it's the object we want.
* Yet another reason why MONO_TYPE_STRING should not be used to indicate char*.
*/
- if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+ if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || runtime) {
x86_push_membase (p, X86_EDX, arg_pos);
break;
}
x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4);
break;
case MONO_TYPE_STRING:
- if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+ if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || runtime) {
x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4);
x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4);
break;
}
+ /* If the argument is non-null, then convert the value back */
+ x86_alu_reg_reg (p, X86_OR, X86_EAX, X86_EAX);
+ x86_branch8 (p, X86_CC_EQ, 11, FALSE);
x86_push_reg (p, X86_EAX);
x86_mov_reg_imm (p, X86_EDX, mono_string_new);
x86_call_reg (p, X86_EDX);
* free the allocated strings.
*/
if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
- if (local_size)
- x86_mov_reg_imm (p, X86_EDX, g_free);
for (i = 1; i <= local_size; ++i) {
+ x86_mov_reg_imm (p, X86_EDX, g_free);
x86_push_membase (p, X86_EBP, LOC_POS * i);
x86_call_reg (p, X86_EDX);
}
return g_memdup (code_buffer, p - code_buffer);
}
-
+/*
+ * mono_create_method_pointer () will insert a pointer to the MonoMethod
+ * so that the interp can easily get at the data: this function will retrieve
+ * the method from the code stream.
+ */
+MonoMethod*
+mono_method_pointer_get (void *code)
+{
+ unsigned char *c = code;
+ if (c [2] != 'M' || c [3] != 'o')
+ return NULL;
+ return *(MonoMethod**)(code + sizeof (gpointer));
+}