X-Git-Url: http://nitlanguage.org diff --git a/lib/jvm.nit b/lib/jvm.nit index 4337d9e..4482a93 100644 --- a/lib/jvm.nit +++ b/lib/jvm.nit @@ -19,8 +19,8 @@ # # See: http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/jniTOC.html module jvm is - c_compiler_option("-I $(JAVA_HOME)/include/") - c_linker_option("-L $(JNI_LIB_PATH) -ljvm") + cflags "-I $(JAVA_HOME)/include/ -I $(JAVA_HOME)/include/linux/" + ldflags "-L $(JNI_LIB_PATH) -ljvm" end in "C Header" `{ @@ -30,7 +30,8 @@ in "C Header" `{ # Utility to select options to create the VM using `create_jvm` # # Usage example: -# ~~~~ +# +# ~~~~nitish # var builder = new JavaVMBuilder # builder.options.add "-Djava.class.path=." # var jvm = builder.create_jvm @@ -39,9 +40,15 @@ in "C Header" `{ class JavaVMBuilder super JniEnvRef - var version: Int = "00010002".to_hex + # Version code of the JVM requested by `create_jvm` + # + # Default at 0x00010002 + var version = 0x00010002 is writable + + # Additional option strings var options = new Array[String] + # Create the JVM and return it on success fun create_jvm: nullable JavaVM do var args = new JavaVMInitArgs @@ -68,7 +75,7 @@ class JavaVMBuilder end end -extern class JavaVMInitArgs `{ JavaVMInitArgs* `} +private extern class JavaVMInitArgs `{ JavaVMInitArgs* `} new `{ return (JavaVMInitArgs*)malloc(sizeof(JavaVMInitArgs)); `} # Set the defaut config for a VM @@ -91,7 +98,7 @@ extern class JavaVMInitArgs `{ JavaVMInitArgs* `} fun n_options=(v: Int) `{ recv->nOptions = v; `} end -extern class JavaVMOption `{ JavaVMOption* `} +private extern class JavaVMOption `{ JavaVMOption* `} fun string: String import NativeString.to_s `{ return NativeString_to_s((char*)recv->optionString); `} @@ -107,7 +114,7 @@ extern class JavaVMOption `{ JavaVMOption* `} `} end -extern class JavaVMOptionArray `{ JavaVMOption* `} +private extern class JavaVMOptionArray `{ JavaVMOption* `} new(size: Int) `{ return (JavaVMOption*)malloc(sizeof(JavaVMOption)*size); `} fun [](i: Int): JavaVMOption `{ return recv+i; `} @@ -118,7 +125,8 @@ extern class JavaVM `{JavaVM *`} # Create the JVM, returns its handle and store the a pointer to JniEnv in `env_ref` # # Unavailable on Android, where you cannot instanciate a new JVM. - new(args: JavaVMInitArgs, env_ref: JniEnvRef) import jni_error, JniEnvRef.jni_env=, JniEnv.as nullable `{ + private new(args: JavaVMInitArgs, env_ref: JniEnvRef) + import jni_error, JniEnvRef.jni_env=, JniEnv.as nullable `{ #ifdef ANDROID JavaVM_jni_error(NULL, "JVM creation not supported on Android", 0); @@ -141,7 +149,7 @@ extern class JavaVM `{JavaVM *`} } `} - fun jni_error(msg: NativeString, v: Int) + private fun jni_error(msg: NativeString, v: Int) do print "JNI Error: {msg} ({v})" abort @@ -161,7 +169,7 @@ extern class JavaVM `{JavaVM *`} return env; `} - fun attach_current_thread: JniEnv `{ + fun attach_current_thread: JniEnv import jni_error `{ JNIEnv *env; #ifdef ANDROID // the signature is different (better actually) on Android @@ -173,35 +181,36 @@ extern class JavaVM `{JavaVM *`} JavaVM_jni_error(NULL, "Could not attach current thread to Java VM", res); return NULL; } + return env; `} end # Represents a jni JNIEnv, which is a thread in a JavaVM extern class JniEnv `{JNIEnv *`} - + # Get a class object from its fully-qualified name or null if the class cannot be found fun find_class(class_name : String): JClass import String.to_cstring `{ return (*recv)->FindClass(recv,String_to_cstring(class_name)); `} - + # Return the method id for an instance of a class or interface # The method is determined by its name and signature # To obtain the method ID of a constructor, supply "" as the method name and "void(V)" as the return type fun get_method_id(clazz : JClass, name : String, signature : String): JMethodID import String.to_cstring `{ return (*recv)->GetMethodID(recv, clazz, String_to_cstring(name), String_to_cstring(signature)); `} - + # Construct a new Java object from the `clazz`, using the constructor ̀ method_id` fun new_object(clazz: JClass, method_id: JMethodID): JavaObject `{ return (*recv)->NewObject(recv, clazz, method_id); `} - + # Return the JClass of `obj` fun get_object_class(obj: JavaObject): JClass `{ return (*recv)->GetObjectClass(recv, obj); `} - # Registers native methods with the class specified by the `clazz` argument + # Registers native methods with the class specified by the `clazz` argument fun register_natives(clazz: JClass, method: JNINativeMethod, n_method : Int): Int `{ return (*recv)->RegisterNatives(recv, clazz, method, n_method); `} @@ -212,40 +221,45 @@ extern class JniEnv `{JNIEnv *`} (*recv)->CallVoidMethodA(recv, obj, method_id, args_tab); free(args_tab); `} - + # Call a method on `obj` designed by `method_id` with an array `args` of argument returning a JavaObject fun call_object_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): JavaObject import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - (*recv)->CallObjectMethod(recv, obj, method_id, args_tab); + jobject res = (*recv)->CallObjectMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} - + # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a Bool fun call_boolean_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Bool import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallBooleanMethod(recv, obj, method_id, args_tab); + jboolean res = (*recv)->CallBooleanMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a Char fun call_char_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Char import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallCharMethod(recv, obj, method_id, args_tab); + jchar res = (*recv)->CallCharMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning an Int fun call_int_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Int import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallIntMethod(recv, obj, method_id, args_tab); + jint res = (*recv)->CallIntMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} - + # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a Float fun call_float_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): Float import convert_args_to_jni `{ jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - return (*recv)->CallFloatMethod(recv, obj, method_id, args_tab); + jfloat res = (*recv)->CallFloatMethod(recv, obj, method_id, args_tab); free(args_tab); + return res; `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments returning a NativeString @@ -298,7 +312,7 @@ extern class JniEnv `{JNIEnv *`} fun get_field_id(clazz: JClass, name: String, sign: String): JFieldID import String.to_cstring `{ return (*recv)->GetFieldID(recv, clazz, String_to_cstring(name), String_to_cstring(sign)); `} - + # returns the value of an instance (nonstatic) field of an object. The field to access is specified by a field ID obtained by calling get_field_id() fun get_object_field(obj: JavaObject, fieldID: JFieldID): JavaObject `{ return (*recv)->GetObjectField(recv, obj, fieldID); @@ -307,7 +321,7 @@ extern class JniEnv `{JNIEnv *`} fun get_boolean_field(obj: JavaObject, fieldID: JFieldID): Bool `{ return (*recv)->GetBooleanField(recv, obj, fieldID); `} - + fun get_char_field(obj: JavaObject, fieldID: JFieldID): Char `{ return (*recv)->GetCharField(recv, obj, fieldID); `} @@ -334,12 +348,12 @@ extern class JniEnv `{JNIEnv *`} fun set_int_field(obj: JavaObject, fieldID: JFieldID, value: Int) `{ (*recv)->SetIntField(recv, obj, fieldID, value); - `} + `} fun set_float_field(obj: JavaObject, fieldID: JFieldID, value: Float) `{ (*recv)->SetFloatField(recv, obj, fieldID, value); `} - + # Check for pending exception without creating a local reference to the exception object fun exception_check: Bool `{ return (*recv)->ExceptionCheck(recv); @@ -364,7 +378,7 @@ extern class JniEnv `{JNIEnv *`} fun exception_clear `{ return (*recv)->ExceptionClear(recv); `} - + # Raise a fatal error fun fatal_error(msg: String) import String.to_cstring `{ (*recv)->FatalError(recv, String_to_cstring(msg)); @@ -388,7 +402,7 @@ extern class JniEnv `{JNIEnv *`} `} end -# used to initialize a JavaVM +# used to initialize a JavaVM class JniEnvRef var jni_env: nullable JniEnv = null end @@ -438,11 +452,11 @@ extern class JValue `{jvalue`} fun get_boolean:Bool `{ return recv.z; `} - + fun set_char(c: Char)`{ recv.c = c; `} - + fun get_char: Char `{ return recv.c; `}