Commits

camlspotter  committed 6546ff2 Draft

added ocamljava-0.3

  • Participants
  • Parent commits fc1d210

Comments (0)

Files changed (31)

File camljava-0.3.tar.gz

Binary file added.

File camljava-0.3/Makefile

+all:
+	cd lib; $(MAKE) all
+
+install:
+	cd lib; $(MAKE) install
+
+tst:
+	cd test; $(MAKE)
+
+clean:
+	cd lib; $(MAKE) clean
+	cd test; $(MAKE) clean

File camljava-0.3/Makefile.config

+################### C compiler ########################
+
+# C compiler to use
+CC=gcc
+
+# Flags for $(CC)
+CFLAGS=-O -g -Wall
+
+################### Java compiler #####################
+
+# Java compiler to use
+JAVAC=javac -g
+
+################### JNI interface #####################
+
+## Defaults are set for Sun's JDK 1.4.2 under Linux.  
+## For other platforms, adjust as required and tell us about it.
+
+# Home location for the JDK.  Only used for setting other variables below. 
+JDKHOME=/usr/local/java_1.4.2
+
+# Where to find the JNI include files (for compiling the OCaml-JNI C stubs)
+JNIINCLUDES=-I$(JDKHOME)/include -I$(JDKHOME)/include/linux
+
+# The library to link with to get the JNI
+JNILIBS=-ljava
+
+# Additional link-time options to pass to $(CC) when linking with $(JNILIBS)
+JNILIBOPTS=-L$(JDKHOME)/jre/lib/i386/ \
+        -Wl,-rpath,$(JDKHOME)/jre/lib/i386/ \
+        -Wl,-rpath,$(JDKHOME)/jre/lib/i386/client \
+        -Wl,-rpath,$(JDKHOME)/jre/lib/i386/native_threads
+
+# Additional options when compiling the OCaml-JNI C stubs.
+# -DJDK122_LINUX_HACK works around a nasty thread-related bug of
+#  Sun's JDK 1.2.2 under Linux
+#JNISTUBSOPTIONS=-DJDK122_LINUX_HACK
+JNISTUBSOPTIONS=

File camljava-0.3/Makefile.config.msvc

+################### C compiler ########################
+
+# C compiler to use
+CC=cl /nologo
+
+# Flags for $(CC)
+CFLAGS=/Ox /MT /Zi
+
+################### Java compiler #####################
+
+# Java compiler to use
+JAVAC=javac -g
+
+################### JNI interface #####################
+
+## Defaults are set for Sun's JDK 1.4.1 under Windows
+
+# Home location for the JDK.  Only used for setting other variables below. 
+JDKHOME=C:/j2sdk1.4.1
+
+# Where to find the JNI include files (for compiling the OCaml-JNI C stubs)
+JNIINCLUDES=-I$(JDKHOME)/include -I$(JDKHOME)/include/win32
+
+# The library to link with to get the JNI
+JNILIBS=$(JDKHOME)/lib/jvm.lib
+
+# Additional link-time options to pass to $(CC) when linking with $(JNILIBS)
+JNILIBOPTS=
+
+# Additional options when compiling the OCaml-JNI C stubs.
+JNISTUBSOPTIONS=

File camljava-0.3/Makefile.msvc

+MK=$(MAKE) -f Makefile.msvc
+
+all:
+	cd lib; $(MK) all
+
+install:
+	cd lib; $(MK) install
+
+tst:
+	cd test; $(MK)
+
+clean:
+	cd lib; $(MK) clean
+	cd test; $(MK) clean

File camljava-0.3/README

+                  CamlJava - an OCaml/Java interface
+                  ==================================
+
+DESCRIPTION:
+
+This is a very preliminary release of CamlJava, an OCaml/Java
+interface based on the following schema:
+
+         Caml/C interface       JNI (Java Native Interface)
+  Caml <------------------> C <-----------------------------> Java
+
+Currently, CamlJava provides a low-level, weakly-typed OCaml interface 
+very similar to the JNI.  Java object references are mapped to an
+abstract type, and various JNI-like operations are provided to allow
+Java method invocation, field access, and more.  A basic callback
+facility (allowing Java code to invoke methods on Caml objects) is
+also provided, although some stub Java code must be written by hand.
+
+In the future, a higher-level, strongly-typed interface will be
+provided, whereas Java classes are mapped directly to Caml classes.
+This raises fairly delicate type mapping issues, though, so don't hold
+your breath.
+
+
+REQUIREMENTS:
+
+- This release of CamlJava requires Objective Caml version 3.08 or later.
+
+- A Java implementation that supports JNI (Java Native Interface).
+  So far, only Sun's JDK has been tested.
+
+INSTALLATION ON A UNIX PLATFORM:
+
+- Edit Makefile.config to define parameters depending on your Java
+  installation.  As distributed, the library is set up for
+  Sun's JDK version 1.4.1 on a Linux x86 platform.
+
+- make
+  become superuser
+  make install
+
+- For testing:
+  make tst
+
+
+INSTALLATION ON A WINDOWS PLATFORM:
+
+- Works with the MSVC port of OCaml for Windows.  
+  GNU make and Cygwin tools are required to do the installation.
+
+- Edit Makefile.config.msvc to define parameters depending on your Java
+  installation.  
+
+- make -f Makefile.msvc
+  make -f Makefile.msvc install
+
+- For testing:
+  make -f Makefile.msvc tst
+
+
+USAGE:
+
+The module is named "Jni".  A good knowledge of the JNI is assumed; see Sun's
+JNI book or http://java.sun.com/products/jdk/1.2/docs/guide/jni/
+Then, the comments in lib/jni.mli should make sense.
+
+Usage:          ocamlc -I +camljava jni.cma ...
+            or  ocamlopt -I +camljava jni.cmxa ...
+
+See the programs in test/ for examples of use.
+
+
+LICENSE:  GNU Library General Public License version 2.
+
+
+FEEDBACK:  e-mail the author, Xavier.Leroy@inria.fr.
+
+
+

File camljava-0.3/lib/.cvsignore

+jni.ml

File camljava-0.3/lib/.depend

+jni.cmo: jni.cmi 
+jni.cmx: jni.cmi 

File camljava-0.3/lib/Makefile

