// Code generated by gobind. DO NOT EDIT.


#include <jni.h>
#include "seq.h"
#include "classes.h"

static jclass class_java_lang_Float;
static jmethodID m_java_lang_Float_toString;
static jclass class_java_lang_Long;
static jmethodID m_java_lang_Long_toString;
static jclass class_java_lang_Object;
static jmethodID m_java_lang_Object_toString;
static jclass class_java_lang_Runnable;

void init_proxies() {
	JNIEnv *env = go_seq_push_local_frame(4);
	jclass clazz;
	clazz = go_seq_find_class("java/lang/Float");
	if (clazz != NULL) {
		class_java_lang_Float = (*env)->NewGlobalRef(env, clazz);
		m_java_lang_Float_toString = go_seq_get_method_id(clazz, "toString", "()Ljava/lang/String;");
	}
	clazz = go_seq_find_class("java/lang/Long");
	if (clazz != NULL) {
		class_java_lang_Long = (*env)->NewGlobalRef(env, clazz);
		m_java_lang_Long_toString = go_seq_get_method_id(clazz, "toString", "()Ljava/lang/String;");
	}
	clazz = go_seq_find_class("java/lang/Object");
	if (clazz != NULL) {
		class_java_lang_Object = (*env)->NewGlobalRef(env, clazz);
		m_java_lang_Object_toString = go_seq_get_method_id(clazz, "toString", "()Ljava/lang/String;");
	}
	clazz = go_seq_find_class("java/lang/Runnable");
	if (clazz != NULL) {
		class_java_lang_Runnable = (*env)->NewGlobalRef(env, clazz);
	}
	go_seq_pop_local_frame(env);
}

ret_nstring cproxy_java_lang_Float_toString(jint this) {
	JNIEnv *env = go_seq_push_local_frame(1);
	// Must be a Java object
	jobject _this = go_seq_from_refnum(env, this, NULL, NULL);
	jstring res = (*env)->CallObjectMethod(env, _this, m_java_lang_Float_toString);
	jobject _exc = go_seq_get_exception(env);
	int32_t _exc_ref = go_seq_to_refnum(env, _exc);
	if (_exc != NULL) {
		res = NULL;
	}
	nstring _res = go_seq_from_java_string(env, res);
	go_seq_pop_local_frame(env);
	ret_nstring __res = {_res, _exc_ref};
	return __res;
}

ret_nstring cproxy_java_lang_Long_toString(jint this) {
	JNIEnv *env = go_seq_push_local_frame(1);
	// Must be a Java object
	jobject _this = go_seq_from_refnum(env, this, NULL, NULL);
	jstring res = (*env)->CallObjectMethod(env, _this, m_java_lang_Long_toString);
	jobject _exc = go_seq_get_exception(env);
	int32_t _exc_ref = go_seq_to_refnum(env, _exc);
	if (_exc != NULL) {
		res = NULL;
	}
	nstring _res = go_seq_from_java_string(env, res);
	go_seq_pop_local_frame(env);
	ret_nstring __res = {_res, _exc_ref};
	return __res;
}

ret_nstring cproxy_java_lang_Object_toString(jint this) {
	JNIEnv *env = go_seq_push_local_frame(1);
	// Must be a Java object
	jobject _this = go_seq_from_refnum(env, this, NULL, NULL);
	jstring res = (*env)->CallObjectMethod(env, _this, m_java_lang_Object_toString);
	jobject _exc = go_seq_get_exception(env);
	int32_t _exc_ref = go_seq_to_refnum(env, _exc);
	if (_exc != NULL) {
		res = NULL;
	}
	nstring _res = go_seq_from_java_string(env, res);
	go_seq_pop_local_frame(env);
	ret_nstring __res = {_res, _exc_ref};
	return __res;
}

// Code generated by gobind. DO NOT EDIT.

// JNI functions for the Go <=> Java bridge.
//
//   autogenerated by gobind -lang=java java

#include <android/log.h>
#include <stdint.h>
#include "seq.h"
#include "_cgo_export.h"
#include "java.h"

jclass proxy_class_java_F;
jmethodID proxy_class_java_F_cons;
static jmethodID mid_F_ToString;
jclass proxy_class_java_L;
jmethodID proxy_class_java_L_cons;
static jmethodID mid_L_ToString;
jclass proxy_class_java_O;
jmethodID proxy_class_java_O_cons;
static jmethodID mid_O_ToString;
jclass proxy_class_java_R;
jmethodID proxy_class_java_R_cons;

JNIEXPORT void JNICALL
Java_java_Java__1init(JNIEnv *env, jclass _unused) {
    jclass clazz;
    clazz = (*env)->FindClass(env, "java/Java$proxyF");
    proxy_class_java_F = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_F_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/F");
    mid_F_ToString = (*env)->GetMethodID(env, clazz, "toString", "()Ljava/lang/String;");
    
    clazz = (*env)->FindClass(env, "java/Java$proxyL");
    proxy_class_java_L = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_L_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/L");
    mid_L_ToString = (*env)->GetMethodID(env, clazz, "toString", "()Ljava/lang/String;");
    
    clazz = (*env)->FindClass(env, "java/Java$proxyO");
    proxy_class_java_O = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_O_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/O");
    mid_O_ToString = (*env)->GetMethodID(env, clazz, "toString", "()Ljava/lang/String;");
    
    clazz = (*env)->FindClass(env, "java/Java$proxyR");
    proxy_class_java_R = (*env)->NewGlobalRef(env, clazz);
    proxy_class_java_R_cons = (*env)->GetMethodID(env, clazz, "<init>", "(I)V");
    clazz = (*env)->FindClass(env, "java/R");
    
}

JNIEXPORT jstring JNICALL
Java_java_Java_00024proxyF_toString(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    nstring r0 = proxyjava_F_ToString(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

nstring cproxyjava_F_ToString(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_java_F, proxy_class_java_F_cons);
    jstring res = (*env)->CallObjectMethod(env, o, mid_F_ToString);
    nstring _res = go_seq_from_java_string(env, res);
    go_seq_pop_local_frame(env);
    return _res;
}

JNIEXPORT jstring JNICALL
Java_java_Java_00024proxyL_toString(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    nstring r0 = proxyjava_L_ToString(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

nstring cproxyjava_L_ToString(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_java_L, proxy_class_java_L_cons);
    jstring res = (*env)->CallObjectMethod(env, o, mid_L_ToString);
    nstring _res = go_seq_from_java_string(env, res);
    go_seq_pop_local_frame(env);
    return _res;
}

JNIEXPORT jstring JNICALL
Java_java_Java_00024proxyO_toString(JNIEnv* env, jobject __this__) {
    int32_t o = go_seq_to_refnum_go(env, __this__);
    nstring r0 = proxyjava_O_ToString(o);
    jstring _r0 = go_seq_to_java_string(env, r0);
    return _r0;
}

nstring cproxyjava_O_ToString(int32_t refnum) {
    JNIEnv *env = go_seq_push_local_frame(0);
    jobject o = go_seq_from_refnum(env, refnum, proxy_class_java_O, proxy_class_java_O_cons);
    jstring res = (*env)->CallObjectMethod(env, o, mid_O_ToString);
    nstring _res = go_seq_from_java_string(env, res);
    go_seq_pop_local_frame(env);
    return _res;
}

