@mentra/crust 3.3.0-dev.656 → 3.3.0-dev.659

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.
Files changed (56) hide show
  1. package/README.md +7 -0
  2. package/android/build.gradle +15 -40
  3. package/android/src/main/java/com/mentra/crust/jsc/JSCRuntime.kt +13 -4
  4. package/android/src/test/java/com/mentra/crust/jsc/QuickJsLifecycleTest.kt +87 -0
  5. package/package.json +2 -2
  6. package/plugin/build/index.d.ts +2 -0
  7. package/plugin/build/index.js +2 -0
  8. package/plugin/build/withAndroid.js +39 -0
  9. package/android/quickjs-consumer-rules.pro +0 -6
  10. package/android/scripts/test-quickjs-lifecycle.py +0 -45
  11. package/android/src/main/cpp/quickjs/CMakeLists.txt +0 -20
  12. package/android/src/main/cpp/quickjs/LICENSE.quickjs-kt.txt +0 -201
  13. package/android/src/main/cpp/quickjs/README.md +0 -30
  14. package/android/src/main/cpp/quickjs/c-vector/LICENSE +0 -21
  15. package/android/src/main/cpp/quickjs/c-vector/cvector.h +0 -479
  16. package/android/src/main/cpp/quickjs/common/quickjs_version.c +0 -9
  17. package/android/src/main/cpp/quickjs/common/quickjs_version.h +0 -9
  18. package/android/src/main/cpp/quickjs/engine/LICENSE +0 -22
  19. package/android/src/main/cpp/quickjs/engine/VERSION +0 -1
  20. package/android/src/main/cpp/quickjs/engine/cutils.c +0 -631
  21. package/android/src/main/cpp/quickjs/engine/cutils.h +0 -347
  22. package/android/src/main/cpp/quickjs/engine/libbf.c +0 -8475
  23. package/android/src/main/cpp/quickjs/engine/libbf.h +0 -535
  24. package/android/src/main/cpp/quickjs/engine/libregexp-opcode.h +0 -57
  25. package/android/src/main/cpp/quickjs/engine/libregexp.c +0 -2501
  26. package/android/src/main/cpp/quickjs/engine/libregexp.h +0 -55
  27. package/android/src/main/cpp/quickjs/engine/libunicode-table.h +0 -4557
  28. package/android/src/main/cpp/quickjs/engine/libunicode.c +0 -1910
  29. package/android/src/main/cpp/quickjs/engine/libunicode.h +0 -182
  30. package/android/src/main/cpp/quickjs/engine/list.h +0 -99
  31. package/android/src/main/cpp/quickjs/engine/quickjs-atom.h +0 -273
  32. package/android/src/main/cpp/quickjs/engine/quickjs-opcode.h +0 -372
  33. package/android/src/main/cpp/quickjs/engine/quickjs.c +0 -55978
  34. package/android/src/main/cpp/quickjs/engine/quickjs.h +0 -1087
  35. package/android/src/main/cpp/quickjs/jni/binding_bridge.c +0 -488
  36. package/android/src/main/cpp/quickjs/jni/binding_bridge.h +0 -32
  37. package/android/src/main/cpp/quickjs/jni/exception_util.c +0 -64
  38. package/android/src/main/cpp/quickjs/jni/exception_util.h +0 -21
  39. package/android/src/main/cpp/quickjs/jni/jni_globals.c +0 -59
  40. package/android/src/main/cpp/quickjs/jni/jni_globals.h +0 -12
  41. package/android/src/main/cpp/quickjs/jni/jni_globals_generated.c +0 -855
  42. package/android/src/main/cpp/quickjs/jni/jni_globals_generated.h +0 -171
  43. package/android/src/main/cpp/quickjs/jni/js_value_util.c +0 -213
  44. package/android/src/main/cpp/quickjs/jni/js_value_util.h +0 -71
  45. package/android/src/main/cpp/quickjs/jni/log_util.h +0 -15
  46. package/android/src/main/cpp/quickjs/jni/mapping/jni_types_util.c +0 -27
  47. package/android/src/main/cpp/quickjs/jni/mapping/jni_types_util.h +0 -15
  48. package/android/src/main/cpp/quickjs/jni/mapping/jobject_to_js_value.c +0 -620
  49. package/android/src/main/cpp/quickjs/jni/mapping/jobject_to_js_value.h +0 -13
  50. package/android/src/main/cpp/quickjs/jni/mapping/js_value_to_jobject.c +0 -421
  51. package/android/src/main/cpp/quickjs/jni/mapping/js_value_to_jobject.h +0 -12
  52. package/android/src/main/cpp/quickjs/jni/promise_rejection_handler.c +0 -20
  53. package/android/src/main/cpp/quickjs/jni/promise_rejection_handler.h +0 -10
  54. package/android/src/main/cpp/quickjs/jni/quickjs_jni.c +0 -735
  55. package/android/src/main/cpp/quickjs/jni/quickjs_jni.h +0 -40
  56. 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
- }
@@ -1,12 +0,0 @@
1
- #ifndef QJS_KT_JNI_GLOBALS_H
2
- #define QJS_KT_JNI_GLOBALS_H
3
-
4
- #include "jni.h"
5
-
6
- void cache_java_vm(JNIEnv *env);
7
-
8
- JNIEnv *get_jni_env();
9
-
10
- void release_shared_jni_resources(JNIEnv *env);
11
-
12
- #endif //QJS_KT_JNI_GLOBALS_H