@mentra/crust 3.3.0-dev.656 → 3.3.0-dev.658
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/android/build.gradle +15 -40
- package/android/src/main/java/com/mentra/crust/jsc/JSCRuntime.kt +13 -4
- package/android/src/test/java/com/mentra/crust/jsc/QuickJsLifecycleTest.kt +87 -0
- package/package.json +2 -2
- package/plugin/build/index.d.ts +2 -0
- package/plugin/build/index.js +2 -0
- package/plugin/build/withAndroid.js +39 -0
- package/android/quickjs-consumer-rules.pro +0 -6
- package/android/scripts/test-quickjs-lifecycle.py +0 -45
- package/android/src/main/cpp/quickjs/CMakeLists.txt +0 -20
- package/android/src/main/cpp/quickjs/LICENSE.quickjs-kt.txt +0 -201
- package/android/src/main/cpp/quickjs/README.md +0 -30
- package/android/src/main/cpp/quickjs/c-vector/LICENSE +0 -21
- package/android/src/main/cpp/quickjs/c-vector/cvector.h +0 -479
- package/android/src/main/cpp/quickjs/common/quickjs_version.c +0 -9
- package/android/src/main/cpp/quickjs/common/quickjs_version.h +0 -9
- package/android/src/main/cpp/quickjs/engine/LICENSE +0 -22
- package/android/src/main/cpp/quickjs/engine/VERSION +0 -1
- package/android/src/main/cpp/quickjs/engine/cutils.c +0 -631
- package/android/src/main/cpp/quickjs/engine/cutils.h +0 -347
- package/android/src/main/cpp/quickjs/engine/libbf.c +0 -8475
- package/android/src/main/cpp/quickjs/engine/libbf.h +0 -535
- package/android/src/main/cpp/quickjs/engine/libregexp-opcode.h +0 -57
- package/android/src/main/cpp/quickjs/engine/libregexp.c +0 -2501
- package/android/src/main/cpp/quickjs/engine/libregexp.h +0 -55
- package/android/src/main/cpp/quickjs/engine/libunicode-table.h +0 -4557
- package/android/src/main/cpp/quickjs/engine/libunicode.c +0 -1910
- package/android/src/main/cpp/quickjs/engine/libunicode.h +0 -182
- package/android/src/main/cpp/quickjs/engine/list.h +0 -99
- package/android/src/main/cpp/quickjs/engine/quickjs-atom.h +0 -273
- package/android/src/main/cpp/quickjs/engine/quickjs-opcode.h +0 -372
- package/android/src/main/cpp/quickjs/engine/quickjs.c +0 -55978
- package/android/src/main/cpp/quickjs/engine/quickjs.h +0 -1087
- package/android/src/main/cpp/quickjs/jni/binding_bridge.c +0 -488
- package/android/src/main/cpp/quickjs/jni/binding_bridge.h +0 -32
- package/android/src/main/cpp/quickjs/jni/exception_util.c +0 -64
- package/android/src/main/cpp/quickjs/jni/exception_util.h +0 -21
- package/android/src/main/cpp/quickjs/jni/jni_globals.c +0 -59
- package/android/src/main/cpp/quickjs/jni/jni_globals.h +0 -12
- package/android/src/main/cpp/quickjs/jni/jni_globals_generated.c +0 -855
- package/android/src/main/cpp/quickjs/jni/jni_globals_generated.h +0 -171
- package/android/src/main/cpp/quickjs/jni/js_value_util.c +0 -213
- package/android/src/main/cpp/quickjs/jni/js_value_util.h +0 -71
- package/android/src/main/cpp/quickjs/jni/log_util.h +0 -15
- package/android/src/main/cpp/quickjs/jni/mapping/jni_types_util.c +0 -27
- package/android/src/main/cpp/quickjs/jni/mapping/jni_types_util.h +0 -15
- package/android/src/main/cpp/quickjs/jni/mapping/jobject_to_js_value.c +0 -620
- package/android/src/main/cpp/quickjs/jni/mapping/jobject_to_js_value.h +0 -13
- package/android/src/main/cpp/quickjs/jni/mapping/js_value_to_jobject.c +0 -421
- package/android/src/main/cpp/quickjs/jni/mapping/js_value_to_jobject.h +0 -12
- package/android/src/main/cpp/quickjs/jni/promise_rejection_handler.c +0 -20
- package/android/src/main/cpp/quickjs/jni/promise_rejection_handler.h +0 -10
- package/android/src/main/cpp/quickjs/jni/quickjs_jni.c +0 -735
- package/android/src/main/cpp/quickjs/jni/quickjs_jni.h +0 -40
- package/android/src/testNative/QuickJsLifecycleTest.kt +0 -56
|
@@ -1,488 +0,0 @@
|
|
|
1
|
-
#include "binding_bridge.h"
|
|
2
|
-
#include "exception_util.h"
|
|
3
|
-
#include "jni_globals.h"
|
|
4
|
-
#include "jni_globals_generated.h"
|
|
5
|
-
#include "log_util.h"
|
|
6
|
-
#include "js_value_to_jobject.h"
|
|
7
|
-
#include "jobject_to_js_value.h"
|
|
8
|
-
#include "js_value_util.h"
|
|
9
|
-
#include "jni_types_util.h"
|
|
10
|
-
|
|
11
|
-
#define COMMON_FUNC_DATA_LEN 2
|
|
12
|
-
|
|
13
|
-
#define GLOBAL_THIS_HANDLE -1
|
|
14
|
-
|
|
15
|
-
void set_eval_exception_to_caller(JNIEnv *env, jobject call_host, jthrowable exception) {
|
|
16
|
-
jmethodID set_exception_method = method_quick_js_set_eval_exception(env);
|
|
17
|
-
(*env)->CallVoidMethod(env, call_host, set_exception_method, exception);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
JSValue jni_invoke_getter(JSContext *context, jobject call_host, int64_t object_handle,
|
|
21
|
-
const char *property_name) {
|
|
22
|
-
JNIEnv *env = get_jni_env();
|
|
23
|
-
if (env == NULL) {
|
|
24
|
-
return JS_EXCEPTION;
|
|
25
|
-
}
|
|
26
|
-
// Don't release
|
|
27
|
-
jstring java_name = (*env)->NewStringUTF(env, property_name);
|
|
28
|
-
jobject result = (*env)->CallObjectMethod(env, call_host,
|
|
29
|
-
method_quick_js_on_call_getter(env),
|
|
30
|
-
object_handle, java_name);
|
|
31
|
-
(*env)->DeleteLocalRef(env, java_name);
|
|
32
|
-
// Check java exceptions
|
|
33
|
-
jthrowable exception = try_catch_java_exceptions(env);
|
|
34
|
-
if (exception != NULL) {
|
|
35
|
-
set_eval_exception_to_caller(env, call_host, exception);
|
|
36
|
-
(*env)->DeleteLocalRef(env, exception);
|
|
37
|
-
return JS_EXCEPTION;
|
|
38
|
-
}
|
|
39
|
-
if (result == NULL) {
|
|
40
|
-
return JS_NULL;
|
|
41
|
-
}
|
|
42
|
-
return jobject_to_js_value(env, context, NULL, result);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
JSValue jni_invoke_setter(JSContext *context, jobject call_host, int64_t object_handle,
|
|
46
|
-
const char *property_name, int argc, JSValueConst *argv) {
|
|
47
|
-
JNIEnv *env = get_jni_env();
|
|
48
|
-
if (env == NULL) {
|
|
49
|
-
return JS_EXCEPTION;
|
|
50
|
-
}
|
|
51
|
-
if (argc < 1) {
|
|
52
|
-
return JS_EXCEPTION;
|
|
53
|
-
}
|
|
54
|
-
jobject value = js_value_to_jobject(env, context, argv[0]);
|
|
55
|
-
// Check mapping exceptions
|
|
56
|
-
jthrowable mapping_exception = try_catch_java_exceptions(env);
|
|
57
|
-
if (mapping_exception != NULL) {
|
|
58
|
-
set_eval_exception_to_caller(env, call_host, mapping_exception);
|
|
59
|
-
(*env)->DeleteLocalRef(env, value);
|
|
60
|
-
(*env)->DeleteLocalRef(env, mapping_exception);
|
|
61
|
-
return JS_EXCEPTION;
|
|
62
|
-
}
|
|
63
|
-
// Don't release
|
|
64
|
-
jstring java_name = (*env)->NewStringUTF(env, property_name);
|
|
65
|
-
(*env)->CallVoidMethod(env, call_host, method_quick_js_on_call_setter(env),
|
|
66
|
-
object_handle, java_name, value);
|
|
67
|
-
(*env)->DeleteLocalRef(env, java_name);
|
|
68
|
-
// Check java exceptions
|
|
69
|
-
jthrowable exception = try_catch_java_exceptions(env);
|
|
70
|
-
if (exception != NULL) {
|
|
71
|
-
set_eval_exception_to_caller(env, call_host, exception);
|
|
72
|
-
(*env)->DeleteLocalRef(env, exception);
|
|
73
|
-
return JS_EXCEPTION;
|
|
74
|
-
}
|
|
75
|
-
return JS_UNDEFINED;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
JSValue jni_invoke_function(JSContext *context, jobject call_host, int64_t object_handle,
|
|
79
|
-
const char *function_name, int argc, JSValueConst *argv) {
|
|
80
|
-
JNIEnv *env = get_jni_env();
|
|
81
|
-
if (env == NULL) {
|
|
82
|
-
return JS_EXCEPTION;
|
|
83
|
-
}
|
|
84
|
-
jobjectArray args = (*env)->NewObjectArray(env, argc, cls_object(env), NULL);
|
|
85
|
-
for (uint32_t i = 0; i < argc; i++) {
|
|
86
|
-
jobject arg = js_value_to_jobject(env, context, argv[i]);
|
|
87
|
-
// Check mapping exceptions
|
|
88
|
-
jthrowable exception = try_catch_java_exceptions(env);
|
|
89
|
-
if (exception != NULL) {
|
|
90
|
-
set_eval_exception_to_caller(env, call_host, exception);
|
|
91
|
-
(*env)->DeleteLocalRef(env, arg);
|
|
92
|
-
(*env)->DeleteLocalRef(env, exception);
|
|
93
|
-
return JS_EXCEPTION;
|
|
94
|
-
}
|
|
95
|
-
(*env)->SetObjectArrayElement(env, args, i, arg);
|
|
96
|
-
(*env)->DeleteLocalRef(env, arg);
|
|
97
|
-
}
|
|
98
|
-
// Don't release
|
|
99
|
-
jstring java_name = (*env)->NewStringUTF(env, function_name);
|
|
100
|
-
jobject result = (*env)->CallObjectMethod(env, call_host,
|
|
101
|
-
method_quick_js_on_call_function(env),
|
|
102
|
-
object_handle,
|
|
103
|
-
java_name,
|
|
104
|
-
args);
|
|
105
|
-
(*env)->DeleteLocalRef(env, java_name);
|
|
106
|
-
// Check java exceptions
|
|
107
|
-
jthrowable exception = try_catch_java_exceptions(env);
|
|
108
|
-
if (exception != NULL) {
|
|
109
|
-
set_eval_exception_to_caller(env, call_host, exception);
|
|
110
|
-
(*env)->DeleteLocalRef(env, exception);
|
|
111
|
-
return JS_EXCEPTION;
|
|
112
|
-
}
|
|
113
|
-
return jobject_to_js_value(env, context, NULL, result);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
JSValue jni_invoke_async_function(JSContext *context, jobject call_host,
|
|
117
|
-
int64_t object_handle,
|
|
118
|
-
const char *function_name,
|
|
119
|
-
uint64_t resolve_handle,
|
|
120
|
-
uint64_t reject_handle,
|
|
121
|
-
int argc, JSValueConst *argv) {
|
|
122
|
-
JNIEnv *env = get_jni_env();
|
|
123
|
-
if (env == NULL) {
|
|
124
|
-
return JS_EXCEPTION;
|
|
125
|
-
}
|
|
126
|
-
int args_len = argc + 2;
|
|
127
|
-
jobjectArray args = (*env)->NewObjectArray(env, args_len, cls_object(env), NULL);
|
|
128
|
-
// Set promise handles
|
|
129
|
-
(*env)->SetObjectArrayElement(env, args, 0, java_boxed_long(env, resolve_handle));
|
|
130
|
-
(*env)->SetObjectArrayElement(env, args, 1, java_boxed_long(env, reject_handle));
|
|
131
|
-
// Fill args
|
|
132
|
-
for (uint32_t i = 0; i < argc; i++) {
|
|
133
|
-
jobject arg = js_value_to_jobject(env, context, argv[i]);
|
|
134
|
-
// Check mapping exceptions
|
|
135
|
-
jthrowable exception = try_catch_java_exceptions(env);
|
|
136
|
-
if (exception != NULL) {
|
|
137
|
-
set_eval_exception_to_caller(env, call_host, exception);
|
|
138
|
-
(*env)->DeleteLocalRef(env, arg);
|
|
139
|
-
(*env)->DeleteLocalRef(env, exception);
|
|
140
|
-
return JS_EXCEPTION;
|
|
141
|
-
}
|
|
142
|
-
(*env)->SetObjectArrayElement(env, args, i + (args_len - argc), arg);
|
|
143
|
-
(*env)->DeleteLocalRef(env, arg);
|
|
144
|
-
}
|
|
145
|
-
// Don't release
|
|
146
|
-
jstring java_name = (*env)->NewStringUTF(env, function_name);
|
|
147
|
-
(*env)->CallObjectMethod(env, call_host,
|
|
148
|
-
method_quick_js_on_call_function(env),
|
|
149
|
-
object_handle,
|
|
150
|
-
java_name,
|
|
151
|
-
args);
|
|
152
|
-
(*env)->DeleteLocalRef(env, java_name);
|
|
153
|
-
// Check java exceptions
|
|
154
|
-
jthrowable exception = try_catch_java_exceptions(env);
|
|
155
|
-
if (exception != NULL) {
|
|
156
|
-
set_eval_exception_to_caller(env, call_host, exception);
|
|
157
|
-
(*env)->DeleteLocalRef(env, exception);
|
|
158
|
-
return JS_EXCEPTION;
|
|
159
|
-
}
|
|
160
|
-
// No return value needs to handle
|
|
161
|
-
return JS_UNDEFINED;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
JSValue
|
|
165
|
-
property_getter(JSContext *context, JSValueConst this_val, int argc, JSValueConst *argv, int magic,
|
|
166
|
-
JSValue *func_data) {
|
|
167
|
-
int64_t host_address;
|
|
168
|
-
JS_ToInt64(context, &host_address, func_data[0]);
|
|
169
|
-
jobject call_host = (jobject) host_address;
|
|
170
|
-
int64_t object_handle;
|
|
171
|
-
JS_ToInt64(context, &object_handle, func_data[1]);
|
|
172
|
-
const char *prop_name = JS_ToCString(context, func_data[2]);
|
|
173
|
-
|
|
174
|
-
JSValue result = jni_invoke_getter(context, call_host, object_handle, prop_name);
|
|
175
|
-
|
|
176
|
-
JS_FreeCString(context, prop_name);
|
|
177
|
-
|
|
178
|
-
return result;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
JSValue
|
|
182
|
-
property_setter(JSContext *context, JSValueConst this_val, int argc, JSValueConst *argv, int magic,
|
|
183
|
-
JSValue *func_data) {
|
|
184
|
-
int64_t host_address;
|
|
185
|
-
JS_ToInt64(context, &host_address, func_data[0]);
|
|
186
|
-
jobject call_host = (jobject) host_address;
|
|
187
|
-
int64_t object_handle;
|
|
188
|
-
JS_ToInt64(context, &object_handle, func_data[1]);
|
|
189
|
-
const char *prop_name = JS_ToCString(context, func_data[2]);
|
|
190
|
-
|
|
191
|
-
JSValue result = jni_invoke_setter(context, call_host, object_handle, prop_name, argc, argv);
|
|
192
|
-
|
|
193
|
-
JS_FreeCString(context, prop_name);
|
|
194
|
-
|
|
195
|
-
return result;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
JSValue
|
|
199
|
-
function_invoke(JSContext *context, JSValueConst this_val, int argc, JSValueConst *argv, int magic,
|
|
200
|
-
JSValue *func_data) {
|
|
201
|
-
int64_t host_address;
|
|
202
|
-
JS_ToInt64(context, &host_address, func_data[0]);
|
|
203
|
-
jobject call_host = (jobject) host_address;
|
|
204
|
-
int64_t object_handle;
|
|
205
|
-
JS_ToInt64(context, &object_handle, func_data[1]);
|
|
206
|
-
const char *func_name = JS_ToCString(context, func_data[2]);
|
|
207
|
-
|
|
208
|
-
JSValue result = jni_invoke_function(context, call_host, object_handle, func_name, argc, argv);
|
|
209
|
-
|
|
210
|
-
JS_FreeCString(context, func_name);
|
|
211
|
-
|
|
212
|
-
return result;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
JSValue async_function_invoke(JSContext *context, JSValueConst this_val,
|
|
216
|
-
int argc, JSValueConst *argv, int magic,
|
|
217
|
-
JSValue *func_data) {
|
|
218
|
-
JNIEnv *env = get_jni_env();
|
|
219
|
-
if (env == NULL) {
|
|
220
|
-
return JS_EXCEPTION;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Get the jni host
|
|
224
|
-
int64_t host_address;
|
|
225
|
-
JS_ToInt64(context, &host_address, func_data[0]);
|
|
226
|
-
jobject call_host = (jobject) host_address;
|
|
227
|
-
|
|
228
|
-
// Get the parent handle
|
|
229
|
-
int64_t object_handle;
|
|
230
|
-
JS_ToInt64(context, &object_handle, func_data[1]);
|
|
231
|
-
|
|
232
|
-
// Get the function name
|
|
233
|
-
const char *function_name = JS_ToCString(context, func_data[2]);
|
|
234
|
-
|
|
235
|
-
// Get globals
|
|
236
|
-
int64_t globals_address_low;
|
|
237
|
-
int64_t globals_address_high;
|
|
238
|
-
JS_ToInt64(context, &globals_address_low, func_data[3]);
|
|
239
|
-
JS_ToInt64(context, &globals_address_high, func_data[4]);
|
|
240
|
-
int64_t globals_address = (globals_address_low & 0xFFFFFFFF) | globals_address_high << 32;
|
|
241
|
-
Globals *globals = (Globals *) globals_address;
|
|
242
|
-
|
|
243
|
-
// Handles are the indices
|
|
244
|
-
int64_t resolve_handle = cvector_size(globals->created_js_functions);
|
|
245
|
-
int64_t reject_handle = resolve_handle + 1;
|
|
246
|
-
|
|
247
|
-
JSValue promise_functions[2];
|
|
248
|
-
JSValue promise = JS_NewPromiseCapability(context, promise_functions);
|
|
249
|
-
|
|
250
|
-
cvector_push_back(globals->managed_js_values, promise);
|
|
251
|
-
cvector_push_back(globals->created_js_functions, promise_functions[0]);
|
|
252
|
-
cvector_push_back(globals->created_js_functions, promise_functions[1]);
|
|
253
|
-
|
|
254
|
-
// Call java function
|
|
255
|
-
JSValue result = jni_invoke_async_function(context, call_host, object_handle,
|
|
256
|
-
function_name, resolve_handle, reject_handle,
|
|
257
|
-
argc, argv);
|
|
258
|
-
|
|
259
|
-
JS_FreeCString(context, function_name);
|
|
260
|
-
|
|
261
|
-
if (JS_IsException(result)) {
|
|
262
|
-
// Error!
|
|
263
|
-
return result;
|
|
264
|
-
} else {
|
|
265
|
-
// Ignore the async return
|
|
266
|
-
JS_FreeValue(context, result);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Return the promise directly will cause a GC error:
|
|
270
|
-
// void gc_decref_child(JSRuntime *, JSGCObjectHeader *): assertion "p->ref_count > 0" failed
|
|
271
|
-
return JS_DupValue(context, promise);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
void define_async_js_function_on(JSContext *context,
|
|
275
|
-
Globals *globals,
|
|
276
|
-
JSValue parent,
|
|
277
|
-
const char *name,
|
|
278
|
-
int func_data_len,
|
|
279
|
-
JSValue *func_data) {
|
|
280
|
-
// Append the globals pointer to the function data
|
|
281
|
-
size_t async_func_data_len = func_data_len + 2;
|
|
282
|
-
JSValue async_func_data[async_func_data_len];
|
|
283
|
-
for (int i = 0; i < func_data_len; ++i) {
|
|
284
|
-
async_func_data[i] = func_data[i];
|
|
285
|
-
}
|
|
286
|
-
int64_t globals_address = (int64_t) (globals);
|
|
287
|
-
int64_t globals_low = globals_address & 0xFFFFFFFF;
|
|
288
|
-
int64_t globals_high = (globals_address >> 32) & 0xFFFFFFFF;
|
|
289
|
-
async_func_data[func_data_len] = JS_NewInt64(context, globals_low);
|
|
290
|
-
async_func_data[func_data_len + 1] = JS_NewInt64(context, globals_high);
|
|
291
|
-
|
|
292
|
-
for (int i = func_data_len; i < async_func_data_len; ++i) {
|
|
293
|
-
// Add to free
|
|
294
|
-
cvector_push_back(globals->managed_js_values, async_func_data[i]);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
JSValue invoke = JS_NewCFunctionData(context, async_function_invoke, 0, 0,
|
|
298
|
-
async_func_data_len,
|
|
299
|
-
async_func_data);
|
|
300
|
-
int flags = JS_PROP_CONFIGURABLE;
|
|
301
|
-
JSAtom prop = JS_NewAtom(context, name);
|
|
302
|
-
// Define async function
|
|
303
|
-
JS_DefinePropertyValue(context, parent, prop, invoke, flags);
|
|
304
|
-
JS_FreeAtom(context, prop);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
void define_js_function_on(JSContext *context,
|
|
308
|
-
JSValue parent,
|
|
309
|
-
const char *name,
|
|
310
|
-
int func_data_len,
|
|
311
|
-
JSValue *func_data) {
|
|
312
|
-
JSValue invoke = JS_NewCFunctionData(context, function_invoke, 0, 0, func_data_len, func_data);
|
|
313
|
-
int flags = JS_PROP_CONFIGURABLE;
|
|
314
|
-
JSAtom prop = JS_NewAtom(context, name);
|
|
315
|
-
// Define function
|
|
316
|
-
JS_DefinePropertyValue(context, parent, prop, invoke, flags);
|
|
317
|
-
JS_FreeAtom(context, prop);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
void define_js_functions_on(JNIEnv *env,
|
|
321
|
-
JSContext *context,
|
|
322
|
-
Globals *globals,
|
|
323
|
-
JSValue parent,
|
|
324
|
-
jobjectArray functions,
|
|
325
|
-
JSValue *common_func_data) {
|
|
326
|
-
jsize func_size = (*env)->GetArrayLength(env, functions);
|
|
327
|
-
|
|
328
|
-
jfieldID field_name = field_js_function_name(env);
|
|
329
|
-
jfieldID field_is_async = field_js_function_is_async(env);
|
|
330
|
-
|
|
331
|
-
// Add functions
|
|
332
|
-
for (jsize i = 0; i < func_size; i++) {
|
|
333
|
-
jobject j_fun = (*env)->GetObjectArrayElement(env, functions, i);
|
|
334
|
-
jstring j_fun_name = (*env)->GetObjectField(env, j_fun, field_name);
|
|
335
|
-
const char *func_name = (*env)->GetStringUTFChars(env, j_fun_name, NULL);
|
|
336
|
-
jboolean is_async = (*env)->GetBooleanField(env, j_fun, field_is_async);
|
|
337
|
-
|
|
338
|
-
// Function data
|
|
339
|
-
uint32_t data_len = COMMON_FUNC_DATA_LEN + 1;
|
|
340
|
-
JSValue func_data[data_len];
|
|
341
|
-
for (int j = 0; j < data_len - 1; j++) {
|
|
342
|
-
func_data[j] = common_func_data[j];
|
|
343
|
-
}
|
|
344
|
-
JSValue js_func_name = JS_NewString(context, func_name);
|
|
345
|
-
cvector_push_back(globals->managed_js_values, js_func_name);
|
|
346
|
-
func_data[data_len - 1] = js_func_name;
|
|
347
|
-
|
|
348
|
-
if (is_async) {
|
|
349
|
-
define_async_js_function_on(context, globals, parent, func_name, data_len, func_data);
|
|
350
|
-
} else {
|
|
351
|
-
define_js_function_on(context, parent, func_name, data_len, func_data);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
(*env)->ReleaseStringUTFChars(env, j_fun_name, func_name);
|
|
355
|
-
(*env)->DeleteLocalRef(env, j_fun_name);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
JSValue define_js_object(JNIEnv *env, JSContext *context,
|
|
360
|
-
Globals *globals,
|
|
361
|
-
jobject host,
|
|
362
|
-
JSValue *parent,
|
|
363
|
-
int64_t handle,
|
|
364
|
-
jstring name,
|
|
365
|
-
jobjectArray properties,
|
|
366
|
-
jobjectArray functions) {
|
|
367
|
-
jobject global_host = (*env)->NewGlobalRef(env, host);
|
|
368
|
-
cvector_push_back(globals->global_object_refs, global_host);
|
|
369
|
-
|
|
370
|
-
jsize prop_size = (*env)->GetArrayLength(env, properties);
|
|
371
|
-
|
|
372
|
-
JSValue common_func_data[COMMON_FUNC_DATA_LEN] = {
|
|
373
|
-
JS_NewInt64(context, (int64_t) global_host), // host address
|
|
374
|
-
JS_NewInt64(context, handle), // object handle
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
// Free these values before freeing the runtime
|
|
378
|
-
for (uint32_t i = 0; i < COMMON_FUNC_DATA_LEN; i++) {
|
|
379
|
-
cvector_push_back(globals->managed_js_values, common_func_data[i]);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
JSValue object = JS_NewObject(context);
|
|
383
|
-
|
|
384
|
-
// Add properties
|
|
385
|
-
for (jsize i = 0; i < prop_size; i++) {
|
|
386
|
-
jobject element = (*env)->GetObjectArrayElement(env, properties, i);
|
|
387
|
-
|
|
388
|
-
jstring j_prop_name = (*env)->GetObjectField(env, element, field_js_property_name(env));
|
|
389
|
-
const char *prop_name = (*env)->GetStringUTFChars(env, j_prop_name, NULL);
|
|
390
|
-
jboolean configurable = (*env)->GetBooleanField(env, element,
|
|
391
|
-
field_js_property_configurable(env));
|
|
392
|
-
jboolean writable = (*env)->GetBooleanField(env, element, field_js_property_writable(env));
|
|
393
|
-
jboolean enumerable = (*env)->GetBooleanField(env, element,
|
|
394
|
-
field_js_property_enumerable(env));
|
|
395
|
-
|
|
396
|
-
// Function data
|
|
397
|
-
uint32_t data_len = COMMON_FUNC_DATA_LEN + 1;
|
|
398
|
-
JSValue func_data[data_len];
|
|
399
|
-
for (int j = 0; j < data_len - 1; j++) {
|
|
400
|
-
func_data[j] = common_func_data[j];
|
|
401
|
-
}
|
|
402
|
-
JSValue js_prop_name = JS_NewString(context, prop_name);
|
|
403
|
-
cvector_push_back(globals->managed_js_values, js_prop_name);
|
|
404
|
-
func_data[data_len - 1] = js_prop_name;
|
|
405
|
-
|
|
406
|
-
JSValue getter = JS_NewCFunctionData(context, property_getter, 0, 0, data_len, func_data);
|
|
407
|
-
int flags = JS_PROP_C_W_E;
|
|
408
|
-
if (configurable == JNI_FALSE) {
|
|
409
|
-
flags = flags & ~JS_PROP_CONFIGURABLE;
|
|
410
|
-
}
|
|
411
|
-
if (writable == JNI_FALSE) {
|
|
412
|
-
flags = flags & ~JS_PROP_WRITABLE;
|
|
413
|
-
}
|
|
414
|
-
if (enumerable == JNI_FALSE) {
|
|
415
|
-
flags = flags & ~JS_PROP_ENUMERABLE;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
JSAtom prop = JS_NewAtom(context, prop_name);
|
|
419
|
-
|
|
420
|
-
// Define property
|
|
421
|
-
if (writable == JNI_FALSE) {
|
|
422
|
-
JS_DefinePropertyGetSet(context, object, prop, getter, JS_UNDEFINED, 0);
|
|
423
|
-
} else {
|
|
424
|
-
JSValue setter = JS_NewCFunctionData(context, property_setter, 0, 0, data_len,
|
|
425
|
-
func_data);
|
|
426
|
-
JS_DefinePropertyGetSet(context, object, prop, getter, setter, flags);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
JS_FreeAtom(context, prop);
|
|
430
|
-
|
|
431
|
-
(*env)->ReleaseStringUTFChars(env, j_prop_name, prop_name);
|
|
432
|
-
(*env)->DeleteLocalRef(env, j_prop_name);
|
|
433
|
-
(*env)->DeleteLocalRef(env, element);
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Add functions
|
|
437
|
-
define_js_functions_on(env, context, globals, object, functions, common_func_data);
|
|
438
|
-
|
|
439
|
-
const char *c_name = (*env)->GetStringUTFChars(env, name, NULL);
|
|
440
|
-
|
|
441
|
-
if (parent == NULL) {
|
|
442
|
-
JSValue global_this = JS_GetGlobalObject(context);
|
|
443
|
-
// Attach object to globalThis
|
|
444
|
-
JS_DefinePropertyValueStr(context, global_this, c_name, object, 0);
|
|
445
|
-
JS_FreeValue(context, global_this);
|
|
446
|
-
} else {
|
|
447
|
-
// Attach object to parent
|
|
448
|
-
JS_DefinePropertyValueStr(context, *parent, c_name, object, 0);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
(*env)->ReleaseStringUTFChars(env, name, c_name);
|
|
452
|
-
|
|
453
|
-
return object;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
void define_js_function(JNIEnv *env, JSContext *context,
|
|
457
|
-
Globals *globals,
|
|
458
|
-
jobject host,
|
|
459
|
-
jstring name,
|
|
460
|
-
jboolean is_async) {
|
|
461
|
-
jobject global_host = (*env)->NewGlobalRef(env, host);
|
|
462
|
-
cvector_push_back(globals->global_object_refs, global_host);
|
|
463
|
-
|
|
464
|
-
const char *func_name = (*env)->GetStringUTFChars(env, name, NULL);
|
|
465
|
-
|
|
466
|
-
// Function data
|
|
467
|
-
uint32_t data_len = COMMON_FUNC_DATA_LEN + 1;
|
|
468
|
-
JSValue func_data[3] = {
|
|
469
|
-
JS_NewInt64(context, (int64_t) global_host), // host address
|
|
470
|
-
JS_NewInt64(context, GLOBAL_THIS_HANDLE), // parent object handle
|
|
471
|
-
JS_NewString(context, func_name), // function name
|
|
472
|
-
};
|
|
473
|
-
|
|
474
|
-
for (uint32_t i = 0; i < data_len; i++) {
|
|
475
|
-
cvector_push_back(globals->managed_js_values, func_data[i]);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
JSValue global_this = JS_GetGlobalObject(context);
|
|
479
|
-
if (is_async) {
|
|
480
|
-
define_async_js_function_on(context, globals, global_this, func_name,
|
|
481
|
-
data_len, func_data);
|
|
482
|
-
} else {
|
|
483
|
-
define_js_function_on(context, global_this, func_name, data_len, func_data);
|
|
484
|
-
}
|
|
485
|
-
JS_FreeValue(context, global_this);
|
|
486
|
-
|
|
487
|
-
(*env)->ReleaseStringUTFChars(env, name, func_name);
|
|
488
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
#ifndef QJS_KT_JS_BINDING_BRIDGE_H
|
|
2
|
-
#define QJS_KT_JS_BINDING_BRIDGE_H
|
|
3
|
-
|
|
4
|
-
#include "jni.h"
|
|
5
|
-
#include "quickjs.h"
|
|
6
|
-
#include "cvector.h"
|
|
7
|
-
#include "quickjs_jni.h"
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Define a JavaScript object. It will be attached to the parent if the parent is not null,
|
|
11
|
-
* otherwise, it will be attached to 'globalThis'.
|
|
12
|
-
*/
|
|
13
|
-
JSValue define_js_object(JNIEnv *env, JSContext *context,
|
|
14
|
-
Globals *globals,
|
|
15
|
-
jobject call_host,
|
|
16
|
-
JSValue *parent,
|
|
17
|
-
int64_t handle,
|
|
18
|
-
jstring name,
|
|
19
|
-
jobjectArray properties,
|
|
20
|
-
jobjectArray function_names);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Define a JavaScript function. It will be attached to 'globalThis'.
|
|
25
|
-
*/
|
|
26
|
-
void define_js_function(JNIEnv *env, JSContext *context,
|
|
27
|
-
Globals *globals,
|
|
28
|
-
jobject call_host,
|
|
29
|
-
jstring name,
|
|
30
|
-
jboolean is_async);
|
|
31
|
-
|
|
32
|
-
#endif //QJS_KT_JS_BINDING_BRIDGE_H
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#include <stdlib.h>
|
|
2
|
-
#include <string.h>
|
|
3
|
-
#include "exception_util.h"
|
|
4
|
-
#include "jni_globals_generated.h"
|
|
5
|
-
#include "log_util.h"
|
|
6
|
-
#include "js_value_util.h"
|
|
7
|
-
|
|
8
|
-
jthrowable new_qjs_exception(JNIEnv *env, const char *format, ...) {
|
|
9
|
-
va_list args;
|
|
10
|
-
va_start(args, format);
|
|
11
|
-
int length = vsnprintf(NULL, 0, format, args);
|
|
12
|
-
va_end(args);
|
|
13
|
-
|
|
14
|
-
char *result = (char *) malloc(length + 1);
|
|
15
|
-
|
|
16
|
-
va_start(args, format);
|
|
17
|
-
vsnprintf(result, length + 1, format, args);
|
|
18
|
-
va_end(args);
|
|
19
|
-
|
|
20
|
-
jstring message = (*env)->NewStringUTF(env, result);
|
|
21
|
-
return (*env)->NewObject(env, cls_quick_js_exception(env),
|
|
22
|
-
method_quick_js_exception_init(env), message);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
void jni_throw_qjs_exception(JNIEnv *env, const char *format, ...) {
|
|
26
|
-
va_list args;
|
|
27
|
-
va_start(args, format);
|
|
28
|
-
int length = vsnprintf(NULL, 0, format, args);
|
|
29
|
-
va_end(args);
|
|
30
|
-
|
|
31
|
-
char *result = (char *) malloc(length + 1);
|
|
32
|
-
|
|
33
|
-
va_start(args, format);
|
|
34
|
-
vsnprintf(result, length + 1, format, args);
|
|
35
|
-
va_end(args);
|
|
36
|
-
|
|
37
|
-
(*env)->ThrowNew(env, cls_quick_js_exception(env), result);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
jthrowable try_catch_java_exceptions(JNIEnv *env) {
|
|
41
|
-
jthrowable exception = (*env)->ExceptionOccurred(env);
|
|
42
|
-
if (exception != NULL) {
|
|
43
|
-
(*env)->ExceptionClear(env);
|
|
44
|
-
return exception;
|
|
45
|
-
} else {
|
|
46
|
-
return NULL;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
int check_js_context_exception(JNIEnv *env, JSContext *context) {
|
|
51
|
-
JSValue exception = JS_GetException(context);
|
|
52
|
-
// Check exception
|
|
53
|
-
if (!JS_IsNull(exception)) {
|
|
54
|
-
char *message = NULL;
|
|
55
|
-
js_error_to_string(context, exception, &message);
|
|
56
|
-
// Free values
|
|
57
|
-
JS_FreeValue(context, exception);
|
|
58
|
-
// Throw java exception
|
|
59
|
-
jni_throw_qjs_exception(env, message);
|
|
60
|
-
return 1;
|
|
61
|
-
} else {
|
|
62
|
-
return 0;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#ifndef QJS_KT_EXCEPTION_UTIL_H
|
|
2
|
-
#define QJS_KT_EXCEPTION_UTIL_H
|
|
3
|
-
|
|
4
|
-
#include <stdarg.h>
|
|
5
|
-
#include "jni.h"
|
|
6
|
-
#include "quickjs.h"
|
|
7
|
-
|
|
8
|
-
jthrowable new_qjs_exception(JNIEnv *env, const char *format, ...);
|
|
9
|
-
|
|
10
|
-
void jni_throw_qjs_exception(JNIEnv *env, const char *format, ...);
|
|
11
|
-
|
|
12
|
-
jthrowable try_catch_java_exceptions(JNIEnv *env);
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Check and throw js context exception, if any.
|
|
16
|
-
*
|
|
17
|
-
* @return 1 if there is an exception in the context, 0 otherwise.
|
|
18
|
-
*/
|
|
19
|
-
int check_js_context_exception(JNIEnv *env, JSContext *context);
|
|
20
|
-
|
|
21
|
-
#endif //QJS_KT_EXCEPTION_UTIL_H
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
#include "jni_globals.h"
|
|
2
|
-
#include "log_util.h"
|
|
3
|
-
#include "jni_globals_generated.h"
|
|
4
|
-
#include <pthread.h>
|
|
5
|
-
|
|
6
|
-
static JavaVM *vm = NULL;
|
|
7
|
-
static unsigned int instance_count = 0;
|
|
8
|
-
static pthread_mutex_t resources_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
9
|
-
|
|
10
|
-
void cache_java_vm(JNIEnv *env) {
|
|
11
|
-
pthread_mutex_lock(&resources_mutex);
|
|
12
|
-
(*env)->GetJavaVM(env, &vm);
|
|
13
|
-
instance_count++;
|
|
14
|
-
pthread_mutex_unlock(&resources_mutex);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
JNIEnv *get_jni_env() {
|
|
18
|
-
pthread_mutex_lock(&resources_mutex);
|
|
19
|
-
JavaVM *current_vm = vm;
|
|
20
|
-
pthread_mutex_unlock(&resources_mutex);
|
|
21
|
-
if (current_vm == NULL) {
|
|
22
|
-
log("Cannot get jni env because the vm is not cached.");
|
|
23
|
-
return NULL;
|
|
24
|
-
}
|
|
25
|
-
JNIEnv *env = NULL;
|
|
26
|
-
int attached = 0;
|
|
27
|
-
jint get_env_result = (*current_vm)->GetEnv(current_vm, (void **) &env, JNI_VERSION_1_6);
|
|
28
|
-
if (get_env_result == JNI_OK) {
|
|
29
|
-
attached = 1;
|
|
30
|
-
} else if (get_env_result == JNI_EDETACHED) {
|
|
31
|
-
// Got a warning on Android Studio when casting &env to (void **)
|
|
32
|
-
#pragma clang diagnostic push
|
|
33
|
-
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
|
|
34
|
-
if ((*current_vm)->AttachCurrentThread(current_vm, (void **) &env, NULL) == JNI_OK) {
|
|
35
|
-
#pragma clang diagnostic pop
|
|
36
|
-
attached = 1;
|
|
37
|
-
} else {
|
|
38
|
-
log("Failed to attach current thread.");
|
|
39
|
-
}
|
|
40
|
-
} else if (get_env_result == JNI_EVERSION) {
|
|
41
|
-
log("Unsupported JNI version.");
|
|
42
|
-
}
|
|
43
|
-
if (attached == 0) {
|
|
44
|
-
return NULL;
|
|
45
|
-
}
|
|
46
|
-
return env;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// Backport upstream 4a003f6: process-wide JNI resources outlive every survivor.
|
|
51
|
-
void release_shared_jni_resources(JNIEnv *env) {
|
|
52
|
-
pthread_mutex_lock(&resources_mutex);
|
|
53
|
-
if (instance_count > 0) instance_count--;
|
|
54
|
-
if (instance_count == 0) {
|
|
55
|
-
vm = NULL;
|
|
56
|
-
clear_jni_refs_cache(env);
|
|
57
|
-
}
|
|
58
|
-
pthread_mutex_unlock(&resources_mutex);
|
|
59
|
-
}
|