[Mono-list] Re: [review] delegates are cascading.

Daniel Stodden stodden@in.tum.de
09 Mar 2002 11:31:29 +0100


--=-4/GwCNuxGXHZWQYheggC
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Sat, 2002-03-09 at 10:55, Daniel Stodden wrote:

> i'm pretty certain it is solid, but since it changes quite 

yeah. big badaboom.

better version below :}

daniel

-- 
___________________________________________________________________________
 mailto:stodden@in.tum.de

--=-4/GwCNuxGXHZWQYheggC
Content-Disposition: attachment; filename=mono.diff
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1

? @
? build
? doc/pending-classes
Index: mono/interpreter/interp.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/mono/mono/interpreter/interp.c,v
retrieving revision 1.146
diff -u -r1.146 interp.c
--- mono/interpreter/interp.c	2002/03/07 12:40:24	1.146
+++ mono/interpreter/interp.c	2002/03/09 06:39:27
@@ -533,16 +533,16 @@
 	MonoObject *obj =3D (MonoObject*)frame->obj;
 	MonoDelegate *delegate =3D (MonoDelegate*)frame->obj;
=20
-	mono_class_init (mono_defaults.delegate_class);
+	mono_class_init (mono_defaults.multicastdelegate_class);
 =09
 	if (*name =3D=3D '.' && (strcmp (name, ".ctor") =3D=3D 0) && obj &&
-			mono_object_isinst (obj, mono_defaults.delegate_class)) {
+			mono_object_isinst (obj, mono_defaults.multicastdelegate_class)) {
 		delegate->target =3D frame->stack_args[0].data.p;
 		delegate->method_ptr =3D frame->stack_args[1].data.p;
 		return;
 	}
 	if (*name =3D=3D 'I' && (strcmp (name, "Invoke") =3D=3D 0) && obj &&
-			mono_object_isinst (obj, mono_defaults.delegate_class)) {
+			mono_object_isinst (obj, mono_defaults.multicastdelegate_class)) {
 		MonoPIFunc func;
 		guchar *code;
 		MonoMethod *method;
Index: mono/jit/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/mono/mono/jit/Makefile.am,v
retrieving revision 1.15
diff -u -r1.15 Makefile.am
--- mono/jit/Makefile.am	2002/03/07 19:08:11	1.15
+++ mono/jit/Makefile.am	2002/03/09 06:39:27
@@ -25,6 +25,8 @@
 	$(GMODULE_LIBS) 		\
 	-lm
=20
+BUILT_SOURCES =3D codegen-x86.c codegen.h
+
 codegen-x86.c codegen.h: x86.brg
 	../monoburg/monoburg $(srcdir)/x86.brg -d codegen.h > codegen-x86.c
=20
Index: mono/jit/emit-x86.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/mono/mono/jit/emit-x86.c,v
retrieving revision 1.61
diff -u -r1.61 emit-x86.c
--- mono/jit/emit-x86.c	2002/03/08 06:08:46	1.61
+++ mono/jit/emit-x86.c	2002/03/09 06:39:27
@@ -918,21 +918,21 @@
 	if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
 		MonoClassField *field;
 		const char *name =3D method->name;
-		static guint target_offset =3D 0;
-		static guint method_offset =3D 0;
+		static guint target_offset =3D 0, method_offset =3D 0, prev_offset =3D 0=
;
+
 		guint8 *code;
 		gboolean delegate =3D FALSE;
=20
-		if (method->klass->parent &&=20
-		    method->klass->parent->parent =3D=3D mono_defaults.delegate_class)
+		if (method->klass->parent =3D=3D mono_defaults.multicastdelegate_class)
 			delegate =3D TRUE;
 			=09
 		if (!target_offset) {
-			mono_class_init (mono_defaults.delegate_class);
-
-			field =3D mono_class_get_field_from_name (mono_defaults.delegate_class,=
 "m_target");
+			mono_class_init (mono_defaults.multicastdelegate_class);
+			field =3D mono_class_get_field_from_name (mono_defaults.multicastdelega=
te_class, "prev");
+			prev_offset =3D field->offset;
+			field =3D mono_class_get_field_from_name (mono_defaults.multicastdelega=
te_class->parent, "m_target");
 			target_offset =3D field->offset;
-			field =3D mono_class_get_field_from_name (mono_defaults.delegate_class,=
 "method_ptr");
+			field =3D mono_class_get_field_from_name (mono_defaults.multicastdelega=
te_class->parent, "method_ptr");
 			method_offset =3D field->offset;
 		}
 	=09
@@ -951,6 +951,8 @@
 			x86_mov_reg_membase (code, X86_EDX, X86_EBP, 16, 4);
 			/* store method_ptr */
 			x86_mov_membase_reg (code, X86_EAX, method_offset, X86_EDX, 4);=20
+			/* set prev to zero */
+			x86_mov_membase_imm (code, X86_EAX, prev_offset, 0, 4);=20
=20
 			x86_leave (code);
 			x86_ret (code);
@@ -958,9 +960,16 @@
 			g_assert ((code - (guint8*)addr) < 32);
=20
 		} else if (delegate && *name =3D=3D 'I' && (strcmp (name, "Invoke") =3D=
=3D 0)) {
+			/*
+			 *	Invoke( args .. ) {
+			 *		if ( prev )
+			 *			prev.Invoke();
+			 *		return this.<m_target>( args );
+			 *	}
+			 */
 			MonoMethodSignature *csig =3D method->signature;
-			int i, arg_size, target, this_pos =3D 4;
-			guint8 *source;
+			guint8 *br[2], *pos[2];
+			int i, arg_size, this_pos =3D 4;
 		=09
 			if (csig->ret->type =3D=3D MONO_TYPE_VALUETYPE) {
 				g_assert (!csig->ret->byref);
@@ -979,50 +988,89 @@
=20
 			addr =3D g_malloc (64 + arg_size);
=20
-			for (i =3D 0; i < 2; i ++) {
-				int j;
+			code =3D addr;
+			/* load the this pointer */
+			x86_mov_reg_membase (code, X86_EAX, X86_ESP, this_pos, 4);
+		=09
+			/* load prev */
+			x86_mov_reg_membase (code, X86_EDX, X86_EAX, prev_offset, 4);
=20
-				code =3D addr;
-				/* load the this pointer */
-				x86_mov_reg_membase (code, X86_EAX, X86_ESP, this_pos, 4);
-				/* load mtarget */
-				x86_mov_reg_membase (code, X86_EDX, X86_EAX, target_offset, 4);=20
-				/* check if zero (static method call without this pointer) */
-				x86_alu_reg_imm (code, X86_CMP, X86_EDX, 0);
-				x86_branch32 (code, X86_CC_EQ, target, TRUE);=20
-				source =3D code;
-
-				/* virtual delegate methods: we have to replace the this pointer=20
-				 * withe the actual target */
-				x86_mov_membase_reg (code, X86_ESP, this_pos, X86_EDX, 4);=20
-				/* jump to method_ptr() */
-				x86_jump_membase (code, X86_EAX, method_offset);
-
-				/* static delegate methods: we have to remove the this pointer=20
-				 * from the activation frame - I do this do creating a new=20
-				 * stack frame an copy all arguments except the this pointer */
-
-				target =3D code - source;
-				g_assert ((arg_size & 3) =3D=3D 0);
-				for (j =3D 0; j < (arg_size>>2); j++) {
-					x86_push_membase (code, X86_ESP, (arg_size + this_pos));
-				}
+			/* prev =3D=3D 0 ? */
+			x86_alu_reg_imm (code, X86_CMP, X86_EDX, 0);
+			br[0] =3D code; x86_branch32 (code, X86_CC_EQ, 0, TRUE );
+			pos[0] =3D code;
+
+			x86_push_reg( code, X86_EAX );
+			/* push args */
+			for ( i =3D 0; i < (arg_size>>2); i++ )
+				x86_push_membase( code, X86_ESP, (arg_size + this_pos + 4) );
+			/* push next */
+			x86_push_reg( code, X86_EDX );
+			if (this_pos =3D=3D 8)
+				x86_push_membase (code, X86_ESP, (arg_size + 8));
+			/* recurse */
+			br[1] =3D code; x86_call_imm( code, 0 );
+			pos[1] =3D code; x86_call_imm( br[1], addr - pos[1] );
+
+			if (this_pos =3D=3D 8)
+				x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size + 8);
+			else
+				x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size + 4);
+			x86_pop_reg( code, X86_EAX );
+		=09
+			/* prev !=3D 0 */=20
+			x86_branch32( br[0], X86_CC_EQ, code - pos[0], TRUE );
+		=09
+			/* load mtarget */
+			x86_mov_reg_membase (code, X86_EDX, X86_EAX, target_offset, 4);=20
+			/* mtarget =3D=3D 0 ? */
+			x86_alu_reg_imm (code, X86_CMP, X86_EDX, 0);
+			br[0] =3D code; x86_branch32 (code, X86_CC_EQ, 0, TRUE);
+			pos[0] =3D code;
+
+			/*=20
+			 * virtual delegate methods: we have to
+			 * replace the this pointer with the actual
+			 * target
+			 */
+			x86_mov_membase_reg (code, X86_ESP, this_pos, X86_EDX, 4);=20
+			/* jump to method_ptr() */
+			x86_jump_membase (code, X86_EAX, method_offset);
+
+			/* mtarget !=3D 0 */=20
+			x86_branch32( br[0], X86_CC_EQ, code - pos[0], TRUE);
+			/*=20
+			 * static delegate methods: we have to remove
+			 * the this pointer from the activation frame
+			 * - I do this creating a new stack frame anx
+			 * copy all arguments except the this pointer
+			 */
+			g_assert ((arg_size & 3) =3D=3D 0);
+			for (i =3D 0; i < (arg_size>>2); i++) {
+				x86_push_membase (code, X86_ESP, (arg_size + this_pos));
+			}
=20
-				if (this_pos =3D=3D 8)=20
-					x86_push_membase (code, X86_ESP, (arg_size + 4));
-			=09
-				x86_call_membase (code, X86_EAX, method_offset);
+			if (this_pos =3D=3D 8)
+				x86_push_membase (code, X86_ESP, (arg_size + 4));
+		=09
+			x86_call_membase (code, X86_EAX, method_offset);
+			if ( arg_size ) {
 				if (this_pos =3D=3D 8)=20
 					x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size + 4);
 				else
 					x86_alu_reg_imm (code, X86_ADD, X86_ESP, arg_size);
-			=09
-				x86_ret (code);
-
 			}
