Java Backend
Ehc
Note: this information is now included in the source tree in text/InternalDocJazy.cltex, so this page is really obsolete.
Java Backend
IO
To do IO, the UHC standard library relies on C code which is called through the Haskell FFI. To make IO work in the Java backend without rewriting large parts of the standard library, we have two options:
- Use the Java Native Interface (JNI) to call the C code that's also used by the other backends. This is described below.
- Re-implement the foreign functions necessary (but not the Haskell functions using them) in Java. This is what we decided to do in UHC (as of 2010/04/20).
Using JNI for IO
To do this, we need to do the following things:
- globally:
- Emulate pointers in Java.We can't use real C pointers because JNI does not support "pinning" memory, and pointers become invalid after a native method call return.
- Compile the C code used to a dynamically-linked library.
- Load the library at runtime, using System.load(..) or System.loadLibrary(..).
- for each function:
- Write a wrapper method in Java.
- Declare a native method in Java.
- Write a wrapper function in C that calls the C function doing the real work.
As an example, here's the code needed for the
write function. This assumes that there is a class uu.jazy.ehc.NativeMethods containing the native method declarations.
- in src/jazy/uu/jazy/ehc/Prim.java:
public static Object write(int fd, int buf, int count) {
byte[] array = (byte[])pointers.dereference(buf);
int result = nativeMethods.write(fd, array, count);
return ioReturn(new Integer(result));
}
- in src/jazy/uu/jazy/ehc/NativeMethods.java:
public native int write(int fd, byte[] buf, int count);
- in C code:
JNIEXPORT jint JNICALL Java_uu_jazy_ehc_NativeMethods_write(
JNIEnv *env, jobject obj, jint fd, jbyteArray buf, jint count) {
jbyte *ptr = (*env)->GetPrimitiveArrayCritical(env, buf, 0);
int result = write(fd, ptr, count);
(*env)->ReleasePrimitiveArrayCritical(env, buf, ptr, 0);
return result;
}