@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,620 +0,0 @@
|
|
|
1
|
-
#include <string.h>
|
|
2
|
-
#include <stdlib.h>
|
|
3
|
-
#include "jobject_to_js_value.h"
|
|
4
|
-
#include "js_value_util.h"
|
|
5
|
-
#include "exception_util.h"
|
|
6
|
-
#include "log_util.h"
|
|
7
|
-
#include "jni_globals_generated.h"
|
|
8
|
-
|
|
9
|
-
void throw_circular_ref_error(JSContext *context) {
|
|
10
|
-
const char *msg = "Unable to map objects with circular reference.";
|
|
11
|
-
JSValue err = new_simple_js_error(context, msg);
|
|
12
|
-
JS_Throw(context, err);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
void visit_first(JNIEnv *env, jobject visited_set, jobject current) {
|
|
16
|
-
if (current == NULL) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
if (!(*env)->CallBooleanMethod(env, visited_set, method_set_is_empty(env))) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
jint hash = (*env)->CallStaticIntMethod(env, cls_system(env),
|
|
23
|
-
method_system_identity_hash_code(env), current);
|
|
24
|
-
jobject hash_boxed = (*env)->CallStaticObjectMethod(env, cls_integer(env),
|
|
25
|
-
method_integer_value_of(env), hash);
|
|
26
|
-
(*env)->CallBooleanMethod(env, visited_set, method_set_add(env), hash_boxed);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
int visit_or_circular_ref_error(JNIEnv *env, JSContext *context,
|
|
30
|
-
jobject visited_set, jobject current) {
|
|
31
|
-
if (current == NULL) {
|
|
32
|
-
return 0;
|
|
33
|
-
}
|
|
34
|
-
jclass cls = (*env)->GetObjectClass(env, current);
|
|
35
|
-
if (!(*env)->CallBooleanMethod(env, cls, method_class_is_array(env)) &&
|
|
36
|
-
!(*env)->IsInstanceOf(env, current, cls_list(env)) &&
|
|
37
|
-
!(*env)->IsInstanceOf(env, current, cls_set(env)) &&
|
|
38
|
-
!(*env)->IsInstanceOf(env, current, cls_map(env)) &&
|
|
39
|
-
!(*env)->IsInstanceOf(env, current, cls_js_object(env))) {
|
|
40
|
-
return 0;
|
|
41
|
-
}
|
|
42
|
-
jint hash = (*env)->CallStaticIntMethod(env, cls_system(env),
|
|
43
|
-
method_system_identity_hash_code(env), current);
|
|
44
|
-
jobject hash_boxed = (*env)->CallStaticObjectMethod(env, cls_integer(env),
|
|
45
|
-
method_integer_value_of(env), hash);
|
|
46
|
-
if ((*env)->CallBooleanMethod(env, visited_set, method_set_contains(env), hash_boxed)) {
|
|
47
|
-
throw_circular_ref_error(context);
|
|
48
|
-
return 1;
|
|
49
|
-
} else {
|
|
50
|
-
(*env)->CallBooleanMethod(env, visited_set, method_set_add(env), hash_boxed);
|
|
51
|
-
return 0;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
JSValue java_list_to_js_array(JNIEnv *env, JSContext *context,
|
|
56
|
-
jobject visited_set, jobject java_list) {
|
|
57
|
-
int delete_global_visited_ref = 0;
|
|
58
|
-
if (visited_set == NULL) {
|
|
59
|
-
jobject visited = (*env)->NewObject(env, cls_hash_set(env), method_hash_set_init(env));
|
|
60
|
-
visited_set = (*env)->NewGlobalRef(env, visited);
|
|
61
|
-
(*env)->DeleteLocalRef(env, visited);
|
|
62
|
-
delete_global_visited_ref = 1;
|
|
63
|
-
}
|
|
64
|
-
visit_first(env, visited_set, java_list);
|
|
65
|
-
|
|
66
|
-
JSValue js_array = JS_NewArray(context);
|
|
67
|
-
jmethodID method_get = method_list_get(env);
|
|
68
|
-
jint size = (*env)->CallIntMethod(env, java_list, method_list_size(env));
|
|
69
|
-
int has_exception = 0;
|
|
70
|
-
for (int i = 0; i < size && has_exception == 0; i++) {
|
|
71
|
-
jobject element = (*env)->CallObjectMethod(env, java_list, method_get, i);
|
|
72
|
-
// Check circular refs
|
|
73
|
-
if (visit_or_circular_ref_error(env, context, visited_set, element)) {
|
|
74
|
-
(*env)->DeleteLocalRef(env, element);
|
|
75
|
-
has_exception = 1;
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
JSValue js_element = jobject_to_js_value(env, context, visited_set, element);
|
|
79
|
-
if (!JS_IsException(js_element)) {
|
|
80
|
-
JS_SetPropertyUint32(context, js_array, i, js_element);
|
|
81
|
-
} else {
|
|
82
|
-
has_exception = 1;
|
|
83
|
-
}
|
|
84
|
-
(*env)->DeleteLocalRef(env, element);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (delete_global_visited_ref) {
|
|
88
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (has_exception) {
|
|
92
|
-
JS_FreeValue(context, js_array);
|
|
93
|
-
return JS_EXCEPTION;
|
|
94
|
-
} else {
|
|
95
|
-
return js_array;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
JSValue new_js_object_from_constructor(JSContext *context, const char *constructor,
|
|
100
|
-
int argc, JSValue *argv) {
|
|
101
|
-
JSValue result;
|
|
102
|
-
|
|
103
|
-
JSValue global_this = JS_GetGlobalObject(context);
|
|
104
|
-
JSValue js_constructor = JS_GetPropertyStr(context, global_this, constructor);
|
|
105
|
-
if (JS_IsUndefined(js_constructor)) {
|
|
106
|
-
JS_FreeValue(context, global_this);
|
|
107
|
-
char message[100];
|
|
108
|
-
sprintf(message, "JS constructor '%s' not found.", constructor);
|
|
109
|
-
JS_Throw(context, new_js_error(context, "TypeMappingError", message, 0, NULL));
|
|
110
|
-
result = JS_EXCEPTION;
|
|
111
|
-
} else {
|
|
112
|
-
result = JS_CallConstructor(context, js_constructor, argc, argv);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
JS_FreeValue(context, js_constructor);
|
|
116
|
-
JS_FreeValue(context, global_this);
|
|
117
|
-
|
|
118
|
-
return result;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
JSValue java_set_to_js_set(JNIEnv *env, JSContext *context,
|
|
122
|
-
jobject visited_set, jobject java_set) {
|
|
123
|
-
int delete_global_visited_ref = 0;
|
|
124
|
-
if (visited_set == NULL) {
|
|
125
|
-
jobject visited = (*env)->NewObject(env, cls_hash_set(env), method_hash_set_init(env));
|
|
126
|
-
visited_set = (*env)->NewGlobalRef(env, visited);
|
|
127
|
-
(*env)->DeleteLocalRef(env, visited);
|
|
128
|
-
delete_global_visited_ref = 1;
|
|
129
|
-
}
|
|
130
|
-
visit_first(env, visited_set, java_set);
|
|
131
|
-
|
|
132
|
-
jobject iterator = (*env)->CallObjectMethod(env, java_set, method_set_iterator(env));
|
|
133
|
-
|
|
134
|
-
jmethodID method_has_next = method_iterator_has_next(env);
|
|
135
|
-
jmethodID method_next = method_iterator_next(env);
|
|
136
|
-
|
|
137
|
-
JSValue js_array = JS_NewArray(context);
|
|
138
|
-
uint32_t index = 0;
|
|
139
|
-
|
|
140
|
-
while ((*env)->CallBooleanMethod(env, iterator, method_has_next)) {
|
|
141
|
-
jobject key = (*env)->CallObjectMethod(env, iterator, method_next);
|
|
142
|
-
// Check circular refs
|
|
143
|
-
if (visit_or_circular_ref_error(env, context, visited_set, key)) {
|
|
144
|
-
JS_FreeValue(context, js_array);
|
|
145
|
-
(*env)->DeleteLocalRef(env, key);
|
|
146
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
147
|
-
return JS_EXCEPTION;
|
|
148
|
-
}
|
|
149
|
-
JSValue item = jobject_to_js_value(env, context, visited_set, key);
|
|
150
|
-
if (JS_IsException(item)) {
|
|
151
|
-
(*env)->DeleteLocalRef(env, key);
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
JS_SetPropertyUint32(context, js_array, index, item);
|
|
155
|
-
(*env)->DeleteLocalRef(env, key);
|
|
156
|
-
index++;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (delete_global_visited_ref) {
|
|
160
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
int argc = 1;
|
|
164
|
-
JSValue argv[] = {js_array};
|
|
165
|
-
JSValue result = new_js_object_from_constructor(context, "Set", argc, argv);
|
|
166
|
-
|
|
167
|
-
JS_FreeValue(context, js_array);
|
|
168
|
-
|
|
169
|
-
return result;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
JSValue java_map_to_js_map(JNIEnv *env, JSContext *context,
|
|
173
|
-
jobject visited_set, jobject java_map) {
|
|
174
|
-
int delete_global_visited_ref = 0;
|
|
175
|
-
if (visited_set == NULL) {
|
|
176
|
-
jobject visited = (*env)->NewObject(env, cls_hash_set(env), method_hash_set_init(env));
|
|
177
|
-
visited_set = (*env)->NewGlobalRef(env, visited);
|
|
178
|
-
(*env)->DeleteLocalRef(env, visited);
|
|
179
|
-
delete_global_visited_ref = 1;
|
|
180
|
-
}
|
|
181
|
-
visit_first(env, visited_set, java_map);
|
|
182
|
-
|
|
183
|
-
jobject entry_set = (*env)->CallObjectMethod(env, java_map, method_map_entry_set(env));
|
|
184
|
-
jobject iterator = (*env)->CallObjectMethod(env, entry_set, method_set_iterator(env));
|
|
185
|
-
|
|
186
|
-
jmethodID method_has_next = method_iterator_has_next(env);
|
|
187
|
-
jmethodID method_next = method_iterator_next(env);
|
|
188
|
-
|
|
189
|
-
jmethodID method_get_key = method_map_entry_get_key(env);
|
|
190
|
-
jmethodID method_get_val = method_map_entry_get_value(env);
|
|
191
|
-
|
|
192
|
-
JSValue js_array = JS_NewArray(context);
|
|
193
|
-
uint32_t index = 0;
|
|
194
|
-
|
|
195
|
-
while ((*env)->CallBooleanMethod(env, iterator, method_has_next)) {
|
|
196
|
-
jobject entry = (*env)->CallObjectMethod(env, iterator, method_next);
|
|
197
|
-
jobject key = (*env)->CallObjectMethod(env, entry, method_get_key);
|
|
198
|
-
|
|
199
|
-
// Check circular refs
|
|
200
|
-
if (visit_or_circular_ref_error(env, context, visited_set, key)) {
|
|
201
|
-
JS_FreeValue(context, js_array);
|
|
202
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
203
|
-
(*env)->DeleteLocalRef(env, key);
|
|
204
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
205
|
-
return JS_EXCEPTION;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
JSValue js_key = jobject_to_js_value(env, context, visited_set, key);
|
|
209
|
-
if (JS_IsException(js_key)) {
|
|
210
|
-
JS_FreeValue(context, js_array);
|
|
211
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
212
|
-
(*env)->DeleteLocalRef(env, key);
|
|
213
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
214
|
-
return JS_EXCEPTION;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
jobject value = (*env)->CallObjectMethod(env, entry, method_get_val);
|
|
218
|
-
|
|
219
|
-
// Check circular refs
|
|
220
|
-
if (visit_or_circular_ref_error(env, context, visited_set, value)) {
|
|
221
|
-
JS_FreeValue(context, js_key);
|
|
222
|
-
JS_FreeValue(context, js_array);
|
|
223
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
224
|
-
(*env)->DeleteLocalRef(env, key);
|
|
225
|
-
(*env)->DeleteLocalRef(env, value);
|
|
226
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
227
|
-
return JS_EXCEPTION;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
JSValue js_value = jobject_to_js_value(env, context, visited_set, value);
|
|
231
|
-
if (JS_IsException(js_value)) {
|
|
232
|
-
JS_FreeValue(context, js_key);
|
|
233
|
-
JS_FreeValue(context, js_array);
|
|
234
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
235
|
-
(*env)->DeleteLocalRef(env, key);
|
|
236
|
-
(*env)->DeleteLocalRef(env, value);
|
|
237
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
238
|
-
return JS_EXCEPTION;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
JSValue js_entry = JS_NewArray(context);
|
|
242
|
-
JS_SetPropertyUint32(context, js_entry, 0, js_key);
|
|
243
|
-
JS_SetPropertyUint32(context, js_entry, 1, js_value);
|
|
244
|
-
|
|
245
|
-
JS_SetPropertyUint32(context, js_array, index, js_entry);
|
|
246
|
-
|
|
247
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
248
|
-
(*env)->DeleteLocalRef(env, key);
|
|
249
|
-
(*env)->DeleteLocalRef(env, value);
|
|
250
|
-
|
|
251
|
-
index++;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (delete_global_visited_ref) {
|
|
255
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
int argc = 1;
|
|
259
|
-
JSValue argv[] = {js_array};
|
|
260
|
-
JSValue result = new_js_object_from_constructor(context, "Map", argc, argv);
|
|
261
|
-
|
|
262
|
-
JS_FreeValue(context, js_array);
|
|
263
|
-
|
|
264
|
-
return result;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
JSValue java_throwable_to_js_error(JNIEnv *env, JSContext *context, jthrowable throwable) {
|
|
268
|
-
JSValue error = JS_NewError(context);
|
|
269
|
-
|
|
270
|
-
jclass exceptionClass = (*env)->GetObjectClass(env, throwable);
|
|
271
|
-
|
|
272
|
-
// Get class js_name
|
|
273
|
-
jstring j_cls_name = (jstring) (*env)->CallObjectMethod(env, exceptionClass,
|
|
274
|
-
method_class_get_name(env));
|
|
275
|
-
const char *cls_name = (*env)->GetStringUTFChars(env, j_cls_name, NULL);
|
|
276
|
-
|
|
277
|
-
// Set error name
|
|
278
|
-
JSValue js_name = JS_NewString(context, cls_name);
|
|
279
|
-
JS_SetPropertyStr(context, error, "name", js_name);
|
|
280
|
-
|
|
281
|
-
(*env)->ReleaseStringUTFChars(env, j_cls_name, cls_name);
|
|
282
|
-
|
|
283
|
-
// Get message
|
|
284
|
-
jstring j_message = (jstring) (*env)->CallObjectMethod(env, throwable,
|
|
285
|
-
method_throwable_get_message(env));
|
|
286
|
-
if (j_message != NULL) {
|
|
287
|
-
const char *message = (*env)->GetStringUTFChars(env, j_message, NULL);
|
|
288
|
-
// Set message name
|
|
289
|
-
JSValue js_message = JS_NewString(context, message);
|
|
290
|
-
JS_SetPropertyStr(context, error, "message", js_message);
|
|
291
|
-
(*env)->ReleaseStringUTFChars(env, j_message, message);
|
|
292
|
-
} else {
|
|
293
|
-
JSValue js_message = JS_NewString(context, "");
|
|
294
|
-
JS_SetPropertyStr(context, error, "message", js_message);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Get stack trace
|
|
298
|
-
jmethodID get_stack_trace = method_throwable_get_stack_trace(env);
|
|
299
|
-
jmethodID to_string = method_object_to_string(env);
|
|
300
|
-
jobjectArray j_stack_trace = (jobjectArray) (*env)->CallObjectMethod(env, throwable,
|
|
301
|
-
get_stack_trace);
|
|
302
|
-
size_t stack_trace_line_count = (*env)->GetArrayLength(env, j_stack_trace);
|
|
303
|
-
|
|
304
|
-
JSValue stack_trace = JS_NewArray(context);
|
|
305
|
-
|
|
306
|
-
for (int i = 0; i < stack_trace_line_count; i++) {
|
|
307
|
-
jobject element = (*env)->GetObjectArrayElement(env, j_stack_trace, i);
|
|
308
|
-
jstring j_string = (jstring) (*env)->CallObjectMethod(env, element, to_string);
|
|
309
|
-
const char *line_string = (*env)->GetStringUTFChars(env, j_string, NULL);
|
|
310
|
-
|
|
311
|
-
// Set stack trace line
|
|
312
|
-
JSValue line = JS_NewString(context, line_string);
|
|
313
|
-
JS_SetPropertyUint32(context, stack_trace, i, line);
|
|
314
|
-
|
|
315
|
-
(*env)->ReleaseStringUTFChars(env, j_string, line_string);
|
|
316
|
-
(*env)->DeleteLocalRef(env, j_string);
|
|
317
|
-
(*env)->DeleteLocalRef(env, element);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// Set stack trace
|
|
321
|
-
JS_SetPropertyStr(context, error, "stack", stack_trace);
|
|
322
|
-
|
|
323
|
-
return error;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
JSValue java_map_to_js_object(JNIEnv *env, JSContext *context,
|
|
327
|
-
jobject visited_set, jobject java_map) {
|
|
328
|
-
int delete_global_visited_ref = 0;
|
|
329
|
-
if (visited_set == NULL) {
|
|
330
|
-
jobject visited = (*env)->NewObject(env, cls_hash_set(env), method_hash_set_init(env));
|
|
331
|
-
visited_set = (*env)->NewGlobalRef(env, visited);
|
|
332
|
-
(*env)->DeleteLocalRef(env, visited);
|
|
333
|
-
delete_global_visited_ref = 1;
|
|
334
|
-
}
|
|
335
|
-
visit_first(env, visited_set, java_map);
|
|
336
|
-
|
|
337
|
-
jobject entry_set = (*env)->CallObjectMethod(env, java_map, method_map_entry_set(env));
|
|
338
|
-
jobject iterator = (*env)->CallObjectMethod(env, entry_set, method_set_iterator(env));
|
|
339
|
-
|
|
340
|
-
jclass cls_str = cls_string(env);
|
|
341
|
-
|
|
342
|
-
jmethodID method_has_next = method_iterator_has_next(env);
|
|
343
|
-
jmethodID method_next = method_iterator_next(env);
|
|
344
|
-
|
|
345
|
-
jmethodID method_get_key = method_map_entry_get_key(env);
|
|
346
|
-
jmethodID method_get_val = method_map_entry_get_value(env);
|
|
347
|
-
|
|
348
|
-
JSValue js_object = JS_NewObject(context);
|
|
349
|
-
|
|
350
|
-
while ((*env)->CallBooleanMethod(env, iterator, method_has_next)) {
|
|
351
|
-
jobject entry = (*env)->CallObjectMethod(env, iterator, method_next);
|
|
352
|
-
|
|
353
|
-
jobject key = (*env)->CallObjectMethod(env, entry, method_get_key);
|
|
354
|
-
|
|
355
|
-
// Check circular refs
|
|
356
|
-
if (visit_or_circular_ref_error(env, context, visited_set, key)) {
|
|
357
|
-
JS_FreeValue(context, js_object);
|
|
358
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
359
|
-
(*env)->DeleteLocalRef(env, key);
|
|
360
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
361
|
-
return JS_EXCEPTION;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// Check key type
|
|
365
|
-
if ((*env)->IsInstanceOf(env, key, cls_str) == JNI_FALSE) {
|
|
366
|
-
JS_FreeValue(context, js_object);
|
|
367
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
368
|
-
(*env)->DeleteLocalRef(env, key);
|
|
369
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
370
|
-
const char *message = "Cannot convert java map to js value: "
|
|
371
|
-
"only string keys are supported.";
|
|
372
|
-
JS_Throw(context, new_js_error(context, "TypeMappingError", message, 0, NULL));
|
|
373
|
-
return JS_EXCEPTION;
|
|
374
|
-
}
|
|
375
|
-
const char *str_key = (*env)->GetStringUTFChars(env, key, NULL);
|
|
376
|
-
|
|
377
|
-
jobject value = (*env)->CallObjectMethod(env, entry, method_get_val);
|
|
378
|
-
|
|
379
|
-
// Check circular refs
|
|
380
|
-
if (visit_or_circular_ref_error(env, context, visited_set, value)) {
|
|
381
|
-
JS_FreeValue(context, js_object);
|
|
382
|
-
(*env)->ReleaseStringUTFChars(env, key, str_key);
|
|
383
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
384
|
-
(*env)->DeleteLocalRef(env, key);
|
|
385
|
-
(*env)->DeleteLocalRef(env, value);
|
|
386
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
387
|
-
return JS_EXCEPTION;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
JSAtom js_key = JS_NewAtom(context, str_key);
|
|
391
|
-
JSValue js_value = jobject_to_js_value(env, context, visited_set, value);
|
|
392
|
-
if (JS_IsException(js_value)) {
|
|
393
|
-
JS_FreeValue(context, js_object);
|
|
394
|
-
(*env)->ReleaseStringUTFChars(env, key, str_key);
|
|
395
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
396
|
-
(*env)->DeleteLocalRef(env, key);
|
|
397
|
-
(*env)->DeleteLocalRef(env, value);
|
|
398
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
399
|
-
return js_value;
|
|
400
|
-
}
|
|
401
|
-
JS_SetProperty(context, js_object, js_key, js_value);
|
|
402
|
-
JS_FreeAtom(context, js_key);
|
|
403
|
-
|
|
404
|
-
(*env)->ReleaseStringUTFChars(env, key, str_key);
|
|
405
|
-
(*env)->DeleteLocalRef(env, entry);
|
|
406
|
-
(*env)->DeleteLocalRef(env, key);
|
|
407
|
-
(*env)->DeleteLocalRef(env, value);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (delete_global_visited_ref) {
|
|
411
|
-
(*env)->DeleteGlobalRef(env, visited_set);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
return js_object;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
void js_free_array_buffer(JSRuntime *runtime, void *opaque, void *ptr) {
|
|
418
|
-
free(ptr);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
JSValue byte_array_to_js_byte_array(JNIEnv *env, JSContext *context, jobject value,
|
|
422
|
-
const char *array_constructor_name) {
|
|
423
|
-
size_t size = (*env)->GetArrayLength(env, value);
|
|
424
|
-
jbyte *bytes = (*env)->GetByteArrayElements(env, value, NULL);
|
|
425
|
-
uint8_t *c_buffer = malloc(size);
|
|
426
|
-
memcpy(c_buffer, bytes, size);
|
|
427
|
-
JSValue array_buffer = JS_NewArrayBuffer(context, c_buffer, size,
|
|
428
|
-
js_free_array_buffer, NULL, 0);
|
|
429
|
-
int argc = 1;
|
|
430
|
-
JSValue argv[1] = {array_buffer};
|
|
431
|
-
JSValue result = new_js_object_from_constructor(context, array_constructor_name,
|
|
432
|
-
argc, argv);
|
|
433
|
-
JS_FreeValue(context, array_buffer);
|
|
434
|
-
return result;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
JSValue byte_array_to_js_int8array(JNIEnv *env, JSContext *context, jobject value) {
|
|
438
|
-
return byte_array_to_js_byte_array(env, context, value, "Int8Array");
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
JSValue kt_ubyte_array_to_js_uint8array(JNIEnv *env, JSContext *context, jobject value) {
|
|
442
|
-
jobject storage = (*env)->GetObjectField(env, value, field_ubyte_array_storage(env));
|
|
443
|
-
return byte_array_to_js_byte_array(env, context, storage, "Uint8Array");
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
JSValue jobject_to_js_value(JNIEnv *env, JSContext *context, jobject visited_set, jobject value) {
|
|
447
|
-
if (value == NULL) {
|
|
448
|
-
return JS_NULL;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
JSValue result = JS_UNDEFINED;
|
|
452
|
-
|
|
453
|
-
if ((*env)->IsInstanceOf(env, value, cls_boolean(env))) {
|
|
454
|
-
// Boolean
|
|
455
|
-
jmethodID method = method_boolean_boolean_value(env);
|
|
456
|
-
jboolean unboxed = (*env)->CallBooleanMethod(env, value, method);
|
|
457
|
-
if (unboxed == JNI_TRUE) {
|
|
458
|
-
result = JS_TRUE;
|
|
459
|
-
} else {
|
|
460
|
-
result = JS_FALSE;
|
|
461
|
-
}
|
|
462
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_byte(env))) {
|
|
463
|
-
// Byte
|
|
464
|
-
jmethodID method = method_byte_byte_value(env);
|
|
465
|
-
jbyte unboxed = (*env)->CallByteMethod(env, value, method);
|
|
466
|
-
result = JS_NewInt32(context, unboxed);
|
|
467
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_short(env))) {
|
|
468
|
-
// Short
|
|
469
|
-
jmethodID method = method_short_short_value(env);
|
|
470
|
-
jshort unboxed = (*env)->CallShortMethod(env, value, method);
|
|
471
|
-
result = JS_NewInt32(context, unboxed);
|
|
472
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_integer(env))) {
|
|
473
|
-
// Integer
|
|
474
|
-
jmethodID method = method_integer_int_value(env);
|
|
475
|
-
jint unboxed = (*env)->CallIntMethod(env, value, method);
|
|
476
|
-
result = JS_NewInt32(context, unboxed);
|
|
477
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_long(env))) {
|
|
478
|
-
// Long
|
|
479
|
-
jmethodID method = method_long_long_value(env);
|
|
480
|
-
jlong unboxed = (*env)->CallLongMethod(env, value, method);
|
|
481
|
-
result = JS_NewInt64(context, unboxed);
|
|
482
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_float(env))) {
|
|
483
|
-
// Float
|
|
484
|
-
jmethodID method = method_float_float_value(env);
|
|
485
|
-
jfloat unboxed = (*env)->CallFloatMethod(env, value, method);
|
|
486
|
-
result = JS_NewFloat64(context, unboxed);
|
|
487
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_double(env))) {
|
|
488
|
-
// Double
|
|
489
|
-
jmethodID method = method_double_double_value(env);
|
|
490
|
-
jdouble unboxed = (*env)->CallDoubleMethod(env, value, method);
|
|
491
|
-
result = JS_NewFloat64(context, unboxed);
|
|
492
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_string(env))) {
|
|
493
|
-
// String
|
|
494
|
-
const char *c_str = (*env)->GetStringUTFChars(env, value, NULL);
|
|
495
|
-
JSValue js_value = JS_NewString(context, c_str);
|
|
496
|
-
(*env)->ReleaseStringUTFChars(env, value, c_str);
|
|
497
|
-
result = js_value;
|
|
498
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_list(env))) {
|
|
499
|
-
// List
|
|
500
|
-
result = java_list_to_js_array(env, context, visited_set, value);
|
|
501
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_js_object(env))) {
|
|
502
|
-
// JsObject (A map delegate)
|
|
503
|
-
result = java_map_to_js_object(env, context, visited_set, value);
|
|
504
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_map(env))) {
|
|
505
|
-
// Map
|
|
506
|
-
result = java_map_to_js_map(env, context, visited_set, value);
|
|
507
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_set(env))) {
|
|
508
|
-
// Set
|
|
509
|
-
result = java_set_to_js_set(env, context, visited_set, value);
|
|
510
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_throwable(env))) {
|
|
511
|
-
// Throwable
|
|
512
|
-
result = java_throwable_to_js_error(env, context, (jthrowable) value);
|
|
513
|
-
} else if ((*env)->IsInstanceOf(env, value, cls_ubyte_array(env))) {
|
|
514
|
-
// UByteArray
|
|
515
|
-
result = kt_ubyte_array_to_js_uint8array(env, context, value);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
if (!JS_IsUndefined(result)) {
|
|
519
|
-
return result;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
jclass cls = (*env)->GetObjectClass(env, value);
|
|
523
|
-
jstring j_cls_name = (jstring) (*env)->CallObjectMethod(env, cls, method_class_get_name(env));
|
|
524
|
-
const char *cls_name = (*env)->GetStringUTFChars(env, j_cls_name, NULL);
|
|
525
|
-
|
|
526
|
-
// Try by the class name
|
|
527
|
-
if (strcmp("kotlin.Unit", cls_name) == 0) {
|
|
528
|
-
result = JS_UNDEFINED;
|
|
529
|
-
} else if (strcmp("[B", cls_name) == 0) {
|
|
530
|
-
result = byte_array_to_js_int8array(env, context, value);
|
|
531
|
-
} else if (strcmp("[Z", cls_name) == 0) {
|
|
532
|
-
// boolean array
|
|
533
|
-
int size = (*env)->GetArrayLength(env, value);
|
|
534
|
-
jboolean *arr = (*env)->GetBooleanArrayElements(env, value, NULL);
|
|
535
|
-
JSValue js_array = JS_NewArray(context);
|
|
536
|
-
for (uint32_t i = 0; i < size; i++) {
|
|
537
|
-
JSValue js_element = JS_NewBool(context, arr[i] == JNI_TRUE);
|
|
538
|
-
JS_SetPropertyUint32(context, js_array, i, js_element);
|
|
539
|
-
}
|
|
540
|
-
result = js_array;
|
|
541
|
-
(*env)->ReleaseBooleanArrayElements(env, value, arr, 0);
|
|
542
|
-
} else if (strcmp("[I", cls_name) == 0) {
|
|
543
|
-
// int array
|
|
544
|
-
int size = (*env)->GetArrayLength(env, value);
|
|
545
|
-
jint *arr = (*env)->GetIntArrayElements(env, value, NULL);
|
|
546
|
-
JSValue js_array = JS_NewArray(context);
|
|
547
|
-
for (uint32_t i = 0; i < size; i++) {
|
|
548
|
-
JSValue js_element = JS_NewInt32(context, arr[i]);
|
|
549
|
-
JS_SetPropertyUint32(context, js_array, i, js_element);
|
|
550
|
-
}
|
|
551
|
-
result = js_array;
|
|
552
|
-
(*env)->ReleaseIntArrayElements(env, value, arr, 0);
|
|
553
|
-
} else if (strcmp("[J", cls_name) == 0) {
|
|
554
|
-
// long array
|
|
555
|
-
int size = (*env)->GetArrayLength(env, value);
|
|
556
|
-
jlong *arr = (*env)->GetLongArrayElements(env, value, NULL);
|
|
557
|
-
JSValue js_array = JS_NewArray(context);
|
|
558
|
-
for (uint32_t i = 0; i < size; i++) {
|
|
559
|
-
JSValue js_element = JS_NewInt64(context, arr[i]);
|
|
560
|
-
JS_SetPropertyUint32(context, js_array, i, js_element);
|
|
561
|
-
}
|
|
562
|
-
result = js_array;
|
|
563
|
-
(*env)->ReleaseLongArrayElements(env, value, arr, 0);
|
|
564
|
-
} else if (strcmp("[F", cls_name) == 0) {
|
|
565
|
-
// float array
|
|
566
|
-
int size = (*env)->GetArrayLength(env, value);
|
|
567
|
-
jfloat *arr = (*env)->GetFloatArrayElements(env, value, NULL);
|
|
568
|
-
JSValue js_array = JS_NewArray(context);
|
|
569
|
-
for (uint32_t i = 0; i < size; i++) {
|
|
570
|
-
JSValue js_element = JS_NewFloat64(context, arr[i]);
|
|
571
|
-
JS_SetPropertyUint32(context, js_array, i, js_element);
|
|
572
|
-
}
|
|
573
|
-
result = js_array;
|
|
574
|
-
(*env)->ReleaseFloatArrayElements(env, value, arr, 0);
|
|
575
|
-
} else if (strcmp("[D", cls_name) == 0) {
|
|
576
|
-
// double array
|
|
577
|
-
int size = (*env)->GetArrayLength(env, value);
|
|
578
|
-
jdouble *arr = (*env)->GetDoubleArrayElements(env, value, NULL);
|
|
579
|
-
JSValue js_array = JS_NewArray(context);
|
|
580
|
-
for (uint32_t i = 0; i < size; i++) {
|
|
581
|
-
JSValue js_element = JS_NewFloat64(context, arr[i]);
|
|
582
|
-
JS_SetPropertyUint32(context, js_array, i, js_element);
|
|
583
|
-
}
|
|
584
|
-
result = js_array;
|
|
585
|
-
(*env)->ReleaseDoubleArrayElements(env, value, arr, 0);
|
|
586
|
-
} else if ('[' == cls_name[0]) {
|
|
587
|
-
// Object array
|
|
588
|
-
int size = (*env)->GetArrayLength(env, value);
|
|
589
|
-
JSValue js_array = JS_NewArray(context);
|
|
590
|
-
int has_exception = 0;
|
|
591
|
-
for (uint32_t i = 0; i < size; i++) {
|
|
592
|
-
jobject element = (*env)->GetObjectArrayElement(env, value, i);
|
|
593
|
-
// Check circular refs
|
|
594
|
-
if ((*env)->IsSameObject(env, value, element)) {
|
|
595
|
-
JS_FreeValue(context, js_array);
|
|
596
|
-
(*env)->DeleteLocalRef(env, element);
|
|
597
|
-
throw_circular_ref_error(context);
|
|
598
|
-
has_exception = 1;
|
|
599
|
-
break;
|
|
600
|
-
}
|
|
601
|
-
JSValue js_element = jobject_to_js_value(env, context, visited_set, element);
|
|
602
|
-
JS_SetPropertyUint32(context, js_array, i, js_element);
|
|
603
|
-
(*env)->DeleteLocalRef(env, element);
|
|
604
|
-
}
|
|
605
|
-
if (has_exception) {
|
|
606
|
-
result = JS_EXCEPTION;
|
|
607
|
-
} else {
|
|
608
|
-
result = js_array;
|
|
609
|
-
}
|
|
610
|
-
} else {
|
|
611
|
-
char message[100];
|
|
612
|
-
sprintf(message, "Cannot convert java type '%s' to a js value.", cls_name);
|
|
613
|
-
JS_Throw(context, new_js_error(context, "TypeError", message, 0, NULL));
|
|
614
|
-
result = JS_EXCEPTION;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
(*env)->ReleaseStringUTFChars(env, j_cls_name, cls_name);
|
|
618
|
-
|
|
619
|
-
return result;
|
|
620
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#ifndef QJS_KT_JOBJECT_TO_JS_VALUE_H
|
|
2
|
-
#define QJS_KT_JOBJECT_TO_JS_VALUE_H
|
|
3
|
-
|
|
4
|
-
#include "jni.h"
|
|
5
|
-
#include "quickjs.h"
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Convert java JsValue to QuickJS JsValue.
|
|
9
|
-
*/
|
|
10
|
-
JSValue jobject_to_js_value(JNIEnv *env, JSContext *context, jobject visited_set, jobject value);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
#endif //QJS_KT_JOBJECT_TO_JS_VALUE_H
|