Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, I'm trying to keep differences minimal, and I have no intention to drop System.Reflection support: #if IKVM_REF_EMIT using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; #else using System.Reflection; using System.Reflection.Emit; #endif I'd prefer not to go this route but it will require some gmcs refactoring to avoid it. My other modifications are around hacks for overcoming limitations of System.Reflection[.Emit] that make mcs depend on the Mono runtime, so actually I'm just trying to make the code hack free. My understanding is that basically we only have two compilers: - static: mcs.exe, gmcs.exe, smcs.exe, dmcs.exe (for each profile) - dynamic: Mono.CSharp.dll, that is used by Microsoft.CSharp.dll and csharp.exe That's not entirely accurate. We have REPL mode which is another dynamic version of all *mcs.exe running on top of SRE and there is possibility in near future for MD to plug-in with it's own type system mostly based on Cecil and most likely another type system is coming with .NET v-next which should expose C# DOM via .NET interfaces. As I see (based on your explanation) only the dynamic (as in the above list) compiler is using MakeExpression methods that will have to use System.Reflection anyway because they generate code that can be executed without saving an assembly first that requires runtime support. Because of conditional compilation and minimal code changes, having support for both SRE implementations - in my opinion - is not (significantly) increasing code maintenance requirements. If the above assumptations are correct then all the MakeExpression methods can safely be #if-ed out when building the static compilers and thus there are no features that cannot be implemented by using IKVM.Reflection. Is this correct? IKVM SRE like interface is quite disadvantage here. Presumably you could reference IKVM with extern alias to avoid System.Type conflicts otherwise we would have to alias every IKVM namespace. Marek ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hello Kornél, Thanks for the proof of concept of using System.Reflection.Emit with latest gmcs. I'll look into this more deeply when I iron out all regressions caused by the big change. It would be interesting to get some numbers out, I don't believe there should be much difference between SR(E) and IKVM but one never know. If you are going to do some testing use any real user assembly (not mscorlib), for instance System.Web or MD. Regards, Marek mcs creates an assembly, then creates types, and only after that is processing the custom attributes. This is how attributes and even assembly name (not the name part) can change after definition. Although there are some other self referencing cases, this order of creation/definition is required especially when building mscorlib.dll. At least some cases of these requirements could be eliminated by doing dependency analysis but there is no use to introduce extra complexity when the solution is very simple. All of these functions are implemented as hacks in Mono's System.Reflection.Emit. Blob encoded pseudo custom attributes are supported by Mono. I've added decoding because they weren't ignored, exceptions were thrown instead. I think that the only problem is that I've removed the exception when emitting backward jumps but since things were working so far, I haven't tried to resove that issue yet. (This is a work-in-progress state.) Unlike Java, C# has support for backward jumps, so does System.Reflection.Emit so support for that will have to be implemented. Some notes on IKVM.Reflection: First of all, thank you very much for creating it, since it's very unique. Based on your questions I belive that you are trying to remain compatible with MS.NET. This good, because both IKVM and mcs has a dynamic mode that is generating code for direct execution that requires System.Reflection.Emit. And to some extent enables IKVM.Reflection to be a drop-in replacement for System.Reflection.Emit on runtimes that have no built-in support. I on the other hand belive that removing arbitrary limitations of System.Reflection.Emit (like preventing access to TypeBuilder's member-builders), and adding missing functionality would make sense. Mono.Cecil is a great tool but it targets tools operating on metadata rather and is too abstract and complex for compilers. It also has a larger memory footprint. So I belive that there is a need for IKVM.Reflection as a replacement for MS.NET's System.Reflection.Emit as well. I also like the concept of having a Universe since that makes possible to have multiple compiler instances in the same AppDomain. I belive that pseudo custom attributes and unmanaged resource generation does not fit well to the concept of System.Reflection.Emit. I would rather remove support for both of these and introduce __methods for setting metadata that currently is built from pseudo custom attributes. Unmanaged resource generation could be automated (and customized) by using a dedicated class. This would be much faster than encoding (either binary or just the constructor arguments) and then decoding pseudo custom attributes. I also belive that CustomAttributeData should not be used as a provider, __GetCustomAttributes (non-standard since is returning constructor arguments rather than class instance) methods should be added to reflection classes. An ICustomAttributeProvider interface (with IsDefined and __GetCustomAttributes methods) would be very useful as well. As a conclusion I would be happy to see features (that make sense) in IKVM.Reflection.Emit that are not present in System.Reflection.Emit. Kornél Jeroen Frijters wrote: Hi, Thanks for the IKVM.Reflection patches. I have a few questions about some of the changes. - Why are the various _SetAttributes methods and the AssemblyBuilder.__SetName() methods necessary? - Do you really need blob encoded pseudo custom attributes in the version info? I intentionally don't suppor that (and also include the attributes as regular attributes) to be compatible with .NET - Why are all the stack height asserts commented out in ILGenerator, do you think they are wrong? Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Tuesday, May 04, 2010 2:03 PM To: mono-devel Cc: Miguel de Icaza; Marek Safar; Jeroen Frijters Subject: Porting mcs to IKVM.Reflection Hi, Inspired by http://tirania.org/blog/archive/2010/Apr-27.html I gave a try to port mcs to IKVM.Reflection. I addition to being able to have a single binary, mcs could run on MS.NET and we would not have to break MS.NET compatibility in System.Reflection. I've attached some work in progress patches both for mcs and IKVM.Reflection. I was impressed by the result that mcs is able to bootstrap itself, compile mscorlib.dll and its other requirements, and the resulting mcs is able to
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi Kornél Can you please tell when are MakeExpression methods used and whether are they required for code generation by mcs? The problem is that SLE MakeExpression methods require System.Reflection types. I was unable to find out when are MakeExpression methods used so I cannot come up with a solution. MakeExpression is used by dynamic C# compiler for dynamic code generation. MakeExpression uses System.Type type-system and always will, therefore gmcs must work with System.Type. You can browse /mcs/class/Microsoft.CSharp for more details. Marek ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
I'm just trying to implement /nostdlib: http://msdn.microsoft.com/en-us/library/fa13yay7.aspx And I belive that having API for setting assembly aliases would be a good solution. Of course LoadMscorlib is not a bug, it's just redundant. The current AssemblyResolve is able to do that just fine. If there was an assembly alias feature, LoadMscorlib was even more redundant. Regards, Kornél Jeroen Frijters wrote: LoadMscorlib was designed to meet your very specific needs of being able to load mscorlib.dll from a specified file. Any API designed without a very specific use case is doomed, so I consider this a feature not a bug. I don't understand what problem you are trying to solve, so maybe we should back up a little and talk about that first. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi Kornél, I'm just trying to implement /nostdlib: http://msdn.microsoft.com/en-us/library/fa13yay7.aspx And I belive that having API for setting assembly aliases would be a good solution. I think I understand better where you're coming from now. I did some more work on it in the mean time and I will soon check in a patch that fixes some issues and should make everything clearer I hope. My idea was that AssemblyResolve could indeed be used to implement -nostdlib, but there were some bugs preventing that from fully working. Of course LoadMscorlib is not a bug, it's just redundant. The current AssemblyResolve is able to do that just fine. If there was an assembly alias feature, LoadMscorlib was even more redundant. I think the alias feature is redundant with the AssemblyResolve, at least it will be after I commit my latest set of fixes. There is one reason why LoadMscorlib will need to stay, because it is the only way to avoid an alias from the current runtime mscorlib version to the one loaded and that is important for scenarios where the code is executing on a later runtime than the one the compiler is targetting. Thanks, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, If I look at it form an API design point of view netiher LoadMscorlib nor SetMscorlib are good. LoadMscorlib was designed to meet your very specific needs of being able to load mscorlib.dll from a specified file. SetMscorlib would remove the restriction of loading from the file and also would be future proof in the sense that it will continue to be compatible with new assembly loading/creating methods and new overloads of existing methods without any modification required. As I see the only was mscorlib.dll could be compiled is that you don't load another mscorlib.dll in DefineDynamicAssembly or in AssemblyBuilder constructor. This would be the defined behavior. Right not I cannot think of any possible requirement for loading mscorlib.dll during DefineDynamicAssembly. Since mscorlib.dll is a corner case if you will have to load mscolib.dll anyway intorducing another solution would only break a marginal set of all the use cases (mainly mcs when building mscorlib.dll) so such a breaking change would be acceptable. And I think that if such a requirement would be introduced that would be a breaking change in MS.NET as well. As a conclusion I think that there are only two properly designed solutions: 1. Remove LoadMscorlib, make HasMscorlib internal, and rely on AssemblyResolve event handler. 2. Remove LoadMscorlib, remove HasMscorlib, and add two new methods: __AddAssembly(string refname, Assembly asm) __TryGetAssembly(string refname, out Assembly asm) The first solution is very straightforward, and I've attached a patch for the second one (it's very straightforwad as well but was easier to express myself by using a patch). I consider the second one to be a more proper solution because compiler writers usually prefer to load a set of assemblier themselves rather than rely on automatic assembly resolution. Since Universe design in based on mapping System.Types to IKVM.Reflection.Types, compiler writers might actually use typeof for other assemblies (not just mscorlib.dll) and they might want those assembiles to be resolved to their preferred assembly. An example for such a behavior is a VB.NET compiler that has its own Microsoft.VisualBasic.dll runtime library treated very similar to how mscorlib.dll is treated by a C# compiler. VB runtime is written in VB and a /novbruntimeref option is required to build the runtime. Regards, Kornél Jeroen Frijters wrote: Please see the attached patch. I belive that this is actually an easier and cleaner solution than the current one. I disagree. You have to look at it from an API development point of view. This creates a huge window for undefined behavior and dependencies on implementation specifics, between calling DefineDynamicAssembly and SetMscorlib. It also makes it impossible for DefineDynamicAssembly (or the AssemblyBuilder constructor) to do anything that requires mscorlib (and who knows, maybe some future change to reflection will require this). Regards, Jeroen Index: Universe.cs === RCS file: /cvsroot/ikvm/ikvm/reflect/Universe.cs,v retrieving revision 1.13 diff -u -r1.13 Universe.cs --- Universe.cs 7 May 2010 16:35:47 - 1.13 +++ Universe.cs 9 May 2010 10:26:13 - @@ -387,33 +387,22 @@ get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = Import(typeof(System.Security.Permissions.SecurityAction))); } } - public bool HasMscorlib - { - get { return importedTypes.Count != 0 || assembliesByName.Count != 0; } - } - public event ResolveEventHandler AssemblyResolve { add { resolvers.Add(value); } remove { resolvers.Remove(value); } + } + + public void __AddAssembly(string refname, Assembly asm) + { + assembliesByName.Add(refname, asm); } - public void LoadMscorlib(string path) - { - if (HasMscorlib) - { - throw new InvalidOperationException(); - } - Assembly asm = LoadFile(path); - if (asm.FullName != typeof(object).Assembly.FullName) - { - // make the current mscorlib full name an alias for the specified mscorlib, - // this ensures that all the runtime built in type are resolved against the - // specified mscorlib. - assembliesByName.Add(typeof(object).Assembly.FullName, asm); - } - } - + public bool __TryGetAssembly(string refname, out Assembly asm) +
Re: [Mono-dev] Porting mcs to IKVM.Reflection
LoadMscorlib was designed to meet your very specific needs of being able to load mscorlib.dll from a specified file. Any API designed without a very specific use case is doomed, so I consider this a feature not a bug. I don't understand what problem you are trying to solve, so maybe we should back up a little and talk about that first. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, Thank you for fixing them. I've just realized that DefineDynamicAssemblyImpl should not hardcode the name mscorlib since C# compiler is able to us any name when compiling with nostdlib. Note that a solution would be to modify (and possibliy rename to SetMscorlib) LoadMscorlib so that it accepts an Assembly rather than a path. It should allow the case when assembliesByName and assemblies only contain the specified assembly. Kornél Jeroen Frijters wrote: Hi Kornél, Thanks. Fixed all three issues. Regards, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Friday, May 07, 2010 6:08 PM To: Jeroen Frijters Cc: mono-devel Subject: Re: Porting mcs to IKVM.Reflection Hi Jeroen, Thank you for the fixes. New problems after the modifications: SetCustomAttribute now fails for example for DllImportAttribute when building mscorlib.dll because ReadFixedArg calls GetEnumUnderlyingType and CheckBaked fails. AssemblyKeyFileAttribute and AssemblyKeyNameAttribute should not be considered pseudo custom attributes because even MS csc.exe emits those attributes and Debug.Assert fails. Also note that according to my tests AssemblyHashAlgorithm.None is changed to AssemblyHashAlgorithm.SHA1 when setting the assembly name because GetName returns AssemblyHashAlgorithm.SHA1 (rather than only when calling Save). Kornél Jeroen Frijters wrote: Hi Kornél, This has now been fixed. Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Friday, May 07, 2010 10:33 AM To: Jeroen Frijters Cc: Marek Safar; mono-devel; Miguel de Icaza Subject: Re: Porting mcs to IKVM.Reflection Hi, Thank you for applying/enhacing the patches. I'll check it out. This code will work on both of Mono and MS.NET, but will fail without the WriteGenericSignature patch: AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(myassembly), AssemblyBuilderAccess.Save); ModuleBuilder mb = ab.DefineDynamicModule(myassembly, myassembly.dll); TypeBuilder tb = mb.DefineType(mytype, TypeAttributes.Public); tb.DefineGenericParameters(new string[] { T, U }); ConstructorBuilder cb = tb.DefineDefaultConstructor(MethodAttributes.Public); MethodBuilder method = tb.DefineMethod(mymethod, MethodAttributes.Static | MethodAttributes.Public, tb, Type.EmptyTypes); ILGenerator ig = method.GetILGenerator(); ig.DeclareLocal(tb); ig.Emit(OpCodes.Newobj, cb); ig.Emit(OpCodes.Stloc_0); ig.Emit(OpCodes.Ldloc_0); ig.Emit(OpCodes.Ret); tb.CreateType(); ab.Save(myassembly.dll); Although using a generic type definition directly makes little sense, neither makes using tb.MakeGenericType(tb.GetGenericArguments()) much more sense, since you still can use the latter in a context that has fewer generic arguments. Kornél Jeroen Frijters wrote: Hi Kornél, I've fixed most of the things that your patch addressed. I also removed support for the TypeForwardedToAttribute and DefaultParameterValueAttribute pseudo custom attributes (because I realized that supporting them is incompatible with my goal to be a drop in replacement for System.Reflection.Emit). One thing I didn't change is WriteGenericSignature, because your change didn't make sense to me. It should not be possible that this method gets called with a generic type definition. I have not yet added anything additional for version info unmanaged resources. I need to do more thinking about this. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
I've just realized that DefineDynamicAssemblyImpl should not hardcode the name mscorlib since C# compiler is able to us any name when compiling with nostdlib. The hardcoded name bother me too, but then I couldn't think of any realistic scenario where you'd build an mscorlib with a different name. Do you have any examples? Also, how does gmcs know that it is compiling mscorlib? BTW, the solution I would prefer would be to add DefineMscorlib() (taking the same parameters as DefineDynamicAssembly). Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, There simply is no special case for building mscorlib.dll. There is a /nostdlib option however that enables features required for building mscorlib.dll. I would recommend SetMscorlib over LoadMscorlib because that would not restrict how you can create or load mscorlib.dll. Kornél Jeroen Frijters wrote: I've just realized that DefineDynamicAssemblyImpl should not hardcode the name mscorlib since C# compiler is able to us any name when compiling with nostdlib. The hardcoded name bother me too, but then I couldn't think of any realistic scenario where you'd build an mscorlib with a different name. Do you have any examples? Also, how does gmcs know that it is compiling mscorlib? BTW, the solution I would prefer would be to add DefineMscorlib() (taking the same parameters as DefineDynamicAssembly). Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
I would recommend SetMscorlib over LoadMscorlib because that would not restrict how you can create or load mscorlib.dll. That feels like painting yourself into a corner to me. Using SetMscorlib would require modifying DefineDynamicAssembly in a way that would make it hard to remain compatible with .NET reflection. Please consider that from my point of view, gmcs building mscorlib is a complete corner case, not what the API should be optimized for. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Please see the attached patch. I belive that this is actually an easier and cleaner solution than the current one. You can use Load, LoadFile, DefineDynamicAssembly, etc. to load mscorlib.dll. Kornél Jeroen Frijters write: I would recommend SetMscorlib over LoadMscorlib because that would not restrict how you can create or load mscorlib.dll. That feels like painting yourself into a corner to me. Using SetMscorlib would require modifying DefineDynamicAssembly in a way that would make it hard to remain compatible with .NET reflection. Please consider that from my point of view, gmcs building mscorlib is a complete corner case, not what the API should be optimized for. Regards, Jeroen Index: Universe.cs === RCS file: /cvsroot/ikvm/ikvm/reflect/Universe.cs,v retrieving revision 1.13 diff -u -r1.13 Universe.cs --- Universe.cs 7 May 2010 16:35:47 - 1.13 +++ Universe.cs 8 May 2010 12:37:44 - @@ -389,7 +389,7 @@ public bool HasMscorlib { - get { return importedTypes.Count != 0 || assembliesByName.Count != 0; } + get { return assembliesByName.ContainsKey(typeof(object).Assembly.FullName); } } public event ResolveEventHandler AssemblyResolve @@ -398,19 +398,20 @@ remove { resolvers.Remove(value); } } - public void LoadMscorlib(string path) - { - if (HasMscorlib) + public void SetMscorlib(Assembly asm) + { + string mscorlibName = typeof(object).Assembly.FullName; + Assembly mscorlibAssembly; + if (assembliesByName.TryGetValue(mscorlibName, out mscorlibAssembly) mscorlibAssembly != asm) { throw new InvalidOperationException(); - } - Assembly asm = LoadFile(path); - if (asm.FullName != typeof(object).Assembly.FullName) + } + if (asm.FullName != mscorlibName) { // make the current mscorlib full name an alias for the specified mscorlib, // this ensures that all the runtime built in type are resolved against the - // specified mscorlib. - assembliesByName.Add(typeof(object).Assembly.FullName, asm); + // specified mscorlib. + assembliesByName.Add(mscorlibName, asm); } } @@ -680,14 +681,9 @@ private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) { - bool mscorlib = !HasMscorlib name.Name == mscorlib; AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions); assembliesByName.Add(GetAssemblyIdentityName(asm.GetName()), asm); assemblies.Add(asm); - if (mscorlib) - { - assembliesByName[typeof(object).Assembly.FullName] = asm; - } return asm; } ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Please see the attached patch. I belive that this is actually an easier and cleaner solution than the current one. I disagree. You have to look at it from an API development point of view. This creates a huge window for undefined behavior and dependencies on implementation specifics, between calling DefineDynamicAssembly and SetMscorlib. It also makes it impossible for DefineDynamicAssembly (or the AssemblyBuilder constructor) to do anything that requires mscorlib (and who knows, maybe some future change to reflection will require this). Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi Kornél, I've fixed most of the things that your patch addressed. I also removed support for the TypeForwardedToAttribute and DefaultParameterValueAttribute pseudo custom attributes (because I realized that supporting them is incompatible with my goal to be a drop in replacement for System.Reflection.Emit). One thing I didn't change is WriteGenericSignature, because your change didn't make sense to me. It should not be possible that this method gets called with a generic type definition. I have not yet added anything additional for version info unmanaged resources. I need to do more thinking about this. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, Thank you for applying/enhacing the patches. I'll check it out. This code will work on both of Mono and MS.NET, but will fail without the WriteGenericSignature patch: AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(myassembly), AssemblyBuilderAccess.Save); ModuleBuilder mb = ab.DefineDynamicModule(myassembly, myassembly.dll); TypeBuilder tb = mb.DefineType(mytype, TypeAttributes.Public); tb.DefineGenericParameters(new string[] { T, U }); ConstructorBuilder cb = tb.DefineDefaultConstructor(MethodAttributes.Public); MethodBuilder method = tb.DefineMethod(mymethod, MethodAttributes.Static | MethodAttributes.Public, tb, Type.EmptyTypes); ILGenerator ig = method.GetILGenerator(); ig.DeclareLocal(tb); ig.Emit(OpCodes.Newobj, cb); ig.Emit(OpCodes.Stloc_0); ig.Emit(OpCodes.Ldloc_0); ig.Emit(OpCodes.Ret); tb.CreateType(); ab.Save(myassembly.dll); Although using a generic type definition directly makes little sense, neither makes using tb.MakeGenericType(tb.GetGenericArguments()) much more sense, since you still can use the latter in a context that has fewer generic arguments. Kornél Jeroen Frijters wrote: Hi Kornél, I've fixed most of the things that your patch addressed. I also removed support for the TypeForwardedToAttribute and DefaultParameterValueAttribute pseudo custom attributes (because I realized that supporting them is incompatible with my goal to be a drop in replacement for System.Reflection.Emit). One thing I didn't change is WriteGenericSignature, because your change didn't make sense to me. It should not be possible that this method gets called with a generic type definition. I have not yet added anything additional for version info unmanaged resources. I need to do more thinking about this. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
This code will work on both of Mono and MS.NET, but will fail without the WriteGenericSignature patch: [...] Although using a generic type definition directly makes little sense, neither makes using tb.MakeGenericType(tb.GetGenericArguments()) much more sense, since you still can use the latter in a context that has fewer generic arguments. Ugh. Thanks. It turns out that ReferenceEquals(typeof(Foo).MakeGenericType(typeof(Foo).GetGenericArguments()), typeof(Foo)) is true and that means that I need to do some fixing... I guess I had it coming that a major flaw in my understanding would come to light after bragging I know so much about Reflection ;-) Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi Kornél, This has now been fixed. Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Friday, May 07, 2010 10:33 AM To: Jeroen Frijters Cc: Marek Safar; mono-devel; Miguel de Icaza Subject: Re: Porting mcs to IKVM.Reflection Hi, Thank you for applying/enhacing the patches. I'll check it out. This code will work on both of Mono and MS.NET, but will fail without the WriteGenericSignature patch: AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(myassembly), AssemblyBuilderAccess.Save); ModuleBuilder mb = ab.DefineDynamicModule(myassembly, myassembly.dll); TypeBuilder tb = mb.DefineType(mytype, TypeAttributes.Public); tb.DefineGenericParameters(new string[] { T, U }); ConstructorBuilder cb = tb.DefineDefaultConstructor(MethodAttributes.Public); MethodBuilder method = tb.DefineMethod(mymethod, MethodAttributes.Static | MethodAttributes.Public, tb, Type.EmptyTypes); ILGenerator ig = method.GetILGenerator(); ig.DeclareLocal(tb); ig.Emit(OpCodes.Newobj, cb); ig.Emit(OpCodes.Stloc_0); ig.Emit(OpCodes.Ldloc_0); ig.Emit(OpCodes.Ret); tb.CreateType(); ab.Save(myassembly.dll); Although using a generic type definition directly makes little sense, neither makes using tb.MakeGenericType(tb.GetGenericArguments()) much more sense, since you still can use the latter in a context that has fewer generic arguments. Kornél Jeroen Frijters wrote: Hi Kornél, I've fixed most of the things that your patch addressed. I also removed support for the TypeForwardedToAttribute and DefaultParameterValueAttribute pseudo custom attributes (because I realized that supporting them is incompatible with my goal to be a drop in replacement for System.Reflection.Emit). One thing I didn't change is WriteGenericSignature, because your change didn't make sense to me. It should not be possible that this method gets called with a generic type definition. I have not yet added anything additional for version info unmanaged resources. I need to do more thinking about this. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi Jeroen, Thank you for the fixes. New problems after the modifications: SetCustomAttribute now fails for example for DllImportAttribute when building mscorlib.dll because ReadFixedArg calls GetEnumUnderlyingType and CheckBaked fails. AssemblyKeyFileAttribute and AssemblyKeyNameAttribute should not be considered pseudo custom attributes because even MS csc.exe emits those attributes and Debug.Assert fails. Also note that according to my tests AssemblyHashAlgorithm.None is changed to AssemblyHashAlgorithm.SHA1 when setting the assembly name because GetName returns AssemblyHashAlgorithm.SHA1 (rather than only when calling Save). Kornél Jeroen Frijters wrote: Hi Kornél, This has now been fixed. Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Friday, May 07, 2010 10:33 AM To: Jeroen Frijters Cc: Marek Safar; mono-devel; Miguel de Icaza Subject: Re: Porting mcs to IKVM.Reflection Hi, Thank you for applying/enhacing the patches. I'll check it out. This code will work on both of Mono and MS.NET, but will fail without the WriteGenericSignature patch: AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(myassembly), AssemblyBuilderAccess.Save); ModuleBuilder mb = ab.DefineDynamicModule(myassembly, myassembly.dll); TypeBuilder tb = mb.DefineType(mytype, TypeAttributes.Public); tb.DefineGenericParameters(new string[] { T, U }); ConstructorBuilder cb = tb.DefineDefaultConstructor(MethodAttributes.Public); MethodBuilder method = tb.DefineMethod(mymethod, MethodAttributes.Static | MethodAttributes.Public, tb, Type.EmptyTypes); ILGenerator ig = method.GetILGenerator(); ig.DeclareLocal(tb); ig.Emit(OpCodes.Newobj, cb); ig.Emit(OpCodes.Stloc_0); ig.Emit(OpCodes.Ldloc_0); ig.Emit(OpCodes.Ret); tb.CreateType(); ab.Save(myassembly.dll); Although using a generic type definition directly makes little sense, neither makes using tb.MakeGenericType(tb.GetGenericArguments()) much more sense, since you still can use the latter in a context that has fewer generic arguments. Kornél Jeroen Frijters wrote: Hi Kornél, I've fixed most of the things that your patch addressed. I also removed support for the TypeForwardedToAttribute and DefaultParameterValueAttribute pseudo custom attributes (because I realized that supporting them is incompatible with my goal to be a drop in replacement for System.Reflection.Emit). One thing I didn't change is WriteGenericSignature, because your change didn't make sense to me. It should not be possible that this method gets called with a generic type definition. I have not yet added anything additional for version info unmanaged resources. I need to do more thinking about this. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi Kornél, Thanks. Fixed all three issues. Regards, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Friday, May 07, 2010 6:08 PM To: Jeroen Frijters Cc: mono-devel Subject: Re: Porting mcs to IKVM.Reflection Hi Jeroen, Thank you for the fixes. New problems after the modifications: SetCustomAttribute now fails for example for DllImportAttribute when building mscorlib.dll because ReadFixedArg calls GetEnumUnderlyingType and CheckBaked fails. AssemblyKeyFileAttribute and AssemblyKeyNameAttribute should not be considered pseudo custom attributes because even MS csc.exe emits those attributes and Debug.Assert fails. Also note that according to my tests AssemblyHashAlgorithm.None is changed to AssemblyHashAlgorithm.SHA1 when setting the assembly name because GetName returns AssemblyHashAlgorithm.SHA1 (rather than only when calling Save). Kornél Jeroen Frijters wrote: Hi Kornél, This has now been fixed. Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Friday, May 07, 2010 10:33 AM To: Jeroen Frijters Cc: Marek Safar; mono-devel; Miguel de Icaza Subject: Re: Porting mcs to IKVM.Reflection Hi, Thank you for applying/enhacing the patches. I'll check it out. This code will work on both of Mono and MS.NET, but will fail without the WriteGenericSignature patch: AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(myassembly), AssemblyBuilderAccess.Save); ModuleBuilder mb = ab.DefineDynamicModule(myassembly, myassembly.dll); TypeBuilder tb = mb.DefineType(mytype, TypeAttributes.Public); tb.DefineGenericParameters(new string[] { T, U }); ConstructorBuilder cb = tb.DefineDefaultConstructor(MethodAttributes.Public); MethodBuilder method = tb.DefineMethod(mymethod, MethodAttributes.Static | MethodAttributes.Public, tb, Type.EmptyTypes); ILGenerator ig = method.GetILGenerator(); ig.DeclareLocal(tb); ig.Emit(OpCodes.Newobj, cb); ig.Emit(OpCodes.Stloc_0); ig.Emit(OpCodes.Ldloc_0); ig.Emit(OpCodes.Ret); tb.CreateType(); ab.Save(myassembly.dll); Although using a generic type definition directly makes little sense, neither makes using tb.MakeGenericType(tb.GetGenericArguments()) much more sense, since you still can use the latter in a context that has fewer generic arguments. Kornél Jeroen Frijters wrote: Hi Kornél, I've fixed most of the things that your patch addressed. I also removed support for the TypeForwardedToAttribute and DefaultParameterValueAttribute pseudo custom attributes (because I realized that supporting them is incompatible with my goal to be a drop in replacement for System.Reflection.Emit). One thing I didn't change is WriteGenericSignature, because your change didn't make sense to me. It should not be possible that this method gets called with a generic type definition. I have not yet added anything additional for version info unmanaged resources. I need to do more thinking about this. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, Can you please tell when are MakeExpression methods used and whether are they required for code generation by mcs? The problem is that SLE MakeExpression methods require System.Reflection types. I was unable to find out when are MakeExpression methods used so I cannot come up with a solution. Thank you. Kornél Kornél Pál wrote: Hi, Inspired by http://tirania.org/blog/archive/2010/Apr-27.html I gave a try to port mcs to IKVM.Reflection. I addition to being able to have a single binary, mcs could run on MS.NET and we would not have to break MS.NET compatibility in System.Reflection. I've attached some work in progress patches both for mcs and IKVM.Reflection. I was impressed by the result that mcs is able to bootstrap itself, compile mscorlib.dll and its other requirements, and the resulting mcs is able to compile a bunch of Mono assemblies. Missing features: - security attributes - embedded resources - .netmodule support - debug info Also note that I was unable to figure out what MakeExpression methods are supposed to do but I had to disable them because they need System.Reflection types. mcs pathes are licensed under the MIT/X11 license. IKVM.Reflection patches are licensed under the zlib license. Kornél ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi Marek, Thank you for your reply. I'm trying to keep differences minimal, and I have no intention to drop System.Reflection support: #if IKVM_REF_EMIT using IKVM.Reflection; using IKVM.Reflection.Emit; using Type = IKVM.Reflection.Type; #else using System.Reflection; using System.Reflection.Emit; #endif My other modifications are around hacks for overcoming limitations of System.Reflection[.Emit] that make mcs depend on the Mono runtime, so actually I'm just trying to make the code hack free. My understanding is that basically we only have two compilers: - static: mcs.exe, gmcs.exe, smcs.exe, dmcs.exe (for each profile) - dynamic: Mono.CSharp.dll, that is used by Microsoft.CSharp.dll and csharp.exe As I see (based on your explanation) only the dynamic (as in the above list) compiler is using MakeExpression methods that will have to use System.Reflection anyway because they generate code that can be executed without saving an assembly first that requires runtime support. Because of conditional compilation and minimal code changes, having support for both SRE implementations - in my opinion - is not (significantly) increasing code maintenance requirements. If the above assumptations are correct then all the MakeExpression methods can safely be #if-ed out when building the static compilers and thus there are no features that cannot be implemented by using IKVM.Reflection. Is this correct? Kornél Marek Safar wrote: Hi Kornél Can you please tell when are MakeExpression methods used and whether are they required for code generation by mcs? The problem is that SLE MakeExpression methods require System.Reflection types. I was unable to find out when are MakeExpression methods used so I cannot come up with a solution. MakeExpression is used by dynamic C# compiler for dynamic code generation. MakeExpression uses System.Type type-system and always will, therefore gmcs must work with System.Type. You can browse /mcs/class/Microsoft.CSharp for more details. Marek ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
My understanding is that basically we only have two compilers: - static: mcs.exe, gmcs.exe, smcs.exe, dmcs.exe (for each profile) - dynamic: Mono.CSharp.dll, that is used by Microsoft.CSharp.dll and csharp.exe As I see (based on your explanation) only the dynamic (as in the above list) compiler is using MakeExpression methods that will have to use System.Reflection anyway because they generate code that can be executed without saving an assembly first that requires runtime support. Because of conditional compilation and minimal code changes, having support for both SRE implementations - in my opinion - is not (significantly) increasing code maintenance requirements. This is exactly the scenario that IVKM.Reflection was designed for, because I'm in the same boat. ikvm.exe is a dynamic runtime, whereas ikvmc.exe is a static compiler. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Kornél Pál wrote: mcs creates an assembly, then creates types, and only after that is processing the custom attributes. This is how attributes and even assembly name (not the name part) can change after definition. Although there are some other self referencing cases, this order of creation/definition is required especially when building mscorlib.dll. OK, that makes sense. I skipped custom attributes in my mcs IKVM.Reflection hack, so that may account for not running into that. I don't really like AssemblyBuilder.__SetName(), however. How about adding __SetVersion(), __SetCulture() and __SetKeyPair()? Blob encoded pseudo custom attributes are supported by Mono. I've added decoding because they weren't ignored, exceptions were thrown instead. Yes, I'll fix the code not to throw exceptions, but silently ignore them (like .NET does). Unlike Java, C# has support for backward jumps, so does System.Reflection.Emit so support for that will have to be implemented. The backwards branch constraint is an ECMA CIL restriction. The Microsoft CLR supports code that violates it, but years ago when I first found out about this it was because ikvm generated code that violated it and Mono didn't support that. So, I don't think it is necessary to support this (as it isn't valid ECMA CIL anyway). If mcs generates code that triggers this exception, then it is a bug in ILGenerator, or a bug in mcs. Based on your questions I belive that you are trying to remain compatible with MS.NET. Yes. However, I'm all for adding extra functionality (either by __ methods or by having ___ settings to enable/disable specific behavior). I on the other hand belive that removing arbitrary limitations of System.Reflection.Emit (like preventing access to TypeBuilder's member- builders), and adding missing functionality would make sense. I agree, but I don't want to create a situation where you unintentionally depend on an IKVM.Reflection specific feature. Based on your work I have identified a couple of cases where things can be improved (e.g. I agree that the __GetDeclaredXxx methods should expose unbaked members in TypeBuilders). I also like the concept of having a Universe since that makes possible to have multiple compiler instances in the same AppDomain. Yes, I made the mistake in ikvm/ikvmc to have lots of statics and didn't want to make that mistake again ;-) I belive that pseudo custom attributes and unmanaged resource generation does not fit well to the concept of System.Reflection.Emit. I kind of agree. I will add a mode to disable them and add specific __ methods to do the equivalent. I also belive that CustomAttributeData should not be used as a provider, __GetCustomAttributes (non-standard since is returning constructor arguments rather than class instance) methods should be added to reflection classes. An ICustomAttributeProvider interface (with IsDefined and __GetCustomAttributes methods) would be very useful as well. Agreed. Regards, Jeroen ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, I'm still in the stage of getting the things work, so I haven't really care about performance yet, but I'll give you some numbers once I consider the patch complete. Also note that IKVM.Reflection support is implemented using conditional compilation directives, so adding support for IKVM.Reflection does not have to mean stwitching to IKVM.Reflection. Kornél Marek Safar wrote: Hello Kornél, Thanks for the proof of concept of using System.Reflection.Emit with latest gmcs. I'll look into this more deeply when I iron out all regressions caused by the big change. It would be interesting to get some numbers out, I don't believe there should be much difference between SR(E) and IKVM but one never know. If you are going to do some testing use any real user assembly (not mscorlib), for instance System.Web or MD. Regards, Marek mcs creates an assembly, then creates types, and only after that is processing the custom attributes. This is how attributes and even assembly name (not the name part) can change after definition. Although there are some other self referencing cases, this order of creation/definition is required especially when building mscorlib.dll. At least some cases of these requirements could be eliminated by doing dependency analysis but there is no use to introduce extra complexity when the solution is very simple. All of these functions are implemented as hacks in Mono's System.Reflection.Emit. Blob encoded pseudo custom attributes are supported by Mono. I've added decoding because they weren't ignored, exceptions were thrown instead. I think that the only problem is that I've removed the exception when emitting backward jumps but since things were working so far, I haven't tried to resove that issue yet. (This is a work-in-progress state.) Unlike Java, C# has support for backward jumps, so does System.Reflection.Emit so support for that will have to be implemented. Some notes on IKVM.Reflection: First of all, thank you very much for creating it, since it's very unique. Based on your questions I belive that you are trying to remain compatible with MS.NET. This good, because both IKVM and mcs has a dynamic mode that is generating code for direct execution that requires System.Reflection.Emit. And to some extent enables IKVM.Reflection to be a drop-in replacement for System.Reflection.Emit on runtimes that have no built-in support. I on the other hand belive that removing arbitrary limitations of System.Reflection.Emit (like preventing access to TypeBuilder's member-builders), and adding missing functionality would make sense. Mono.Cecil is a great tool but it targets tools operating on metadata rather and is too abstract and complex for compilers. It also has a larger memory footprint. So I belive that there is a need for IKVM.Reflection as a replacement for MS.NET's System.Reflection.Emit as well. I also like the concept of having a Universe since that makes possible to have multiple compiler instances in the same AppDomain. I belive that pseudo custom attributes and unmanaged resource generation does not fit well to the concept of System.Reflection.Emit. I would rather remove support for both of these and introduce __methods for setting metadata that currently is built from pseudo custom attributes. Unmanaged resource generation could be automated (and customized) by using a dedicated class. This would be much faster than encoding (either binary or just the constructor arguments) and then decoding pseudo custom attributes. I also belive that CustomAttributeData should not be used as a provider, __GetCustomAttributes (non-standard since is returning constructor arguments rather than class instance) methods should be added to reflection classes. An ICustomAttributeProvider interface (with IsDefined and __GetCustomAttributes methods) would be very useful as well. As a conclusion I would be happy to see features (that make sense) in IKVM.Reflection.Emit that are not present in System.Reflection.Emit. Kornél Jeroen Frijters wrote: Hi, Thanks for the IKVM.Reflection patches. I have a few questions about some of the changes. - Why are the various _SetAttributes methods and the AssemblyBuilder.__SetName() methods necessary? - Do you really need blob encoded pseudo custom attributes in the version info? I intentionally don't suppor that (and also include the attributes as regular attributes) to be compatible with .NET - Why are all the stack height asserts commented out in ILGenerator, do you think they are wrong? Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Tuesday, May 04, 2010 2:03 PM To: mono-devel Cc: Miguel de Icaza; Marek Safar; Jeroen Frijters Subject: Porting mcs to IKVM.Reflection Hi, Inspired by http://tirania.org/blog/archive/2010/Apr-27.html I gave a try to port mcs to
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, Jeroen Frijters wrote: Kornél Pál wrote: mcs creates an assembly, then creates types, and only after that is processing the custom attributes. This is how attributes and even assembly name (not the name part) can change after definition. Although there are some other self referencing cases, this order of creation/definition is required especially when building mscorlib.dll. OK, that makes sense. I skipped custom attributes in my mcs IKVM.Reflection hack, so that may account for not running into that. I don't really like AssemblyBuilder.__SetName(), however. How about adding __SetVersion(), __SetCulture() and __SetKeyPair()? That would be a better idea. Updating Universe.assembliesByName also would make sense. Unlike Java, C# has support for backward jumps, so does System.Reflection.Emit so support for that will have to be implemented. The backwards branch constraint is an ECMA CIL restriction. The Microsoft CLR supports code that violates it, but years ago when I first found out about this it was because ikvm generated code that violated it and Mono didn't support that. So, I don't think it is necessary to support this (as it isn't valid ECMA CIL anyway). If mcs generates code that triggers this exception, then it is a bug in ILGenerator, or a bug in mcs. Right, your check implements the ECMA requirements. There must be some other problem then... I'll analyze that later. Based on your questions I belive that you are trying to remain compatible with MS.NET. Yes. However, I'm all for adding extra functionality (either by __ methods or by having ___ settings to enable/disable specific behavior). Using global (or instance-wide) flags may not be that good. Having __methods that behave differently or have arguments (boolean or enum) that either enable MS.NET compatible behavior or some other custom behavior should be considered as well. In the latter case MS.NET compatible methods could simply call the __ methods with parameters that ensure MS.NET compatible behavior. I belive that pseudo custom attributes and unmanaged resource generation does not fit well to the concept of System.Reflection.Emit. I kind of agree. I will add a mode to disable them and add specific __ methods to do the equivalent. That would be awesome. I also belive that CustomAttributeData should not be used as a provider, __GetCustomAttributes (non-standard since is returning constructor arguments rather than class instance) methods should be added to reflection classes. An ICustomAttributeProvider interface (with IsDefined and __GetCustomAttributes methods) would be very useful as well. Agreed. Marek Safar wrote: I am not sure I follow here, CustomAttributeData exists because they behave very differently to ICustomAttributeProvider. Why would you unify them? CustomAttributeData is not just the data store, it's methods are the only public API to obtain custom attributes (using the provider design pattern). ICustomAttributeProvider name can be retained because IsDefined is totally compatible while using __GetCustomAttributes marks that it is non-standard. I belive that pseudo custom attributes and unmanaged resource generation does not fit well to the concept of System.Reflection.Emit. I kind of agree. I will add a mode to disable them and add specific __ methods to do the equivalent. I am not that convinced, everyone writing non-trivial app will have to deal with them in some way. My bad. I should have say that unmanaged resource generation does not well fit to the concept of AssemblyBuilder. There should be a better unmanaged resource generation class that fits System.Reflection.Emit better. The best example is that Mono's SRE has hack for unmanaged resource generation in compiler context mode. After reading both of your responses I belive that pseudo custom attributes is not that harmful but there should be SetCustomAttribute methods (on each SRE class that supports custom attributes) that treats pseudo custom attributes like a compiler does, and a variant that just emits all the attributes. Maybe there should be three modes: - processing all pseudo custom attributes - emitting all of them as custom attributes - MS.NET compatible Kornél ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, Thanks for the IKVM.Reflection patches. I have a few questions about some of the changes. - Why are the various _SetAttributes methods and the AssemblyBuilder.__SetName() methods necessary? - Do you really need blob encoded pseudo custom attributes in the version info? I intentionally don't suppor that (and also include the attributes as regular attributes) to be compatible with .NET - Why are all the stack height asserts commented out in ILGenerator, do you think they are wrong? Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Tuesday, May 04, 2010 2:03 PM To: mono-devel Cc: Miguel de Icaza; Marek Safar; Jeroen Frijters Subject: Porting mcs to IKVM.Reflection Hi, Inspired by http://tirania.org/blog/archive/2010/Apr-27.html I gave a try to port mcs to IKVM.Reflection. I addition to being able to have a single binary, mcs could run on MS.NET and we would not have to break MS.NET compatibility in System.Reflection. I've attached some work in progress patches both for mcs and IKVM.Reflection. I was impressed by the result that mcs is able to bootstrap itself, compile mscorlib.dll and its other requirements, and the resulting mcs is able to compile a bunch of Mono assemblies. Missing features: - security attributes - embedded resources - .netmodule support - debug info Also note that I was unable to figure out what MakeExpression methods are supposed to do but I had to disable them because they need System.Reflection types. mcs pathes are licensed under the MIT/X11 license. IKVM.Reflection patches are licensed under the zlib license. Kornél ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Porting mcs to IKVM.Reflection
Hi, mcs creates an assembly, then creates types, and only after that is processing the custom attributes. This is how attributes and even assembly name (not the name part) can change after definition. Although there are some other self referencing cases, this order of creation/definition is required especially when building mscorlib.dll. At least some cases of these requirements could be eliminated by doing dependency analysis but there is no use to introduce extra complexity when the solution is very simple. All of these functions are implemented as hacks in Mono's System.Reflection.Emit. Blob encoded pseudo custom attributes are supported by Mono. I've added decoding because they weren't ignored, exceptions were thrown instead. I think that the only problem is that I've removed the exception when emitting backward jumps but since things were working so far, I haven't tried to resove that issue yet. (This is a work-in-progress state.) Unlike Java, C# has support for backward jumps, so does System.Reflection.Emit so support for that will have to be implemented. Some notes on IKVM.Reflection: First of all, thank you very much for creating it, since it's very unique. Based on your questions I belive that you are trying to remain compatible with MS.NET. This good, because both IKVM and mcs has a dynamic mode that is generating code for direct execution that requires System.Reflection.Emit. And to some extent enables IKVM.Reflection to be a drop-in replacement for System.Reflection.Emit on runtimes that have no built-in support. I on the other hand belive that removing arbitrary limitations of System.Reflection.Emit (like preventing access to TypeBuilder's member-builders), and adding missing functionality would make sense. Mono.Cecil is a great tool but it targets tools operating on metadata rather and is too abstract and complex for compilers. It also has a larger memory footprint. So I belive that there is a need for IKVM.Reflection as a replacement for MS.NET's System.Reflection.Emit as well. I also like the concept of having a Universe since that makes possible to have multiple compiler instances in the same AppDomain. I belive that pseudo custom attributes and unmanaged resource generation does not fit well to the concept of System.Reflection.Emit. I would rather remove support for both of these and introduce __methods for setting metadata that currently is built from pseudo custom attributes. Unmanaged resource generation could be automated (and customized) by using a dedicated class. This would be much faster than encoding (either binary or just the constructor arguments) and then decoding pseudo custom attributes. I also belive that CustomAttributeData should not be used as a provider, __GetCustomAttributes (non-standard since is returning constructor arguments rather than class instance) methods should be added to reflection classes. An ICustomAttributeProvider interface (with IsDefined and __GetCustomAttributes methods) would be very useful as well. As a conclusion I would be happy to see features (that make sense) in IKVM.Reflection.Emit that are not present in System.Reflection.Emit. Kornél Jeroen Frijters wrote: Hi, Thanks for the IKVM.Reflection patches. I have a few questions about some of the changes. - Why are the various _SetAttributes methods and the AssemblyBuilder.__SetName() methods necessary? - Do you really need blob encoded pseudo custom attributes in the version info? I intentionally don't suppor that (and also include the attributes as regular attributes) to be compatible with .NET - Why are all the stack height asserts commented out in ILGenerator, do you think they are wrong? Thanks, Jeroen -Original Message- From: Kornél Pál [mailto:kornel...@gmail.com] Sent: Tuesday, May 04, 2010 2:03 PM To: mono-devel Cc: Miguel de Icaza; Marek Safar; Jeroen Frijters Subject: Porting mcs to IKVM.Reflection Hi, Inspired by http://tirania.org/blog/archive/2010/Apr-27.html I gave a try to port mcs to IKVM.Reflection. I addition to being able to have a single binary, mcs could run on MS.NET and we would not have to break MS.NET compatibility in System.Reflection. I've attached some work in progress patches both for mcs and IKVM.Reflection. I was impressed by the result that mcs is able to bootstrap itself, compile mscorlib.dll and its other requirements, and the resulting mcs is able to compile a bunch of Mono assemblies. Missing features: - security attributes - embedded resources - .netmodule support - debug info Also note that I was unable to figure out what MakeExpression methods are supposed to do but I had to disable them because they need System.Reflection types. mcs pathes are licensed under the MIT/X11 license. IKVM.Reflection patches are licensed under the zlib license. Kornél ___ Mono-devel-list mailing list