xtc.lang.jeannie |
A compiler contributed to xtc that integrates Java with C. Both
language and compiler are described in
an OOPSLA '07
paper by Martin Hirzel and Robert Grimm.
Prerequisites
You need Java 1.5, gcc, and the usual GNU tooling (in particular, gcc
and make). We have tested Jeannie under Mac OS X with HotSpot, and
under Linux and Cygwin with IBM Java.
Environment variables
JAVA_DEV_ROOT |
set this such that $JAVA_DEV_ROOT/xtc is the top-level xtc directory |
PATH_SEP |
':' for MacOS or Linux, or ';' for Cygwin |
CLASSPATH |
$JAVA_DEV_ROOT/classes$PATH_SEP$JAVA_DEV_ROOT/bin/junit.jar$PATH_SEP$JAVA_DEV_ROOT/bin/antlr.jar |
JAVA_HOME |
set this such that $JAVA_HOME/bin/java is the Java virtual machine |
CPATH |
should include the directory that contains jni.h, which is most likely $JAVA_HOME/include |
PATH |
should include $JAVA_HOME/bin |
---|
OSTYPE |
should be either cygwin, or have linux or darwin as a substring |
Testing using the Makefile
Try the following:
make -C $JAVA_DEV_ROOT/fonda/jeannie_testsuite test_000
If all goes well, that should produce the output:
==== integration test_000 ====
Processing tmp/000sugared/Main.jni ...
diff tmp/000mangled/output.txt tmp/000sugared/output.txt
What happened is that the Makefile compiled and ran the same test
written in Jeannie (fonda/jeannie_testsuite/input/000sugared_Main.jni)
and in JNI (fonda/jeannie_testsuite/input/000mangled_Main.{c,java}),
and compared the output.
You can also run all included integration tests in batch mode:
make -C $JAVA_DEV_ROOT/fonda/jeannie_testsuite test
To find out the individual compilation steps, uncomment the following
line in the Makefile:
# export VERBOSE_MAKE=true
Compiling your own programs
The easiest way is to follow the existing examples and use the
existing Makefiles. But if you prefer to compile by hand, the
following example compiles and runs foo/Bar.jni
- Run Jeannie preprocessor to inject "#include <jni.h>" at the start of the file.
java -ea xtc.lang.jeannie.PreJeannieParser foo/Main.jni > foo/Main.jni.pp
- Run C prepreocessor to resolve #includes, #ifdefs, and macros.
# Mac OS:
cc -DSPECIALIZE_RELPROD -DSPECIALIZE_AND -DSPECIALIZE_OR -DSMALL_NODES -fomit-frame-pointer -fno-common -I/System/Library/Frameworks/JavaVM.framework/Headers -E -x c foo/Bar.jni.pp > foo/Bar.jni.i
# Linux:
gcc -E -x c foo/Bar.jni.pp > foo/Bar.jni.i
# Cygwin:
gcc -mno-cygwin -I$JAVA_HOME/include -E -x c foo/Bar.jni.pp > foo/Bar.jni.i
- Run Jeannie compiler.
# Mac OS or Linux:
java -ea -DJNICALL='' xtc.lang.jeannie.Jeannie -analyze -translate -in foo foo/Bar.jni.i
# Cygwin:
java -ea -DJNICALL='__attribute__((__stdcall__))' xtc.lang.jeannie.Jeannie -analyze -translate -in foo foo/Bar.jni.i
- Compile resulting C code into a shared object file (dynamically linked libary):
# Mac OS:
cc -DSPECIALIZE_RELPROD -DSPECIALIZE_AND -DSPECIALIZE_OR -DSMALL_NODES -fomit-frame-pointer -fno-common -I/System/Library/Frameworks/JavaVM.framework/Headers -dynamiclib -framework JavaVM -o foo/libBar.jnilib foo/Bar.i
# Linux:
gcc -shared -o foo/libBar.so foo/Bar.i
# Cygwin:
gcc -mno-cygwin -I$JAVA_HOME/include -Wl,--add-stdcall-alias -shared -o foo/Bar.dll foo/Bar.i
- Compile resulting Java code into class files (bytecode):
javac -sourcepath foo -d foo foo/Bar.java
- Tell the dynamic linker where to find the shared object file.
export PATH=foo:"$PATH"
export LD_LIBRARY_PATH=foo:"$LD_LIBRARY_PATH"
- Run the code with a Java virtual machine.
java -cp foo -Djava.library.path=foo Bar
|
Java Source File Name | Type | Comment |
Analyzer.java | Class | A visitor that constructs a symbol table for a Jeannie file. |
AstSimplifier.java | Class | A visitor that simplifies Jeannie ASTs. |
CodeGenerator.java | Class | A visitor that constructs separate C and Java ASTs from a JNI AST. |
Debugger.java | Class | The Blink terminal debugger. |
DebuggerAstAnalyzer.java | Class | |
DebuggerAstPrinter.java | Class | |
DebuggerCommand.java | Class | The Blink macro command implementation. |
DebuggerExpression.java | Class | A Jeannie expression handler for the Blink debugger. |
DebuggerInterpreter.java | Class | |
DebuggerParser.java | Class | Packrat parser for grammar xtc.lang.jeannie.Debugger . |
DebuggerSymbolMapper.java | Interface | |
Jeannie.java | Class | A compiler from Jeannie to separate Java and C files that use JNI. |
JeannieCFactory.java | Class | Node factory xtc.lang.jeannie.JeannieCFactory . |
JeannieJavaFactory.java | Class | Node factory xtc.lang.jeannie.JeannieJavaFactory . |
JeannieParser.java | Class | Packrat parser for grammar xtc.lang.jeannie.Jeannie . |
JeanniePrinter.java | Class | A pretty printer for Jeannie (pretty JNI).
This is an example of combining two visitors (CPrinter and JavaPrinter). |
PreJeannieParser.java | Class | Packrat parser for grammar xtc.lang.jeannie.PreJeannie . |
Preprocessor.java | Class | |
UnitTests.java | Class | JUnit tests for classes in package xtc.lang.jeannie.
This class is a good place to quickly try a method on some simple
inputs. |
Utilities.java | Class | Static helper routines related to JNI and Jeannie.
This is a good place to put code that is useful for more than one visitor. |