=20
+			x86_ret (code);
+	=09
 			g_assert ((code - (guint8*)addr) < (64 + arg_size));
=20
+			if (mono_jit_dump_asm) {
+				char *id =3D g_strdup_printf ("%s.%s_%s", method->klass->name_space,
+							    method->klass->name, method->name);
+				mono_disassemble_code( addr, code - (guint8*)addr, id );
+				g_free (id);
+			}
 		} else {
 			if (mono_debug_handle)=20
 				return NULL;
Index: mono/metadata/appdomain.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/mono/mono/metadata/appdomain.c,v
retrieving revision 1.14
diff -u -r1.14 appdomain.c
--- mono/metadata/appdomain.c	2002/03/07 12:41:42	1.14
+++ mono/metadata/appdomain.c	2002/03/09 06:39:27
@@ -199,9 +199,9 @@
                 mono_defaults.corlib, "System", "Array");
 	g_assert (mono_defaults.array_class !=3D 0);
=20
-	mono_defaults.delegate_class =3D mono_class_from_name (
-                mono_defaults.corlib, "System", "Delegate");
-	g_assert (mono_defaults.delegate_class !=3D 0);
+	mono_defaults.multicastdelegate_class =3D mono_class_from_name (
+		mono_defaults.corlib, "System", "MulticastDelegate");
+	g_assert (mono_defaults.multicastdelegate_class !=3D 0 );
=20
 	mono_defaults.typehandle_class =3D mono_class_from_name (
                 mono_defaults.corlib, "System", "RuntimeTypeHandle");
