@@ -23,6 +23,13 @@ static string getJavaName(JNIEnv* env, jobject javaClass) {
2323    return  str;
2424}
2525
26+ //  quickjs 没有提供 JS_IsArrayBuffer 方法,这里通过取巧的方式来实现,后续可以替换掉
27+ static  bool  JS_IsArrayBuffer (JSValue  value) {
28+     //  quickjs 里的 ArrayBuffer 对应的类型枚举值
29+     int8_t  JS_CLASS_ARRAY_BUFFER = 19 ;
30+     return  JS_GetClassID (value) == JS_CLASS_ARRAY_BUFFER;
31+ }
32+ 
2633static  void  tryToTriggerOnError (JSContext *ctx, JSValueConst *error) {
2734    JSValue global = JS_GetGlobalObject (ctx);
2835    JSValue onerror = JS_GetPropertyStr (ctx, global, " onError" 
@@ -231,6 +238,12 @@ jsModuleLoaderFunc(JSContext *ctx, const char *module_name, void *opaque) {
231238        int  scriptLen = env->GetStringUTFLength ((jstring) result);
232239        JSValue func_val = JS_Eval (ctx, script, scriptLen, module_name,
233240                                   JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
241+         if  (JS_IsException (func_val)) {
242+             JS_FreeValue (ctx, func_val);
243+             throwJSException (env, ctx);
244+             return  (JSModuleDef *) JS_VALUE_GET_PTR (JS_EXCEPTION);
245+         }
246+ 
234247        m = JS_VALUE_GET_PTR (func_val);
235248        JS_FreeValue (ctx, func_val);
236249    }
@@ -333,6 +346,7 @@ QuickJSWrapper::QuickJSWrapper(JNIEnv *env, jobject thiz, JSRuntime *rt) {
333346    quickjsContextClass = (jclass)(jniEnv->NewGlobalRef (jniEnv->FindClass (" com/whl/quickjs/wrapper/QuickJSContext" 
334347    moduleLoaderClass = (jclass)(jniEnv->NewGlobalRef (jniEnv->FindClass (" com/whl/quickjs/wrapper/ModuleLoader" 
335348    creatorClass = (jclass)(jniEnv->NewGlobalRef (jniEnv->FindClass (" com/whl/quickjs/wrapper/JSObjectCreator" 
349+     byteArrayClass = (jclass) jniEnv->NewGlobalRef (env->FindClass (" [B" 
336350
337351    booleanValueOf = jniEnv->GetStaticMethodID (booleanClass, " valueOf" " (Z)Ljava/lang/Boolean;" 
338352    integerValueOf = jniEnv->GetStaticMethodID (integerClass, " valueOf" " (I)Ljava/lang/Integer;" 
@@ -376,6 +390,7 @@ QuickJSWrapper::~QuickJSWrapper() {
376390    jniEnv->DeleteGlobalRef (moduleLoaderClass);
377391    jniEnv->DeleteGlobalRef (quickjsContextClass);
378392    jniEnv->DeleteGlobalRef (creatorClass);
393+     jniEnv->DeleteGlobalRef (byteArrayClass);
379394}
380395
381396jobject QuickJSWrapper::toJavaObject (JNIEnv *env, jobject thiz, JSValueConst& this_obj, JSValueConst& value) const {
@@ -436,6 +451,16 @@ jobject QuickJSWrapper::toJavaObject(JNIEnv *env, jobject thiz, JSValueConst& th
436451                result = env->CallObjectMethod (creatorObj, newFunctionM, thiz, value_ptr, obj_ptr);
437452            } else  if  (JS_IsArray (context, value)) {
438453                result = env->CallObjectMethod (creatorObj, newArrayM, thiz, value_ptr);
454+             } else  if  (JS_IsArrayBuffer (value)) {
455+                 size_t  byteLength = 0 ;
456+                 uint8_t  *buffer = JS_GetArrayBuffer (context, &byteLength, value);
457+                 jbyteArray byteArray = env->NewByteArray (byteLength);
458+                 void  *elementsPtr = env->GetPrimitiveArrayCritical (byteArray, nullptr );
459+                 jbyte *elements = reinterpret_cast <jbyte *>(elementsPtr);
460+                 memcpy (elements, buffer, byteLength);
461+                 result = byteArray;
462+                 JS_FreeValue (context, value);
463+                 env->ReleasePrimitiveArrayCritical (byteArray, elements, 0 );
439464            } else  {
440465                result = env->CallObjectMethod (creatorObj, newObjectM, thiz, value_ptr);
441466            }
@@ -514,7 +539,8 @@ jobject QuickJSWrapper::call(JNIEnv *env, jobject thiz, jlong func, jlong this_o
514539        //  基础类型(例如 string )和 Java callback 类型需要使用完 free.
515540        if  (env->IsInstanceOf (arg, stringClass) || env->IsInstanceOf (arg, doubleClass) ||
516541            env->IsInstanceOf (arg, integerClass) || env->IsInstanceOf (arg, longClass) ||
517-             env->IsInstanceOf (arg, booleanClass) || env->IsInstanceOf (arg, jsCallFunctionClass)) {
542+             env->IsInstanceOf (arg, booleanClass) || env->IsInstanceOf (arg, jsCallFunctionClass)
543+             || env->IsInstanceOf (arg, byteArrayClass)) {
518544            freeArguments.push_back (jsArg);
519545        }
520546
@@ -676,6 +702,12 @@ JSValue QuickJSWrapper::toJSValue(JNIEnv *env, jobject thiz, jobject value) cons
676702        }
677703    } else  if  (env->IsInstanceOf (value, booleanClass)) {
678704        result = JS_NewBool (context, env->CallBooleanMethod (value, booleanGetValue));
705+     } else  if  (env->IsInstanceOf (value, byteArrayClass)) {
706+         jbyteArray bytes = static_cast <jbyteArray>(value);
707+         jbyte* byteData = env->GetByteArrayElements (bytes, nullptr );
708+         jsize length = env->GetArrayLength (bytes);
709+         result = JS_NewArrayBufferCopy (context, reinterpret_cast <uint8_t *>(byteData), length);
710+         env->ReleaseByteArrayElements (bytes, byteData, JNI_ABORT);
679711    } else  if  (env->IsInstanceOf (value, jsObjectClass)) {
680712        result = JS_MKPTR (JS_TAG_OBJECT, reinterpret_cast <void  *>(env->CallLongMethod (value, jsObjectGetValue)));
681713    } else  if  (env->IsInstanceOf (value, jsCallFunctionClass)) {
0 commit comments