A fairly massive set of changes this time, mostly around .NET 4.0 suport and IKVM.Reflection fixes.
Targetting .NET 4.0
Please note that the work isn't done yet (in particular, I haven't checked in all the changes required for the .NET 4.0 security model), but it is now possible to build assemblies with ikvmc that target and reference .NET 4.0 while running ikvmc on the .NET 2.0 runtime.
C:\j>ikvmc test.class -nostdlib -lib:\windows\microsoft.net\framework\v4.0.30319 -r:mscorlib.dll
Note IKVMC0001: found main method in class "test"
Note IKVMC0002: output file is "test.exe"
Hello World, running on CLR 4.0.30319.1
Note that (like the C# compiler) you can also reference .NET 4.0 assemblies while targetting .NET 2.0, but when you run the resulting assembly on .NET 2.0 and it tries to load the .NET 4.0 assembly that will fail with a BadImageFormatException.
The algorithm that ikvmc uses to load assemblies now resembles what csc uses and does not involve the CLR anymore. The same switches are used (-nostdlib, -lib and -reference), but there are some subtle differences. The most important being that ikvmc's -nostdlib also removes the current CLR runtime directory from the search path and that the -reference option (like it always has) has a runtime consequence (because it affects class loader delegation) and the assemblies that aren't explicitly required by the code being compiled will be silently loaded from the library search path (which is: current directory, CLR directory (except if -nostdlib is specified), -lib:<dir> directories, LIB environment directories).
The above mentioned changes to assembly loading by ikvmc result in some (potential) breaking changes for build scripts. In particular, the -reference option could previously be used with a partial name (which would be resolved by the CLR with the Assembly.LoadWithPartialName() method), but this is no longer supported (to ease transitioning you can still specify the simple name of the assembly and the ikvmc assembly resolver will append ".dll" to it, but it will issue a warning about this.)
- Started implementing the various required changes for the .NET 4.0 security model. This is not finished yet, so running on .NET 4.0 with this snapshot is not yet supported.
- .NET 4.0 fix: When class GC is enabled, don't intrinsify ThreadLocal.
- .NET 4.0 support: When class GC is enabled, throw a VerifyError when custom attributes as used that aren't allowed in RunAndCollect assemblies.
- Added parameter validation to ikvmc's -version option (bug #2987144).
- Added System.Core target to build a tiny custom version of System.Core.dll that contains only System.Runtime.CompilerServices.ExtensionAttribute and will allow us to build on .NET 2.0 without having to figure out where System.Core.dll lives (or without it even being present).
- Removed lib/security/local_policy.jar from vfs.zip (because, by default, OpenJDK builds the restricted version) and instead make a vfs alias for it that points to the unrestricted US_export_policy.jar.
- Changed ikvm.runtime.Startup.setProperties() to take an IDictionary instead of Hashtable. This allows a Dictionary<string, string> to be passed in now and avoids future problems if/when we want to target Silverlight (which doesn't have System.Collections.Hashtable).
- Rewrote assembly loading for ikvmc and ikvmstub (and unified it). It now no longer depends on the runtime to do assembly name to path resolution and behaves more csc like.
- Added -nostdlib and -lib options to ikvmc and ikvmstub.
- IKVM.Reflection: Fixed stack height updating for jmp instruction.
- IKVM.Reflection: Don't crash when a DllImportAttribute doesn't have an ImportScope (which can happen for C++ code).
- IKVM.Reflection: Version parts should be treated as unsigned.
- IKVM.Reflection: Don't loop infinitely when field RVA lies outside of the file.
- IKVM.Reflection: Don't try to return a MethodBody if the method isn't in IL.
- IKVM.Reflection: Implemented ModuleRef ResolutionScope for TypeRef.
- IKVM.Reflection: Fixed type name parsing bug (thanks to Jb Evain for reporting this). Generic type parameter type names can be without assembly name and then need to be resolved in context.
- IKVM.Reflection: Added workaround for broken compiler(s) that add terminating NUL to type names in custom attribute data.
- IKVM.Reflection: Added support for custom modifiers in generic type instantions (in signatures).
- IKVM.Reflection: Having PinvokeImpl set doesn't necessarily imply having an ImplMap record (for mixed mode assemblies).
- IKVM.Reflection: Made __GetDataFromRVA more general by taking an offset and a length (to be able to reuse the byte array) and this also removes the need for the field type to have a StructLayout.
- IKVM.Reflection: A Version object that only has Major.Minor set will return -1 for Build and Revision. Handle that case by setting these parts to zero, instead of casting to 65535.
- IKVM.Reflection: Added support for delay signing (i.e. setting the public key without having the private key).
- IKVM.Reflection: Dynamic assemblies should also be visible in the universe.
- IKVM.Reflection: Fixed default assembly resolver to throw/not throw the right exceptions.
- IKVM.Reflection: Made method/field signature reading lazy. This makes building assemblies with circular dependencies easier.
- IKVM.Reflection: Fixed method signature handling of custom modifiers (required and optional were mixed up).
Binaries available here: ikvmbin-0.43.3765.zip