Blob Blame History Raw
diff -Nru jamvm-2.0.0.orig/configure.ac jamvm-2.0.0/configure.ac
--- jamvm-2.0.0.orig/configure.ac       2014-06-10 22:33:37.000000000 +0200
+++ jamvm-2.0.0/configure.ac    2018-06-03 17:23:55.719602871 +0200
@@ -32,6 +32,7 @@

 case "$host" in
 i[[3456]]86-*-linux*) host_cpu=i386 host_os=linux ;;
+i[[3456]]86-*-midipix*) host_cpu=i386 host_os=midipix ;;
 i[[3456]]86-*-kfreebsd*) host_cpu=i386 host_os=linux ;;
 i[[3456]]86-*-darwin*) host_cpu=i386 host_os=darwin ;;
 arm*-*-darwin*) host_cpu=arm host_os=darwin libdl_needed=no ;;
@@ -39,6 +40,7 @@
 i386-*-freebsd*) host_os=bsd libdl_needed=no ;;
 i386-*-solaris*) host_cpu=x86 host_os=solaris ;;
 x86_64-*-linux*) host_os=linux ;;
+x86_64-*-midipix*) host_os=midipix ;;
 hppa*-*-linux*) host_cpu=parisc host_os=linux ;;
 mips*-*-linux*) host_cpu=mips host_os=linux ;;
 x86_64-*-openbsd*) host_os=bsd libdl_needed=no ;;
@@ -397,6 +399,7 @@
     src/arch/Makefile \
     src/os/Makefile \
     src/os/linux/Makefile \
+    src/os/midipix/Makefile \
     src/os/darwin/Makefile \
     src/os/bsd/Makefile \
     src/os/solaris/Makefile \
@@ -407,6 +410,8 @@
     src/os/linux/x86_64/Makefile \
     src/os/linux/parisc/Makefile \
     src/os/linux/mips/Makefile \
+    src/os/midipix/x86_64/Makefile \
+    src/os/midipix/i386/Makefile \
     src/os/darwin/i386/Makefile \
     src/os/darwin/arm/Makefile \
     src/os/darwin/powerpc/Makefile \
diff -Nru jamvm-2.0.0.orig/src/os/Makefile.am jamvm-2.0.0/src/os/Makefile.am
--- jamvm-2.0.0.orig/src/os/Makefile.am	2012-05-17 23:01:47.000000000 +0200
+++ jamvm-2.0.0/src/os/Makefile.am	2018-06-03 17:01:50.560924958 +0200
@@ -20,5 +20,5 @@
 ##
 
 SUBDIRS = @os@
-DIST_SUBDIRS = linux darwin bsd solaris
+DIST_SUBDIRS = linux darwin bsd solaris midipix
 
