Permalink
Browse files

avoid cyclic dependency in CEE_LDFTN

svn path=/trunk/mono/; revision=3259
  • Loading branch information...
1 parent 2115ca9 commit 579f146c9d103ebdee692808578091963b526286 Dietmar Maurer committed Mar 21, 2002
View
@@ -1,6 +1,7 @@
2002-03-21 Dietmar Maurer <dietmar@ximian.com>
* jit.c (usage): new option to specify maximum number of worker threads
+ (mono_analyze_stack): avoid cyclic dependency in CEE_LDFTN
* delegate.c (async_invoke_abort): added support for asynchronous exceptions
(arch_get_async_invoke): notify listeners before we call the
View
@@ -211,6 +211,8 @@ arch_begin_invoke (MonoMethod *method, gpointer ret_ip, MonoObject *this, ...)
ares = mono_async_result_new (domain, ac->wait_semaphore, ac->state, ac);
+ ares->async_delegate = this;
+
EnterCriticalSection (&delegate_section);
async_call_queue = g_list_append (async_call_queue, ares);
LeaveCriticalSection (&delegate_section);
@@ -242,6 +244,8 @@ arch_end_invoke (MonoObject *this, gpointer handle, ...)
mono_raise_exception (e);
}
+ ares->endinvoke_called = 1;
+
EnterCriticalSection (&delegate_section);
if ((l = g_list_find (async_call_queue, handle))) {
async_call_queue = g_list_remove_link (async_call_queue, l);
View
@@ -2902,8 +2902,8 @@ mono_analyze_stack (MonoFlowGraph *cfg)
cm = mono_get_method (image, token, NULL);
g_assert (cm);
- t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
- t1->data.p = arch_compile_method (cm);
+ t1 = mono_ctree_new_leaf (mp, MB_TERM_LDFTN);
+ t1->data.m = cm;
PUSH_TREE (t1, VAL_POINTER);
break;
}
@@ -2925,7 +2925,7 @@ mono_analyze_stack (MonoFlowGraph *cfg)
t2->data.m = cm;
- t1 = mono_ctree_new (mp, MB_TERM_LDFTN, *sp, t2);
+ t1 = mono_ctree_new (mp, MB_TERM_LDVIRTFTN, *sp, t2);
PUSH_TREE (t1, VAL_POINTER);
View
@@ -190,7 +190,7 @@ void *MEMCOPY (void *dest, const void *src, size_t n);
%term CONV_OVF_I4_UN CONV_OVF_U1_UN CONV_OVF_U2_UN
%term CONV_OVF_I2_UN CONV_OVF_I8_UN CONV_OVF_I1_UN
%term EXCEPTION THROW RETHROW HANDLER
-%term LDLEN LDELEMA LDFTN LDSTR LDSFLDA
+%term LDLEN LDELEMA LDFTN LDVIRTFTN LDSTR LDSFLDA
#
# we start at stmt
@@ -1572,7 +1572,7 @@ reg: CALL_I4 (this, ADDR_G) {
mono_assert (tree->reg1 == X86_EAX);
}
-reg: LDFTN (reg, INTF_ADDR) {
+reg: LDVIRTFTN (reg, INTF_ADDR) {
int lreg = tree->left->reg1;
x86_mov_reg_membase (s->code, lreg, lreg, 0, 4);
@@ -1615,14 +1615,35 @@ reg: CALL_I4 (this, INTF_ADDR) {
mono_assert (tree->reg1 == X86_EAX);
}
-reg: LDFTN (reg, VFUNC_ADDR) {
+reg: LDVIRTFTN (reg, VFUNC_ADDR) {
int lreg = tree->left->reg1;
x86_mov_reg_membase (s->code, tree->reg1, lreg, 0, 4);
x86_mov_reg_membase (s->code, tree->reg1, tree->reg1, G_STRUCT_OFFSET (MonoVTable, vtable) + (tree->right->data.m->slot << 2), 4);
}
+reg: LDFTN {
+ if (tree->reg1 != X86_EAX)
+ x86_push_reg (s->code, X86_EAX);
+ x86_push_reg (s->code, X86_ECX);
+ x86_push_reg (s->code, X86_EDX);
+
+ x86_push_imm (s->code, tree->data.m);
+ mono_add_jump_info (s, s->code + 1, MONO_JUMP_INFO_ABS, arch_compile_method);
+ x86_call_code (s->code, 0);
+ x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, sizeof (gpointer));
+
+ x86_pop_reg (s->code, X86_EDX);
+ x86_pop_reg (s->code, X86_ECX);
+ if (tree->reg1 != X86_EAX) {
+ x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
+ x86_pop_reg (s->code, X86_EAX);
+ }
+ PRINT_REG ("LDFTN", tree->reg1);
+}
+
+
reg: CALL_I4 (this, VFUNC_ADDR) {
MethodCallInfo *ci = tree->data.ci;
int lreg = tree->left->reg1;
@@ -279,7 +279,8 @@ mono_init (const char *filename)
g_assert (mono_defaults.multicastdelegate_class != 0 );
mono_defaults.asyncresult_class = mono_class_from_name (
- mono_defaults.corlib, "System", "MonoAsyncResult");
+ mono_defaults.corlib, "System.Runtime.Remoting.Messaging",
+ "AsyncResult");
g_assert (mono_defaults.asyncresult_class != 0 );
mono_defaults.waithandle_class = mono_class_from_name (
View
@@ -102,9 +102,11 @@ typedef struct {
MonoObject object;
MonoObject *async_state;
MonoObject *handle;
+ MonoObject *async_delegate;
gpointer data;
MonoBoolean sync_completed;
MonoBoolean completed;
+ MonoBoolean endinvoke_called;
} MonoAsyncResult;
typedef struct {
View
@@ -1845,17 +1845,24 @@ static FieldDesc
async_result_fields[] = {
{"async_state", G_STRUCT_OFFSET (MonoAsyncResult, async_state)},
{"handle", G_STRUCT_OFFSET (MonoAsyncResult, handle)},
+ {"async_delegate", G_STRUCT_OFFSET (MonoAsyncResult, async_delegate)},
{"data", G_STRUCT_OFFSET (MonoAsyncResult, data)},
{"sync_completed", G_STRUCT_OFFSET (MonoAsyncResult, sync_completed)},
{"completed", G_STRUCT_OFFSET (MonoAsyncResult, completed)},
+ {"endinvoke_called", G_STRUCT_OFFSET (MonoAsyncResult, endinvoke_called)},
{NULL, 0}
};
static const ClassDesc
system_classes_to_check [] = {
{"Delegate", delegate_fields},
{"MulticastDelegate", multicast_delegate_fields},
- {"MonoAsyncResult", async_result_fields},
+ {NULL, NULL}
+};
+
+static const ClassDesc
+messaging_classes_to_check [] = {
+ {"AsyncResult", async_result_fields},
{NULL, NULL}
};
@@ -1879,6 +1886,7 @@ typedef struct {
static const NameSpaceDesc
namespaces_to_check[] = {
+ {"System.Runtime.Remoting.Messaging", messaging_classes_to_check},
{"System.Reflection.Emit", emit_classes_to_check},
{"System.Threading", threading_classes_to_check},
{"System", system_classes_to_check},
View
@@ -85,7 +85,8 @@ TESTSRC= \
rounding.cs \
hashcode.cs \
delegate1.cs \
- delegate2.cs
+ delegate2.cs \
+ delegate3.cs
TESTSI=$(TESTSRC:.cs=.exe)
View
@@ -0,0 +1,45 @@
+using System;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Runtime.Remoting.Messaging;
+
+class Test {
+ delegate int SimpleDelegate (int a);
+
+ static int cb_state = 0;
+
+ static int F (int a) {
+ Console.WriteLine ("Test.F from delegate: " + a);
+ throw new NotImplementedException ();
+ }
+
+ static void async_callback (IAsyncResult ar)
+ {
+ AsyncResult ares = (AsyncResult)ar;
+ AsyncCallback ac = new AsyncCallback (async_callback);
+
+ Console.WriteLine ("Async Callback " + ar.AsyncState);
+ cb_state++;
+ SimpleDelegate d = (SimpleDelegate)ares.AsyncDelegate;
+
+ if (cb_state < 5)
+ d.BeginInvoke (cb_state, ac, cb_state);
+
+ //throw new NotImplementedException ();
+ }
+
+ static int Main () {
+ SimpleDelegate d = new SimpleDelegate (F);
+ AsyncCallback ac = new AsyncCallback (async_callback);
+
+ IAsyncResult ar1 = d.BeginInvoke (cb_state, ac, cb_state);
+
+ ar1.AsyncWaitHandle.WaitOne ();
+
+
+ while (cb_state < 5)
+ Thread.Sleep (200);
+
+ return 0;
+ }
+}

0 comments on commit 579f146

Please sign in to comment.