+include ../Makefile.config
+
+OCAMLC=ocamlc -g
+OCAMLOPT=ocamlopt
+OCAMLDEP=ocamldep
+OCAMLLIB=`ocamlc -where`
+CAMLJAVALIB=$(OCAMLLIB)/camljava
+
+all: jni.cma jni.cmxa javaclasses
+
+install:
+	mkdir -p $(CAMLJAVALIB)
+	cp jni.cma jni.cmi jni.cmxa jni.a libcamljni.a jni.mli $(CAMLJAVALIB)
+	jar cf $(CAMLJAVALIB)/camljava.jar fr/inria/caml/camljava/*.class
+
+jni.cma: jni.cmo libcamljni.a
+	$(OCAMLC) -linkall -a -o jni.cma -custom jni.cmo \
+            -ccopt "$(JNILIBOPTS)" -cclib -lcamljni -cclib "$(JNILIBS)"
+
+jni.cmxa: jni.cmx libcamljni.a
+	$(OCAMLOPT) -linkall -a -o jni.cmxa jni.cmx \
+            -ccopt "$(JNILIBOPTS)" -cclib -lcamljni -cclib "$(JNILIBS)"
+
+libcamljni.a: jnistubs.o
+	rm -f libcamljni.a
+	ar rcs libcamljni.a jnistubs.o
+
+clean::
+	rm -f libcamljni.a
+
+jni.ml: jni.mlp jni.mli ../Makefile.config
+	rm -f jni.ml
+	sed -e 's|%PATH%|'$(CAMLJAVALIB)/camljava.jar'|' \
+                jni.mlp > jni.ml
+	chmod -w jni.ml
+
+clean::
+	rm -f jni.ml
+
+beforedepend:: jni.ml
+
+javaclasses:
+	$(JAVAC) fr/inria/caml/camljava/*.java
+
+clean::
+	rm -f fr/inria/caml/camljava/*.class
+
+clean::
+	rm -f *.cm? *.[oa]
+
+.SUFFIXES: .ml .mli .cmo .cmi .cmx
+
+.c.o:
+	$(CC) -c $(CFLAGS) $(JNIINCLUDES) -I$(OCAMLLIB) $*.c
+
+.ml.cmo:
+	$(OCAMLC) -c $*.ml
+
+.ml.cmx:
+	$(OCAMLOPT) -c $*.ml
+
+.mli.cmi:
+	$(OCAMLC) -c $*.mli
+
+depend: beforedepend
+	$(OCAMLDEP) *.mli *.ml > .depend
+
+include .depend
+

File camljava-0.3/lib/Makefile.msvc

+include ../Makefile.config.msvc
+
+OCAMLC=ocamlc -g
+OCAMLOPT=ocamlopt
+OCAMLDEP=ocamldep
+OCAMLLIB=`ocamlc -where`
+CAMLJAVALIB=$(OCAMLLIB)/camljava
+
+all: jni.cma jni.cmxa javaclasses
+
+install:
+	mkdir -p $(CAMLJAVALIB)
+	cp jni.cma jni.cmi jni.cmxa jni.lib libcamljni.lib jni.mli $(CAMLJAVALIB)
+	jar cf $(CAMLJAVALIB)/camljava.jar fr/inria/caml/camljava/*.class
+
+jni.cma: jni.cmo libcamljni.lib
+	$(OCAMLC) -linkall -a -o jni.cma -custom jni.cmo \
+            -ccopt "$(JNILIBOPTS)" -cclib -lcamljni -cclib "$(JNILIBS)"
+
+jni.cmxa: jni.cmx libcamljni.lib
+	$(OCAMLOPT) -linkall -a -o jni.cmxa jni.cmx \
+            -ccopt "$(JNILIBOPTS)" -cclib -lcamljni -cclib "$(JNILIBS)"
+
+libcamljni.lib: jnistubs.obj
+	lib /nologo /debugtype:CV /out:libcamljni.lib jnistubs.obj
+
+clean::
+	rm -f libcamljni.lib
+
+jni.ml: jni.mlp jni.mli ../Makefile.config
+	rm -f jni.ml
+	sed -e 's|%PATH%|'$(CAMLJAVALIB)/camljava.jar'|' \
+                jni.mlp > jni.ml
+	chmod -w jni.ml
+
+clean::
+	rm -f jni.ml
+
+beforedepend:: jni.ml
+
+javaclasses:
+	$(JAVAC) fr/inria/caml/camljava/*.java
+
+clean::
+	rm -f fr/inria/caml/camljava/*.class
+
+clean::
+	rm -f *.cm? *.obj *.lib
+
+.SUFFIXES: .c .obj .ml .mli .cmo .cmi .cmx
+
+.c.obj:
+	$(CC) -c $(CFLAGS) $(JNIINCLUDES) -I$(OCAMLLIB) $*.c
+
+.ml.cmo:
+	$(OCAMLC) -c $*.ml
+
+.ml.cmx:
+	$(OCAMLOPT) -c $*.ml
+
+.mli.cmi:
+	$(OCAMLC) -c $*.mli
+
+depend: beforedepend
+	$(OCAMLDEP) *.mli *.ml > .depend
+
+include .depend
+

File camljava-0.3/lib/fr/inria/caml/camljava/Boolean.java

+package fr.inria.caml.camljava;
+
+public class Boolean {
+    public boolean contents;
+    public Boolean(boolean c) { contents = c; }
+}
+

File camljava-0.3/lib/fr/inria/caml/camljava/Byte.java

+package fr.inria.caml.camljava;
+
+public class Byte {
+    public byte contents;
+    public Byte(byte c) { contents = c; }
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Callback.java

+package fr.inria.caml.camljava;
+
+public class Callback {
+    public Callback(long obj) { objref = obj; }
+
+    protected void finalize() { freeWrapper(objref); }
+
+    public native static long getCamlMethodID(String method_name);
+
+    public void callVoid(long methid, Object args[])
+    { callbackVoid(objref, methid, args); }
+
+    public boolean callBoolean(long methid, Object args[])
+    { return callbackBoolean(objref, methid, args); }
+
+    public byte callByte(long methid, Object args[])
+    { return callbackByte(objref, methid, args); }
+
+    public char callChar(long methid, Object args[])
+    { return callbackChar(objref, methid, args); }
+
+    public short callShort(long methid, Object args[])
+    { return callbackShort(objref, methid, args); }
+
+    public int callCamlint(long methid, Object args[])
+    { return callbackCamlint(objref, methid, args); }
+
+    public int callInt(long methid, Object args[])
+    { return callbackInt(objref, methid, args); }
+
+    public long callLong(long methid, Object args[])
+    { return callbackLong(objref, methid, args); }
+
+    public float callFloat(long methid, Object args[])
+    { return callbackFloat(objref, methid, args); }
+
+    public double callDouble(long methid, Object args[])
+    { return callbackDouble(objref, methid, args); }
+
+    public Object callObject(long methid, Object args[])
+    { return callbackObject(objref, methid, args); }
+
+    private long objref;
+    private native static
+        void callbackVoid(long obj, long methid, Object args[]);
+    private native static
+        boolean callbackBoolean(long obj, long methid, Object args[]);
+    private native static
+        byte callbackByte(long obj, long methid, Object args[]);
+    private native static
+        char callbackChar(long obj, long methid, Object args[]);
+    private native static
+        short callbackShort(long obj, long methid, Object args[]);
+    private native static
+        int callbackCamlint(long obj, long methid, Object args[]);
+    private native static
+        int callbackInt(long obj, long methid, Object args[]);
+    private native static
+        long callbackLong(long obj, long methid, Object args[]);
+    private native static
+        float callbackFloat(long obj, long methid, Object args[]);
+    private native static
+        double callbackDouble(long obj, long methid, Object args[]);
+    private native static
+        Object callbackObject(long obj, long methid, Object args[]);
+    private native static void freeWrapper(long obj);
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Camlint.java

+package fr.inria.caml.camljava;
+
+public class Camlint {
+    public int contents;
+    public Camlint(int c) { contents = c; }
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Char.java

+package fr.inria.caml.camljava;
+
+public class Char {
+    public char contents;
+    public Char(char c) { contents = c; }
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Double.java

+package fr.inria.caml.camljava;
+
+public class Double {
+    public double contents;
+    public Double(double c) { contents = c; }
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Exception.java

+package fr.inria.caml.camljava;
+
+public class Exception extends java.lang.Exception {
+
+    public Exception () { super(); }
+
+    public Exception (String msg) { super(msg); }
+
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Float.java

+package fr.inria.caml.camljava;
+
+public class Float {
+    public float contents;
+    public Float(float c) { contents = c; }
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Int.java

+package fr.inria.caml.camljava;
+
+public class Int {
+    public int contents;
+    public Int(int c) { contents = c; }
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Long.java

+package fr.inria.caml.camljava;
+
+public class Long {
+    public long contents;
+    public Long(long c) { contents = c; }
+}

File camljava-0.3/lib/fr/inria/caml/camljava/Readclass.java

+package fr.inria.caml.camljava;
+
+import java.util.Vector;
+import java.io.*;
+import java.util.jar.*;
+import java.util.HashSet;
+
+public class Readclass {
+
+  public static void main(String argv[])
+  {
+    Vector path = new Vector(10);
+    String cmdline;
+
+    addPath(path, System.getProperty("sun.boot.class.path"));
+    addPath(path, System.getProperty("java.class.path"));
+    while (true) {
+      try {
+        cmdline = readLine(System.in);
+        if (cmdline == null) return;
+        if (cmdline.length() < 1) continue;
+        switch (cmdline.charAt(0)) {
+        case '?':
+          System.out.write(1);
+          break;
+        case 'Q':
+          return;
+        case 'R':
+          readClass(path, cmdline.substring(1));
+          System.err.println("Done R");
+          break;
+        case 'P':
+          readPackage(path, cmdline.substring(1));
+          System.err.println("Done P");
+          break;
+        }
+        System.out.flush();
+      } catch (IOException e) {
+        /*nothing*/;
+      }
+    }
+  }
+
+  private static void addPath(Vector pathvect, String path)
+  {
+    if (path == null) return;
+    for (int i = 0; i < path.length(); /*nothing*/) {
+      int j = path.indexOf(java.io.File.pathSeparatorChar, i);
+      if (j == -1) {
+        addElementToPath(pathvect, path.substring(i));
+        break;
+      } else {
+        addElementToPath(pathvect, path.substring(i, j));
+        i = j + 1;
+      }
+    }
+  }
+  
+  private static void addElementToPath(Vector pathvect, String element)
+  {
+    if (! pathvect.contains(element)) pathvect.add(element);
+  }
+  
+  private static void readClass(Vector path, String classname)
+  {
+    for (int i = path.size() - 1; i >= 0; i--) {
+      try {
+        File pathcomp = new File((String) (path.elementAt(i)));
+        if (!pathcomp.exists()) continue;
+        if (pathcomp.isDirectory()) {
+          File f =
+            new File(pathcomp,
+                     classname.replace('/', File.separatorChar) + ".class");
+          if (! f.exists()) continue;
+          byte [] data = readFile(f);
+          System.out.write(1);
+          System.out.write(data);
+          return;
+        }
+        else if (pathcomp.isFile()) {
+          JarFile jf = new JarFile(pathcomp);
+          JarEntry je = jf.getJarEntry(classname + ".class");
+          if (je == null) { jf.close(); continue; }
+          byte [] data = readStream(jf.getInputStream(je), je.getSize());
+          jf.close();
+          System.out.write(1);
+          System.out.write(data);
+          return;
+        }
+      } catch (IOException e) {
+        /*nothing*/;
+      }
+    }
+    System.out.write(0);
+  }
+
+  private static void readPackage(Vector path, String packagename)
+  {
+    HashSet classes = new HashSet();
+    for (int i = path.size() - 1; i >= 0; i--) {
+      try {
+        File pathcomp = new File((String) (path.elementAt(i)));
+        if (!pathcomp.exists()) continue;
+        if (pathcomp.isDirectory()) {
+          File d = new File(pathcomp,
+                            packagename.replace('/', File.separatorChar));
+          String [] contents = d.list();
+          if (contents == null) continue;
+          for (int j = 0; j < contents.length; j++) {
+            String f = contents[i];
+            if (! f.endsWith(".class")) continue;
+            if (! classes.add(packagename + '/' + f)) continue;
+            byte [] data = readFile(new File(d, f));
+            System.out.write(1);
+            System.out.write(data);
+          }
+        }
+        else if (pathcomp.isFile()) {
+          JarInputStream js =
+            new JarInputStream(new FileInputStream(pathcomp));
+          JarEntry je;
+          while ((je = js.getNextJarEntry()) != null) {
+            String entryname = je.getName();
+            // System.err.println(entryname);
+            int lastslash = entryname.lastIndexOf('/');
+            if (lastslash == -1) continue;
+            if (! packagename.equals(entryname.substring(0, lastslash)))
+              continue;
+            if (! entryname.endsWith(".class")) continue;
+            if (! classes.add(entryname)) continue;
+            byte [] data = readStream(js, je.getSize());
+            System.out.write(1);
+            System.out.write(data);
+          }
+          js.close();
+        }
+      } catch (IOException e) {
+        /*nothing*/;
+      }
+    }
+    System.out.write(0);
+  }
+
+  private static byte[] readFile(File f) throws IOException
+  {
+    FileInputStream s = new FileInputStream(f);
+    try {
+      return readStream(s, f.length());
+    } finally {
+      s.close();
+    }
+  }
+
+  private static byte[] readStream(InputStream s, long length)
+  throws IOException
+  {
+    int len = (int) length;
+    byte[] buffer = new byte[len];
+    for (int i = 0; i < len; /*nothing*/) {
+      int nread = s.read(buffer, i, len - i);
+      i += nread;
+    }
+    return buffer;
+  }
+
+  private static String readLine(InputStream s) throws IOException
+  {
+    StringBuffer sb = new StringBuffer();
+    while (true) {
+      int i = s.read();
+      if (i == -1) return null;
+      System.err.write(i);  System.err.flush();
+      if (i == 10) return sb.toString();
+      sb.append((char) i);
+    }
+  }
+}
+
+      

