lib: intro `Float.lerp` for simple linear interpolation
[nit.git] / lib / jvm.nit
index 44c59df..abdcab6 100644 (file)
@@ -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
@@ -73,7 +74,13 @@ extern class JavaVMInitArgs `{ JavaVMInitArgs* `}
 
        # Set the defaut config for a VM
        # Can be called after setting the version
-       fun set_default `{ JNI_GetDefaultJavaVMInitArgs(recv); `}
+       #
+       # Unavailable on Android, where you cannot instanciate a new JVM.
+       fun set_default `{
+       #ifndef ANDROID
+               JNI_GetDefaultJavaVMInitArgs(recv);
+       #endif
+       `}
 
        fun version: Int `{ return recv->version; `}
        fun version=(v: Int) `{ recv->version = v; `}
@@ -87,14 +94,14 @@ end
 
 extern class JavaVMOption `{ JavaVMOption* `}
        fun string: String import NativeString.to_s `{
-               return NativeString_to_s(recv->optionString);
+               return NativeString_to_s((char*)recv->optionString);
        `}
        fun string=(v: String) import String.to_cstring `{
                recv->optionString = String_to_cstring(v);
        `}
 
        fun extra_info: String import NativeString.to_s `{
-               return NativeString_to_s(recv->extraInfo);
+               return NativeString_to_s((char*)recv->extraInfo);
        `}
        fun extra_info=(v: String) import String.to_cstring `{
                recv->extraInfo = String_to_cstring(v);
@@ -110,7 +117,15 @@ end
 # Represents a jni JavaVM
 extern class JavaVM `{JavaVM *`}
        # Create the JVM, returns its handle and store the a pointer to JniEnv in `env_ref`
-       new(args: JavaVMInitArgs, env_ref: JniEnvRef) import jni_error, JniEnvRef.jni_env=, JniEnv as nullable `{
+       #
+       # 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 `{
+
+       #ifdef ANDROID
+               JavaVM_jni_error(NULL, "JVM creation not supported on Android", 0);
+               return NULL;
+       #endif
+
                JavaVM *jvm;
                JNIEnv *env;
                jint res;
@@ -149,11 +164,17 @@ extern class JavaVM `{JavaVM *`}
 
        fun attach_current_thread: JniEnv `{
                JNIEnv *env;
+       #ifdef ANDROID
+               // the signature is different (better actually) on Android
+               int res = (*recv)->AttachCurrentThread(recv, &env, NULL);
+       #else
                int res = (*recv)->AttachCurrentThread(recv, (void**)&env, NULL);
+       #endif
                if (res != JNI_OK) {
                        JavaVM_jni_error(NULL, "Could not attach current thread to Java VM", res);
                        return NULL;
                }
+               return env;
        `}
 end
 
@@ -197,36 +218,41 @@ extern class JniEnv `{JNIEnv *`}
        # 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
@@ -237,7 +263,7 @@ extern class JniEnv `{JNIEnv *`}
                return (char*)(*recv)->GetStringUTFChars(recv, (jstring)jobj, NULL);
        `}
 
-       private fun convert_args_to_jni(args: nullable Array[nullable Object]): Pointer import Array[nullable Object] as not nullable, Array[nullable Object].[], Array[nullable Object].length, nullable Object.as(Int), nullable Object.as(Char), nullable Object.as(Bool), nullable Object.as(Float), nullable Object.as(JavaObject), nullable Object.as(String), String.to_cstring, String.length `{
+       private fun convert_args_to_jni(args: nullable Array[nullable Object]): Pointer import Array[nullable Object].as not nullable, Array[nullable Object].[], Array[nullable Object].length, nullable Object.as(Int), nullable Object.as(Char), nullable Object.as(Bool), nullable Object.as(Float), nullable Object.as(JavaObject), nullable Object.as(String), String.to_cstring, String.length `{
                if(nullable_Array_of_nullable_Object_is_null(args)){
                        return NULL;
                }
@@ -355,6 +381,18 @@ extern class JniEnv `{JNIEnv *`}
        fun string_to_jobject(string: String): JavaObject `{
                return (*recv)->NewStringUTF(recv, String_to_cstring(string));
        `}
+
+       # Pushes a local reference frame on the JNI stack
+       fun push_local_frame(capacity: Int): Bool `{
+               return (*recv)->PushLocalFrame(recv, capacity);
+       `}
+
+       # Pops the current local reference frame on the JNI stack
+       #
+       # Similiar to `JavaObject::pop_from_local_frame` which returns a value.
+       fun pop_local_frame `{
+               (*recv)->PopLocalFrame(recv, NULL);
+       `}
 end
 
 # used to initialize a JavaVM 
@@ -371,13 +409,13 @@ extern class JMethodID `{jmethodID`}
 end
 
 # Represens a jni jobject
-extern class JavaObject `{jobject`}
+extern class JavaObject in "Java" `{ java.lang.Object `}
 end
 
 # Represents a jni JNINNativeMethod
 extern class JNINativeMethod `{ JNINativeMethod* `}
        fun name: String import NativeString.to_s `{
-               return NativeString_to_s(recv->name);
+               return NativeString_to_s((void*)recv->name);
        `}
 
        fun name=(name: String) import String.to_cstring `{
@@ -385,7 +423,7 @@ extern class JNINativeMethod `{ JNINativeMethod* `}
        `}
 
        fun signature: String import NativeString.to_s `{
-               return NativeString_to_s(recv->signature);
+               return NativeString_to_s((void*)recv->signature);
        `}
 
        fun signature=(signature: String) import String.to_cstring `{