Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ByteArray and UByteArray mapping #23

Merged
merged 2 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ Some built-in types are mapped automatically between C and Kotlin, this table sh
| Map | Map<Any?, Any?> |
| Error | Error |
| Object | Map<Any?, Any?> (4) |
| Int8Array | ByteArray |
| UInt8Array | UByteArray |

(1) A Kotlin `Unit` will be mapped to a JavaScript `undefined`, conversely, JavaScript `undefined` won't be mapped to Kotlin `Unit`.

Expand Down
75 changes: 53 additions & 22 deletions quickjs/native/jni/jni_globals_generated.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "jni_globals_generated.h"

// Cached classes
static jclass _cls_ubyte_array = NULL;
static jclass _cls_integer = NULL;
static jclass _cls_long = NULL;
static jclass _cls_float = NULL;
Expand All @@ -18,8 +19,8 @@ static jclass _cls_iterator = NULL;
static jclass _cls_list = NULL;
static jclass _cls_map = NULL;
static jclass _cls_map_entry = NULL;
static jclass _cls_linked_hash_map = NULL;
static jclass _cls_hash_set = NULL;
static jclass _cls_linked_hash_map = NULL;
static jclass _cls_linked_hash_set = NULL;
static jclass _cls_quick_js_exception = NULL;
static jclass _cls_quick_js = NULL;
Expand All @@ -29,6 +30,7 @@ static jclass _cls_js_function = NULL;
static jclass _cls_js_object = NULL;

// Cached methods
static jmethodID _method_ubyte_array_init = NULL;
static jmethodID _method_integer_value_of = NULL;
static jmethodID _method_integer_int_value = NULL;
static jmethodID _method_long_value_of = NULL;
Expand Down Expand Up @@ -56,9 +58,9 @@ static jmethodID _method_list_get = NULL;
static jmethodID _method_map_entry_set = NULL;
static jmethodID _method_map_entry_get_key = NULL;
static jmethodID _method_map_entry_get_value = NULL;
static jmethodID _method_hash_set_init = NULL;
static jmethodID _method_linked_hash_map_init = NULL;
static jmethodID _method_linked_hash_map_put = NULL;
static jmethodID _method_hash_set_init = NULL;
static jmethodID _method_linked_hash_set_init = NULL;
static jmethodID _method_linked_hash_set_add = NULL;
static jmethodID _method_quick_js_on_call_getter = NULL;
Expand All @@ -69,6 +71,7 @@ static jmethodID _method_quick_js_create_delay = NULL;
static jmethodID _method_memory_usage_init = NULL;

// Cached fields
static jfieldID _field_ubyte_array_storage = NULL;
static jfieldID _field_double_na_n = NULL;
static jfieldID _field_js_property_name = NULL;
static jfieldID _field_js_property_configurable = NULL;
Expand All @@ -77,6 +80,14 @@ static jfieldID _field_js_property_enumerable = NULL;
static jfieldID _field_js_function_name = NULL;
static jfieldID _field_js_function_is_async = NULL;

jclass cls_ubyte_array(JNIEnv *env) {
if (_cls_ubyte_array == NULL) {
jclass cls = (*env)->FindClass(env, "kotlin/UByteArray");
_cls_ubyte_array = (*env)->NewGlobalRef(env, cls);
}
return _cls_ubyte_array;
}

