X-Git-Url: http://nitlanguage.org diff --git a/lib/jvm.nit b/lib/jvm.nit index a9d815e..379e6ec 100644 --- a/lib/jvm.nit +++ b/lib/jvm.nit @@ -15,7 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Manipulates the Java Virtual Machine +# Java Virtual Machine services # # See: http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/jniTOC.html module jvm is @@ -84,40 +84,40 @@ private extern class JavaVMInitArgs `{ JavaVMInitArgs* `} # Unavailable on Android, where you cannot instanciate a new JVM. fun set_default `{ #ifndef ANDROID - JNI_GetDefaultJavaVMInitArgs(recv); + JNI_GetDefaultJavaVMInitArgs(self); #endif `} - fun version: Int `{ return recv->version; `} - fun version=(v: Int) `{ recv->version = v; `} + fun version: Int `{ return self->version; `} + fun version=(v: Int) `{ self->version = v; `} - fun options: JavaVMOptionArray `{ return recv->options; `} - fun options=(v: JavaVMOptionArray) `{ recv->options = v; `} + fun options: JavaVMOptionArray `{ return self->options; `} + fun options=(v: JavaVMOptionArray) `{ self->options = v; `} - fun n_options: Int `{ return recv->nOptions; `} - fun n_options=(v: Int) `{ recv->nOptions = v; `} + fun n_options: Int `{ return self->nOptions; `} + fun n_options=(v: Int) `{ self->nOptions = v; `} end private extern class JavaVMOption `{ JavaVMOption* `} fun string: String import NativeString.to_s `{ - return NativeString_to_s((char*)recv->optionString); + return NativeString_to_s((char*)self->optionString); `} fun string=(v: String) import String.to_cstring `{ - recv->optionString = String_to_cstring(v); + self->optionString = String_to_cstring(v); `} fun extra_info: String import NativeString.to_s `{ - return NativeString_to_s((char*)recv->extraInfo); + return NativeString_to_s((char*)self->extraInfo); `} fun extra_info=(v: String) import String.to_cstring `{ - recv->extraInfo = String_to_cstring(v); + self->extraInfo = String_to_cstring(v); `} end private extern class JavaVMOptionArray `{ JavaVMOption* `} new(size: Int) `{ return (JavaVMOption*)malloc(sizeof(JavaVMOption)*size); `} - fun [](i: Int): JavaVMOption `{ return recv+i; `} + fun [](i: Int): JavaVMOption `{ return self+i; `} end # Represents a jni JavaVM @@ -156,12 +156,12 @@ extern class JavaVM `{JavaVM *`} end fun destroy `{ - (*recv)->DestroyJavaVM(recv); + (*self)->DestroyJavaVM(self); `} fun env: JniEnv import jni_error `{ JNIEnv *env; - int res = (*recv)->GetEnv(recv, (void **)&env, JNI_VERSION_1_6); + int res = (*self)->GetEnv(self, (void **)&env, JNI_VERSION_1_6); if (res != JNI_OK) { JavaVM_jni_error(NULL, "Could not get JNIEnv from Java VM", res); return NULL; @@ -169,13 +169,13 @@ 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 - int res = (*recv)->AttachCurrentThread(recv, &env, NULL); + int res = (*self)->AttachCurrentThread(self, &env, NULL); #else - int res = (*recv)->AttachCurrentThread(recv, (void**)&env, NULL); + int res = (*self)->AttachCurrentThread(self, (void**)&env, NULL); #endif if (res != JNI_OK) { JavaVM_jni_error(NULL, "Could not attach current thread to Java VM", res); @@ -183,6 +183,14 @@ extern class JavaVM `{JavaVM *`} } return env; `} + + # Detach the calling thread from this JVM + fun detach_current_thread import jni_error `{ + int res = (*self)->DetachCurrentThread(self); + if (res != JNI_OK) { + JavaVM_jni_error(NULL, "Could not detach current thread to Java VM", res); + } + `} end # Represents a jni JNIEnv, which is a thread in a JavaVM @@ -190,84 +198,84 @@ 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 (*self)->FindClass(self,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)); + return (*self)->GetMethodID(self, 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 (*self)->NewObject(self, clazz, method_id); `} # Return the JClass of `obj` fun get_object_class(obj: JavaObject): JClass `{ - return (*recv)->GetObjectClass(recv, obj); + return (*self)->GetObjectClass(self, obj); `} # 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); + return (*self)->RegisterNatives(self, clazz, method, n_method); `} # Call a method on `obj` designed by `method_id` with an array `args` of arguments fun call_void_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]) import convert_args_to_jni `{ - jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - (*recv)->CallVoidMethodA(recv, obj, method_id, args_tab); + jvalue * args_tab = JniEnv_convert_args_to_jni(self, args); + (*self)->CallVoidMethodA(self, 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); - jobject res = (*recv)->CallObjectMethod(recv, obj, method_id, args_tab); + jvalue * args_tab = JniEnv_convert_args_to_jni(self, args); + jobject res = (*self)->CallObjectMethod(self, 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); - jboolean res = (*recv)->CallBooleanMethod(recv, obj, method_id, args_tab); + jvalue * args_tab = JniEnv_convert_args_to_jni(self, args); + jboolean res = (*self)->CallBooleanMethod(self, 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); - jchar res = (*recv)->CallCharMethod(recv, obj, method_id, args_tab); + jvalue * args_tab = JniEnv_convert_args_to_jni(self, args); + jchar res = (*self)->CallCharMethod(self, 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); - jint res = (*recv)->CallIntMethod(recv, obj, method_id, args_tab); + jvalue * args_tab = JniEnv_convert_args_to_jni(self, args); + jint res = (*self)->CallIntMethod(self, 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); - jfloat res = (*recv)->CallFloatMethod(recv, obj, method_id, args_tab); + jvalue * args_tab = JniEnv_convert_args_to_jni(self, args); + jfloat res = (*self)->CallFloatMethod(self, 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 fun call_string_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): NativeString import convert_args_to_jni `{ - jvalue * args_tab = JniEnv_convert_args_to_jni(recv, args); - jobject jobj = (*recv)->CallObjectMethod(recv, obj, method_id, args_tab); + jvalue * args_tab = JniEnv_convert_args_to_jni(self, args); + jobject jobj = (*self)->CallObjectMethod(self, obj, method_id, args_tab); free(args_tab); - return (char*)(*recv)->GetStringUTFChars(recv, (jstring)jobj, NULL); + return (char*)(*self)->GetStringUTFChars(self, (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 `{ @@ -298,7 +306,7 @@ extern class JniEnv `{JNIEnv *`} } else if(nullable_Object_is_a_String(nullable_obj)){ String val = nullable_Object_as_String(nullable_obj); char* c = String_to_cstring(val); - jstring js = (*recv)->NewStringUTF(recv, c); + jstring js = (*self)->NewStringUTF(self, c); c_array[i].l = js; } else { fprintf(stderr, "NOT YET SUPPORTED: nit objects are not supported\n"); @@ -310,95 +318,95 @@ extern class JniEnv `{JNIEnv *`} # Returns the field ID for an instance field of a class. The field is specified by its name and signature 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)); + return (*self)->GetFieldID(self, 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); + return (*self)->GetObjectField(self, obj, fieldID); `} fun get_boolean_field(obj: JavaObject, fieldID: JFieldID): Bool `{ - return (*recv)->GetBooleanField(recv, obj, fieldID); + return (*self)->GetBooleanField(self, obj, fieldID); `} fun get_char_field(obj: JavaObject, fieldID: JFieldID): Char `{ - return (*recv)->GetCharField(recv, obj, fieldID); + return (*self)->GetCharField(self, obj, fieldID); `} fun get_int_field(obj: JavaObject, fieldID: JFieldID): Int `{ - return (*recv)->GetIntField(recv, obj, fieldID); + return (*self)->GetIntField(self, obj, fieldID); `} fun get_float_field(obj: JavaObject, fieldID: JFieldID): Float `{ - return (*recv)->GetFloatField(recv, obj, fieldID); + return (*self)->GetFloatField(self, obj, fieldID); `} fun set_object_field(obj: JavaObject, fieldID: JFieldID, value: JavaObject) `{ - (*recv)->SetObjectField(recv, obj, fieldID, value); + (*self)->SetObjectField(self, obj, fieldID, value); `} fun set_boolean_field(obj: JavaObject, fieldID: JFieldID, value: Bool) `{ - (*recv)->SetBooleanField(recv, obj, fieldID, value); + (*self)->SetBooleanField(self, obj, fieldID, value); `} fun set_char_field(obj: JavaObject, fieldID: JFieldID, value: Char) `{ - (*recv)->SetCharField(recv, obj, fieldID, value); + (*self)->SetCharField(self, obj, fieldID, value); `} fun set_int_field(obj: JavaObject, fieldID: JFieldID, value: Int) `{ - (*recv)->SetIntField(recv, obj, fieldID, value); + (*self)->SetIntField(self, obj, fieldID, value); `} fun set_float_field(obj: JavaObject, fieldID: JFieldID, value: Float) `{ - (*recv)->SetFloatField(recv, obj, fieldID, value); + (*self)->SetFloatField(self, obj, fieldID, value); `} # Check for pending exception without creating a local reference to the exception object fun exception_check: Bool `{ - return (*recv)->ExceptionCheck(recv); + return (*self)->ExceptionCheck(self); `} # Construct an exception object from the specified class with the message specified by `message` and causes that exception to be thrown fun throw_new(clazz: JClass, message: String): Int import String.to_cstring `{ - return (*recv)->ThrowNew(recv, clazz, String_to_cstring(message)); + return (*self)->ThrowNew(self, clazz, String_to_cstring(message)); `} # return the exception if there is one in the process of being thrown, or NULL if no exception is currently being thrown fun exception_occurred: JavaObject `{ - return (*recv)->ExceptionOccurred(recv); + return (*self)->ExceptionOccurred(self); `} # prints an exception and backtrace to error channel fun exception_describe `{ - return (*recv)->ExceptionDescribe(recv); + return (*self)->ExceptionDescribe(self); `} # clears any exception currently being thrown, has no effect if there is no exception fun exception_clear `{ - return (*recv)->ExceptionClear(recv); + return (*self)->ExceptionClear(self); `} # Raise a fatal error fun fatal_error(msg: String) import String.to_cstring `{ - (*recv)->FatalError(recv, String_to_cstring(msg)); + (*self)->FatalError(self, String_to_cstring(msg)); `} # Transform a NIT String into a JavaObject fun string_to_jobject(string: String): JavaObject `{ - return (*recv)->NewStringUTF(recv, String_to_cstring(string)); + return (*self)->NewStringUTF(self, 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); + return (*self)->PushLocalFrame(self, 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); + (*self)->PopLocalFrame(self, NULL); `} end @@ -422,19 +430,19 @@ end # Represents a jni JNINNativeMethod extern class JNINativeMethod `{ JNINativeMethod* `} fun name: String import NativeString.to_s `{ - return NativeString_to_s((void*)recv->name); + return NativeString_to_s((void*)self->name); `} fun name=(name: String) import String.to_cstring `{ - recv->name = String_to_cstring(name); + self->name = String_to_cstring(name); `} fun signature: String import NativeString.to_s `{ - return NativeString_to_s((void*)recv->signature); + return NativeString_to_s((void*)self->signature); `} fun signature=(signature: String) import String.to_cstring `{ - recv->signature = String_to_cstring(signature); + self->signature = String_to_cstring(signature); `} end @@ -446,50 +454,50 @@ end extern class JValue `{jvalue`} fun set_boolean(b: Bool) `{ - recv.z = b; + self.z = b; `} fun get_boolean:Bool `{ - return recv.z; + return self.z; `} fun set_char(c: Char)`{ - recv.c = c; + self.c = c; `} fun get_char: Char `{ - return recv.c; + return self.c; `} fun set_int(i: Int) `{ - recv.i = i; + self.i = i; `} fun get_int: Int `{ - return recv.i; + return self.i; `} fun set_float(f: Float) `{ - recv.f = f; + self.f = f; `} fun get_float: Float `{ - return recv.f; + return self.f; `} fun set_jobject(obj: JavaObject) `{ - recv.l = obj; + self.l = obj; `} fun get_jobject: JavaObject `{ - return recv.l; + return self.l; `} end redef class Int redef fun to_jvalue(env): JValue `{ jvalue value; - value.i = recv; + value.i = self; return value; `} end @@ -497,7 +505,7 @@ end redef class Float redef fun to_jvalue(env): JValue `{ jvalue value; - value.f = recv; + value.f = self; return value; `} end @@ -505,7 +513,7 @@ end redef class Bool redef fun to_jvalue(env): JValue `{ jvalue value; - value.z = recv; + value.z = self; return value; `} end @@ -513,7 +521,7 @@ end redef class NativeString redef fun to_jvalue(env)`{ jvalue value; - value.l = (*env)->NewStringUTF(env, recv); + value.l = (*env)->NewStringUTF(env, self); return value; `} end