@@ -160,25 +160,44 @@ void javaDetachCurrentThread(JavaVM* jvm) {
160160}
161161
162162jvalueType javaGetType (JNIEnv *env, jclass type) {
163- // TODO: has to be a better way
164- std::string str = javaObjectToString (env, type);
165- const char *typeStr = str.c_str ();
166- // printf("javaGetType: %s\n", typeStr);
167- if (strcmp (typeStr, " int" ) == 0 ) {
168- return TYPE_INT;
169- } else if (strcmp (typeStr, " long" ) == 0 ) {
170- return TYPE_LONG;
171- } else if (strcmp (typeStr, " void" ) == 0 ) {
172- return TYPE_VOID;
173- } else if (strcmp (typeStr, " boolean" ) == 0 ) {
174- return TYPE_BOOLEAN;
175- } else if (strcmp (typeStr, " byte" ) == 0 ) {
176- return TYPE_BYTE;
177- } else if (strcmp (typeStr, " class java.lang.String" ) == 0 ) {
178- return TYPE_STRING;
163+ jclass clazzClazz = env->FindClass (" java/lang/Class" );
164+ jmethodID class_isArray = env->GetMethodID (clazzClazz, " isArray" , " ()Z" );
165+ jmethodID class_getComponentType = env->GetMethodID (clazzClazz, " getComponentType" , " ()Ljava/lang/Class;" );
166+
167+ jboolean isArray = env->CallBooleanMethod (type, class_isArray);
168+ if (isArray) {
169+ jclass componentTypeClass = (jclass)env->CallObjectMethod (type, class_getComponentType);
170+ jvalueType componentType = javaGetType (env, componentTypeClass);
171+ switch (componentType) {
172+ case TYPE_INT: return TYPE_ARRAY_INT;
173+ case TYPE_LONG: return TYPE_ARRAY_LONG;
174+ case TYPE_OBJECT: return TYPE_ARRAY_OBJECT;
175+ case TYPE_STRING: return TYPE_ARRAY_STRING;
176+ case TYPE_BOOLEAN: return TYPE_ARRAY_BOOLEAN;
177+ case TYPE_BYTE: return TYPE_ARRAY_BYTE;
178+ default :
179+ return TYPE_ARRAY_OBJECT;
180+ }
181+ } else {
182+ // TODO: has to be a better way
183+ std::string str = javaObjectToString (env, type);
184+ const char *typeStr = str.c_str ();
185+ // printf("javaGetType: %s\n", typeStr);
186+ if (strcmp (typeStr, " int" ) == 0 ) {
187+ return TYPE_INT;
188+ } else if (strcmp (typeStr, " long" ) == 0 ) {
189+ return TYPE_LONG;
190+ } else if (strcmp (typeStr, " void" ) == 0 ) {
191+ return TYPE_VOID;
192+ } else if (strcmp (typeStr, " boolean" ) == 0 ) {
193+ return TYPE_BOOLEAN;
194+ } else if (strcmp (typeStr, " byte" ) == 0 ) {
195+ return TYPE_BYTE;
196+ } else if (strcmp (typeStr, " class java.lang.String" ) == 0 ) {
197+ return TYPE_STRING;
198+ }
199+ return TYPE_OBJECT;
179200 }
180-
181- return TYPE_OBJECT;
182201}
183202
184203jclass javaFindClass (JNIEnv* env, std::string className) {
@@ -197,8 +216,8 @@ jobject javaFindField(JNIEnv* env, jclass clazz, std::string fieldName) {
197216 jsize fieldCount = env->GetArrayLength (fieldObjects);
198217 for (jsize i=0 ; i<fieldCount; i++) {
199218 jobject field = env->GetObjectArrayElement (fieldObjects, i);
200- std::string fieldName = javaToString (env, (jstring)env->CallObjectMethod (field, field_getName));
201- if (strcmp (fieldName .c_str (), fieldName.c_str ()) == 0 ) {
219+ std::string itFieldName = javaToString (env, (jstring)env->CallObjectMethod (field, field_getName));
220+ if (strcmp (itFieldName .c_str (), fieldName.c_str ()) == 0 ) {
202221 return field;
203222 }
204223 }
@@ -211,6 +230,20 @@ jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg, jvalueType *methodArgTyp
211230 return NULL ;
212231 }
213232
233+ if (arg->IsArray ()) {
234+ v8::Local<v8::Array> array = v8::Array::Cast (*arg);
235+ uint32_t arraySize = array->Length ();
236+ jclass objectClazz = env->FindClass (" java/lang/Object" );
237+ jobjectArray result = env->NewObjectArray (arraySize, objectClazz, NULL );
238+ for (uint32_t i=0 ; i<arraySize; i++) {
239+ jvalueType argType;
240+ jobject val = v8ToJava (env, array->Get (i), &argType);
241+ env->SetObjectArrayElement (result, i, val);
242+ }
243+ *methodArgType = TYPE_ARRAY_OBJECT;
244+ return result;
245+ }
246+
214247 if (arg->IsString ()) {
215248 *methodArgType = TYPE_STRING;
216249 v8::String::AsciiValue val (arg->ToString ());
@@ -301,44 +334,76 @@ v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternat
301334 return scope.Close (javaExceptionToV8 (env, ex, alternateMessage));
302335}
303336
337+ v8::Handle<v8::Value> javaArrayToV8 (Java* java, JNIEnv* env, jvalueType itemType, jobjectArray objArray) {
338+ v8::HandleScope scope;
339+
340+ if (objArray == NULL ) {
341+ return v8::Null ();
342+ }
343+
344+ // printf("javaArrayToV8: %d %s\n", itemType, javaObjectToString(env, objArray).c_str());
345+
346+ jsize arraySize = env->GetArrayLength (objArray);
347+ // printf("array size: %d\n", arraySize);
348+
349+ v8::Handle<v8::Array> result = v8::Array::New (arraySize);
350+ for (jsize i=0 ; i<arraySize; i++) {
351+ jobject obj = env->GetObjectArrayElement (objArray, i);
352+ v8::Handle<v8::Value> item = javaToV8 (java, env, itemType, obj);
353+ result->Set (i, item);
354+ }
355+
356+ return scope.Close (result);
357+ }
358+
304359v8::Handle<v8::Value> javaToV8 (Java* java, JNIEnv* env, jvalueType resultType, jobject obj) {
305- v8::HandleScope scope;
360+ v8::HandleScope scope;
306361
307- switch (resultType) {
308- case TYPE_VOID:
309- return v8::Undefined ();
310- case TYPE_BOOLEAN:
311- {
312- jclass booleanClazz = env->FindClass (" java/lang/Boolean" );
313- jmethodID boolean_booleanValue = env->GetMethodID (booleanClazz, " booleanValue" , " ()Z" );
314- bool result = env->CallBooleanMethod (obj, boolean_booleanValue);
315- return scope.Close (v8::Boolean::New (result));
316- }
317- case TYPE_BYTE:
318- {
319- jclass byteClazz = env->FindClass (" java/lang/Byte" );
320- jmethodID byte_byteValue = env->GetMethodID (byteClazz, " byteValue" , " ()B" );
321- jbyte result = env->CallByteMethod (obj, byte_byteValue);
322- return scope.Close (v8::Number::New (result));
323- }
324- case TYPE_LONG:
325- {
326- jclass longClazz = env->FindClass (" java/lang/Long" );
327- jmethodID long_longValue = env->GetMethodID (longClazz, " longValue" , " ()J" );
328- jlong result = env->CallLongMethod (obj, long_longValue);
329- return scope.Close (v8::Number::New (result));
330- }
331- case TYPE_INT:
332- {
333- jclass integerClazz = env->FindClass (" java/lang/Integer" );
334- jmethodID integer_intValue = env->GetMethodID (integerClazz, " intValue" , " ()I" );
335- jint result = env->CallIntMethod (obj, integer_intValue);
336- return scope.Close (v8::Integer::New (result));
337- }
338- case TYPE_OBJECT:
339- return scope.Close (JavaObject::New (java, obj));
340- case TYPE_STRING:
341- return scope.Close (v8::String::New (javaObjectToString (env, obj).c_str ()));
362+ // printf("javaToV8: %d %s\n", resultType, javaObjectToString(env, obj).c_str());
363+
364+ if ((resultType & VALUE_TYPE_ARRAY) == VALUE_TYPE_ARRAY) {
365+ v8::Handle<v8::Value> result = javaArrayToV8 (java, env, (jvalueType)(resultType & ~VALUE_TYPE_ARRAY), (jobjectArray)obj);
366+ return scope.Close (result);
367+ } else {
368+ switch (resultType) {
369+ case TYPE_VOID:
370+ return v8::Undefined ();
371+ case TYPE_BOOLEAN:
372+ {
373+ jclass booleanClazz = env->FindClass (" java/lang/Boolean" );
374+ jmethodID boolean_booleanValue = env->GetMethodID (booleanClazz, " booleanValue" , " ()Z" );
375+ bool result = env->CallBooleanMethod (obj, boolean_booleanValue);
376+ return scope.Close (v8::Boolean::New (result));
377+ }
378+ case TYPE_BYTE:
379+ {
380+ jclass byteClazz = env->FindClass (" java/lang/Byte" );
381+ jmethodID byte_byteValue = env->GetMethodID (byteClazz, " byteValue" , " ()B" );
382+ jbyte result = env->CallByteMethod (obj, byte_byteValue);
383+ return scope.Close (v8::Number::New (result));
384+ }
385+ case TYPE_LONG:
386+ {
387+ jclass longClazz = env->FindClass (" java/lang/Long" );
388+ jmethodID long_longValue = env->GetMethodID (longClazz, " longValue" , " ()J" );
389+ jlong result = env->CallLongMethod (obj, long_longValue);
390+ return scope.Close (v8::Number::New (result));
391+ }
392+ case TYPE_INT:
393+ {
394+ jclass integerClazz = env->FindClass (" java/lang/Integer" );
395+ jmethodID integer_intValue = env->GetMethodID (integerClazz, " intValue" , " ()I" );
396+ jint result = env->CallIntMethod (obj, integer_intValue);
397+ return scope.Close (v8::Integer::New (result));
398+ }
399+ case TYPE_STRING:
400+ return scope.Close (v8::String::New (javaObjectToString (env, obj).c_str ()));
401+ case TYPE_OBJECT:
402+ return scope.Close (JavaObject::New (java, obj));
403+ default :
404+ printf (" unhandled type: 0x%03x\n " , resultType);
405+ return scope.Close (JavaObject::New (java, obj));
406+ }
342407 }
343408 return v8::Undefined ();
344409}
0 commit comments