The attached patches add a partial implementation of DynamicILInfo --
basically enough that you can specify the IL code and locals for a
method, and have that method runnable.

I might work on this more if I have time, *plus* I'm not sure if this
here is too naive, and would need to change a lot for a full
implementation.

Thanks.
Index: mono/metadata/object-internals.h
===================================================================
--- mono/metadata/object-internals.h	(revision 97635)
+++ mono/metadata/object-internals.h	(working copy)
@@ -1004,6 +1004,15 @@
 } MonoReflectionGuidAttribute;
 
 typedef struct {
+    MonoObject object;
+    MonoArray *code;
+    gint32 code_len;
+    gint32 max_stack;
+    MonoArray *exceptions;
+    MonoArray *localsig;
+} MonoReflectionDynamicILInfo;
+
+typedef struct {
 	MonoObject object;
 	MonoMethod *mhandle;
 	MonoString *name;
@@ -1019,8 +1028,10 @@
 	MonoArray *refs;
 	GSList *referenced_by;
 	MonoReflectionType *owner;
+    MonoReflectionDynamicILInfo *dynil;
 } MonoReflectionDynamicMethod;	
 
+
 typedef struct {
 	MonoObject object;
 	MonoReflectionModuleBuilder *module;
Index: mono/metadata/reflection.c
===================================================================
--- mono/metadata/reflection.c	(revision 97635)
+++ mono/metadata/reflection.c	(working copy)
@@ -75,6 +75,7 @@
 	/* for PInvoke */
 	int charset, extra_flags, native_cc;
 	MonoString *dll, *dllentry;
+	MonoReflectionDynamicILInfo *dynil;
 } ReflectionMethodBuilder;
 
 typedef struct {
@@ -1454,7 +1455,7 @@
 	rmb->attrs = mb->attrs;
 	rmb->iattrs = 0;
 	rmb->call_conv = mb->call_conv;
-	rmb->code = NULL;
+    rmb->code = NULL;
 	rmb->type = (MonoObject *) mb->owner;
 	rmb->name = mb->name;
 	rmb->table_idx = NULL;
@@ -1468,6 +1469,7 @@
 	rmb->mhandle = mb->mhandle;
 	rmb->nrefs = 0;
 	rmb->refs = NULL;
+	rmb->dynil = mb->dynil;
 }	
 
 static void
@@ -8682,6 +8684,16 @@
 			num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
 			if (rmb->ilgen->ex_handlers)
 				num_clauses = method_count_clauses (rmb->ilgen);