jclass cls_integer(JNIEnv *env) {
if (_cls_integer == NULL) {
jclass cls = (*env)->FindClass(env, "java/lang/Integer");
Expand Down Expand Up @@ -205,14 +216,6 @@ jclass cls_map_entry(JNIEnv *env) {
return _cls_map_entry;
}

jclass cls_linked_hash_map(JNIEnv *env) {
if (_cls_linked_hash_map == NULL) {
jclass cls = (*env)->FindClass(env, "java/util/LinkedHashMap");
_cls_linked_hash_map = (*env)->NewGlobalRef(env, cls);
}
return _cls_linked_hash_map;
}

jclass cls_hash_set(JNIEnv *env) {
if (_cls_hash_set == NULL) {
jclass cls = (*env)->FindClass(env, "java/util/HashSet");
Expand All @@ -221,6 +224,14 @@ jclass cls_hash_set(JNIEnv *env) {
return _cls_hash_set;
}

jclass cls_linked_hash_map(JNIEnv *env) {
if (_cls_linked_hash_map == NULL) {
jclass cls = (*env)->FindClass(env, "java/util/LinkedHashMap");
_cls_linked_hash_map = (*env)->NewGlobalRef(env, cls);
}
return _cls_linked_hash_map;
}

jclass cls_linked_hash_set(JNIEnv *env) {
if (_cls_linked_hash_set == NULL) {
jclass cls = (*env)->FindClass(env, "java/util/LinkedHashSet");
Expand Down Expand Up @@ -277,6 +288,13 @@ jclass cls_js_object(JNIEnv *env) {
return _cls_js_object;
}

jmethodID method_ubyte_array_init(JNIEnv *env) {
if (_method_ubyte_array_init == NULL) {
_method_ubyte_array_init = (*env)->GetMethodID(env, cls_ubyte_array(env), "<init>", "([B)V");
}
return _method_ubyte_array_init;
}

jmethodID method_integer_value_of(JNIEnv *env) {
if (_method_integer_value_of == NULL) {
_method_integer_value_of = (*env)->GetStaticMethodID(env, cls_integer(env), "valueOf", "(I)Ljava/lang/Integer;");
Expand Down Expand Up @@ -466,6 +484,13 @@ jmethodID method_map_entry_get_value(JNIEnv *env) {
return _method_map_entry_get_value;
}

jmethodID method_hash_set_init(JNIEnv *env) {
if (_method_hash_set_init == NULL) {
_method_hash_set_init = (*env)->GetMethodID(env, cls_hash_set(env), "<init>", "()V");
}
return _method_hash_set_init;
}

jmethodID method_linked_hash_map_init(JNIEnv *env) {
if (_method_linked_hash_map_init == NULL) {
_method_linked_hash_map_init = (*env)->GetMethodID(env, cls_linked_hash_map(env), "<init>", "()V");
Expand All @@ -480,13 +505,6 @@ jmethodID method_linked_hash_map_put(JNIEnv *env) {
return _method_linked_hash_map_put;
}

jmethodID method_hash_set_init(JNIEnv *env) {
if (_method_hash_set_init == NULL) {
_method_hash_set_init = (*env)->GetMethodID(env, cls_hash_set(env), "<init>", "()V");
}
return _method_hash_set_init;
}

jmethodID method_linked_hash_set_init(JNIEnv *env) {
if (_method_linked_hash_set_init == NULL) {
_method_linked_hash_set_init = (*env)->GetMethodID(env, cls_linked_hash_set(env), "<init>", "()V");
Expand Down Expand Up @@ -543,6 +561,13 @@ jmethodID method_memory_usage_init(JNIEnv *env) {
return _method_memory_usage_init;
}

jfieldID field_ubyte_array_storage(JNIEnv *env) {
if (_field_ubyte_array_storage == NULL) {
_field_ubyte_array_storage = (*env)->GetFieldID(env, cls_ubyte_array(env), "storage", "[B");
}
return _field_ubyte_array_storage;
}

jfieldID field_double_na_n(JNIEnv *env) {
if (_field_double_na_n == NULL) {
_field_double_na_n = (*env)->GetStaticFieldID(env, cls_double(env), "NaN", "D");
Expand Down Expand Up @@ -593,6 +618,9 @@ jfieldID field_js_function_is_async(JNIEnv *env) {
}

void clear_jni_refs_cache(JNIEnv *env) {
if (_cls_ubyte_array != NULL) {
(*env)->DeleteGlobalRef(env, _cls_ubyte_array);
}
if (_cls_integer != NULL) {
(*env)->DeleteGlobalRef(env, _cls_integer);
}
Expand Down Expand Up @@ -641,12 +669,12 @@ void clear_jni_refs_cache(JNIEnv *env) {
if (_cls_map_entry != NULL) {
(*env)->DeleteGlobalRef(env, _cls_map_entry);
}
if (_cls_linked_hash_map != NULL) {
(*env)->DeleteGlobalRef(env, _cls_linked_hash_map);
}
if (_cls_hash_set != NULL) {
(*env)->DeleteGlobalRef(env, _cls_hash_set);
}
if (_cls_linked_hash_map != NULL) {
(*env)->DeleteGlobalRef(env, _cls_linked_hash_map);
}
if (_cls_linked_hash_set != NULL) {
(*env)->DeleteGlobalRef(env, _cls_linked_hash_set);
}
Expand All @@ -669,6 +697,7 @@ void clear_jni_refs_cache(JNIEnv *env) {
(*env)->DeleteGlobalRef(env, _cls_js_object);
}

_cls_ubyte_array = NULL;
_cls_integer = NULL;
_cls_long = NULL;
_cls_float = NULL;
Expand All @@ -685,8 +714,8 @@ void clear_jni_refs_cache(JNIEnv *env) {
_cls_list = NULL;
_cls_map = NULL;
_cls_map_entry = NULL;
_cls_linked_hash_map = NULL;
_cls_hash_set = NULL;
_cls_linked_hash_map = NULL;
_cls_linked_hash_set = NULL;
_cls_quick_js_exception = NULL;
_cls_quick_js = NULL;
Expand All @@ -695,6 +724,7 @@ void clear_jni_refs_cache(JNIEnv *env) {
_cls_js_function = NULL;
_cls_js_object = NULL;

_method_ubyte_array_init = NULL;
_method_integer_value_of = NULL;
_method_integer_int_value = NULL;
_method_long_value_of = NULL;
Expand Down Expand Up @@ -722,9 +752,9 @@ void clear_jni_refs_cache(JNIEnv *env) {
_method_map_entry_set = NULL;
_method_map_entry_get_key = NULL;
_method_map_entry_get_value = NULL;
_method_hash_set_init = NULL;
_method_linked_hash_map_init = NULL;
_method_linked_hash_map_put = NULL;
_method_hash_set_init = NULL;
_method_linked_hash_set_init = NULL;
_method_linked_hash_set_add = NULL;
_method_quick_js_on_call_getter = NULL;
Expand All @@ -734,6 +764,7 @@ void clear_jni_refs_cache(JNIEnv *env) {
_method_quick_js_create_delay = NULL;
_method_memory_usage_init = NULL;

_field_ubyte_array_storage = NULL;
_field_double_na_n = NULL;
_field_js_property_name = NULL;
_field_js_property_configurable = NULL;
Expand Down
14 changes: 10 additions & 4 deletions quickjs/native/jni/jni_globals_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include <jni.h>

jclass cls_ubyte_array(JNIEnv *env);

jclass cls_integer(JNIEnv *env);

jclass cls_long(JNIEnv *env);
Expand Down Expand Up @@ -36,10 +38,10 @@ jclass cls_map(JNIEnv *env);

jclass cls_map_entry(JNIEnv *env);

jclass cls_linked_hash_map(JNIEnv *env);

jclass cls_hash_set(JNIEnv *env);

jclass cls_linked_hash_map(JNIEnv *env);

jclass cls_linked_hash_set(JNIEnv *env);

jclass cls_quick_js_exception(JNIEnv *env);
Expand All @@ -54,6 +56,8 @@ jclass cls_js_function(JNIEnv *env);

jclass cls_js_object(JNIEnv *env);

jmethodID method_ubyte_array_init(JNIEnv *env);

jmethodID method_integer_value_of(JNIEnv *env);

jmethodID method_integer_int_value(JNIEnv *env);
Expand Down Expand Up @@ -108,12 +112,12 @@ jmethodID method_map_entry_get_key(JNIEnv *env);

jmethodID method_map_entry_get_value(JNIEnv *env);

jmethodID method_hash_set_init(JNIEnv *env);

jmethodID method_linked_hash_map_init(JNIEnv *env);

jmethodID method_linked_hash_map_put(JNIEnv *env);

jmethodID method_hash_set_init(JNIEnv *env);

jmethodID method_linked_hash_set_init(JNIEnv *env);

jmethodID method_linked_hash_set_add(JNIEnv *env);
Expand All @@ -130,6 +134,8 @@ jmethodID method_quick_js_create_delay(JNIEnv *env);

jmethodID method_memory_usage_init(JNIEnv *env);

jfieldID field_ubyte_array_storage(JNIEnv *env);

jfieldID field_double_na_n(JNIEnv *env);

jfieldID field_js_property_name(JNIEnv *env);
Expand Down
43 changes: 35 additions & 8 deletions quickjs/native/jni/js_value_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,43 @@ JSValue new_js_error(JSContext *context,
return error;
}

int js_is_promise(JSContext *context, JSValue value) {
if (!JS_IsObject(value)) {
int js_is_instance_of(JSContext *context, JSValue global_this, JSValue value,
const char *constructor_name) {
JSValue constructor = JS_GetPropertyStr(context, global_this, constructor_name);
if (JS_IsUndefined(constructor)) {
JS_FreeValue(context, constructor);
return 0;
}
JSValue prototype = JS_GetPrototype(context, value);
const char *prototype_str = JS_ToCString(context, prototype);
int is_promise = strcmp("[object Promise]", prototype_str) == 0;
JS_FreeCString(context, prototype_str);
JS_FreeValue(context, prototype);
return is_promise;
int result = JS_IsInstanceOf(context, value, constructor);
JS_FreeValue(context, constructor);
return result;
}

int js_is_promise(JSContext *context, JSValue value) {
JSValue global_this = JS_GetGlobalObject(context);
int result = js_is_promise_2(context, global_this, value);
JS_FreeValue(context, global_this);
return result;
}

int js_is_promise_2(JSContext *context, JSValue global_this, JSValue value) {
return js_is_instance_of(context, global_this, value, "Promise");
}

int js_is_uint8array(JSContext *context, JSValue global_this, JSValue value) {
return js_is_instance_of(context, global_this, value, "Uint8Array");
}

int js_is_int8array(JSContext *context, JSValue global_this, JSValue value) {
return js_is_instance_of(context, global_this, value, "Int8Array");
}

int js_is_set(JSContext *context, JSValue global_this, JSValue value) {
return js_is_instance_of(context, global_this, value, "Set");
}

int js_is_map(JSContext *context, JSValue global_this, JSValue value) {
return js_is_instance_of(context, global_this, value, "Map");
}

JSValue js_promise_get_fulfilled_value(JSContext *context, JSValue promise) {
Expand Down
25 changes: 25 additions & 0 deletions quickjs/native/jni/js_value_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@ JSValue new_js_error(JSContext *context,
*/
int js_is_promise(JSContext *context, JSValue value);

/**
* Check if the js value is a Promise.
*/
int js_is_promise_2(JSContext *context, JSValue global_this, JSValue value);

/**
* Check if the js value is a Uint8Array.
*/
int js_is_uint8array(JSContext *context, JSValue global_this, JSValue value);

/**
* Check if the js value is a Int8Array.
*/
int js_is_int8array(JSContext *context, JSValue global_this, JSValue value);

/**
* Check if the js value is a Set.
*/
int js_is_set(JSContext *context, JSValue global_this, JSValue value);

/**
* Check if the js value is a Map.
*/
int js_is_map(JSContext *context, JSValue global_this, JSValue value);

/**
* Get the value of a fulfilled promise.
*/
Expand Down
Loading
Loading