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