diff --git a/examples/jvm-interop/bridge.c b/examples/jvm-interop/bridge.c index 75621e4877..0585e075c2 100644 --- a/examples/jvm-interop/bridge.c +++ b/examples/jvm-interop/bridge.c @@ -14,6 +14,11 @@ JavaVM* vm; +#define ERR_MSG_MAX_SIZE 256 + +jmp_buf exception_buffer; +char* err_msg[ERR_MSG_MAX_SIZE] = {0}; + jint JNI_OnLoad(JavaVM *loadedVM, void *reserved) { // https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html @@ -37,27 +42,17 @@ void roc_dealloc(void *ptr, unsigned int alignment) free(ptr); } -jint javaException(void *ptr) -{ - JNIEnv* env = NULL; - jint returnCode = (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6); - - if (returnCode != JNI_OK) { - printf("failed to get jvm env"); - exit(1); - } - - char* msg = ptr == NULL ? "roc panic" : (char*)ptr; - jclass exceptionClass = (*env)->FindClass(env, "java/lang/RuntimeException"); - return (*env)->ThrowNew(env, exceptionClass, msg); -} - __attribute__((noreturn)) void roc_panic(void *ptr, unsigned int alignment) { - // TODO throw a RuntimeException from JNI - if (ptr != NULL) - printf("%s", ptr); - exit(1); + if (ptr != NULL) { + int ptr_len = strlen((char*)ptr); + int len = ptr_len > ERR_MSG_MAX_SIZE ? ERR_MSG_MAX_SIZE : ptr_len; + strncpy((char*)err_msg, ptr, (len + 1)); + } + else { + strncpy((char *)err_msg, "roc paniced", strlen("roc paniced") + 1); + } + longjmp(exception_buffer, 1); } @@ -327,6 +322,15 @@ JNIEXPORT jlong JNICALL Java_javaSource_Demo_factorial (JNIEnv *env, jobject thisObj, jlong n) { int64_t ret; - roc__programForHost_1__Factorial_caller(&n, 0, &ret); - return ret; + // can crash - meaning call roc_panic, so we set a jump here + if (setjmp(exception_buffer)) { + // exception was thrown, handle it + jclass exClass = (*env)->FindClass(env, "java/lang/RuntimeException"); + const char *msg = (const char *)err_msg; + return (*env)->ThrowNew(env, exClass, msg); + } + else { + roc__programForHost_1__Factorial_caller(&n, 0, &ret); + return ret; + } } diff --git a/examples/jvm-interop/javaSource/Demo.java b/examples/jvm-interop/javaSource/Demo.java index 677dfc63df..aa233aea79 100644 --- a/examples/jvm-interop/javaSource/Demo.java +++ b/examples/jvm-interop/javaSource/Demo.java @@ -12,7 +12,7 @@ public class Demo { public static native int[] mulArrByScalar(int[] arr, int scalar); - public static native long factorial(long n); + public static native long factorial(long n) throws RuntimeException; public static void main(String[] args) { @@ -23,7 +23,7 @@ public class Demo { // array demo int[] arr = {10, 20, 30, 40}; int x = 3; - System.out.println("Array " + Arrays.toString(arr) + + System.out.println(Arrays.toString(arr) + " multipled by " + x + " results in " + Arrays.toString(mulArrByScalar(arr, x)) + "\n"); @@ -33,7 +33,7 @@ public class Demo { // this will panic from the roc side if n is negative // and in turn will throw a JVM RuntimeException long n = 5; - System.out.println("Factorial of " + n + " is " + factorial(n) + "\n"); + System.out.println("Factorial of " + n + " is " + factorial(n)); } }