Reviewed by Geoff.
[WebKit-https.git] / JavaScriptCore / bindings / jni / jni_utility.cpp
1 /*
2  * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "jni_utility.h"
27
28 #include "interpreter.h"
29 #include "list.h"
30 #include "jni_runtime.h"
31 #include "runtime_array.h"
32 #include "runtime_object.h"
33 #include "softlinking.h"
34
35 namespace KJS {
36
37 namespace Bindings {
38
39 static JavaVM *jvm = 0;
40
41 JavaVM *getJavaVM()
42 {
43     if (jvm)
44         return jvm;
45
46     JavaVM *jvmArray[1];
47     jsize bufLen = 1;
48     jsize nJVMs = 0;
49     jint jniError = 0;
50
51     // Assumes JVM is already running ..., one per process
52     jniError = KJS_GetCreatedJavaVMs(jvmArray, bufLen, &nJVMs);
53     if ( jniError == JNI_OK && nJVMs > 0 ) {
54         jvm = jvmArray[0];
55     }
56     else 
57         fprintf(stderr, "%s: JNI_GetCreatedJavaVMs failed, returned %ld\n", __PRETTY_FUNCTION__, jniError);
58         
59     return jvm;
60 }
61
62 JNIEnv *getJNIEnv()
63 {
64     JNIEnv *env;
65     jint jniError = 0;
66
67     jniError = (getJavaVM())->AttachCurrentThread((void**)&env, (void *)NULL);
68     if ( jniError == JNI_OK )
69         return env;
70     else
71         fprintf(stderr, "%s: AttachCurrentThread failed, returned %ld\n", __PRETTY_FUNCTION__, jniError);
72     return NULL;
73 }
74
75 static jvalue callJNIMethod (JNIType type, jobject obj, const char *name, const char *sig, va_list args)
76 {
77     JavaVM *jvm = getJavaVM();
78     JNIEnv *env = getJNIEnv();
79     jvalue result;
80
81     bzero (&result, sizeof(jvalue));
82     if ( obj != NULL && jvm != NULL && env != NULL) {
83         jclass cls = env->GetObjectClass(obj);
84         if ( cls != NULL ) {
85             jmethodID mid = env->GetMethodID(cls, name, sig);
86             if ( mid != NULL )
87             {
88                 switch (type) {
89                 case void_type:
90                     env->functions->CallVoidMethodV(env, obj, mid, args);
91                     break;
92                 case object_type:
93                     result.l = env->functions->CallObjectMethodV(env, obj, mid, args);
94                     break;
95                 case boolean_type:
96                     result.z = env->functions->CallBooleanMethodV(env, obj, mid, args);
97                     break;
98                 case byte_type:
99                     result.b = env->functions->CallByteMethodV(env, obj, mid, args);
100                     break;
101                 case char_type:
102                     result.c = env->functions->CallCharMethodV(env, obj, mid, args);
103                     break;
104                 case short_type:
105                     result.s = env->functions->CallShortMethodV(env, obj, mid, args);
106                     break;
107                 case int_type:
108                     result.i = env->functions->CallIntMethodV(env, obj, mid, args);
109                     break;
110                 case long_type:
111                     result.j = env->functions->CallLongMethodV(env, obj, mid, args);
112                     break;
113                 case float_type:
114                     result.f = env->functions->CallFloatMethodV(env, obj, mid, args);
115                     break;
116                 case double_type:
117                     result.d = env->functions->CallDoubleMethodV(env, obj, mid, args);
118                     break;
119                 default:
120                     fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
121                 }
122             }
123             else
124             {
125                 fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj);
126                 env->ExceptionDescribe();
127                 env->ExceptionClear();
128                 fprintf (stderr, "\n");
129             }
130
131             env->DeleteLocalRef(cls);
132         }
133         else {
134             fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, obj);
135         }
136     }
137
138     return result;
139 }
140
141 static jvalue callJNIStaticMethod (JNIType type, jclass cls, const char *name, const char *sig, va_list args)
142 {
143     JavaVM *jvm = getJavaVM();
144     JNIEnv *env = getJNIEnv();
145     jvalue result;
146
147     bzero (&result, sizeof(jvalue));
148     if ( cls != NULL && jvm != NULL && env != NULL) {
149         jmethodID mid = env->GetStaticMethodID(cls, name, sig);
150         if ( mid != NULL )
151         {
152             switch (type) {
153             case void_type:
154                 env->functions->CallStaticVoidMethodV(env, cls, mid, args);
155                 break;
156             case object_type:
157                 result.l = env->functions->CallStaticObjectMethodV(env, cls, mid, args);
158                 break;
159             case boolean_type:
160                 result.z = env->functions->CallStaticBooleanMethodV(env, cls, mid, args);
161                 break;
162             case byte_type:
163                 result.b = env->functions->CallStaticByteMethodV(env, cls, mid, args);
164                 break;
165             case char_type:
166                 result.c = env->functions->CallStaticCharMethodV(env, cls, mid, args);
167                 break;
168             case short_type:
169                 result.s = env->functions->CallStaticShortMethodV(env, cls, mid, args);
170                 break;
171             case int_type:
172                 result.i = env->functions->CallStaticIntMethodV(env, cls, mid, args);
173                 break;
174             case long_type:
175                 result.j = env->functions->CallStaticLongMethodV(env, cls, mid, args);
176                 break;
177             case float_type:
178                 result.f = env->functions->CallStaticFloatMethodV(env, cls, mid, args);
179                 break;
180             case double_type:
181                 result.d = env->functions->CallStaticDoubleMethodV(env, cls, mid, args);
182                 break;
183             default:
184                 fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
185             }
186         }
187         else
188         {
189             fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, cls);
190             env->ExceptionDescribe();
191             env->ExceptionClear();
192             fprintf (stderr, "\n");
193         }
194     }
195
196     return result;
197 }
198
199 static jvalue callJNIMethodIDA (JNIType type, jobject obj, jmethodID mid, jvalue *args)
200 {
201     JNIEnv *env = getJNIEnv();
202     jvalue result;
203     
204     bzero (&result, sizeof(jvalue));
205     if ( obj != NULL && mid != NULL )
206     {
207         switch (type) {
208         case void_type:
209             env->functions->CallVoidMethodA(env, obj, mid, args);
210             break;
211         case object_type:
212             result.l = env->functions->CallObjectMethodA(env, obj, mid, args);
213             break;
214         case boolean_type:
215             result.z = env->functions->CallBooleanMethodA(env, obj, mid, args);
216             break;
217         case byte_type:
218             result.b = env->functions->CallByteMethodA(env, obj, mid, args);
219             break;
220         case char_type:
221             result.c = env->functions->CallCharMethodA(env, obj, mid, args);
222             break;
223         case short_type:
224             result.s = env->functions->CallShortMethodA(env, obj, mid, args);
225             break;
226         case int_type:
227             result.i = env->functions->CallIntMethodA(env, obj, mid, args);
228             break;
229         case long_type:
230             result.j = env->functions->CallLongMethodA(env, obj, mid, args);
231             break;
232         case float_type:
233             result.f = env->functions->CallFloatMethodA(env, obj, mid, args);
234             break;
235         case double_type:
236             result.d = env->functions->CallDoubleMethodA(env, obj, mid, args);
237             break;
238         default:
239             fprintf(stderr, "%s: invalid function type (%d)\n", __PRETTY_FUNCTION__, (int)type);
240         }
241     }
242
243     return result;
244 }
245
246 static jvalue callJNIMethodA (JNIType type, jobject obj, const char *name, const char *sig, jvalue *args)
247 {
248     JavaVM *jvm = getJavaVM();
249     JNIEnv *env = getJNIEnv();
250     jvalue result;
251     
252     bzero (&result, sizeof(jvalue));
253     if ( obj != NULL && jvm != NULL && env != NULL) {
254         jclass cls = env->GetObjectClass(obj);
255         if ( cls != NULL ) {
256             jmethodID mid = env->GetMethodID(cls, name, sig);
257             if ( mid != NULL ) {
258                 result = callJNIMethodIDA (type, obj, mid, args);
259             }
260             else {
261                 fprintf(stderr, "%s: Could not find method: %s\n", __PRETTY_FUNCTION__, name);
262                 env->ExceptionDescribe();
263                 env->ExceptionClear();
264                 fprintf (stderr, "\n");
265             }
266
267             env->DeleteLocalRef(cls);
268         }
269         else {
270             fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__);
271         }
272     }
273
274     return result;
275 }
276
277 jmethodID getMethodID (jobject obj, const char *name, const char *sig)
278 {
279     JNIEnv *env = getJNIEnv();
280     jmethodID mid = 0;
281         
282     if ( env != NULL) {
283     jclass cls = env->GetObjectClass(obj);
284     if ( cls != NULL ) {
285             mid = env->GetMethodID(cls, name, sig);
286             if (!mid) {
287                 env->ExceptionClear();
288                 mid = env->GetStaticMethodID(cls, name, sig);
289                 if (!mid) {
290                     env->ExceptionClear();
291                 }
292             }
293         }
294         env->DeleteLocalRef(cls);
295     }
296     return mid;
297 }
298
299
300 #define CALL_JNI_METHOD(function_type,obj,name,sig) \
301     va_list args;\
302     va_start (args, sig);\
303     \
304     jvalue result = callJNIMethod(function_type, obj, name, sig, args);\
305     \
306     va_end (args);
307
308 #define CALL_JNI_STATIC_METHOD(function_type,cls,name,sig) \
309     va_list args;\
310     va_start (args, sig);\
311     \
312     jvalue result = callJNIStaticMethod(function_type, cls, name, sig, args);\
313     \
314     va_end (args);
315
316 void callJNIVoidMethod (jobject obj, const char *name, const char *sig, ... )
317 {
318     CALL_JNI_METHOD (void_type, obj, name, sig);
319 }
320
321 jobject callJNIObjectMethod (jobject obj, const char *name, const char *sig, ... )
322 {
323     CALL_JNI_METHOD (object_type, obj, name, sig);
324     return result.l;
325 }
326
327 jboolean callJNIBooleanMethod( jobject obj, const char *name, const char *sig, ... )
328 {
329     CALL_JNI_METHOD (boolean_type, obj, name, sig);
330     return result.z;
331 }
332
333 jboolean callJNIStaticBooleanMethod (jclass cls, const char *name, const char *sig, ... )
334 {
335     CALL_JNI_STATIC_METHOD (boolean_type, cls, name, sig);
336     return result.z;
337 }
338
339 jbyte callJNIByteMethod( jobject obj, const char *name, const char *sig, ... )
340 {
341     CALL_JNI_METHOD (byte_type, obj, name, sig);
342     return result.b;
343 }
344
345 jchar callJNICharMethod (jobject obj, const char *name, const char *sig, ... )
346 {
347     CALL_JNI_METHOD (char_type, obj, name, sig);
348     return result.c;
349 }
350
351 jshort callJNIShortMethod (jobject obj, const char *name, const char *sig, ... )
352 {
353     CALL_JNI_METHOD (short_type, obj, name, sig);
354     return result.s;
355 }
356
357 jint callJNIIntMethod (jobject obj, const char *name, const char *sig, ... )
358 {
359     CALL_JNI_METHOD (int_type, obj, name, sig);
360     return result.i;
361 }
362
363 jlong callJNILongMethod (jobject obj, const char *name, const char *sig, ... )
364 {
365     CALL_JNI_METHOD (long_type, obj, name, sig);
366     return result.j;
367 }
368
369 jfloat callJNIFloatMethod (jobject obj, const char *name, const char *sig, ... )
370 {
371     CALL_JNI_METHOD (float_type, obj, name, sig);
372     return result.f;
373 }
374
375 jdouble callJNIDoubleMethod (jobject obj, const char *name, const char *sig, ... )
376 {
377     CALL_JNI_METHOD (double_type, obj, name, sig);
378     return result.d;
379 }
380
381 void callJNIVoidMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
382 {
383     jvalue result = callJNIMethodA (void_type, obj, name, sig, args);
384 }
385
386 jobject callJNIObjectMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
387 {
388     jvalue result = callJNIMethodA (object_type, obj, name, sig, args);
389     return result.l;
390 }
391
392 jbyte callJNIByteMethodA ( jobject obj, const char *name, const char *sig, jvalue *args)
393 {
394     jvalue result = callJNIMethodA (byte_type, obj, name, sig, args);
395     return result.b;
396 }
397
398 jchar callJNICharMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
399 {
400     jvalue result = callJNIMethodA (char_type, obj, name, sig, args);
401     return result.c;
402 }
403
404 jshort callJNIShortMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
405 {
406     jvalue result = callJNIMethodA (short_type, obj, name, sig, args);
407     return result.s;
408 }
409
410 jint callJNIIntMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
411 {
412     jvalue result = callJNIMethodA (int_type, obj, name, sig, args);
413     return result.i;
414 }
415
416 jlong callJNILongMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
417 {
418     jvalue result = callJNIMethodA (long_type, obj, name, sig, args);
419     return result.j;
420 }
421
422 jfloat callJNIFloatMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
423 {
424     jvalue result = callJNIMethodA  (float_type, obj, name, sig, args);
425     return result.f;
426 }
427
428 jdouble callJNIDoubleMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
429 {
430     jvalue result = callJNIMethodA (double_type, obj, name, sig, args);
431     return result.d;
432 }
433
434 jboolean callJNIBooleanMethodA (jobject obj, const char *name, const char *sig, jvalue *args)
435 {
436     jvalue result = callJNIMethodA (boolean_type, obj, name, sig, args);
437     return result.z;
438 }
439
440 void callJNIVoidMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
441 {
442     jvalue result = callJNIMethodIDA (void_type, obj, methodID, args);
443 }
444
445 jobject callJNIObjectMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
446 {
447     jvalue result = callJNIMethodIDA (object_type, obj, methodID, args);
448     return result.l;
449 }
450
451 jbyte callJNIByteMethodIDA ( jobject obj, jmethodID methodID, jvalue *args)
452 {
453     jvalue result = callJNIMethodIDA (byte_type, obj, methodID, args);
454     return result.b;
455 }
456
457 jchar callJNICharMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
458 {
459     jvalue result = callJNIMethodIDA (char_type, obj, methodID, args);
460     return result.c;
461 }
462
463 jshort callJNIShortMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
464 {
465     jvalue result = callJNIMethodIDA (short_type, obj, methodID, args);
466     return result.s;
467 }
468
469 jint callJNIIntMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
470 {
471     jvalue result = callJNIMethodIDA (int_type, obj, methodID, args);
472     return result.i;
473 }
474
475 jlong callJNILongMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
476 {
477     jvalue result = callJNIMethodIDA (long_type, obj, methodID, args);
478     return result.j;
479 }
480
481 jfloat callJNIFloatMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
482 {
483     jvalue result = callJNIMethodIDA  (float_type, obj, methodID, args);
484     return result.f;
485 }
486
487 jdouble callJNIDoubleMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
488 {
489     jvalue result = callJNIMethodIDA (double_type, obj, methodID, args);
490     return result.d;
491 }
492
493 jboolean callJNIBooleanMethodIDA (jobject obj, jmethodID methodID, jvalue *args)
494 {
495     jvalue result = callJNIMethodIDA (boolean_type, obj, methodID, args);
496     return result.z;
497 }
498
499 const char *getCharactersFromJString (jstring aJString)
500 {
501     return getCharactersFromJStringInEnv (getJNIEnv(), aJString);
502 }
503
504 void releaseCharactersForJString (jstring aJString, const char *s)
505 {
506     releaseCharactersForJStringInEnv (getJNIEnv(), aJString, s);
507 }
508
509 const char *getCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
510 {
511     jboolean isCopy;
512     const char *s = env->GetStringUTFChars((jstring)aJString, &isCopy);
513     if (!s) {
514         env->ExceptionDescribe();
515         env->ExceptionClear();
516                 fprintf (stderr, "\n");
517     }
518     return s;
519 }
520
521 void releaseCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const char *s)
522 {
523     env->ReleaseStringUTFChars (aJString, s);
524 }
525
526 const jchar *getUCharactersFromJStringInEnv (JNIEnv *env, jstring aJString)
527 {
528     jboolean isCopy;
529     const jchar *s = env->GetStringChars((jstring)aJString, &isCopy);
530     if (!s) {
531         env->ExceptionDescribe();
532         env->ExceptionClear();
533                 fprintf (stderr, "\n");
534     }
535     return s;
536 }
537
538 void releaseUCharactersForJStringInEnv (JNIEnv *env, jstring aJString, const jchar *s)
539 {
540     env->ReleaseStringChars (aJString, s);
541 }
542
543 JNIType JNITypeFromClassName(const char *name)
544 {
545     JNIType type;
546     
547     if (strcmp("byte",name) == 0)
548         type = byte_type;
549     else if (strcmp("short",name) == 0)
550         type = short_type;
551     else if (strcmp("int",name) == 0)
552         type = int_type;
553     else if (strcmp("long",name) == 0)
554         type = long_type;
555     else if (strcmp("float",name) == 0)
556         type = float_type;
557     else if (strcmp("double",name) == 0)
558         type = double_type;
559     else if (strcmp("char",name) == 0)
560         type = char_type;
561     else if (strcmp("boolean",name) == 0)
562         type = boolean_type;
563     else if (strcmp("void",name) == 0)
564         type = void_type;
565     else
566         type = object_type;
567         
568     return type;
569 }
570
571 const char *signatureFromPrimitiveType(JNIType type)
572 {
573     switch (type){
574         case void_type: 
575             return "V";
576         
577         case object_type:
578             return "L";
579         
580         case boolean_type:
581             return "Z";
582         
583         case byte_type:
584             return "B";
585             
586         case char_type:
587             return "C";
588         
589         case short_type:
590             return "S";
591         
592         case int_type:
593             return "I";
594         
595         case long_type:
596             return "J";
597         
598         case float_type:
599             return "F";
600         
601         case double_type:
602             return "D";
603
604         case invalid_type:
605         default:
606         break;
607     }
608     return "";
609 }
610
611 JNIType JNITypeFromPrimitiveType(char type)
612 {
613     switch (type){
614         case 'V': 
615             return void_type;
616         
617         case 'L':
618         case '[':
619             return object_type;
620         
621         case 'Z':
622             return boolean_type;
623         
624         case 'B':
625             return byte_type;
626             
627         case 'C':
628             return char_type;
629         
630         case 'S':
631             return short_type;
632         
633         case 'I':
634             return int_type;
635         
636         case 'J':
637             return long_type;
638         
639         case 'F':
640             return float_type;
641         
642         case 'D':
643             return double_type;
644
645         default:
646         break;
647     }
648     return invalid_type;
649 }
650
651 jvalue getJNIField( jobject obj, JNIType type, const char *name, const char *signature)
652 {
653     JavaVM *jvm = getJavaVM();
654     JNIEnv *env = getJNIEnv();
655     jvalue result;
656
657     bzero (&result, sizeof(jvalue));
658     if ( obj != NULL && jvm != NULL && env != NULL) {
659         jclass cls = env->GetObjectClass(obj);
660         if ( cls != NULL ) {
661             jfieldID field = env->GetFieldID(cls, name, signature);
662             if ( field != NULL ) {
663                 switch (type) {
664                 case object_type:
665                     result.l = env->functions->GetObjectField(env, obj, field);
666                     break;
667                 case boolean_type:
668                     result.z = env->functions->GetBooleanField(env, obj, field);
669                     break;
670                 case byte_type:
671                     result.b = env->functions->GetByteField(env, obj, field);
672                     break;
673                 case char_type:
674                     result.c = env->functions->GetCharField(env, obj, field);
675                     break;
676                 case short_type:
677                     result.s = env->functions->GetShortField(env, obj, field);
678                     break;
679                 case int_type:
680                     result.i = env->functions->GetIntField(env, obj, field);
681                     break;
682                 case long_type:
683                     result.j = env->functions->GetLongField(env, obj, field);
684                     break;
685                 case float_type:
686                     result.f = env->functions->GetFloatField(env, obj, field);
687                     break;
688                 case double_type:
689                     result.d = env->functions->GetDoubleField(env, obj, field);
690                     break;
691                 default:
692                     fprintf(stderr, "%s: invalid field type (%d)\n", __PRETTY_FUNCTION__, (int)type);
693                 }
694             }
695             else
696             {
697                 fprintf(stderr, "%s: Could not find field: %s\n", __PRETTY_FUNCTION__, name);
698                 env->ExceptionDescribe();
699                 env->ExceptionClear();
700                 fprintf (stderr, "\n");
701             }
702
703             env->DeleteLocalRef(cls);
704         }
705         else {
706             fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__);
707         }
708     }
709
710     return result;
711 }
712
713 jvalue convertValueToJValue (ExecState *exec, ValueImp *value, JNIType _JNIType, const char *javaClassName)
714 {
715     jvalue result;
716    
717     switch (_JNIType){
718         case object_type: {
719             result.l = (jobject)0;
720             
721             // First see if we have a Java instance.
722             if (value->isObject()){
723                 ObjectImp *objectImp = static_cast<ObjectImp*>(value);
724                 if (objectImp->classInfo() == &RuntimeObjectImp::info) {
725                     RuntimeObjectImp *imp = static_cast<RuntimeObjectImp *>(value);
726                     JavaInstance *instance = static_cast<JavaInstance*>(imp->getInternalInstance());
727                     result.l = instance->javaInstance();
728                 }
729                 else if (objectImp->classInfo() == &RuntimeArrayImp::info) {
730                     RuntimeArrayImp *imp = static_cast<RuntimeArrayImp *>(value);
731                     JavaArray *array = static_cast<JavaArray*>(imp->getConcreteArray());
732                     result.l = array->javaArray();
733                 }
734             }
735             
736             // Now convert value to a string if the target type is a java.lang.string, and we're not
737             // converting from a Null.
738             if (result.l == 0 && strcmp(javaClassName, "java.lang.String") == 0) {
739 #if CONVERT_NULL_TO_EMPTY_STRING
740                 if (value->isNull()) {
741                     JNIEnv *env = getJNIEnv();
742                     jchar buf[2];
743                     jobject javaString = env->functions->NewString (env, buf, 0);
744                     result.l = javaString;
745                 }
746                 else 
747 #else
748                 if (!value->isNull())
749 #endif
750                 {
751                     UString stringValue = value->toString(exec);
752                     JNIEnv *env = getJNIEnv();
753                     jobject javaString = env->functions->NewString (env, (const jchar *)stringValue.data(), stringValue.size());
754                     result.l = javaString;
755                 }
756             }
757         }
758         break;
759         
760         case boolean_type: {
761             result.z = (jboolean)value->toNumber(exec);
762         }
763         break;
764             
765         case byte_type: {
766             result.b = (jbyte)value->toNumber(exec);
767         }
768         break;
769         
770         case char_type: {
771             result.c = (jchar)value->toNumber(exec);
772         }
773         break;
774
775         case short_type: {
776             result.s = (jshort)value->toNumber(exec);
777         }
778         break;
779
780         case int_type: {
781             result.i = (jint)value->toNumber(exec);
782         }
783         break;
784
785         case long_type: {
786             result.j = (jlong)value->toNumber(exec);
787         }
788         break;
789
790         case float_type: {
791             result.f = (jfloat)value->toNumber(exec);
792         }
793         break;
794
795         case double_type: {
796             result.d = (jdouble)value->toNumber(exec);
797         }
798         break;
799             
800         break;
801
802         case invalid_type:
803         default:
804         case void_type: {
805             bzero (&result, sizeof(jvalue));
806         }
807         break;
808     }
809     return result;
810 }
811
812 }
813
814 }