# Tuesday, 24 January 2012
New Development Snapshot

Time for a new snapshot. Not too many changes, but the IKVM.Reflection API changes should suggest what I've been working on.


  • Updated version to 7.1.4406.0.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • When constructing a generic class loader we can't use GetWrapperFromType() on the type arguments, because they might refer to a subtype that is currently being loaded.
  • Made base TypeWrapper resolution lazy for compiled and .NET TypeWrappers.
  • Use modopt custom modifiers for methods instead of name mangling and NameSigAttribute.
  • Added version info resource to JVM.DLL. Modified version of patch #3472413.
  • Added version info resource to ikvm-native-win32-{arch}.dll. Modified version of patch #3472413.
  • Added support for delegates with ByRef parameters.
  • When a dynamic only interface method ends up being "implemented" by a static or non-public method, it should throw the appropriate exception.
  • When instantiating a delegate and the object passed in does not properly implement the delegate's Method interface, bind the delegate to an error stub that throws the appropriate error.
  • The right remap filename should be put in the SourceFileAttribute, instead of the last one.
  • Stack trace elements in methods in remapped .NET types should not list the source filename as map.xml.
  • IKVM.Reflection: FieldInfo.IsAssembly should test for FieldAttributes.Assembly access, not FieldAttributes.Family.
  • IKVM.Reflection: Added Module.__FileAlignment property.
  • IKVM.Reflection: Added ManifestResourceInfo.__Offset property.
  • IKVM.Reflection: Avoid the need for (expensive) ResolveMethod call when emitting debug symbols. Thanks to Miguel Garcia for pointing this out.
  • IKVM.Reflection: Add AssemblyName.__Hash property (to expose the hash in an AssemblyRef).
  • IKVM.Reflection: Added Module.__EntryPointRVA and Module.__EntryPointToken properties.
  • IKVM.Reflection: Added MethodBase.__MethodRVA property.
  • IKVM.Reflection: Fixed regression introduced with AssemblyName rewrite. The AssemblyName returned from __GetReferencedAssemblies() should include an empty public key token if the referenced assembly is not strong named.
  • IKVM.Reflection: API change. Allow Type.MetadataToken to be called on missing type (it will return 0 or the token hint when the type was forwarded).
  • IKVM.Reflection: Added Universe.ResolveType() API that can be used to construct missing types.
  • IKVM.Reflection: Fixed various Module.Resolve* methods to throw proper exception when wrong metadata token is supplied.
  • IKVM.Reflection: Fixed type parameter binding for missing types.
  • IKVM.Reflection: Added Module.__EnumerateCustomAttributeTable() API.
  • IKVM.Reflection: Removed Module.__GetDeclarativeSecurityFor() API.
  • IKVM.Reflection: Added CustomAttributeData.__Parent API.
  • IKVM.Reflection: Added Module.__ImageRuntimeVersion API.

Binaries available here: ikvmbin-7.1.4406.zip

Tuesday, 24 January 2012 13:48:53 (W. Europe Standard Time, UTC+01:00)  #    Comments [3]
# Tuesday, 03 January 2012
IKVM.NET 7.0 Update 1 Release Candidate 0