File camljava-0.3/lib/fr/inria/caml/camljava/Short.java

+package fr.inria.caml.camljava;
+
+public class Short {
+    public short contents;
+    public Short(short c) { contents = c; }
+}

File camljava-0.3/lib/jni.mli

+(***********************************************************************)
+(*                                                                     *)
+(*             OCamlJava: Objective Caml / Java interface              *)
+(*                                                                     *)
+(*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         *)
+(*                                                                     *)
+(*  Copyright 2001 Institut National de Recherche en Informatique et   *)
+(*  en Automatique.  All rights reserved.  This file is distributed    *)
+(*  under the terms of the GNU Library General Public License.         *)
+(*                                                                     *)
+(***********************************************************************)
+
+(* $Id: jni.mli,v 1.1 2001/06/05 12:19:55 xleroy Exp $ *)
+
+(* Low-level Java interface (JNI level) *)
+
+(* Object operations *)
+
+type obj
+        (* The type of Java object references *)
+val null: obj
+        (* The [null] object reference *)
+exception Null_pointer
+        (* Exception raised by the operations below when they
+           encounter a null object reference in arguments that must
+           be non-null. *)
+external is_null: obj -> bool = "camljava_IsNull"
+        (* Determine if the given object reference is [null] *)
+external is_same_object: obj -> obj -> bool = "camljava_IsSameObject"
+        (* Determine if two object references are the same 
+           (as per [==] in Java). *)
+
+(* String operations.  Java strings are represented in Caml
+   by their UTF8 encoding. *)
+
+external string_to_java: string -> obj = "camljava_MakeJavaString"
+external string_from_java: obj -> string = "camljava_ExtractJavaString"
+        (* Conversion between Caml strings and Java strings. *)
+val null_string: string
+        (* A distinguished Caml string that represents the [null]
+           Java string reference. *)
+val is_null_string: string -> bool
+        (* Determine whether its argument is the distinguished Caml string
+           representing the [null] Java string reference. *)
+
+(* Class operations *)
+
+type clazz
+        (* The type of class identifiers *)
+
+external find_class: string -> clazz
+        = "camljava_FindClass"
+        (* Find a class given its fully qualified name, e.g. 
+           "java/lang/Object".  Note the use of slashes [/] to separate
+           components of the name. *)
+external get_superclass: clazz -> clazz
+        = "camljava_GetSuperclass"
+        (* Return the super-class of the given class. *)
+external is_assignable_from: clazz -> clazz -> bool
+        = "camljava_IsAssignableFrom"
+        (* Assignment compatibility predicate. *)
+external get_object_class: obj -> clazz = "camljava_GetObjectClass"
+        (* Return the class of an object. *)
+external is_instance_of: obj -> clazz -> bool = "camljava_IsInstanceOf"
+        (* Determine if the given object reference is an instance of the
+           given class *)
+external alloc_object: clazz -> obj = "camljava_AllocObject"
+        (* Allocate a new instance of the given class *)
+
+(* Field and method identifiers *)
+
+type fieldID
+        (* The type of field identifiers *)
+type methodID
+        (* The type of method identifiers *)
+
+external get_fieldID: clazz -> string -> string -> fieldID
+        = "camljava_GetFieldID"
+        (* [get_fieldID cls name descr] returns the identifier of
+           the instance field named [name] with descriptor (type) [descr]
+           in class [cls]. *)
+external get_static_fieldID: clazz -> string -> string -> fieldID
+        = "camljava_GetStaticFieldID"
+        (* Same, for a static field. *)
+external get_methodID: clazz -> string -> string -> methodID
+        = "camljava_GetMethodID"
+        (* [get_methodID cls name descr] returns the identifier of
+           the virtual method named [name] with descriptor (type) [descr]
+           in class [cls]. *)
+external get_static_methodID: clazz -> string -> string -> methodID
+        = "camljava_GetStaticMethodID"
+        (* Same, for a static method. *)
+
+(* Field access *)
+
+external get_object_field: obj -> fieldID -> obj
+        = "camljava_GetObjectField"
+external get_boolean_field: obj -> fieldID -> bool
+        = "camljava_GetBooleanField"
+external get_byte_field: obj -> fieldID -> int
+        = "camljava_GetByteField"
+external get_char_field: obj -> fieldID -> int
+        = "camljava_GetCharField"
+external get_short_field: obj -> fieldID -> int
+        = "camljava_GetShortField"
+external get_int_field: obj -> fieldID -> int32
+        = "camljava_GetIntField"
+external get_camlint_field: obj -> fieldID -> int
+        = "camljava_GetCamlintField"
+external get_long_field: obj -> fieldID -> int64
+        = "camljava_GetLongField"
+external get_float_field: obj -> fieldID -> float
+        = "camljava_GetFloatField"
+external get_double_field: obj -> fieldID -> float
+        = "camljava_GetFloatField"
+
+external set_object_field: obj -> fieldID -> obj -> unit
+        = "camljava_SetObjectField"
+external set_boolean_field: obj -> fieldID -> bool -> unit
+        = "camljava_SetBooleanField"
+external set_byte_field: obj -> fieldID -> int -> unit
+        = "camljava_SetByteField"
+external set_char_field: obj -> fieldID -> int -> unit
+        = "camljava_SetCharField"
+external set_short_field: obj -> fieldID -> int -> unit
+        = "camljava_SetShortField"
+external set_int_field: obj -> fieldID -> int32 -> unit
+        = "camljava_SetIntField"
+external set_camlint_field: obj -> fieldID -> int -> unit
+        = "camljava_SetCamlintField"
+external set_long_field: obj -> fieldID -> int64 -> unit
+        = "camljava_SetLongField"
+external set_float_field: obj -> fieldID -> float -> unit
+        = "camljava_SetFloatField"
+external set_double_field: obj -> fieldID -> float -> unit
+        = "camljava_SetFloatField"
+
+external get_static_object_field: clazz -> fieldID -> obj
+        = "camljava_GetStaticObjectField"
+external get_static_boolean_field: clazz -> fieldID -> bool
+        = "camljava_GetStaticBooleanField"
+external get_static_byte_field: clazz -> fieldID -> int
+        = "camljava_GetStaticByteField"
+external get_static_char_field: clazz -> fieldID -> int
+        = "camljava_GetStaticCharField"
+external get_static_short_field: clazz -> fieldID -> int
+        = "camljava_GetStaticShortField"
+external get_static_int_field: clazz -> fieldID -> int32
+        = "camljava_GetStaticIntField"
+external get_static_camlint_field: clazz -> fieldID -> int
+        = "camljava_GetStaticCamlintField"
+external get_static_long_field: clazz -> fieldID -> int64
+        = "camljava_GetStaticLongField"
+external get_static_float_field: clazz -> fieldID -> float
+        = "camljava_GetStaticFloatField"
+external get_static_double_field: clazz -> fieldID -> float
+        = "camljava_GetStaticFloatField"
+
+external set_static_obj_field: clazz -> fieldID -> obj -> unit
+        = "camljava_SetStaticObjectField"
+external set_static_boolean_field: clazz -> fieldID -> bool -> unit
+        = "camljava_SetStaticBooleanField"
+external set_static_byte_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticByteField"
+external set_static_char_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticCharField"
+external set_static_short_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticShortField"
+external set_static_int_field: clazz -> fieldID -> int32 -> unit
+        = "camljava_SetStaticIntField"
+external set_static_camlint_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticCamlintField"
+external set_static_long_field: clazz -> fieldID -> int64 -> unit
+        = "camljava_SetStaticLongField"
+external set_static_float_field: clazz -> fieldID -> float -> unit
+        = "camljava_SetStaticFloatField"
+external set_static_double_field: clazz -> fieldID -> float -> unit
+        = "camljava_SetStaticFloatField"
+
+(* Method invocation *)
+
+type argument =
+    Boolean of bool
+  | Byte of int
+  | Char of int
+  | Short of int
+  | Camlint of int
+  | Int of int32
+  | Long of int64
+  | Float of float
+  | Double of float
+  | Obj of obj
+        (* Datatype representing one argument of a Java method. *)
+
+external call_object_method: obj -> methodID -> argument array -> obj
+        = "camljava_CallObjectMethod"
+external call_boolean_method: obj -> methodID -> argument array -> bool
+        = "camljava_CallBooleanMethod"
+external call_byte_method: obj -> methodID -> argument array -> int
+        = "camljava_CallByteMethod"
+external call_char_method: obj -> methodID -> argument array -> int
+        = "camljava_CallCharMethod"
+external call_short_method: obj -> methodID -> argument array -> int
+        = "camljava_CallShortMethod"
+external call_int_method: obj -> methodID -> argument array -> int32
+        = "camljava_CallIntMethod"
+external call_camlint_method: obj -> methodID -> argument array -> int
+        = "camljava_CallCamlintMethod"
+external call_long_method: obj -> methodID -> argument array -> int64
+        = "camljava_CallLongMethod"
+external call_float_method: obj -> methodID -> argument array -> float
+        = "camljava_CallFloatMethod"
+external call_double_method: obj -> methodID -> argument array -> float
+        = "camljava_CallDoubleMethod"
+external call_void_method: obj -> methodID -> argument array -> unit
+        = "camljava_CallVoidMethod"
+
+external call_static_object_method:
+                 clazz -> methodID -> argument array -> obj
+        = "camljava_CallStaticObjectMethod"
+external call_static_boolean_method:
+                 clazz -> methodID -> argument array -> bool
+        = "camljava_CallStaticBooleanMethod"
+external call_static_byte_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticByteMethod"
+external call_static_char_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticCharMethod"
+external call_static_short_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticShortMethod"
+external call_static_int_method:
+                 clazz -> methodID -> argument array -> int32
+        = "camljava_CallStaticIntMethod"
+external call_static_camlint_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticCamlintMethod"
+external call_static_long_method:
+                 clazz -> methodID -> argument array -> int64
+        = "camljava_CallStaticLongMethod"
+external call_static_float_method:
+                 clazz -> methodID -> argument array -> float
+        = "camljava_CallStaticFloatMethod"
+external call_static_double_method:
+                 clazz -> methodID -> argument array -> float
+        = "camljava_CallStaticDoubleMethod"
+external call_static_void_method:
+                 clazz -> methodID -> argument array -> unit
+        = "camljava_CallStaticVoidMethod"
+
+external call_nonvirtual_object_method:
+                 obj -> clazz -> methodID -> argument array -> obj
+        = "camljava_CallNonvirtualObjectMethod"
+external call_nonvirtual_boolean_method:
+                 obj -> clazz -> methodID -> argument array -> bool
+        = "camljava_CallNonvirtualBooleanMethod"
+external call_nonvirtual_byte_method: 
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualByteMethod"
+external call_nonvirtual_char_method:
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualCharMethod"
+external call_nonvirtual_short_method:
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualShortMethod"
+external call_nonvirtual_int_method:
+                 obj -> clazz -> methodID -> argument array -> int32
+        = "camljava_CallNonvirtualIntMethod"
+external call_nonvirtual_camlint_method:
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualCamlintMethod"
+external call_nonvirtual_long_method:
+                 obj -> clazz -> methodID -> argument array -> int64
+        = "camljava_CallNonvirtualLongMethod"
+external call_nonvirtual_float_method:
+                 obj -> clazz -> methodID -> argument array -> float
+        = "camljava_CallNonvirtualFloatMethod"
+external call_nonvirtual_double_method:
+                 obj -> clazz -> methodID -> argument array -> float
+        = "camljava_CallNonvirtualDoubleMethod"
+external call_nonvirtual_void_method:
+                 obj -> clazz -> methodID -> argument array -> unit
+        = "camljava_CallNonvirtualVoidMethod"
+
+(* Arrays *)
+
+external get_array_length: obj -> int = "camljava_GetArrayLength"
+
+external new_object_array: int -> clazz -> obj
+        = "camljava_NewObjectArray"
+external get_object_array_element: obj -> int -> obj
+        = "camljava_GetObjectArrayElement"
+external set_object_array_element: obj -> int -> obj -> unit
+        = "camljava_SetObjectArrayElement"
+external new_boolean_array: int -> obj
+        = "camljava_NewBooleanArray"
+external get_boolean_array_element: obj -> int -> bool
+        = "camljava_GetBooleanArrayElement"
+external set_boolean_array_element: obj -> int -> bool -> unit
+        = "camljava_SetBooleanArrayElement"
+external new_byte_array: int -> obj
+        = "camljava_NewByteArray"
+external get_byte_array_element: obj -> int -> int
+        = "camljava_GetByteArrayElement"
+external set_byte_array_element: obj -> int -> int -> unit
+        = "camljava_SetByteArrayElement"
+external get_byte_array_region: obj -> int -> string -> int -> int -> unit
+        = "camljava_GetByteArrayRegion"
+external set_byte_array_region: string -> int -> obj -> int -> int -> unit
+        = "camljava_SetByteArrayRegion"
+external new_char_array: int -> obj
+        = "camljava_NewCharArray"
+external get_char_array_element: obj -> int -> int
+        = "camljava_GetCharArrayElement"
+external set_char_array_element: obj -> int -> int -> unit
+        = "camljava_SetCharArrayElement"
+external new_short_array: int -> obj
+        = "camljava_NewShortArray"
+external get_short_array_element: obj -> int -> int
+        = "camljava_GetShortArrayElement"
+external set_short_array_element: obj -> int -> int -> unit
+        = "camljava_SetShortArrayElement"
+external new_int_array: int -> obj
+        = "camljava_NewIntArray"
+external get_int_array_element: obj -> int -> int32
+        = "camljava_GetIntArrayElement"
+external set_int_array_element: obj -> int -> int32 -> unit
+        = "camljava_SetIntArrayElement"
+external get_camlint_array_element: obj -> int -> int
+        = "camljava_GetCamlintArrayElement"
+external set_camlint_array_element: obj -> int -> int -> unit
+        = "camljava_SetCamlintArrayElement"
+external new_long_array: int -> obj
+        = "camljava_NewLongArray"
+external get_long_array_element: obj -> int -> int64
+        = "camljava_GetLongArrayElement"
+external set_long_array_element: obj -> int -> int64 -> unit
+        = "camljava_SetLongArrayElement"
+external new_float_array: int -> obj
+        = "camljava_NewFloatArray"
+external get_float_array_element: obj -> int -> float
+        = "camljava_GetFloatArrayElement"
+external set_float_array_element: obj -> int -> float -> unit
+        = "camljava_SetFloatArrayElement"
+external new_double_array: int -> obj
+        = "camljava_NewDoubleArray"
+external get_double_array_element: obj -> int -> float
+        = "camljava_GetDoubleArrayElement"
+external set_double_array_element: obj -> int -> float -> unit
+        = "camljava_SetDoubleArrayElement"
+
+(* Auxiliaries for Java->OCaml callbacks *)
+
+val wrap_object: < .. > -> obj
+

