aboutsummaryrefslogtreecommitdiff
path: root/third_party/jni/emjvm.cpp
blob: 77ec387121b36ae13952a11d87088c108ca389f0 (plain)
1
2
3
4
5
6
7
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Emscripten shims for JVM support

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "emjvm.h"

// invoke interface

jint DestroyJavaVM(JavaVM*) { exit(55); return NULL; }
jint AttachCurrentThread(JavaVM*, JNIEnv**, void*) { exit(66); return NULL; }
jint DetachCurrentThread(JavaVM*) { exit(77); return NULL; }
jint GetEnv(JavaVM*, void** env, jint); // forward def
jint AttachCurrentThreadAsDaemon(JavaVM*, JNIEnv**, void*) { exit(88); return NULL; }

// env - some of these are externs that are implemented in JS

jobject EMJVM_NewGlobalRef(JNIEnv*, jobject obj) {
  return obj; // XXX no global refcounting, we just keep global singletons alive etc.
}

extern "C" {
  extern jstring emjvm_newString(const jchar *chars, jsize len);
}
jstring EMJVM_NewString(JNIEnv*, const jchar* unicodeChars, jsize len) {
  return emjvm_newString(unicodeChars, len);
}

extern "C" {
  extern jclass emjvm_getObjectClass(JNIEnv*, jobject obj);
}

extern "C" {
  extern jmethodID emjvm_getMethodID(jclass, const char*, const char*);
}
extern jmethodID EMJVM_GetMethodID(JNIEnv*, jclass clazz, const char* methodName, const char* sig) {
  return emjvm_getMethodID(clazz, methodName, sig);
}

extern "C" {
  extern jobject emjvm_callObjectMethod(JNIEnv*, jobject, jmethodID, va_list);

  extern void emjvm_deleteLocalRef(JNIEnv*, jobject);

  jsize emjvm_getArrayLength(JNIEnv*, jarray);

  void emjvm_getByteArrayRegion(JNIEnv*, jbyteArray, jsize, jsize, jbyte*);

  jclass emjvm_findClass(JNIEnv*, const char*);

  jmethodID emjvm_getStaticMethodID(JNIEnv*, jclass, const char*, const char*);

  jobject emjvm_callStaticObjectMethod(JNIEnv*, jclass, jmethodID, va_list);

  jboolean emjvm_callBooleanMethod(JNIEnv*, jobject, jmethodID, va_list);
  jboolean emjvm_callStaticBooleanMethod(JNIEnv*, jclass, jmethodID, va_list);

  void emjvm_callVoidMethod(JNIEnv*, jobject, jmethodID, va_list);

  jint emjvm_callIntMethod(JNIEnv*, jobject, jmethodID, va_list);

  const char* emjvm_getStringUTFChars(JNIEnv*, jstring, jboolean*);
  jsize emjvm_getStringUTFLength(JNIEnv*, jstring);
  void emjvm_releaseStringUTFChars(JNIEnv*, jstring, const char*);
}

// JVM

struct EmJVM {
  JavaVM jvm;
  JNIInvokeInterface jvmFunctions;

  JNIEnv env;
  JNINativeInterface envFunctions;

  EmJVM() {
    // jvm
    jvm.functions = &jvmFunctions;

    jvmFunctions.DestroyJavaVM = DestroyJavaVM;
    jvmFunctions.AttachCurrentThread = AttachCurrentThread;
    jvmFunctions.DetachCurrentThread = DetachCurrentThread;
    jvmFunctions.GetEnv = GetEnv;
    jvmFunctions.AttachCurrentThreadAsDaemon = AttachCurrentThreadAsDaemon;

    // env
    memset(&envFunctions, 0, sizeof(envFunctions));

    env.functions = &envFunctions;

    envFunctions.NewGlobalRef = EMJVM_NewGlobalRef;
    envFunctions.NewString = EMJVM_NewString;
    envFunctions.GetObjectClass = emjvm_getObjectClass;
    envFunctions.GetMethodID = EMJVM_GetMethodID;
    envFunctions.CallObjectMethodV = emjvm_callObjectMethod;
    envFunctions.DeleteLocalRef = emjvm_deleteLocalRef;
    envFunctions.GetArrayLength = emjvm_getArrayLength;
    envFunctions.GetByteArrayRegion = emjvm_getByteArrayRegion;
    envFunctions.FindClass = emjvm_findClass;
    envFunctions.GetStaticMethodID = emjvm_getStaticMethodID;
    envFunctions.CallStaticObjectMethodV = emjvm_callStaticObjectMethod;
    envFunctions.CallBooleanMethodV = emjvm_callBooleanMethod;
    envFunctions.CallStaticBooleanMethodV = emjvm_callStaticBooleanMethod;
    envFunctions.CallVoidMethodV = emjvm_callVoidMethod;
    envFunctions.CallIntMethodV = emjvm_callIntMethod;
    envFunctions.GetStringUTFChars = emjvm_getStringUTFChars;
    envFunctions.GetStringUTFLength = emjvm_getStringUTFLength;
    envFunctions.ReleaseStringUTFChars = emjvm_releaseStringUTFChars;
  }
};

EmJVM emJVM;

// implement forward defs

jint GetEnv(JavaVM*, void** env, jint) {
  *env = &emJVM.env;
  return 0;
}

// external access from JS

extern "C" {

JavaVM* emscripten_get_jvm() { return &emJVM.jvm; }

JNIEnv* emscripten_get_jni_env() { return &emJVM.env; }

}