A couple of annoying bugs have been reported since 7.0 was released, so I decided to do an update.


  • Changed version to 7.0.4335.1.
  • FileStore for non-accessible drive should throw exception when trying to create the FileStore, not when accessing the name() or type() properties.
  • Graphics2D.clip(null) should only throw NPE for a Component graphics.
  • Don't crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • Informational messages should not be treated as error when -warnaserror is specified. Fix for #3443377.
  • Don't enforce pre-1.5 class name rules in ikvmc (since HotSpot doesn't enforce any naming rules for classes loaded by the system (and boot) class loader, by default). Fix for #3443373.
  • Fix for #3441959.
  • Throwable.addSuppressed() didn't have a proper parameter name.
  • Mark getSpace0 with SecuritySafeCritical to avoid getting an exception with .NET 4
  • Bug fix. Removed incorrect check for uninitialized objects on backward branch.
  • Don't crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Added AssemblyInformationalVersionAttribute to OpenJDK assemblies (to set the "Product Version"). Part of patch #3458997.
  • Include copyright and metadata in IKVM.OpenJDK.Tools.dll. Part of patch #3458997.
  • Bug fix. Don't call Finish on unloadable TypeWrapper.
  • Bug fix. When constructing a generic class loader we can't use GetWrapperFromType() on the type arguments, because they might refer to a subtype that is currently being loaded.
  • Fix. When decoding a NameSigAttribute it is possible that a type does not exist (i.e. is an unloadable) and that results in a warning emitted against the referenced assemblies class loader.
  • Suppress annotation custom attributes when enumerating inner classes.
  • IKVM.Reflection: Bug fix. FieldInfo.IsAssembly should test for FieldAttributes.Assembly access, not FieldAttributes.Family.

Binaries available here: ikvmbin-7.0.4335.1.zip

Sources: ikvmsrc-7.0.4335.1.zip, openjdk7-b147-stripped.zip

Tuesday, 03 January 2012 13:24:44 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Wednesday, 21 December 2011
IKVM.NET 0.46 Update 1 Release Candidate 0

