refimpl2-start.c 2.96 KB
Newer Older
1 2
#include <stdint.h>
#include <stdlib.h>
Kunshan Wang's avatar
Kunshan Wang committed
3 4 5
#include <string.h>

#include <jni.h>
6 7

#include "refimpl2-start.h"
Kunshan Wang's avatar
Kunshan Wang committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
#include "classpath.h"

static JavaVM *jvm;
static JNIEnv *env;
static jclass cinitiater_cls;
static jmethodID new_mid;
static jmethodID new_ex_mid;
static jmethodID close_mid;

static char *cinitiater_class = "uvm/refimpl/nat/CInitiater";
static char *new_method = "mu_refimpl2_new";
static char *new_ex_method = "mu_refimpl2_new_ex";
static char *close_method = "mu_refimpl2_close";

static int refimpl2_start_debug;

static void init_jvm() {
    char *debug_env = getenv("REFIMPL2_START_DEBUG");

    if (debug_env != NULL) {
        refimpl2_start_debug = 1;
    }

    JavaVMInitArgs vm_args;

    JavaVMOption options[1];

    char *cpoptionstr = (char*)calloc(classpath_txt_len + 100, 1);
    strcat(cpoptionstr, "-Djava.class.path=");
    strncat(cpoptionstr, (const char*)classpath_txt, classpath_txt_len);
    options[0].optionString = cpoptionstr;

    if (refimpl2_start_debug) {
        printf("Classpath option: '%s'\n", cpoptionstr);
    }

    vm_args.version = JNI_VERSION_1_8;
    vm_args.nOptions = 1;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = JNI_FALSE;

    int rv = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

    if (rv != JNI_OK) {
        printf("ERROR: Failed to create JVM: %d\n", rv);
        exit(1);
    }

    free(cpoptionstr);

    jclass cinitiater_cls = (*env)->FindClass(env, cinitiater_class);

    if (cinitiater_cls == NULL) {
        printf("ERROR: class %s cannot be found.\n", cinitiater_class);
        exit(1);
    }

    new_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, new_method, "()J");
    if (new_mid == NULL) {
        printf("ERROR: method %s cannot be found.\n", new_method);
        exit(1);
    }

71
    new_ex_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, new_ex_method, "(Ljava/lang/String;)J");
Kunshan Wang's avatar
Kunshan Wang committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85

    if (new_ex_mid == NULL) {
        printf("ERROR: method %s cannot be found.\n", new_ex_method);
        exit(1);
    }

    close_mid = (*env)->GetStaticMethodID(env, cinitiater_cls, close_method, "(J)V");

    if (close_mid == NULL) {
        printf("ERROR: method %s cannot be found.\n", close_method);
        exit(1);
    }

}
86 87

MuVM *mu_refimpl2_new() {
Kunshan Wang's avatar
Kunshan Wang committed
88 89 90 91 92 93 94
    if (jvm == NULL) {
        init_jvm();
    }

    uintptr_t rv = (*env)->CallStaticLongMethod(env, cinitiater_cls, new_mid);

    return (MuVM*)rv;
95 96
}

97
MuVM *mu_refimpl2_new_ex(const char *gc_conf) {
Kunshan Wang's avatar
Kunshan Wang committed
98 99 100 101
    if (jvm == NULL) {
        init_jvm();
    }

102 103 104 105 106 107 108
    jstring conf_str = (*env)->NewStringUTF(env, gc_conf);

    if (conf_str == NULL) {
        printf("ERROR: Cannot convert gc_conf to Java String\n");
        exit(1);
    }

Kunshan Wang's avatar
Kunshan Wang committed
109
    uintptr_t rv = (*env)->CallStaticLongMethod(env, cinitiater_cls, new_ex_mid,
110 111 112
            conf_str);

    (*env)->DeleteLocalRef(env, conf_str);
Kunshan Wang's avatar
Kunshan Wang committed
113 114

    return (MuVM*)rv;
115 116 117
}

void mu_refimpl2_close(MuVM *mvm) {
Kunshan Wang's avatar
Kunshan Wang committed
118 119 120 121 122
    if (jvm == NULL) {
        init_jvm();
    }

    (*env)->CallStaticVoidMethod(env, cinitiater_cls, close_mid, mvm);
123
}