+		} else if (rmb->dynil) {
+			char *ptr = mono_array_addr (rmb->dynil->localsig, guint8, 0);
+			code = mono_array_addr (rmb->dynil->code, guint8, 0);
+			code_size = rmb->dynil->code_len;
+			max_stack = rmb->dynil->max_stack;
+			if (*ptr == 0x07)
+			{
+				ptr++;
+				num_locals = mono_metadata_decode_value (ptr, &ptr);
+			}
 		} else {
 			if (rmb->code) {
 				code = mono_array_addr (rmb->code, guint8, 0);
@@ -8705,20 +8717,38 @@
 		header->init_locals = rmb->init_locals;
 		header->num_locals = num_locals;
 
-		for (i = 0; i < num_locals; ++i) {
-			MonoReflectionLocalBuilder *lb = 
-				mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
+		if (rmb->ilgen)
+		{
+			for (i = 0; i < num_locals; ++i) {
+				MonoReflectionLocalBuilder *lb = 
+					mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
 
-			header->locals [i] = mp_g_new0 (mp, MonoType, 1);
-			memcpy (header->locals [i], lb->type->type, sizeof (MonoType));
+				header->locals [i] = mp_g_new0 (mp, MonoType, 1);
+				memcpy (header->locals [i], lb->type->type, sizeof (MonoType));
+			}
 		}
 
+		if (rmb->dynil)
+		{
+			const char *ptr = mono_array_addr (rmb->dynil->localsig, guint8, 0);
+			ptr += 2;
+			for (i = 0; i < num_locals; i++)
+			{
+				MonoType *t = mono_metadata_parse_type_full(NULL, NULL, MONO_PARSE_LOCAL,
+															0, ptr, &ptr);
+				header->locals[i] = mp_g_new0 (mp, MonoType, 1);
+				memcpy (header->locals[i], t, sizeof (MonoType));
+			}
+		}
+
 		header->num_clauses = num_clauses;
 		if (num_clauses) {
 			header->clauses = method_encode_clauses ((MonoDynamicImage*)klass->image,
 				 rmb->ilgen, num_clauses);
 		}
 
+		/* FIXME - handle clauses for dynil */
+
 		pm->header = header;
 	}
 
@@ -9611,12 +9641,15 @@
 MonoArray *
 mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
 {
-	MonoDynamicImage *assembly = sig->module->dynamic_image;
+	MonoDynamicImage *assembly = NULL;
 	guint32 na = mono_array_length (sig->arguments);
 	guint32 buflen, i;
 	MonoArray *result;
 	SigBuffer buf;
 
+	if (sig->module)
+		assembly = sig->module->dynamic_image;
+
 	sigbuffer_init (&buf, 32);
 
 	sigbuffer_add_value (&buf, 0x07);
Index: class/corlib/System.Reflection.Emit/DynamicMethod.cs
===================================================================
--- class/corlib/System.Reflection.Emit/DynamicMethod.cs	(revision 97638)
+++ class/corlib/System.Reflection.Emit/DynamicMethod.cs	(working copy)
@@ -61,6 +61,7 @@
 		private object[] refs;
 		private IntPtr referenced_by;
 		private Type owner;
+        private DynamicILInfo dynil;
 		#endregion
 		private Delegate deleg;
 		private MonoMethod method;
@@ -128,10 +129,12 @@
 
 		private void CreateDynMethod () {
 			if (mhandle.Value == IntPtr.Zero) {
-				if (ilgen == null || (ILGenerator.Mono_GetCurrentOffset (ilgen) == 0))
+				if ((ilgen == null || (ILGenerator.Mono_GetCurrentOffset (ilgen) == 0))
+					&& dynil == null)
 					throw new InvalidOperationException ("Method '" + name + "' does not have a method body.");
 
-				ilgen.label_fixup ();
+				if (ilgen != null)
+					ilgen.label_fixup ();
 
 				// Have to create all DynamicMethods referenced by this one
 				try {
@@ -217,9 +220,11 @@
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO("Not implemented")]
+		[MonoTODO("Some functionality still missing")]
 		public DynamicILInfo GetDynamicILInfo () {
-			throw new NotImplementedException ();
+			if (dynil == null)
+				dynil = new DynamicILInfo(this);
+			return dynil;
 		}
 
 		public ILGenerator GetILGenerator () {
Index: class/corlib/System.Reflection.Emit/DynamicILInfo.cs
===================================================================
--- class/corlib/System.Reflection.Emit/DynamicILInfo.cs	(revision 97638)
+++ class/corlib/System.Reflection.Emit/DynamicILInfo.cs	(working copy)
@@ -37,14 +37,24 @@
 	[ComVisible (true)]
 	public class DynamicILInfo {
 
-		internal DynamicILInfo ()
+#region Sync with object-internals.h
+		private byte[] code;
+		private int code_len;
+		private int max_stack;
+		private byte[] exceptions;
+		private byte[] localsig;
+#endregion
+		private DynamicMethod dm;
+
+		internal DynamicILInfo (DynamicMethod dm)
 		{
+			this.dm = dm;
 		}
 
 		[MonoTODO]
 		public DynamicMethod DynamicMethod { 
 			get {
-				throw new NotImplementedException ();
+				return dm;
 			}
 		}
 
@@ -83,9 +93,10 @@
 			throw new NotImplementedException ();
 		}
 		
-		[MonoTODO]
 		public void SetCode (byte[] code, int maxStackSize) {
-			throw new NotImplementedException ();
+			this.code = (byte[]) code.Clone();
+			code_len = this.code.Length;
+			this.max_stack = maxStackSize;
 		}
 
 		[MonoTODO]
@@ -96,7 +107,7 @@
 
 		[MonoTODO]
 		public void SetExceptions (byte[] exceptions) {
-			throw new NotImplementedException ();
+			this.exceptions = (byte[]) exceptions.Clone();
 		}
 
 		[MonoTODO]
@@ -105,9 +116,8 @@
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
 		public void SetLocalSignature (byte[] localSignature) {
-			throw new NotImplementedException ();
+			localsig = (byte[]) localSignature.Clone();
 		}
 
 		[MonoTODO]
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to