File camljava-0.3/lib/jni.mlp

+(***********************************************************************)
+(*                                                                     *)
+(*             OCamlJava: Objective Caml / Java interface              *)
+(*                                                                     *)
+(*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         *)
+(*                                                                     *)
+(*  Copyright 2001 Institut National de Recherche en Informatique et   *)
+(*  en Automatique.  All rights reserved.  This file is distributed    *)
+(*  under the terms of the GNU Library General Public License.         *)
+(*                                                                     *)
+(***********************************************************************)
+
+(* $Id: jni.mlp,v 1.3 2003/02/20 13:42:40 xleroy Exp $ *)
+
+(* Low-level Java interface (JNI level) *)
+
+external init: string -> unit = "camljava_Init"
+external shutdown: unit -> unit = "camljava_Shutdown"
+
+let _ =
+  let libpath = "%PATH%" in  
+  let sep =
+    match Sys.os_type with
+      "Unix" -> ":"
+    | "Win32" -> ";"
+    | _ -> assert false in
+  let path =
+    try
+      Sys.getenv "CLASSPATH" ^ sep ^ libpath
+    with Not_found ->
+      libpath in
+  init path;
+  at_exit shutdown
+
+type obj
+
+external get_null: unit -> obj = "camljava_GetNull"
+
+let null = get_null()
+
+exception Null_pointer
+
+let _ = Callback.register_exception "camljava_null_pointer" Null_pointer
+
+exception Exception of obj
+
+let _ = Callback.register "camljava_raise_exception"
+          (fun obj -> raise (Exception obj))
+
+external register_natives: unit -> unit = "camljava_RegisterNatives"
+
+let _ = register_natives()
+
+let _ = Callback.register "Oo.new_method" Oo.new_method
+
+(* String operations *)
+
+external string_to_java: string -> obj = "camljava_MakeJavaString"
+external string_from_java: obj -> string = "camljava_ExtractJavaString"
+
+let null_string = ""
+
+let is_null_string s = s == null_string
+
+external register_null_string: string -> unit = "camljava_RegisterNullString"
+
+let _ = register_null_string null_string
+
+(* Class operations *)
+
+type clazz
+        (* The type of class identifiers *)
+
+external find_class: string -> clazz
+        = "camljava_FindClass"
+external get_superclass: clazz -> clazz
+        = "camljava_GetSuperclass"
+external is_assignable_from: clazz -> clazz -> bool
+        = "camljava_IsAssignableFrom"
+
+(* Field and method identifiers *)
+
+type fieldID
+type methodID
+
+external get_fieldID: clazz -> string -> string -> fieldID
+        = "camljava_GetFieldID"
+external get_static_fieldID: clazz -> string -> string -> fieldID
+        = "camljava_GetStaticFieldID"
+external get_methodID: clazz -> string -> string -> methodID
+        = "camljava_GetMethodID"
+external get_static_methodID: clazz -> string -> string -> methodID
+        = "camljava_GetStaticMethodID"
+
+(* Field access *)
+
+external get_object_field: obj -> fieldID -> obj
+        = "camljava_GetObjectField"
+external get_boolean_field: obj -> fieldID -> bool
+        = "camljava_GetBooleanField"
+external get_byte_field: obj -> fieldID -> int
+        = "camljava_GetByteField"
+external get_char_field: obj -> fieldID -> int
+        = "camljava_GetCharField"
+external get_short_field: obj -> fieldID -> int
+        = "camljava_GetShortField"
+external get_int_field: obj -> fieldID -> int32
+        = "camljava_GetIntField"
+external get_camlint_field: obj -> fieldID -> int
+        = "camljava_GetCamlintField"
+external get_long_field: obj -> fieldID -> int64
+        = "camljava_GetLongField"
+external get_float_field: obj -> fieldID -> float
+        = "camljava_GetFloatField"
+external get_double_field: obj -> fieldID -> float
+        = "camljava_GetFloatField"
+
+external set_object_field: obj -> fieldID -> obj -> unit
+        = "camljava_SetObjectField"
+external set_boolean_field: obj -> fieldID -> bool -> unit
+        = "camljava_SetBooleanField"
+external set_byte_field: obj -> fieldID -> int -> unit
+        = "camljava_SetByteField"
+external set_char_field: obj -> fieldID -> int -> unit
+        = "camljava_SetCharField"
+external set_short_field: obj -> fieldID -> int -> unit
+        = "camljava_SetShortField"
+external set_int_field: obj -> fieldID -> int32 -> unit
+        = "camljava_SetIntField"
+external set_camlint_field: obj -> fieldID -> int -> unit
+        = "camljava_SetCamlintField"
+external set_long_field: obj -> fieldID -> int64 -> unit
+        = "camljava_SetLongField"
+external set_float_field: obj -> fieldID -> float -> unit
+        = "camljava_SetFloatField"
+external set_double_field: obj -> fieldID -> float -> unit
+        = "camljava_SetFloatField"
+
+external get_static_object_field: clazz -> fieldID -> obj
+        = "camljava_GetStaticObjectField"
+external get_static_boolean_field: clazz -> fieldID -> bool
+        = "camljava_GetStaticBooleanField"
+external get_static_byte_field: clazz -> fieldID -> int
+        = "camljava_GetStaticByteField"
+external get_static_char_field: clazz -> fieldID -> int
+        = "camljava_GetStaticCharField"
+external get_static_short_field: clazz -> fieldID -> int
+        = "camljava_GetStaticShortField"
+external get_static_int_field: clazz -> fieldID -> int32
+        = "camljava_GetStaticIntField"
+external get_static_camlint_field: clazz -> fieldID -> int
+        = "camljava_GetStaticCamlintField"
+external get_static_long_field: clazz -> fieldID -> int64
+        = "camljava_GetStaticLongField"
+external get_static_float_field: clazz -> fieldID -> float
+        = "camljava_GetStaticFloatField"
+external get_static_double_field: clazz -> fieldID -> float
+        = "camljava_GetStaticFloatField"
+
+external set_static_obj_field: clazz -> fieldID -> obj -> unit
+        = "camljava_SetStaticObjectField"
+external set_static_boolean_field: clazz -> fieldID -> bool -> unit
+        = "camljava_SetStaticBooleanField"
+external set_static_byte_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticByteField"
+external set_static_char_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticCharField"
+external set_static_short_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticShortField"
+external set_static_int_field: clazz -> fieldID -> int32 -> unit
+        = "camljava_SetStaticIntField"
+external set_static_camlint_field: clazz -> fieldID -> int -> unit
+        = "camljava_SetStaticCamlintField"
+external set_static_long_field: clazz -> fieldID -> int64 -> unit
+        = "camljava_SetStaticLongField"
+external set_static_float_field: clazz -> fieldID -> float -> unit
+        = "camljava_SetStaticFloatField"
+external set_static_double_field: clazz -> fieldID -> float -> unit
+        = "camljava_SetStaticFloatField"
+
+type argument =
+    Boolean of bool
+  | Byte of int
+  | Char of int
+  | Short of int
+  | Camlint of int
+  | Int of int32
+  | Long of int64
+  | Float of float
+  | Double of float
+  | Obj of obj
+
+external call_object_method: obj -> methodID -> argument array -> obj
+        = "camljava_CallObjectMethod"
+external call_boolean_method: obj -> methodID -> argument array -> bool
+        = "camljava_CallBooleanMethod"
+external call_byte_method: obj -> methodID -> argument array -> int
+        = "camljava_CallByteMethod"
+external call_char_method: obj -> methodID -> argument array -> int
+        = "camljava_CallCharMethod"
+external call_short_method: obj -> methodID -> argument array -> int
+        = "camljava_CallShortMethod"
+external call_int_method: obj -> methodID -> argument array -> int32
+        = "camljava_CallIntMethod"
+external call_camlint_method: obj -> methodID -> argument array -> int
+        = "camljava_CallCamlintMethod"
+external call_long_method: obj -> methodID -> argument array -> int64
+        = "camljava_CallLongMethod"
+external call_float_method: obj -> methodID -> argument array -> float
+        = "camljava_CallFloatMethod"
+external call_double_method: obj -> methodID -> argument array -> float
+        = "camljava_CallDoubleMethod"
+external call_void_method: obj -> methodID -> argument array -> unit
+        = "camljava_CallVoidMethod"
+
+external call_static_object_method:
+                 clazz -> methodID -> argument array -> obj
+        = "camljava_CallStaticObjectMethod"
+external call_static_boolean_method:
+                 clazz -> methodID -> argument array -> bool
+        = "camljava_CallStaticBooleanMethod"
+external call_static_byte_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticByteMethod"
+external call_static_char_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticCharMethod"
+external call_static_short_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticShortMethod"
+external call_static_int_method:
+                 clazz -> methodID -> argument array -> int32
+        = "camljava_CallStaticIntMethod"
+external call_static_camlint_method:
+                 clazz -> methodID -> argument array -> int
+        = "camljava_CallStaticCamlintMethod"
+external call_static_long_method:
+                 clazz -> methodID -> argument array -> int64
+        = "camljava_CallStaticLongMethod"
+external call_static_float_method:
+                 clazz -> methodID -> argument array -> float
+        = "camljava_CallStaticFloatMethod"
+external call_static_double_method:
+                 clazz -> methodID -> argument array -> float
+        = "camljava_CallStaticDoubleMethod"
+external call_static_void_method:
+                 clazz -> methodID -> argument array -> unit
+        = "camljava_CallStaticVoidMethod"
+
+external call_nonvirtual_object_method:
+                 obj -> clazz -> methodID -> argument array -> obj
+        = "camljava_CallNonvirtualObjectMethod"
+external call_nonvirtual_boolean_method:
+                 obj -> clazz -> methodID -> argument array -> bool
+        = "camljava_CallNonvirtualBooleanMethod"
+external call_nonvirtual_byte_method: 
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualByteMethod"
+external call_nonvirtual_char_method:
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualCharMethod"
+external call_nonvirtual_short_method:
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualShortMethod"
+external call_nonvirtual_int_method:
+                 obj -> clazz -> methodID -> argument array -> int32
+        = "camljava_CallNonvirtualIntMethod"
+external call_nonvirtual_camlint_method:
+                 obj -> clazz -> methodID -> argument array -> int
+        = "camljava_CallNonvirtualCamlintMethod"
+external call_nonvirtual_long_method:
+                 obj -> clazz -> methodID -> argument array -> int64
+        = "camljava_CallNonvirtualLongMethod"
+external call_nonvirtual_float_method:
+                 obj -> clazz -> methodID -> argument array -> float
+        = "camljava_CallNonvirtualFloatMethod"
+external call_nonvirtual_double_method:
+                 obj -> clazz -> methodID -> argument array -> float
+        = "camljava_CallNonvirtualDoubleMethod"
+external call_nonvirtual_void_method:
+                 obj -> clazz -> methodID -> argument array -> unit
+        = "camljava_CallNonvirtualVoidMethod"
+
+(* Arrays *)
+
+external get_array_length: obj -> int = "camljava_GetArrayLength"
+
+external new_object_array: int -> clazz -> obj
+        = "camljava_NewObjectArray"
+external get_object_array_element: obj -> int -> obj
+        = "camljava_GetObjectArrayElement"
+external set_object_array_element: obj -> int -> obj -> unit
+        = "camljava_SetObjectArrayElement"
+external new_boolean_array: int -> obj
+        = "camljava_NewBooleanArray"
+external get_boolean_array_element: obj -> int -> bool
+        = "camljava_GetBooleanArrayElement"
+external set_boolean_array_element: obj -> int -> bool -> unit
+        = "camljava_SetBooleanArrayElement"
+external new_byte_array: int -> obj
+        = "camljava_NewByteArray"
+external get_byte_array_element: obj -> int -> int
+        = "camljava_GetByteArrayElement"
+external set_byte_array_element: obj -> int -> int -> unit
+        = "camljava_SetByteArrayElement"
+external get_byte_array_region: obj -> int -> string -> int -> int -> unit
+        = "camljava_GetByteArrayRegion"
+external set_byte_array_region: string -> int -> obj -> int -> int -> unit
+        = "camljava_SetByteArrayRegion"
+external new_char_array: int -> obj
+        = "camljava_NewCharArray"
+external get_char_array_element: obj -> int -> int
+        = "camljava_GetCharArrayElement"
+external set_char_array_element: obj -> int -> int -> unit
+        = "camljava_SetCharArrayElement"
+external new_short_array: int -> obj
+        = "camljava_NewShortArray"
+external get_short_array_element: obj -> int -> int
+        = "camljava_GetShortArrayElement"
+external set_short_array_element: obj -> int -> int -> unit
+        = "camljava_SetShortArrayElement"
+external new_int_array: int -> obj
+        = "camljava_NewIntArray"
+external get_int_array_element: obj -> int -> int32
+        = "camljava_GetIntArrayElement"
+external set_int_array_element: obj -> int -> int32 -> unit
+        = "camljava_SetIntArrayElement"
+external get_camlint_array_element: obj -> int -> int
+        = "camljava_GetCamlintArrayElement"
+external set_camlint_array_element: obj -> int -> int -> unit
+        = "camljava_SetCamlintArrayElement"
+external new_long_array: int -> obj
+        = "camljava_NewLongArray"
+external get_long_array_element: obj -> int -> int64
+        = "camljava_GetLongArrayElement"
+external set_long_array_element: obj -> int -> int64 -> unit
+        = "camljava_SetLongArrayElement"
+external new_float_array: int -> obj
+        = "camljava_NewFloatArray"
+external get_float_array_element: obj -> int -> float
+        = "camljava_GetFloatArrayElement"
+external set_float_array_element: obj -> int -> float -> unit
+        = "camljava_SetFloatArrayElement"
+external new_double_array: int -> obj
+        = "camljava_NewDoubleArray"
+external get_double_array_element: obj -> int -> float
+        = "camljava_GetDoubleArrayElement"
+external set_double_array_element: obj -> int -> float -> unit
+        = "camljava_SetDoubleArrayElement"
+
+(* Object operations *)
+
+external is_null: obj -> bool = "camljava_IsNull"
+external alloc_object: clazz -> obj = "camljava_AllocObject"
+external get_object_class: obj -> clazz = "camljava_GetObjectClass"
+external is_instance_of: obj -> clazz -> bool = "camljava_IsInstanceOf"
+external is_same_object: obj -> obj -> bool = "camljava_IsSameObject"
+
+(* Auxiliaries for Java->OCaml callbacks *)
+
+external wrap_caml_object : < .. > -> int64 = "camljava_WrapCamlObject"
+
+let callback_class =
+  find_class "fr/inria/caml/camljava/Callback"
+let callback_init =
+  get_methodID callback_class "<init>" "(J)V"
+let wrap_object camlobj =
+  let javaobj = alloc_object callback_class in
+  call_nonvirtual_void_method javaobj callback_class callback_init
+                              [|Long (wrap_caml_object camlobj)|];
+  javaobj