Index: mono/metadata/loader.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/mono/mono/metadata/loader.c,v
retrieving revision 1.51
diff -u -r1.51 loader.c
--- mono/metadata/loader.c	2002/02/13 07:44:58	1.51
+++ mono/metadata/loader.c	2002/03/09 06:39:28
@@ -230,7 +230,7 @@
 			 * in delegates constructors you get in user code (native int)
 			 * and in mscorlib (native unsigned int)
 			 */
-			if (klass->parent && klass->parent->parent =3D=3D mono_defaults.delegat=
e_class) {
+			if (klass->parent =3D=3D mono_defaults.multicastdelegate_class) {
 				for (i =3D 0; i < klass->method.count; ++i) {
 					MonoMethod *m =3D klass->methods [i];
 					if (!strcmp (mname, m->name)) {
Index: mono/metadata/loader.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/mono/mono/metadata/loader.h,v
retrieving revision 1.16
diff -u -r1.16 loader.h
--- mono/metadata/loader.h	2002/02/13 07:44:58	1.16
+++ mono/metadata/loader.h	2002/03/09 06:39:28
@@ -48,7 +48,7 @@
 	MonoClass *string_class;
 	MonoClass *enum_class;
 	MonoClass *array_class;
-	MonoClass *delegate_class;
+	MonoClass *multicastdelegate_class;
 	MonoClass *typehandle_class;
 	MonoClass *fieldhandle_class;
 	MonoClass *methodhandle_class;
Index: mono/metadata/threads.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvs/public/mono/mono/metadata/threads.c,v
retrieving revision 1.10
diff -u -r1.10 threads.c
--- mono/metadata/threads.c	2002/02/25 11:01:46	1.10
+++ mono/metadata/threads.c	2002/03/09 06:39:29
@@ -119,7 +119,7 @@
 		  this, start);
 #endif
 =09
-	field=3Dmono_class_get_field_from_name(mono_defaults.delegate_class, "met=
hod_ptr");
+	field=3Dmono_class_get_field_from_name(mono_defaults.multicastdelegate_cl=
ass->parent, "method_ptr");
 	start_func=3D *(gpointer *)(((char *)start) + field->offset);
 =09
 	if(start_func=3D=3DNULL) {

--=-4/GwCNuxGXHZWQYheggC--