IKVM.NET 0.46 is the last OpenJDK 6 based release, so it will be supported longer than usual. I haven't yet decided how long exactly, but in any case here is a release candidate for an update release that incorporates many of the fixes that have been done since 0.46 was released.


  • Changed version to
  • Bug fix. TypeWrapper.IsAssignableTo() didn't handle arrays with primitive elements properly.
  • Bug fix. Exception blocks inside potential try { } finally { } blocks were not handled correctly. Could result in finally blocks that run multiple times (when an exception occurs).
  • Fix for #3404229.
  • Bug fix. Don't create a miranda method if the class already has a static method with the same signature.
  • Added workaround for another x64 JIT bug. See https://sourceforge.net/mailarchive/message.php?msg_id=28250469
  • Newer versions of ICSharpCode.SharpZipLib.dll require the ZipEntry size to be set explicitly, otherwise the generated archive will not be compatible with older zip implementations (like Java 6's java.util.zip).
  • Fixed serialization interop bugs.
  • Bug fix. When an abstract .NET type implements System.IComparable (and hence java.lang.Comparable) the resulting stub is not usable from Java because the compareTo method is missing. This fix adds the missing method.
  • Fix and enhancement. When a .NET type implements a shadowed interface, we now also publish the original interface (e.g. if the .NET type implements System.IComparable, Java code will now see java.lang.Comparable and System.IComparable). In addition, the new code makes sure that when a .NET type explicitly implements both System.IComparable and java.lang.Comparable that the Java code will not see java.lang.Comparable twice.
  • Bug fix. Make FileOutputStream in append mode always append.
  • Add support for overriding constructor body in map.xml.
  • Make sure that Thread.getContextClassLoader() and Thread.setContextClassLoader() are JITed before Thread.isCCLOverridden().
  • Workaround .NET 2.0 bug in GetType() that could cause problems with creating proxies for compiled types.
  • Bug fix. Exceptions declared with ThrowsAttribute(Type) (in .NET code) did not get exported properly by ikvmstub.
  • Fix ClassLoader.findLoadedClass0() to handle null string.
  • Implemented support for annotation defaults in ikvmstub.
  • Bug fix. Final instance fields that have a type 2 access property should also have a (private) setter for reflection and serialization.
  • Bug fix. Set os.name and os.version properties correctly when running on unknown Windows version (Windows 8).
  • Bug fix. IPInterfaceProperties.GetIPv_Properties() can throw an exception (and does so on Win 8 for some interfaces).
  • Don't open the remap file in read/write mode.
  • Bug fix. Make sure sun.misc.Launcher is initialized before setting a security manager, because Launcher assumes there is no security manager yet.
  • Implemented com.sun.security.auth.module.NTSystem.getCurrent().
  • Bug fix. When calling a final method on a remapped type we can't call the instance method in the remapped type, but we have to call the instancehelper instead.
  • Fix. When decoding a NameSigAttribute it is possible that a type does not exist (i.e. is an unloadable) and that results in a warning emitted against the referenced assemblies class loader.
  • Bug fix. Removed incorrect verifier check for uninitialized objects on backward branch.
  • Handle Main-Class manifest value that spans multiple lines. Fix for bug #3461012.
  • Retain reflection field ordering for ikvmc compiled code (not required by spec, but to improve compatibility with broken code).
  • Don't use "slow path" for field reflection on remapped types (as getting a Throwable field from cli.System.Exception will cause an exception, but the slow path will generate a different exception).
  • Backported the new method override resolution code.

Binaries available here: ikvmbin-

Sources: ikvmsrc-, openjdk6-b22-stripped.zip

Wednesday, 21 December 2011 09:54:46 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Monday, 19 December 2011
Accessibility, Visibility and Transparency

There are a couple of subtle differences between the JVM and CLR with respect to member accessibility. For example, the JVM will allow you to access public members in non-public base classes:

package p1;

class Base {
    public int foo;

public class Derived extends Base {

package p2;

class Test {
    public static void main(String[] args) {
       p1.Derived d = new p1.Derived();
       d.foo = 42;

If you compile p1 and p2 seperately with ikvmc and look inside the resulting assemblies, you'll see that ikvmc generated a foo property in Derived. It needs to do this, because the CLR won't allow code from another assembly to access the members of Base.

In the IKVM source code this type of access stubs is known as type 1. As you'd expect there are also type 2 access stubs. These are generated when a public (or protected) member exposes a non-public type:

package p1;

class Foo { }

public class Bar {
  public Foo field = new Foo();

package p2;

class Test {
    public static void main(String[] args) {
       p1.Bar b = new p1.Bar();
       b.field = null;

Once again, if you compile p1 and p2 into separate assemblies with ikvmc, you'll see that field will be accessed through a property. In this case the property type is erased to the first public base type and a custom modifier is attached to make sure the property signature is unique (and to be able to recover the real type).

These type 2 access stubs were originally generated (in some cases) by ikvmc to support accessing these members from C#, because the CLR, like the JVM, doesn't care about the visibility of the types in a signature when it considers member accessibility.

However, since .NET 4.0 there is a new factor to consider, when level 2 transparent code  tries to access a member, the types in the member signature (except for the custom modifiers) must all be visible to the caller.

I have not seen this last fact documented anywhere yet.

Monday, 19 December 2011 11:57:13 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Friday, 16 December 2011
New Development Snapshot

I've been doing some cleanup and refactoring and in the process removed some limitations and fixed a bunch of corner cases.


  • Updated version to 7.1.4366.0.
  • Fixed Class.getDeclaredClasses() to throw correct exception when one on the inner classes cannot be loaded.
  • Removed class name length limitation.
  • Split ikvmc compilation into three passes to support classes that extend a class nested inside itself.
  • Include copyright and metadata in IKVM.OpenJDK.Tools.dll. Part of patch #3458997.
  • Added AssemblyInformationalVersionAttribute to OpenJDK assemblies (to set the "Product Version"). Part of patch #3458997.
  • When casting arguments we should use the actual method parameter types, instead of the call site types (which can differ in the case of unloadable types (with crazy class loader trickery)).
  • Unloadable types can't violate loader constraints.
  • Made override stub generation more consistent.
  • Generate override stub for miranda method, when necessary.
  • Fixed ikvcm to not crash when ikvmc -resource: or -externalresource: option doesn't contain an = sign.
  • Fixed unloadable corner case (that can only be generated by playing weird class loader tricks).
  • Verifier bug fix. Removed incorrect check for uninitialized objects on backward branch.
  • IKVM.Reflection: Support setting an invalid culture using AssemblyBuilder.__SetAssemblyCulture().
  • IKVM.Reflection: AssemblyCultureAttribute should not influence the LCID of the version info resource.
  • IKVM.Reflection: Removed static Create() from __StandAloneMethodSig and added Universe.MakeStandAloneMethodSig().

Binaries available here: ikvmbin-7.1.4366.zip

Friday, 16 December 2011 10:07:11 (W. Europe Standard Time, UTC+01:00)  #    Comments [1]
# Monday, 05 December 2011
IKVM.NET 7.0 Released

I've released IKVM.NET 7.0 to SourceForge. The binaries are identical to the ones in release candidate 0.

Release Notes

This document lists the improvements, known issues and incompatibilities.

What's New (relative to IKVM.NET 0.46):

  • Integrated OpenJDK 7 b147.
  • Implemented Java 7 JVM changes.
  • Java annotations on statically compiled code are now returned as java.lang.reflect.Proxy objects for compability with broken code that assumes this is always the case.
  • Added delegate conversion for java.lang.reflect.InvocationHandler to ikvm.runtime.Delegates.
  • Various remap file improvements.
  • Changed build and JNI code to use different names for the Windows x86 and x64 versions of the native dll.
  • Retain reflection field ordering for ikvmc compiled code (not required by spec, but to improve compatibility with broken code).
  • Various AWT fixes.
  • Interop between java.lang.AutoCloseable and System.IDisposable.
  • Various build system improvements.
  • Added ikvmc -warnaserror option.
  • Fixed java.io.FileOutputStream in append mode to use atomic append.
  • Various performance improvements.
  • Added -Xnoglobbing option to ikvm.exe.
  • Various minor fixes.
  • Implemented dual stack sockets (Windows Vista and up only).
  • Implemented platform MBean server.
  • Implemented SocketChannel.sendOutOfBandData().
  • Implemented DatagramChannel multicast methods.
  • Removed mapping of System.Security.VerificationException to java.lang.VerifyError.
  • IKVM.Reflection: Massive enhancements to support a very large portion of the managed PE capabilities (much more than System.Reflection.Emit).


  • Code unloading (aka class GC) is not supported.
  • In Java static initializers can deadlock, on .NET some threads can see uninitialized state in cases where deadlock would occur on the JVM.
  • JNI
    • Only supported in the default AppDomain.
    • Only the JNICALL calling convention is supported! (On Windows, HotSpot appears to also support the cdecl calling convention).
    • Cannot call string contructors on already existing string instances
    • A few limitations in Invocation API support
      • The Invocation API is only supported when running on .NET.
      • JNI_CreateJavaVM: init options "-verbose[:class|:gc|:jni]", "vfprintf", "exit" and "abort" are not implemented. The JDK 1.1 version of JavaVMInitArgs isn't supported.
      • JNI_GetDefaultJavaVMInitArgs not implemented
      • JNI_GetCreatedJavaVMs only returns the JavaVM if the VM was started through JNI or a JNI call that retrieves the JavaVM has already occurred.
      • DestroyJVM is only partially implemented (it waits until there are no more non-daemon Java threads and then returns JNI_ERR).
      • DetachCurrentThread doesn't release monitors held by the thread.
    • Native libraries are never unloaded (because code unloading is not supported).
  • The JVM allows any reference type to be passed where an interface reference is expected (and to store any reference type in an interface reference type field), on IKVM this results in an IncompatibleClassChangeError.
  • monitorenter / monitorexit cannot be used on unitialized this reference.
  • Floating point is not fully spec compliant.
  • A method returning a boolean that returns an integer other than 0 or 1 behaves differently (this also applies to byte/char/short and for method parameters).
  • Synchronized blocks are not async exception safe.
  • Ghost arrays don't throw ArrayStoreException when you store an object that doesn't implement the ghost interface.
  • Class loading is more eager than on the reference VM.
  • Interface implementation methods are never really final (interface can be reimplemented by .NET subclasses).
  • JSR-133 finalization spec change is not fully implemented. The JSR-133 changes dictate that an object should not be finalized unless the Object constructor has run successfully, but this isn't implemented.
  • Strict class-file checking is not implemented.

Static Compiler (ikvmc)

  • Some subtle differences with ikvmc compiled code for public members inherited from non-public base classes (so called "access stubs"). Because the access stub lives in a derived class, when accessing a member in a base class, the derived cctor will be run whereas java (and ikvm) only runs the base cctor.
  • Try blocks around base class ctor invocation result in unverifiable code (no known compilers produce this type of code).
  • Try/catch blocks before base class ctor invocation result in unverifiable code (this actually happens with the Eclipse compiler when you pass a class literal to the base class ctor and compile with -target 1.4).
  • Only code compiled together during a single compilation fully obeys the JLS binary compatibility rules.

Class Library

Most class library code is based on OpenJDK 7 build 147. Below is a list of divergences and IKVM.NET specific implementation notes.

com.sun.security.auth.module        Not supported.
java.applet Not implemented.
java.awt Partial System.Windows.Forms based back-end. Not supported.
java.io.Console Not implemented.
java.lang.instrument Not implemented.
java.lang.management Limited implementation.
java.net SCTP and SDP not implemented.
java.net.ProxySelector Getting the default system proxy for a URL is not implemented.
java.nio.file Most optional features (e.g. ACLs) are not implemented.
java.text.Bidi Not supported.
java.util.zip Partially based on GNU Classpath implementation.
javax.crypto ECC is not implemented.
javax.imageio.plugins.jpeg Partial implementation. JPEGs can be read and written and there is limited metadata support.
javax.management Limited implementation.
javax.print There is a Win32 specific printing implementation. Not supported.
javax.script ECMAScript implementation is not included.
javax.smartcardio Not implemented.
javax.sound Not implemented.
javax.swing Not supported.
javax.tools Not supported.
org.ietfs.jgss Not implemented.
sun.jdbc.odbc Implementation based on .NET ODBC managed provider.
sun.net.www.content.audio Audio content handlers not implemented.
sun.net.www.content.image Not supported.

The entire public API is available, so "Not implemented." for javax.smartcardio, for example, means that the API is there but there is no back-end to provide the actual smartcard communication support. "Not supported." means that the code is there and probably works at least somewhat, but that I'm less likely to fix bugs reported in these areas, but patches are welcome, of course.

Specific API notes:

  • java.lang.Thread.stop(Throwable t) doesn't support throwing arbitrary exceptions on other threads (only java.lang.ThreadDeath).
  • java.lang.Thread.holdsLock(Object o) causes a spurious notify on the object (this is allowed by the J2SE 5.0 spec).
  • java.lang.String.intern() strings are never garbage collected.
  • Weak/soft references and reference queues are inefficient and do not fully implement the required semantics.
  • java.lang.ref.SoftReference: Soft references are not guaranteed to be cleared before an OutOfMemoryError is thrown.
  • Threads started outside of Java aren't "visible" (e.g. in ThreadGroup.enumerate()) until they first call Thread.currentThread().
  • java.lang.Thread.getState() returns WAITING or TIMED_WAITING instead of BLOCKING when we're inside Object.wait() and blocking to re-acquire the monitor.
  • java.nio.channel.FileChannel.lock() shared locks are only supported on Windows NT derived operating systems.
  • java.lang.SecurityManager: Deprecated methods not implemented: classDepth(String), inClass(String), classLoaderDepth(), currentLoadedClass(), currentClassLoader(), inClassLoader()

Supported Platforms

This release has been tested on the following CLI implementations / platforms:

CLI Implementation       Architecture      Operating System
.NET 2.0 SP2 x86 Windows
.NET 2.0 SP2 x64 Windows
.NET 4.0 x86 Windows
.NET 4.0 x64 Windows

Partial Trust

There is experimental support for running in partial trust.

Monday, 05 December 2011 07:56:27 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Friday, 02 December 2011
Function Pointer Types

In today's snapshot I also added support for function pointer types. The CLI supports both managed and unmanaged function pointer types, however both are unverifiable.

Here's a small C++/CLI example of using a managed function pointer type (in the call method signature):

void func() {
  System::Console::WriteLine("Hello from Func");

void call(void (*p)()) {

void main() {

Compile this with cl /clr:pure test.cpp and the resulting test.exe will be a managed PE file with these three methods (and a lot of other junk).

Here's an IKVM.Reflection example to create an equivalent foo.exe (without the extra junk):

using System;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type;

class Program {
  public static void Main() {
    var u = new Universe();
    var ab = u.DefineDynamicAssembly(new AssemblyName("Foo"), AssemblyBuilderAccess.Save);
    var modb = ab.DefineDynamicModule("Foo", "Foo.exe");
    var mb2 = modb.DefineGlobalMethod("func", MethodAttributes.Static, null, null);
    var ilgen = mb2.GetILGenerator();
    ilgen.EmitWriteLine("Hello from Func");
    Type func = u.MakeFunctionPointer(u.MakeStandAloneMethodSig(CallingConventions.Standard, null, default(CustomModifiers), null, null, null));
    var mb3 = modb.DefineGlobalMethod("call", MethodAttributes.Static, null, new Type[] { func });
    ilgen = mb3.GetILGenerator();
    ilgen.__EmitCalli(OpCodes.Calli, func.__MethodSignature);
    var mb1 = modb.DefineGlobalMethod("main", MethodAttributes.Static, null, null);
    ilgen = mb1.GetILGenerator();
    ilgen.Emit(OpCodes.Ldftn, mb2);
    ilgen.Emit(OpCodes.Call, mb3);

(I should point out that this won't work with today's snapshot, because while writing this I discovered that I had incorrectly added a static Create() method to __StandAloneMethodSig, but that should instead be an instance method on Universe.)

Friday, 02 December 2011 09:43:53 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
Custom Modifiers

As I wrote earlier today, the theme of today's snapshot is custom modifiers, but I decided to expand a bit on that, since they are a relatively unknown feature of .NET.

In the early days of IKVM.NET I ran into the problem that some Java types must be erased in .NET signatures. An example are arrays of what I call ghost types. Fortunately these are not very common, but here's an example method:

void foo(CharSequence[] array) { }

When this is compiled with ikvmc, you end up with something like this:

[NameSig("foo", "([Ljava.lang.CharSequence;)V")]
void foo(object[] array) { }

If the class happened to already have a foo method with that signature, the method name would be mangled with a numerical suffix (e.g. foo_0).

Now, instead of adding a custom attribute and using name mangling, .NET has a much better solution for this. Custom modifiers, but unfortunately you couldn't use them via .NET's System.Reflection.Emit API back in the .NET 1.x days.

When .NET 2.0 came around they added (some) support for custom modifiers, but it both had some issues and by then I already had a working solution, so there was not much need for changing the implementation. The one exception was in constructor signatures, since there you cannot mangle the method name, you have to rely on the signature types to make the signature unique, so there I did add custom modifiers when necessary to make sure the signatures are unique.

In today's snapshot I've changed fields and constructors to always use custom modifiers (when necessary) and removed the usage of the NameSigAttribute. Methods still need to be done.

Here's an example with two constructors that end up with the same signatures:

public class Test {
  public Test(Object obj) { }
  public Test(cli.System.Object obj) { }

When you compile this with ikvmc, you get something like this:

public class Test {
  public Test(object obj) { }
  public Test(object modopt(object) obj) { }

The modopt(object) construct here stands for an optional custom modifier of type object. When this class is encountered by IKVM (reflection or ikvmc) it can recover the original Java types based on the signature and custom modifier. When you use this class from C#, the C# compiler will prefer the constructor without the custom modifier, so you can still use the class. The cli.System.Object overload is not useable from C#, but when there is no signature conflict, C# will also allow you to use the version with the custom modifier. So it allows for nice cross language interop (especially given how unlikely all these scenarios are).

As I said, I haven't done methods yet, but I did experiment a little to see if C# interop would work. I was especially concerned about overriding/implementing methods with a custom modifier in the signature, but the .NET C# compiler supports this pretty well. The Mono C# compiler does not yet have support for this. Only when you have two or more abstract methods with the same signature, you can run into a problem. For base classes with "duplicate" abstract methods, the C# compiler will not allow you to subclass that class, but you can implement interfaces with "duplicate" methods and in that case the C# compiler will emit bridge methods for all signatures that call into your (necessarily) single implemenation method.

Crazy Stuff

With the new IKVM.Reflection custom modifier support, you can now generate signatures that cannot be generated with System.Reflection.Emit. Here's an example of interleaved required and optional custom modifiers:

var u = new Universe();
var ab = u.DefineDynamicAssembly(new AssemblyName("Foo"), AssemblyBuilderAccess.Save);
var modb = ab.DefineDynamicModule("Foo", "Foo.dll");
var tb = modb.DefineType("FooType", TypeAttributes.Public | TypeAttributes.Abstract);
CustomModifiersBuilder mods = new CustomModifiersBuilder();
var mb = tb.DefineMethod("M", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.NewSlot | MethodAttributes.Virtual);
mb.__SetSignature(null, new CustomModifiers(), new Type[] { u.Import(typeof(int)) }, new CustomModifiers[] { mods.Create() });

The resulting FooType in Foo.dll contains a method M that cannot be called (or overridden) by System.Reflection.Emit generated code. It also can't be used from C#,  but that is by design, the C# compiler will not allow you to use any members that have required custom modifiers that it doesn't understand (I think that the only required custom modifier that it understands is IsVolatile on fields).

Of course, IKVM itself is not very good about dealing with custom modifiers yet. It only understands its own custom modifiers, but can get confused when accessing other .NET code with custom modifiers.

Friday, 02 December 2011 08:57:09 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
New Development Snapshot

The theme of this snapshot is custom modifiers. I've been working on ikvmc to make more use of custom modifiers for fields and constructors that have "special" types in their signatures and on the IKVM.Reflection side I completly rewrote custom modifier handling (unrelated to ikvmc) to allow roundtripping C++/CLI files (minus the unmanaged bits, obviously) and support interleaved modreq and modopt sequences.


  • Updated version to 7.1.4352.0.
  • Fixed dynamic mode with class GC enabled to automatically add required InternalsVisibleToAttribute to the dynamic assemblies.
  • Greatly improved access stub generation. Fixed many related bugs.
  • Fixed ikvmc exception when decoding NameSigAttribute with missing type.
  • Added ikvm.runtime.Util.getClassFromTypeHandle() overload for classes that represent arrays of remapped .NET types and .NET primitives.
  • Instead of mangling field names and using NameSigAttribute, we now use modopt to modify the signature and record the real type.
  • Removed legacy remap feature that allowed final fields as properties to be defined (long time ago this was used for the System.in/out/err fields).
  • Fixed Graphics2D.clip(null) to not throw an exception for bitmap and print graphics.
  • Fixed java.nio.file.FileStore for non-accessible drive to throw exception when trying to create the FileStore, not when accessing the name() or type() properties.
  • Stop mangling property names for access stubs (instead we rely on custom modifiers to make them unique).
  • Stop mangling property accessor method names, but use a custom modifier instead.
  • Generate access stubs for final fields (when -strictfinalfieldsemantics isn't specified).
  • Fixed ikvmc to not treat informational messages as error when -warnaserror is specified. Fix for #3443377.
  • Changed ikvmc to not enforce pre-1.5 class name rules (since HotSpot, by default doesn't enforce any naming rules for classes loaded by trusted class loaders). Fix for #3443373.
  • Relax dynamic mode class name validation for trusted class loaders.
  • Implemented NetToolkit.isModalExclusionTypeSupported() (by always returning false). Fix for #3441959.
  • Added extension methods for (almost) all instance methods in Object, String and Throwable to ikvm.extensions.ExtensionMethods.
  • Added ObsoleteAttribute to instancehelper_ methods in remapped types (with a message saying that the extension methods should be used).
  • Added parameter name to Throwable.addSuppressed() in map.xml.
  • Added -Xverify option to ikvm.exe.
  • Use custom modifiers (instead of NameSigAttribute) for constructors with mangled types.
  • When a member with unloadable types in its signature is exposed via reflection, the unloadable types should be resolved to actual types.
  • Mark getSpace0 with SecuritySafeCritical to avoid getting an exception with .NET 4.0 build.
  • IKVM.Reflection: Rewrote custom modifier handling to retain ordering.
  • IKVM.Reflection: Added ConstructorInfo.__ReturnParameter to expose custom modifiers.
  • IKVM.Reflection: Added __GetCustomModifiers() to various *Info types.
  • IKVM.Reflection: Added CustomModifiers type to encapsulate a custom modifier sequence.
  • IKVM.Reflection: Added CustomModifiersBuilder to create a CustomModifiers sequence.
  • IKVM.Reflection: Marked a number of IKVM.Reflection specific methods Obsolete, because they are replaced with method that take CustomModifiers value(s).
  • IKVM.Reflection: Added support for function pointer types.
  • IKVM.Reflection: Added support for custom modifiers to StandAloneMethodSig.
  • IKVM.Reflection: Added custom modifier support in local variable signatures.
  • IKVM.Reflection: Fixed SignatureHelper to support custom modifiers in method signatures.
  • IKVM.Reflection: Added new overload of __ResolveOptionalParameterTypes() that supports resolving generic type parameters and custom modifiers.

Binaries available here: ikvmbin-7.1.4352.0.zip

Friday, 02 December 2011 07:49:54 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Tuesday, 15 November 2011
New Development Snapshot

Hot on the heels of the 7.0 release candidate, the first development snapshot of 7.1. The most visible change is a new feature. The ikvm.lang.DllExport annotation to export static methods as unmanaged entry points.

Here's a crazy example:

import ikvm.lang.DllExport;
import cli.System.Runtime.InteropServices.DllImportAttribute;

public class test {
  @DllExport(name = "Foo", ordinal = 42)
  static void Dummy() {
    System.out.println("Hello World");

  static native void Foo();

  public static void main(String[] args) {

Compile as follows:

ikvmstub mscorlib
javac -cp \ikvm\lib\ikvm-api.jar;mscorlib.jar test.java
ikvmc test.class -r:mscorlib -platform:x86

The DllExport annotation only works when you explicitly specify -platform:x86 or -platform:x64. In the future ARM will also be supported, but I'll need to have an ARM Windows 8 system first. Since it emits an unmanaged entry point, the resulting assembly is a platform specific mixed assembly.


  • Updated version to 7.1.4336.0.
  • Added ikvmc warnings for referencing non-primary assembly in shared class loader group and duplicate references.
  • Removed ikvmc -platform:Itanium option.
  • Added ikvm.lang.DllExport annotation to export static methods as unmanaged exports.
  • Implemented a different pinning scheme for GetPrimitiveArrayCritical() that tolerates broken code that passes back the wrong pointer to Release. Should also perform better in most cases. GetStringCritical() now also pins instead of copies. Note that we intentionally ignore the mode parameter in ReleasePrimitiveArrayCritical() as HotSpot does the same.
  • Added include stdarg.h to jni.h make the header file compile by itself.
  • Added JNI_TRUE and JNI_FALSE to jni.h.
  • IKVM.Reflection: Fixed various assembly name parsing bugs in managed Fusion CompareAssemblyIdentity.
  • IKVM.Reflection: Re-implemented (most of) AssemblyName without dependency on System.Reflection.AssemblyName.

Binaries available here: ikvmbin-7.1.4336.zip

Tuesday, 15 November 2011 07:25:45 (W. Europe Standard Time, UTC+01:00)  #    Comments [1]