File camljava-0.3/lib/jnistubs.c

+#include <stddef.h>
+#include <string.h>
+#include <jni.h>
+#include <caml/mlvalues.h>
+#include <caml/memory.h>
+#include <caml/alloc.h>
+#include <caml/custom.h>
+#include <caml/fail.h>
+#include <caml/callback.h>
+
+static JavaVM * jvm;
+static JNIEnv * jenv;
+
+#define Val_jboolean(b) ((b) == JNI_FALSE ? Val_false : Val_true)
+#define Jboolean_val(v) (Val_bool(v) ? JNI_TRUE : JNI_FALSE)
+
+/************ Wrapping of Java objects as Caml values *************/
+
+#define JObject(v) (*((jobject *) Data_custom_val(v)))
+
+static void finalize_jobject(value v)
+{
+  jobject obj = JObject(v);
+  if (obj != NULL) (*jenv)->DeleteGlobalRef(jenv, obj);
+}
+
+static struct custom_operations jobject_ops = {
+  "java.lang.Object",
+  finalize_jobject,
+  custom_compare_default,       /* TODO? call equals() or compareTo() */
+  custom_hash_default,          /* TODO? call hashCode() */
+  custom_serialize_default,     /* TODO? use Java serialization intf */
+  custom_deserialize_default    /* TODO? use Java serialization intf */
+};
+
+static value alloc_jobject(jobject obj)
+{
+  value v = alloc_custom(&jobject_ops, sizeof(jobject), 0, 1);
+  if (obj != NULL) {
+    obj = (*jenv)->NewGlobalRef(jenv, obj);
+    if (obj == NULL) raise_out_of_memory();
+  }
+  JObject(v) = obj;
+  return v;
+}
+
+value camljava_GetNull(value unit)
+{
+  return alloc_jobject(NULL);
+}
+
+value camljava_IsNull(value vobj)
+{
+  return Val_bool(JObject(vobj) == NULL);
+}
+
+/*********** Reflecting Java exceptions as Caml exceptions *************/
+
+static void check_java_exception(void)
+{
+  jthrowable exn;
+  value vobj;
+  static value * camljava_raise_exception = NULL;
+
+  exn = (*jenv)->ExceptionOccurred(jenv);
+  if (exn != NULL) {
+#if 0
+    /* For debugging */
+    (*jenv)->ExceptionDescribe(jenv);
+#endif
+    (*jenv)->ExceptionClear(jenv);
+    /* TODO: check Caml exception embedded into Java exception */
+    if (camljava_raise_exception == NULL) {
+      camljava_raise_exception = caml_named_value("camljava_raise_exception");
+      if (camljava_raise_exception == NULL)
+        invalid_argument("Java_lang not linked in");
+    }
+    vobj = alloc_jobject(exn);
+    (*jenv)->DeleteLocalRef(jenv, exn);
+    callback(*camljava_raise_exception, vobj);
+  }
+}
+
+static void check_non_null(value jobj)
+{
+  static value * camljava_null_pointer;
+  if (JObject(jobj) != NULL) return;
+  if (camljava_null_pointer == NULL) {
+    camljava_null_pointer = caml_named_value("camljava_null_pointer");
+    if (camljava_null_pointer == NULL)
+      invalid_argument("Java not linked in");
+  }
+  raise_constant(*camljava_null_pointer);
+}
+
+/*********** Class operations ************/
+
+value camljava_FindClass(value vname)
+{
+  jclass c = (*jenv)->FindClass(jenv, String_val(vname));
+  if (c == NULL) check_java_exception();
+  return alloc_jobject(c);
+}
+
+value camljava_GetSuperclass(value vclass)
+{
+  jclass c = (*jenv)->GetSuperclass(jenv, JObject(vclass));
+  if (c == NULL) check_java_exception();
+  return alloc_jobject(c);
+}
+
+value camljava_IsAssignableFrom(value vclass1, value vclass2)
+{
+  jboolean b =
+    (*jenv)->IsAssignableFrom(jenv, JObject(vclass1), JObject(vclass2));
+  return Val_jboolean(b);
+}
+
+/*********** Field IDs ***************/
+
+#define JField(v) (*((jfieldID *) (v)))
+
+static value alloc_jfieldID(jfieldID id)
+{
+  value v = alloc((sizeof(jfieldID) + sizeof(value) - 1) / sizeof(value),
+                  Abstract_tag);
+  JField(v) = id;
+  return v;
+}
+
+value camljava_GetFieldID(value vclass, value vname, value vsig)
+{
+  jfieldID id = (*jenv)->GetFieldID(jenv, JObject(vclass),
+                                    String_val(vname), String_val(vsig));
+  if (id == NULL) check_java_exception();
+  return alloc_jfieldID(id);
+}
+
+value camljava_GetStaticFieldID(value vclass, value vname, value vsig)
+{
+  jfieldID id = (*jenv)->GetStaticFieldID(jenv, JObject(vclass),
+                                          String_val(vname), String_val(vsig));
+  if (id == NULL) check_java_exception();
+  return alloc_jfieldID(id);
+}
+
+/*********** Field access *************/
+
+#define GETFIELD(name,restyp,resconv)                                       \
+value camljava_##name(value vobj, value vfield)                             \
+{                                                                           \
+  restyp res;                                                               \
+  check_non_null(vobj);                                                     \
+  res = (*jenv)->name(jenv, JObject(vobj), JField(vfield));                 \
+  return resconv(res);                                                      \
+}
+
+GETFIELD(GetObjectField, jobject, alloc_jobject)
+GETFIELD(GetBooleanField, jboolean, Val_jboolean)
+GETFIELD(GetByteField, jbyte, Val_int)
+GETFIELD(GetCharField, jchar, Val_int)
+GETFIELD(GetShortField, jshort, Val_int)
+GETFIELD(GetIntField, jint, copy_int32)
+GETFIELD(GetLongField, jlong, copy_int64)
+GETFIELD(GetFloatField, jfloat, copy_double)
+GETFIELD(GetDoubleField, jdouble, copy_double)
+
+value camljava_GetCamlintField(value vobj, value vfield)
+{
+  jint res;
+  check_non_null(vobj);
+  res = (*jenv)->GetIntField(jenv, JObject(vobj), JField(vfield));
+  return Val_int(res);
+}
+
+#define SETFIELD(name,argtyp,argconv)                                       \
+value camljava_##name(value vobj, value vfield, value vnewval)              \
+{                                                                           \
+  argtyp arg = argconv(vnewval);                                            \
+  check_non_null(vobj);                                                     \
+  (*jenv)->name(jenv, JObject(vobj), JField(vfield), arg);                  \
+  return Val_unit;                                                          \
+}
+
+SETFIELD(SetObjectField, jobject, JObject)
+SETFIELD(SetBooleanField, jboolean, Jboolean_val)
+SETFIELD(SetByteField, jbyte, Int_val)
+SETFIELD(SetCharField, jchar, Int_val)
+SETFIELD(SetShortField, jshort, Int_val)
+SETFIELD(SetIntField, jint, Int32_val)
+SETFIELD(SetLongField, jlong, Int64_val)
+SETFIELD(SetFloatField, jfloat, Double_val)
+SETFIELD(SetDoubleField, jdouble, Double_val)
+
+value camljava_SetCamlintField(value vobj, value vfield, value vnewval)
+{
+  jint arg = Int_val(vnewval);
+  check_non_null(vobj);
+  (*jenv)->SetIntField(jenv, JObject(vobj), JField(vfield), arg);
+  return Val_unit;
+}
+
+#define GETSTATICFIELD(name,restyp,resconv)                                   \
+value camljava_##name(value vclass, value vfield)                             \
+{                                                                             \
+  restyp res = (*jenv)->name(jenv, JObject(vclass), JField(vfield));          \
+  return resconv(res);                                                        \
+}
+
+GETSTATICFIELD(GetStaticObjectField, jobject, alloc_jobject)
+GETSTATICFIELD(GetStaticBooleanField, jboolean, Val_jboolean)
+GETSTATICFIELD(GetStaticByteField, jbyte, Val_int)
+GETSTATICFIELD(GetStaticCharField, jchar, Val_int)
+GETSTATICFIELD(GetStaticShortField, jshort, Val_int)
+GETSTATICFIELD(GetStaticIntField, jint, copy_int32)
+GETSTATICFIELD(GetStaticLongField, jlong, copy_int64)
+GETSTATICFIELD(GetStaticFloatField, jfloat, copy_double)
+GETSTATICFIELD(GetStaticDoubleField, jdouble, copy_double)
+
+value camljava_GetStaticCamlintField(value vclass, value vfield)
+{
+  jint res = (*jenv)->GetStaticIntField(jenv, JObject(vclass), JField(vfield));
+  return Val_int(res);
+}
+
+#define SETSTATICFIELD(name,argtyp,argconv)                                   \
+value camljava_##name(value vclass, value vfield, value vnewval)              \
+{                                                                             \
+  argtyp arg = argconv(vnewval);                                              \
+  (*jenv)->name(jenv, JObject(vclass), JField(vfield), arg);                  \
+  return Val_unit;                                                            \
+}
+
+SETSTATICFIELD(SetStaticObjectField, jobject, JObject)
+SETSTATICFIELD(SetStaticBooleanField, jboolean, Jboolean_val)
+SETSTATICFIELD(SetStaticByteField, jbyte, Int_val)
+SETSTATICFIELD(SetStaticCharField, jchar, Int_val)
+SETSTATICFIELD(SetStaticShortField, jshort, Int_val)
+SETSTATICFIELD(SetStaticIntField, jint, Int32_val)
+SETSTATICFIELD(SetStaticLongField, jlong, Int64_val)
+SETSTATICFIELD(SetStaticFloatField, jfloat, Double_val)
+SETSTATICFIELD(SetStaticDoubleField, jdouble, Double_val)
+
+value camljava_SetStaticCamlintField(value vclass, value vfield, value vnewval)
+{
+  jint arg = Val_int(vnewval);
+  (*jenv)->SetStaticIntField(jenv, JObject(vclass), JField(vfield), arg);
+  return Val_unit;
+}
+
+/*********** Method IDs ***************/
+
+#define JMethod(v) (*((jmethodID *) (v)))
+
+static value alloc_jmethodID(jmethodID id)
+{
+  value v = alloc((sizeof(jmethodID) + sizeof(value) - 1) / sizeof(value),
+                  Abstract_tag);
+  JMethod(v) = id;
+  return v;
+}
+
+value camljava_GetMethodID(value vclass, value vname, value vsig)
+{
+  jmethodID id = (*jenv)->GetMethodID(jenv, JObject(vclass),
+                                      String_val(vname), String_val(vsig));
+  if (id == NULL) check_java_exception();
+  return alloc_jmethodID(id);
+}
+
+value camljava_GetStaticMethodID(value vclass, value vname, value vsig)
+{
+  jmethodID id =
+    (*jenv)->GetStaticMethodID(jenv, JObject(vclass),
+                               String_val(vname), String_val(vsig));
+  if (id == NULL) check_java_exception();
+  return alloc_jmethodID(id);
+}
+
+/*************** The jvalue union ***************/
+
+enum {
+  Tag_Boolean,
+  Tag_Byte,
+  Tag_Char,
+  Tag_Short,
+  Tag_Camlint,
+  Tag_Int,
+  Tag_Long,
+  Tag_Float,
+  Tag_Double,
+  Tag_Object
+};
+
+static void jvalue_val(value v, /*out*/ jvalue * j)
+{
+  switch (Tag_val(v)) {
+  case Tag_Boolean:  j->z = Jboolean_val(Field(v, 0));
+  case Tag_Byte:     j->b = Int_val(Field(v, 0)); break;
+  case Tag_Char:     j->c = Int_val(Field(v, 0)); break;
+  case Tag_Short:    j->s = Int_val(Field(v, 0)); break;
+  case Tag_Camlint:  j->i = Int_val(Field(v, 0)); break;
+  case Tag_Int:      j->i = Int32_val(Field(v, 0)); break;
+  case Tag_Long:     j->j = Int64_val(Field(v, 0)); break;
+  case Tag_Float:    j->f = Double_val(Field(v, 0)); break;
+  case Tag_Double:   j->d = Double_val(Field(v, 0)); break;
+  case Tag_Object:   j->l = JObject(Field(v, 0)); break;
+  }
+}
+
+#define NUM_DEFAULT_ARGS 8
+
+static jvalue * convert_args(value vargs, jvalue default_args[])
+{
+  mlsize_t nargs = Wosize_val(vargs);
+  jvalue * args;
+  mlsize_t i;
+
+  if (nargs <= NUM_DEFAULT_ARGS)
+    args = default_args;
+  else
+    args = stat_alloc(nargs * sizeof(jvalue));
+  for (i = 0; i < nargs; i++) jvalue_val(Field(vargs, i), &(args[i]));
+  return args;
+}
+
+/************* Method invocation **************/
+
+#define CALLMETHOD(callname,restyp,resconv)                                 \
+value camljava_##callname(value vobj, value vmeth, value vargs)             \
+{                                                                           \
+  jvalue default_args[NUM_DEFAULT_ARGS];                                    \
+  jvalue * args;                                                            \
+  restyp res;                                                               \
+  check_non_null(vobj);                                                     \
+  args = convert_args(vargs, default_args);                                 \
+  res = (*jenv)->callname##A(jenv, JObject(vobj), JMethod(vmeth), args);    \
+  if (args != default_args) stat_free(args);                                \
+  check_java_exception();                                                   \
+  return resconv(res);                                                      \
+}
+
+CALLMETHOD(CallObjectMethod, jobject, alloc_jobject)
+CALLMETHOD(CallBooleanMethod, jboolean, Val_jboolean)
+CALLMETHOD(CallByteMethod, jbyte, Val_int)
+CALLMETHOD(CallCharMethod, jchar, Val_int)
+CALLMETHOD(CallShortMethod, jshort, Val_int)
+CALLMETHOD(CallIntMethod, jint, copy_int32)
+CALLMETHOD(CallLongMethod, jlong, copy_int64)
+CALLMETHOD(CallFloatMethod, jfloat, copy_double)
+CALLMETHOD(CallDoubleMethod, jdouble, copy_double)
+
+value camljava_CallCamlintMethod(value vobj, value vmeth, value vargs)
+{
+  jvalue default_args[NUM_DEFAULT_ARGS];
+  jvalue * args;
+  jint res;
+  check_non_null(vobj);
+  args = convert_args(vargs, default_args);
+  res = (*jenv)->CallIntMethodA(jenv, JObject(vobj), JMethod(vmeth), args);
+  if (args != default_args) stat_free(args);
+  check_java_exception();
+  return Val_int(res);
+}
+
+value camljava_CallVoidMethod(value vobj, value vmeth, value vargs)
+{
+  jvalue default_args[NUM_DEFAULT_ARGS];
+  jvalue * args;
+  check_non_null(vobj);
+  args = convert_args(vargs, default_args);
+  (*jenv)->CallVoidMethodA(jenv, JObject(vobj), JMethod(vmeth), args);
+  if (args != default_args) stat_free(args);
+  check_java_exception();
+  return Val_unit;
+}
+
+#define CALLSTATICMETHOD(callname,restyp,resconv)                           \
+value camljava_##callname(value vclass, value vmeth, value vargs)           \
+{                                                                           \
+  jvalue default_args[NUM_DEFAULT_ARGS];                                    \
+  jvalue * args = convert_args(vargs, default_args);                        \
+  restyp res =                                                              \
+    (*jenv)->callname##A(jenv, JObject(vclass), JMethod(vmeth), args);      \
+  if (args != default_args) stat_free(args);                                \
+  check_java_exception();                                                   \
+  return resconv(res);                                                      \
+}
+
+CALLSTATICMETHOD(CallStaticObjectMethod, jobject, alloc_jobject)
+CALLSTATICMETHOD(CallStaticBooleanMethod, jboolean, Val_int)
+CALLSTATICMETHOD(CallStaticByteMethod, jbyte, Val_int)
+CALLSTATICMETHOD(CallStaticCharMethod, jchar, Val_int)
+CALLSTATICMETHOD(CallStaticShortMethod, jshort, Val_int)
+CALLSTATICMETHOD(CallStaticIntMethod, jint, copy_int32)
+CALLSTATICMETHOD(CallStaticLongMethod, jlong, copy_int64)
+CALLSTATICMETHOD(CallStaticFloatMethod, jfloat, copy_double)
+CALLSTATICMETHOD(CallStaticDoubleMethod, jdouble, copy_double)
+
+value camljava_CallStaticCamlintMethod(value vclass, value vmeth, value vargs)
+{
+  jvalue default_args[NUM_DEFAULT_ARGS];
+  jvalue * args = convert_args(vargs, default_args);
+  jint res =
+    (*jenv)->CallStaticIntMethodA(jenv, JObject(vclass), JMethod(vmeth), args);
+  if (args != default_args) stat_free(args);
+  check_java_exception();
+  return Val_int(res);
+}
+
+value camljava_CallStaticVoidMethod(value vclass, value vmeth, value vargs)
+{
+  jvalue default_args[NUM_DEFAULT_ARGS];
+  jvalue * args = convert_args(vargs, default_args);
+  (*jenv)->CallStaticVoidMethodA(jenv, JObject(vclass), JMethod(vmeth), args);
+  if (args != default_args) stat_free(args);
+  check_java_exception();
+  return Val_unit;
+}
+
+#define CALLNONVIRTUALMETHOD(callname,restyp,resconv)                       \
+value camljava_##callname(value vobj, value vclass, value vmeth, value vargs)\
+{                                                                           \
+  jvalue default_args[NUM_DEFAULT_ARGS];                                    \
+  jvalue * args;                                                            \
+  restyp res;                                                               \
+  check_non_null(vobj);                                                     \
+  args = convert_args(vargs, default_args);                                 \
+  res = (*jenv)->callname##A(jenv, JObject(vobj), JObject(vclass),          \
+                             JMethod(vmeth), args);                         \
+  if (args != default_args) stat_free(args);                                \
+  check_java_exception();                                                   \
+  return resconv(res);                                                      \
+}
+
+CALLNONVIRTUALMETHOD(CallNonvirtualObjectMethod, jobject, alloc_jobject)
+CALLNONVIRTUALMETHOD(CallNonvirtualBooleanMethod, jboolean, Val_int)
+CALLNONVIRTUALMETHOD(CallNonvirtualByteMethod, jbyte, Val_int)
+CALLNONVIRTUALMETHOD(CallNonvirtualCharMethod, jchar, Val_int)
+CALLNONVIRTUALMETHOD(CallNonvirtualShortMethod, jshort, Val_int)
+CALLNONVIRTUALMETHOD(CallNonvirtualIntMethod, jint, copy_int32)
+CALLNONVIRTUALMETHOD(CallNonvirtualLongMethod, jlong, copy_int64)
+CALLNONVIRTUALMETHOD(CallNonvirtualFloatMethod, jfloat, copy_double)
+CALLNONVIRTUALMETHOD(CallNonvirtualDoubleMethod, jdouble, copy_double)
+
+value camljava_CallNonvirtualCamlintMethod(value vobj, value vclass,
+                                           value vmeth, value vargs)
+{
+  jvalue default_args[NUM_DEFAULT_ARGS];
+  jvalue * args;
+  jint res;
+  check_non_null(vobj);
+  args = convert_args(vargs, default_args);
+  res = (*jenv)->CallNonvirtualIntMethodA(jenv, JObject(vobj), JObject(vclass),
+                                          JMethod(vmeth), args);
+  if (args != default_args) stat_free(args);
+  check_java_exception();
+  return Val_int(res);
+}
+
+value camljava_CallNonvirtualVoidMethod(value vobj, value vclass,
+                                        value vmeth, value vargs)
+{
+  jvalue default_args[NUM_DEFAULT_ARGS];
+  jvalue * args;
+  check_non_null(vobj);
+  args = convert_args(vargs, default_args);
+  (*jenv)->CallNonvirtualVoidMethodA(jenv, JObject(vobj), JObject(vclass),
+                                     JMethod(vmeth), args);
+  if (args != default_args) stat_free(args);
+  check_java_exception();
+  return Val_unit;
+}
+
+/************** Strings ********************/
+
+/* Note: by lack of wide strings in Caml, we map Java strings to
+   UTF8-encoded Caml strings */
+
+static value camljava_null_string;
+
+value camljava_RegisterNullString(value null_string)
+{
+  camljava_null_string = null_string;
+  register_global_root(&camljava_null_string);
+  return Val_unit;
+}
+
+value camljava_MakeJavaString (value vstr)
+{
+  jstring jstr;
+  if (vstr == camljava_null_string)
+    jstr = NULL;
+  else {
+    jstr = (*jenv)->NewStringUTF(jenv, String_val(vstr));
+    if (jstr == NULL) check_java_exception();
+  }
+  return alloc_jobject(jstr);
+}
+
+static value extract_java_string (JNIEnv * env, jstring jstr)
+{
+  jsize len;
+  value res;
+  jboolean isCopy;
+  const char * chrs;
+
+  if (jstr == NULL) return camljava_null_string;
+  len = (*env)->GetStringUTFLength(env, jstr);
+  res = alloc_string(len);
+  chrs = (*env)->GetStringUTFChars(env, jstr, &isCopy);
+  memcpy(String_val(res), chrs, len);
+  (*env)->ReleaseStringUTFChars(env, jstr, chrs);
+  return res;
+}
+
+value camljava_ExtractJavaString (value vobj)
+{
+  value res;
+
+  Begin_root(vobj)              /* prevent deallocation of Java string */
+    res = extract_java_string(jenv, (jstring) JObject(vobj));
+  End_roots();
+  return res;
+}
+
+/******************** Arrays *******************/
+
+value camljava_GetArrayLength(value varray)
+{
+  jsize len;
+  check_non_null(varray);
+  len = (*jenv)->GetArrayLength(jenv, (jarray) JObject(varray));
+  return Val_int(len);
+}
+
+value camljava_NewObjectArray(value vsize, value vclass)
+{
+  jobjectArray arr =
+    (*jenv)->NewObjectArray(jenv, Int_val(vsize), 
+                           (jclass) JObject(vclass), NULL);
+  if (arr == NULL) check_java_exception();
+  return alloc_jobject(arr);
+}
+
+value camljava_GetObjectArrayElement(value varray, value vidx)
+{
+  jobject res;
+  check_non_null(varray);
+  res = (*jenv)->GetObjectArrayElement(jenv, (jobjectArray) JObject(varray),
+                                       Int_val(vidx));
+  check_java_exception();
+  return alloc_jobject(res);
+}
+
+value camljava_SetObjectArrayElement(value varray, value vidx, value vnewval)
+{
+  check_non_null(varray);
+  (*jenv)->SetObjectArrayElement(jenv, (jobjectArray) JObject(varray),
+                                Int_val(vidx), JObject(vnewval));
+  check_java_exception();
+  return Val_unit;
+}
+
+#define ARRAYNEWGETSET(name,array_typ,elt_typ,from_value,to_value)            \
+value camljava_New##name##Array(value vsize)                                  \
+{                                                                             \
+  array_typ arr = (*jenv)->New##name##Array(jenv, Int_val(vsize));            \
+  if (arr == NULL) check_java_exception();                                    \
+  return alloc_jobject(arr);                                                  \
+}                                                                             \
+                                                                              \
+value camljava_Get##name##ArrayElement(value varray, value vidx)              \
+{                                                                             \
+  elt_typ elt;                                                                \
+  check_non_null(varray);                                                     \