Property definitions

jvm $ JniEnv :: defaultinit
# 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 (*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 "<init>" 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 (*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 (*self)->NewObject(self, clazz, method_id);
	`}

	# Return the JClass of `obj`
	fun get_object_class(obj: JavaObject): JClass `{
		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 (*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(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(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(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(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(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(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 CString
	fun call_string_method(obj: JavaObject, method_id: JMethodID, args: nullable Array[nullable Object]): CString import convert_args_to_jni `{
		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*)(*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 `{
		if(nullable_Array_of_nullable_Object_is_null(args)){
			return NULL;
		}
		Array_of_nullable_Object nit_array = nullable_Array_of_nullable_Object_as_Array_of_nullable_Object(args);
		int nit_array_length = Array_of_nullable_Object_length(nit_array);
		int i;
		jvalue *c_array = malloc(sizeof(jvalue)*(nit_array_length));
		for (i = 0; i < nit_array_length; i ++) {
			nullable_Object nullable_obj = Array_of_nullable_Object__index(nit_array, i);
			if(nullable_Object_is_a_Int(nullable_obj)) {
				int val = nullable_Object_as_Int(nullable_obj);
				c_array[i].i = val;
			} else if (nullable_Object_is_a_Char(nullable_obj)){
				char val = nullable_Object_as_Char(nullable_obj);
				c_array[i].c = val;
			} else if (nullable_Object_is_a_Bool(nullable_obj)){
				int val = nullable_Object_as_Bool(nullable_obj);
				c_array[i].z = val;
			} else if(nullable_Object_is_a_Float(nullable_obj)){
				float val = nullable_Object_as_Float(nullable_obj);
				c_array[i].f = val;
			} else if(nullable_Object_is_a_JavaObject(nullable_obj)){
				jobject val = nullable_Object_as_JavaObject(nullable_obj);
				c_array[i].l = val;
			} 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 = (*self)->NewStringUTF(self, c);
				c_array[i].l = js;
			} else {
				fprintf(stderr, "NOT YET SUPPORTED: nit objects are not supported\n");
				exit(1);
			}
		}
		return c_array;
	`}

	# 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 (*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 (*self)->GetObjectField(self, obj, fieldID);
	`}

	fun get_boolean_field(obj: JavaObject, fieldID: JFieldID): Bool `{
		return (*self)->GetBooleanField(self, obj, fieldID);
	`}

	fun get_char_field(obj: JavaObject, fieldID: JFieldID): Char `{
		return (*self)->GetCharField(self, obj, fieldID);
	`}

	fun get_int_field(obj: JavaObject, fieldID: JFieldID): Int `{
		return (*self)->GetIntField(self, obj, fieldID);
	`}

	fun get_float_field(obj: JavaObject, fieldID: JFieldID): Float `{
		return (*self)->GetFloatField(self, obj, fieldID);
	`}

	fun set_object_field(obj: JavaObject, fieldID: JFieldID, value: JavaObject) `{
		(*self)->SetObjectField(self, obj, fieldID, value);
	`}

	fun set_boolean_field(obj: JavaObject, fieldID: JFieldID, value: Bool) `{
		(*self)->SetBooleanField(self, obj, fieldID, value);
	`}

	fun set_char_field(obj: JavaObject, fieldID: JFieldID, value: Char) `{
		(*self)->SetCharField(self, obj, fieldID, value);
	`}

	fun set_int_field(obj: JavaObject, fieldID: JFieldID, value: Int) `{
		(*self)->SetIntField(self, obj, fieldID, value);
	`}

	fun set_float_field(obj: JavaObject, fieldID: JFieldID, value: Float) `{
		(*self)->SetFloatField(self, obj, fieldID, value);
	`}

	# Check for pending exception without creating a local reference to the exception object
	fun exception_check: Bool `{
		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 (*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 (*self)->ExceptionOccurred(self);
	`}

	# prints an exception and backtrace to error channel
	fun exception_describe `{
		return (*self)->ExceptionDescribe(self);
	`}

	# clears any exception currently being thrown, has no effect if there is no exception
	fun exception_clear `{
		return (*self)->ExceptionClear(self);
	`}

	# Raise a fatal error
	fun fatal_error(msg: String) import String.to_cstring `{
		(*self)->FatalError(self, String_to_cstring(msg));
	`}

	# Transform a NIT String into a JavaObject
	fun string_to_jobject(string: String): JavaObject `{
		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 (*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 `{
		(*self)->PopLocalFrame(self, NULL);
	`}
end
lib/jvm/jvm.nit:213,1--428,3