diff -Nru jamvm-2.0.0.orig/src/os/midipix/i386/dll_md.c jamvm-2.0.0/src/os/midipix/i386/dll_md.c
--- jamvm-2.0.0.orig/src/os/midipix/i386/dll_md.c	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/i386/dll_md.c	2012-05-17 23:01:47.000000000 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
+ * Robert Lougher <rob@jamvm.org.uk>.
+ *
+ * This file is part of JamVM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "jam.h"
+
+#ifndef USE_FFI
+#include <string.h>
+#include "sig.h"
+
+#define RET_VOID    0
+#define RET_DOUBLE  1
+#define RET_LONG    2
+#define RET_FLOAT   3
+#define RET_BYTE    4
+#define RET_CHAR    5
+#define RET_SHORT   6
+#define RET_DFLT    7
+
+int nativeExtraArg(MethodBlock *mb) {
+    int len = strlen(mb->type);
+    if(mb->type[len-2] == ')')
+        switch(mb->type[len-1]) {
+            case 'V':
+                return RET_VOID;
+            case 'D':
+                return RET_DOUBLE;
+            case 'J':
+                return RET_LONG;
+            case 'F':
+                return RET_FLOAT;
+            case 'B':
+            case 'Z':
+                return RET_BYTE;
+            case 'C':
+                return RET_CHAR;
+            case 'S':
+                return RET_SHORT;
+        }
+
+    return RET_DFLT;
+}
+
+u4 *callJNIMethod(void *env, Class *class, char *sig, int ret_type,
+                  u4 *ostack, unsigned char *f, int args) {
+
+    int i;
+    u4 *sp;
+    u4 method_args[args + (class ? 2 : 1)];
+
+    asm volatile ("movl %%esp,%0" : "=m" (sp) :);
+
+    *sp++ = (u4)env;
+
+    if(class)
+        *sp++ = (u4)class;
+
+    for(i = 0; i < args; i++)
+        sp[i] = ostack[i];
+
+    switch(ret_type) {
+        case RET_VOID:
+            (*(void (*)())f)();
+            break;
+
+        case RET_DOUBLE:
+            *(double*)ostack = (*(double (*)())f)();
+            ostack += 2;
+            break;
+
+        case RET_LONG:
+            *(long long*)ostack = (*(long long (*)())f)();
+            ostack += 2;
+            break;
+
+        case RET_FLOAT:
+            *(float*)ostack = (*(float (*)())f)();
+            ostack++;
+            break;
+
+        case RET_BYTE:
+            *ostack++ = (*(signed char (*)())f)();
+            break;
+
+        case RET_CHAR:
+            *ostack++ = (*(unsigned short (*)())f)();
+            break;
+
+        case RET_SHORT:
+            *ostack++ = (*(signed short (*)())f)();
+            break;
+
+        default:
+            *ostack++ = (*(u4 (*)())f)();
+            break;
+    }
+
+    return ostack;
+}
+#endif
diff -Nru jamvm-2.0.0.orig/src/os/midipix/i386/init.c jamvm-2.0.0/src/os/midipix/i386/init.c
--- jamvm-2.0.0.orig/src/os/midipix/i386/init.c	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/i386/init.c	2012-05-17 23:01:47.000000000 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2003, 2004, 2006, 2007
+ * Robert Lougher <rob@jamvm.org.uk>.
+ *
+ * This file is part of JamVM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <fpu_control.h>
+
+/* Change floating point precision to double (64-bit) from
+ * the extended (80-bit) Linux default. */
+
+void setDoublePrecision() {
+    fpu_control_t cw;
+
+    _FPU_GETCW(cw);
+    cw &= ~_FPU_EXTENDED;
+    cw |= _FPU_DOUBLE;
+    _FPU_SETCW(cw);
+}
+
+void initialisePlatform() {
+    setDoublePrecision();
+}
diff -Nru jamvm-2.0.0.orig/src/os/midipix/i386/jni-stubs.c jamvm-2.0.0/src/os/midipix/i386/jni-stubs.c
--- jamvm-2.0.0.orig/src/os/midipix/i386/jni-stubs.c	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/i386/jni-stubs.c	2012-06-27 02:35:00.000000000 +0200
@@ -0,0 +1,927 @@
+/* Generated by gen-stubs.c from signature file sigs (profiling off) */
+
+#include "jam.h"
+
+#ifdef USE_MD_STUBS
+#include "stubs.h"
+#include "properties.h"
+#include "jni-internal.h"
+
+extern void *jni_env;
+
+/* Static signatures */
+
+/* ()I */
+static uintptr_t *static__I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*))mb->code) (
+	&jni_env,
+	class);
+
+    return ostack + 1;
+}
+
+/* ()J */
+static uintptr_t *static__J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*))mb->code) (
+	&jni_env,
+	class);
+
+    return ostack + 2;
+}
+
+/* ()L */
+static uintptr_t *static__L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*))mb->code) (
+	&jni_env,
+	class));
+
+    return ostack + 1;
+}
+
+/* ()V */
+static uintptr_t *static__V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*))mb->code) (
+	&jni_env,
+	class);
+
+    return ostack + 0;
+}
+
+/* (I)B */
+static uintptr_t *static_I_B(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(int8_t (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(uintptr_t *)&ostack[0]);
+
+    return ostack + 1;
+}
+
+/* (I)F */
+static uintptr_t *static_I_F(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *((float*)ostack + IS_BE64) = (*(float (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(uintptr_t *)&ostack[0]);
+
+    return ostack + 1;
+}
+
+/* (I)I */
+static uintptr_t *static_I_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(uintptr_t *)&ostack[0]);
+
+    return ostack + 1;
+}
+
+/* (I)L */
+static uintptr_t *static_I_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(uintptr_t *)&ostack[0]));
+
+    return ostack + 1;
+}
+
+/* (J)D */
+static uintptr_t *static_J_D(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(double*)ostack = (*(double (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0]);
+
+    return ostack + 2;
+}
+
+/* (J)I */
+static uintptr_t *static_J_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0]);
+
+    return ostack + 1;
+}
+
+/* (J)J */
+static uintptr_t *static_J_J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0]);
+
+    return ostack + 2;
+}
+
+/* (J)L */
+static uintptr_t *static_J_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0]));
+
+    return ostack + 1;
+}
+
+/* (J)V */
+static uintptr_t *static_J_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0]);
+
+    return ostack + 0;
+}
+
+/* (JI)I */
+static uintptr_t *static_JI_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(uintptr_t *)&ostack[2]);
+
+    return ostack + 1;
+}
+
+/* (JI)J */
+static uintptr_t *static_JI_J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(uintptr_t *)&ostack[2]);
+
+    return ostack + 2;
+}
+
+/* (JI)L */
+static uintptr_t *static_JI_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(uintptr_t *)&ostack[2]));
+
+    return ostack + 1;
+}
+
+/* (JI)V */
+static uintptr_t *static_JI_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(uintptr_t *)&ostack[2]);
+
+    return ostack + 0;
+}
+
+/* (JJ)B */
+static uintptr_t *static_JJ_B(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(int8_t (*)(void*, void*, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2]);
+
+    return ostack + 1;
+}
+
+/* (JJ)D */
+static uintptr_t *static_JJ_D(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(double*)ostack = (*(double (*)(void*, void*, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2]);
+
+    return ostack + 2;
+}
+
+/* (JJ)I */
+static uintptr_t *static_JJ_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2]);
+
+    return ostack + 1;
+}
+
+/* (JJ)J */
+static uintptr_t *static_JJ_J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2]);
+
+    return ostack + 2;
+}
+
+/* (JJ)L */
+static uintptr_t *static_JJ_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2]));
+
+    return ostack + 1;
+}
+
+/* (JJ)V */
+static uintptr_t *static_JJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2]);
+
+    return ostack + 0;
+}
+
+/* (JJI)L */
+static uintptr_t *static_JJI_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(uintptr_t *)&ostack[4]));
+
+    return ostack + 1;
+}
+
+/* (JJI)V */
+static uintptr_t *static_JJI_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(uintptr_t *)&ostack[4]);
+
+    return ostack + 0;
+}
+
+/* (JJJI)V */
+static uintptr_t *static_JJJI_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(int64_t *)&ostack[4],
+	*(uintptr_t *)&ostack[6]);
+
+    return ostack + 0;
+}
+
+/* (JJJJ)V */
+static uintptr_t *static_JJJJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(int64_t *)&ostack[4],
+	*(int64_t *)&ostack[6]);
+
+    return ostack + 0;
+}
+
+/* (JJJJI)I */
+static uintptr_t *static_JJJJI_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t, int64_t, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(int64_t *)&ostack[4],
+	*(int64_t *)&ostack[6],
+	*(uintptr_t *)&ostack[8]);
+
+    return ostack + 1;
+}
+
+/* (JJJJJJ)V */
+static uintptr_t *static_JJJJJJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(int64_t *)&ostack[4],
+	*(int64_t *)&ostack[6],
+	*(int64_t *)&ostack[8],
+	*(int64_t *)&ostack[10]);
+
+    return ostack + 0;
+}
+
+/* (JJJJJJJJJI)V */
+static uintptr_t *static_JJJJJJJJJI_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(int64_t *)&ostack[4],
+	*(int64_t *)&ostack[6],
+	*(int64_t *)&ostack[8],
+	*(int64_t *)&ostack[10],
+	*(int64_t *)&ostack[12],
+	*(int64_t *)&ostack[14],
+	*(int64_t *)&ostack[16],
+	*(uintptr_t *)&ostack[18]);
+
+    return ostack + 0;
+}
+
+/* (JJJJJJJJJJJJ)I */
+static uintptr_t *static_JJJJJJJJJJJJ_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	class,
+	*(int64_t *)&ostack[0],
+	*(int64_t *)&ostack[2],
+	*(int64_t *)&ostack[4],
+	*(int64_t *)&ostack[6],
+	*(int64_t *)&ostack[8],
+	*(int64_t *)&ostack[10],
+	*(int64_t *)&ostack[12],
+	*(int64_t *)&ostack[14],
+	*(int64_t *)&ostack[16],
+	*(int64_t *)&ostack[18],
+	*(int64_t *)&ostack[20],
+	*(int64_t *)&ostack[22]);
+
+    return ostack + 1;
+}
+
+/* Non-static signatures */
+
+/* ()B */
+static uintptr_t *__B(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(int8_t (*)(void*, void*))mb->code) (
+	&jni_env,
+	(void*)ostack[0]);
+
+    return ostack + 1;
+}
+
+/* ()I */
+static uintptr_t *__I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*))mb->code) (
+	&jni_env,
+	(void*)ostack[0]);
+
+    return ostack + 1;
+}
+
+/* ()J */
+static uintptr_t *__J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*))mb->code) (
+	&jni_env,
+	(void*)ostack[0]);
+
+    return ostack + 2;
+}
+
+/* ()L */
+static uintptr_t *__L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*))mb->code) (
+	&jni_env,
+	(void*)ostack[0]));
+
+    return ostack + 1;
+}
+
+/* ()V */
+static uintptr_t *__V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*))mb->code) (
+	&jni_env,
+	(void*)ostack[0]);
+
+    return ostack + 0;
+}
+
+/* (I)B */
+static uintptr_t *_I_B(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(int8_t (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(uintptr_t *)&ostack[1]);
+
+    return ostack + 1;
+}
+
+/* (I)I */
+static uintptr_t *_I_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(uintptr_t *)&ostack[1]);
+
+    return ostack + 1;
+}
+
+/* (I)J */
+static uintptr_t *_I_J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(uintptr_t *)&ostack[1]);
+
+    return ostack + 2;
+}
+
+/* (I)L */
+static uintptr_t *_I_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(uintptr_t *)&ostack[1]));
+
+    return ostack + 1;
+}
+
+/* (I)V */
+static uintptr_t *_I_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(uintptr_t *)&ostack[1]);
+
+    return ostack + 0;
+}
+
+/* (J)B */
+static uintptr_t *_J_B(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(int8_t (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1]);
+
+    return ostack + 1;
+}
+
+/* (J)J */
+static uintptr_t *_J_J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1]);
+
+    return ostack + 2;
+}
+
+/* (J)L */
+static uintptr_t *_J_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1]));
+
+    return ostack + 1;
+}
+
+/* (J)V */
+static uintptr_t *_J_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1]);
+
+    return ostack + 0;
+}
+
+/* (JI)I */
+static uintptr_t *_JI_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(uintptr_t *)&ostack[3]);
+
+    return ostack + 1;
+}
+
+/* (JI)J */
+static uintptr_t *_JI_J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(uintptr_t *)&ostack[3]);
+
+    return ostack + 2;
+}
+
+/* (JI)V */
+static uintptr_t *_JI_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(uintptr_t *)&ostack[3]);
+
+    return ostack + 0;
+}
+
+/* (JJ)V */
+static uintptr_t *_JJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3]);
+
+    return ostack + 0;
+}
+
+/* (JJI)I */
+static uintptr_t *_JJI_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(uintptr_t *)&ostack[5]);
+
+    return ostack + 1;
+}
+
+/* (JJI)L */
+static uintptr_t *_JJI_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(uintptr_t *)&ostack[5]));
+
+    return ostack + 1;
+}
+
+/* (JJJ)I */
+static uintptr_t *_JJJ_I(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (*(uintptr_t (*)(void*, void*, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5]);
+
+    return ostack + 1;
+}
+
+/* (JJJ)J */
+static uintptr_t *_JJJ_J(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *(int64_t*)ostack = (*(int64_t (*)(void*, void*, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5]);
+
+    return ostack + 2;
+}
+
+/* (JJJ)L */
+static uintptr_t *_JJJ_L(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    *ostack = (uintptr_t)REF_TO_OBJ((*(uintptr_t (*)(void*, void*, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5]));
+
+    return ostack + 1;
+}
+
+/* (JJJ)V */
+static uintptr_t *_JJJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5]);
+
+    return ostack + 0;
+}
+
+/* (JJJJ)V */
+static uintptr_t *_JJJJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5],
+	*(int64_t *)&ostack[7]);
+
+    return ostack + 0;
+}
+
+/* (JJJJJ)V */
+static uintptr_t *_JJJJJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5],
+	*(int64_t *)&ostack[7],
+	*(int64_t *)&ostack[9]);
+
+    return ostack + 0;
+}
+
+/* (JJJJJJI)V */
+static uintptr_t *_JJJJJJI_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, uintptr_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5],
+	*(int64_t *)&ostack[7],
+	*(int64_t *)&ostack[9],
+	*(int64_t *)&ostack[11],
+	*(uintptr_t *)&ostack[13]);
+
+    return ostack + 0;
+}
+
+/* (JJJJJJJJJ)V */
+static uintptr_t *_JJJJJJJJJ_V(Class *class, MethodBlock *mb, uintptr_t *ostack) {
+    if(!initJNILrefs())
+        return NULL;
+
+    (*(void (*)(void*, void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t))mb->code) (
+	&jni_env,
+	(void*)ostack[0],
+	*(int64_t *)&ostack[1],
+	*(int64_t *)&ostack[3],
+	*(int64_t *)&ostack[5],
+	*(int64_t *)&ostack[7],
+	*(int64_t *)&ostack[9],
+	*(int64_t *)&ostack[11],
+	*(int64_t *)&ostack[13],
+	*(int64_t *)&ostack[15],
+	*(int64_t *)&ostack[17]);
+
+    return ostack + 0;
+}
+
+
+JNIStub jni_static_stubs[] = {
+    {"()I", static__I},
+    {"()J", static__J},
+    {"()L", static__L},
+    {"()V", static__V},
+    {"(I)B", static_I_B},
+    {"(I)F", static_I_F},
+    {"(I)I", static_I_I},
+    {"(I)L", static_I_L},
+    {"(J)D", static_J_D},
+    {"(J)I", static_J_I},
+    {"(J)J", static_J_J},
+    {"(J)L", static_J_L},
+    {"(J)V", static_J_V},
+    {"(JI)I", static_JI_I},
+    {"(JI)J", static_JI_J},
+    {"(JI)L", static_JI_L},
+    {"(JI)V", static_JI_V},
+    {"(JJ)B", static_JJ_B},
+    {"(JJ)D", static_JJ_D},
+    {"(JJ)I", static_JJ_I},
+    {"(JJ)J", static_JJ_J},
+    {"(JJ)L", static_JJ_L},
+    {"(JJ)V", static_JJ_V},
+    {"(JJI)L", static_JJI_L},
+    {"(JJI)V", static_JJI_V},
+    {"(JJJI)V", static_JJJI_V},
+    {"(JJJJ)V", static_JJJJ_V},
+    {"(JJJJI)I", static_JJJJI_I},
+    {"(JJJJJJ)V", static_JJJJJJ_V},
+    {"(JJJJJJJJJI)V", static_JJJJJJJJJI_V},
+    {"(JJJJJJJJJJJJ)I", static_JJJJJJJJJJJJ_I},
+    {NULL, NULL}
+};
+
+JNIStub jni_stubs[] = {
+    {"()B", __B},
+    {"()I", __I},
+    {"()J", __J},
+    {"()L", __L},
+    {"()V", __V},
+    {"(I)B", _I_B},
+    {"(I)I", _I_I},
+    {"(I)J", _I_J},
+    {"(I)L", _I_L},
+    {"(I)V", _I_V},
+    {"(J)B", _J_B},
+    {"(J)J", _J_J},
+    {"(J)L", _J_L},
+    {"(J)V", _J_V},
+    {"(JI)I", _JI_I},
+    {"(JI)J", _JI_J},
+    {"(JI)V", _JI_V},
+    {"(JJ)V", _JJ_V},
+    {"(JJI)I", _JJI_I},
+    {"(JJI)L", _JJI_L},
+    {"(JJJ)I", _JJJ_I},
+    {"(JJJ)J", _JJJ_J},
+    {"(JJJ)L", _JJJ_L},
+    {"(JJJ)V", _JJJ_V},
+    {"(JJJJ)V", _JJJJ_V},
+    {"(JJJJJ)V", _JJJJJ_V},
+    {"(JJJJJJI)V", _JJJJJJI_V},
+    {"(JJJJJJJJJ)V", _JJJJJJJJJ_V},
+    {NULL, NULL}
+};
+#endif
diff -Nru jamvm-2.0.0.orig/src/os/midipix/i386/Makefile.am jamvm-2.0.0/src/os/midipix/i386/Makefile.am
--- jamvm-2.0.0.orig/src/os/midipix/i386/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/i386/Makefile.am	2012-05-17 23:01:47.000000000 +0200
@@ -0,0 +1,25 @@
+##
+## Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
+## Robert Lougher <rob@jamvm.org.uk>.
+##
+## This file is part of JamVM.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2,
+## or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+
+noinst_LTLIBRARIES = libnative.la
+libnative_la_SOURCES = init.c dll_md.c stubs_md.c jni-stubs.c
+
+AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
diff -Nru jamvm-2.0.0.orig/src/os/midipix/i386/stubs_md.c jamvm-2.0.0/src/os/midipix/i386/stubs_md.c
--- jamvm-2.0.0.orig/src/os/midipix/i386/stubs_md.c	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/i386/stubs_md.c	2012-06-27 02:35:00.000000000 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010, 2012 Robert Lougher <rob@jamvm.org.uk>.
+ *
+ * This file is part of JamVM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GEN_STUBS_INC
+#include "jam.h"
+#endif
+
+#if defined(GEN_STUBS_INC) || defined(USE_MD_STUBS)
+#include <string.h>
+#include "sig.h"
+
+char *convertSig2Simple(char *sig) {
+    char *simple_sig, *simple_pntr;
+    int count = 0;
+    int i;
+
+    SCAN_SIG(sig, count+=2, count++);
+    simple_sig = simple_pntr = sysMalloc((count + 1)/2 + 4);
+
+    *simple_pntr++ = '(';
+    for(i = 0; i < count/2; i++)
+        *simple_pntr++ = 'J';
+
+    if(count&0x1)
+        *simple_pntr++ = 'I';
+    *simple_pntr++ = ')';
+
+    switch(*sig) {
+        case 'Z':
+            *simple_pntr++ = 'B';
+            break;
+
+        case '[':
+            *simple_pntr++ = 'L';
+            break;
+
+        default:
+            *simple_pntr++ = *sig;
+            break;
+    }
+
+    *simple_pntr = '\0';
+    return simple_sig;
+}
+#endif
+
diff -Nru jamvm-2.0.0.orig/src/os/midipix/Makefile.am jamvm-2.0.0/src/os/midipix/Makefile.am
--- jamvm-2.0.0.orig/src/os/midipix/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/Makefile.am	2012-05-17 23:01:47.000000000 +0200
@@ -0,0 +1,28 @@
+##
+## Copyright (C) 2003, 2004, 2005, 2006, 2007
+## Robert Lougher <rob@jamvm.org.uk>.
+##
+## This file is part of JamVM.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2,
+## or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+
+SUBDIRS = @arch@
+DIST_SUBDIRS = i386 x86_64
+
+noinst_LTLIBRARIES = libos.la
+libos_la_SOURCES = os.c
+
+AM_CPPFLAGS = -I$(top_builddir)/src
diff -Nru jamvm-2.0.0.orig/src/os/midipix/os.c jamvm-2.0.0/src/os/midipix/os.c
--- jamvm-2.0.0.orig/src/os/midipix/os.c	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/os.c	2014-02-03 20:37:36.000000000 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014
+ * Robert Lougher <rob@jamvm.org.uk>.
+ *
+ * This file is part of JamVM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/sysinfo.h>
+
+#define __USE_GNU
+#include <dlfcn.h>
+#include <pthread.h>
+
+#include "../../jam.h"
+
+long long nativePhysicalMemory() {
+    /* Long longs are used here because with PAE, a 32-bit
+       machine can have more than 4GB of physical memory */
+
+    long long num_pages = sysconf(_SC_PHYS_PAGES);
+    long long page_size = sysconf(_SC_PAGESIZE);
+
+    return num_pages * page_size;
+}
+
+void *nativeStackBase() {
+#ifdef __UCLIBC__
+    return NULL;
+#else
+    pthread_attr_t attr;
+    void *addr;
+    size_t size;
+
+    pthread_getattr_np(pthread_self(), &attr);
+    pthread_attr_getstack(&attr, &addr, &size);
+
+    return addr+size;
+#endif
+}
+
+int nativeAvailableProcessors() {
+#ifdef __UCLIBC__
+    return 1;
+#else
+    return get_nprocs();
+#endif
+}
+
+char *nativeLibError() {
+    return dlerror();
+}
+
+char *nativeLibPath() {
+    return getenv("LD_LIBRARY_PATH");
+}
+
+void *nativeLibOpen(char *path) {
+    return dlopen(path, RTLD_LAZY);
+}
+
+void nativeLibClose(void *handle) {
+    dlclose(handle);
+}
+
+void *nativeLibSym(void *handle, char *symbol) {
+    return dlsym(handle, symbol);
+}
+
+char *nativeLibMapName(char *name) {
+   char *buff = sysMalloc(strlen(name) + sizeof("lib.so") + 1);
+
+   sprintf(buff, "lib%s.so", name);
+   return buff;
+}
+
+char *nativeJVMPath() {
+    Dl_info info;
+    char *path;
+
+    if(dladdr(nativeJVMPath, &info) == 0) {
+        printf("Error: dladdr failed.  Aborting VM\n");
+        exitVM(1);
+    }
+
+    path = sysMalloc(strlen(info.dli_fname) + 1);
+    strcpy(path, info.dli_fname);
+
+    return path;
+}
+
diff -Nru jamvm-2.0.0.orig/src/os/midipix/x86_64/callNative.S jamvm-2.0.0/src/os/midipix/x86_64/callNative.S
--- jamvm-2.0.0.orig/src/os/midipix/x86_64/callNative.S	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/x86_64/callNative.S	2018-06-03 16:40:48.062473407 +0200
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2008, 2009 Robert Lougher <rob@jamvm.org.uk>.
+ *
+ * This file is part of JamVM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include  "config.h"
+
+#ifndef USE_FFI
+.text
+.align  2
+.global callJNIMethod
+.type   callJNIMethod,function
+
+/*
+ * Arguments passed in:
+ *
+ * %rdi JNIEnv
+ * %rsi class or NULL
+ * %rdx sig
+ * %rcx extra arg
+ * %r8  ostack
+ * %r9  function pntr
+ */
+
+callJNIMethod:
+    pushq   %rbp
+    movq    %rsp, %rbp
+
+    pushq   %r8
+    pushq   %r9
+    pushq   %rbx
+    pushq   %r12
+    pushq   %r14
+    pushq   %r15
+
+    testq   %rsi, %rsi
+    jne     alloc_space
+
+    movq    (%r8), %rsi
+    addq    $8, %r8
+
+alloc_space:
+    subq    %rcx, %rsp
+
+/* Setup argument registers:
+ * rdx, rcx, r8, r9
+ * xmm0 - xmm7
+ *
+ * local register usage:
+ *  r10 = int reg count
+ *  r11 = double handler
+ *  r12 = float handler
+ *  r14 = sig pntr
+ *  r15 = stack pntr
+ *  rbx = ostack pntr
+ */
+
+    leaq    double_regs-10(%rip), %r11
+    leaq    float_regs-10(%rip), %r12
+    leaq    1(%rdx), %r14
+    movq    %rsp, %r15
+    xorq    %r10, %r10
+    movq    %r8, %rbx
+
+next:
+    movzbq  (%r14), %rax
+    incq    %r14
+
+    cmpq    $41, %rax                /* ')' */
+    je      done
+    cmpq    $68, %rax                /* 'D' */
+    je      double
+    cmpq    $70, %rax                /* 'F' */
+    je      float
+    cmpq    $74, %rax                /* 'J' */
+    je      long
+
+skip_brackets:
+    cmpq    $91, %rax                /* '[' */
+    jne     check_ref
+    movzbq  (%r14), %rax
+    incq    %r14
+    jmp     skip_brackets
+
+check_ref:
+    cmpq    $76, %rax                /* 'L' */
+    jne     int
+
+skip_ref:
+    movzbq  (%r14), %rax
+    incq    %r14
+    cmpq    $59, %rax                /* ';' */
+    jne     skip_ref
+
+int:
+    movq    (%rbx), %rax
+    addq    $8, %rbx
+
+check_regs:
+    incq    %r10
+    cmpq    $2, %r10
+    jg      check_4
+
+    cmovneq %rax, %rdx
+    cmoveq  %rax, %rcx
+    jmp     next
+
+check_4:
+    cmpq    $4, %r10
+    jg      stack_push
+
+    cmovneq %rax, %r8
+    cmoveq  %rax, %r9
+    jmp     next
+
+stack_push:
+    movq    %rax, (%r15)
+    addq    $8, %r15
+    jmp     next
+
+long:
+    movq    (%rbx), %rax
+    addq    $16, %rbx
+    jmp     check_regs
+
+double:
+    addq    $10, %r11
+    addq    $10, %r12
+    addq    $16, %rbx
+    jmp     *%r11
+
+double_regs:
+    movsd   -16(%rbx), %xmm0
+    jmp     next
+    movsd   -16(%rbx), %xmm1
+    jmp     next
+    movsd   -16(%rbx), %xmm2
+    jmp     next
+    movsd   -16(%rbx), %xmm3
+    jmp     next
+    movsd   -16(%rbx), %xmm4
+    jmp     next
+    movsd   -16(%rbx), %xmm5
+    jmp     next
+    movsd   -16(%rbx), %xmm6
+    jmp     next
+    movsd   -16(%rbx), %xmm7
+    jmp     next
+    movq    -16(%rbx), %rax
+    subq    $10, %r11
+    subq    $10, %r12
+    jmp     stack_push
+
+float:
+    addq    $10, %r11
+    addq    $10, %r12
+    addq    $8, %rbx
+    jmp     *%r12
+
+float_regs:
+    movss   -8(%rbx), %xmm0
+    jmp     next
+    movss   -8(%rbx), %xmm1
+    jmp     next
+    movss   -8(%rbx), %xmm2
+    jmp     next
+    movss   -8(%rbx), %xmm3
+    jmp     next
+    movss   -8(%rbx), %xmm4
+    jmp     next
+    movss   -8(%rbx), %xmm5
+    jmp     next
+    movss   -8(%rbx), %xmm6
+    jmp     next
+    movss   -8(%rbx), %xmm7
+    jmp     next
+    movl    -8(%rbx), %eax
+    subq    $10, %r11
+    subq    $10, %r12
+    jmp     stack_push
+
+done:
+    /* Arguments all setup --
+       call the native method */
+
+    callq   *-16(%rbp)
+
+    /* Get back ostack for return value */
+    movq    -8(%rbp), %rcx
+
+    /* Handle return type */
+
+    movzbq  (%r14), %rbx
+    cmpq    $86, %rbx                /* 'V' */
+    je      return
+    cmpq    $76, %rbx                /* 'L' */
+    je      int_ret
+    cmpq    $91, %rbx                /* '[' */
+    je      int_ret
+    cmpq    $73, %rbx                /* 'I' */
+    je      int_ret
+    cmpq    $68, %rbx                /* 'D' */
+    je      double_ret
+    cmpq    $70, %rbx                /* 'F' */
+    je      float_ret
+    cmpq    $74, %rbx                /* 'J' */
+    je      long_ret
+    cmpq    $67, %rbx                /* 'C' */
+    je      char_ret
+    cmpq    $83, %rbx                /* 'S' */
+    je      short_ret
+
+    /* remaining types Z and B */
+    movsbq  %al, %rax
+
+int_ret:
+    movq    %rax, (%rcx)
+    addq    $8, %rcx
+
+return:
+    movq    -24(%rbp), %rbx
+    movq    -32(%rbp), %r12
+    movq    -40(%rbp), %r14
+    movq    -48(%rbp), %r15
+
+    movq    %rbp, %rsp
+    popq    %rbp
+
+    movq    %rcx, %rax
+    retq
+
+char_ret:
+    movzwq  %ax, %rax
+    jmp     int_ret
+
+short_ret:
+    movswq  %ax, %rax
+    jmp     int_ret
+
+long_ret:
+    movq    %rax, (%rcx)
+    addq    $16, %rcx
+    jmp     return
+
+double_ret:
+    movsd   %xmm0, (%rcx)
+    addq    $16, %rcx
+    jmp     return
+
+float_ret:
+    movss   %xmm0, (%rcx)
+    addq    $8, %rcx
+    jmp     return
+#endif
diff -Nru jamvm-2.0.0.orig/src/os/midipix/x86_64/dll_md.c jamvm-2.0.0/src/os/midipix/x86_64/dll_md.c
--- jamvm-2.0.0.orig/src/os/midipix/x86_64/dll_md.c	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/x86_64/dll_md.c	2012-05-17 23:01:47.000000000 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008, 2010 Robert Lougher <rob@jamvm.org.uk>.
+ *
+ * This file is part of JamVM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "jam.h"
+
+#ifndef USE_FFI
+#include <stdio.h>
+
+int nativeExtraArg(MethodBlock *mb) {
+    char *sig = mb->type;
+    int stack_space;
+    int iargs = 0;
+    int fargs = 0;
+
+    while(*++sig != ')')
+        switch(*sig) {
+            case 'D':
+            case 'F':
+                fargs++;
+                break;
+
+            default:
+                iargs++;
+
+                if(*sig == '[')
+                    while(*++sig == '[');
+                if(*sig == 'L')
+                    while(*++sig != ';');
+                break;
+        }
+
+    stack_space = ((iargs > 4 ? iargs - 4 : 0) +
+                   (fargs > 8 ? fargs - 8 : 0)) << 3;
+
+    /* Ensure the stack remains 16 byte aligned.  As
+       callJNIMethod pushes an even number of registers
+       the extra space must also be even. */
+    return (stack_space + 15) & ~15;
+}
+#endif
diff -Nru jamvm-2.0.0.orig/src/os/midipix/x86_64/init.c jamvm-2.0.0/src/os/midipix/x86_64/init.c
--- jamvm-2.0.0.orig/src/os/midipix/x86_64/init.c	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/x86_64/init.c	2012-05-17 23:01:47.000000000 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007
+ * Robert Lougher <rob@jamvm.org.uk>.
+ *
+ * This file is part of JamVM.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef __linux__
+#include <fpu_control.h>
+#endif
+
+/* Change the x87 FPU precision to double (64-bit) from the extended
+   (80-bit) Linux default.  Note, unlike on i386, my testcases pass
+   without this.  This is probably because gcc assumes and uses SSE
+   by default, not the x87 FPU.  However, keep it in to be safe.
+*/
+
+void setDoublePrecision() {
+#ifdef __linux__
+    fpu_control_t cw;
+
+    _FPU_GETCW(cw);
+    cw &= ~_FPU_EXTENDED;
+    cw |= _FPU_DOUBLE;
+    _FPU_SETCW(cw);
+#endif
+}
+
+void initialisePlatform() {
+    setDoublePrecision();
+}
diff -Nru jamvm-2.0.0.orig/src/os/midipix/x86_64/Makefile.am jamvm-2.0.0/src/os/midipix/x86_64/Makefile.am
--- jamvm-2.0.0.orig/src/os/midipix/x86_64/Makefile.am	1970-01-01 01:00:00.000000000 +0100
+++ jamvm-2.0.0/src/os/midipix/x86_64/Makefile.am	2012-05-17 23:01:47.000000000 +0200
@@ -0,0 +1,26 @@
+##
+## Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010
+## Robert Lougher <rob@jamvm.org.uk>.
+##
+## This file is part of JamVM.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2,
+## or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+##
+
+noinst_LTLIBRARIES = libnative.la
+libnative_la_SOURCES = init.c dll_md.c callNative.S
+
+AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
+AM_CCASFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src