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