1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdio.h>
29
30 #include "jvm.h"
31 #include "jni.h"
32 #include "jni_util.h"
33
34 /* Due to a bug in the win32 C runtime library strings
35 * such as "z:" need to be appended with a "." so we
36 * must allocate at least 4 bytes to allow room for
37 * this expansion. See 4235353 for details.
38 */
39 #define MALLOC_MIN4(len) ((char *)malloc((len) + 1 < 4 ? 4 : (len) + 1))
40
41 /**
42 * Throw a Java exception by name. Similar to SignalError.
43 */
44 JNIEXPORT void JNICALL
JNU_ThrowByName(JNIEnv * env,const char * name,const char * msg)45 JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg)
46 {
47 jclass cls = (*env)->FindClass(env, name);
48
49 if (cls != 0) /* Otherwise an exception has already been thrown */
50 (*env)->ThrowNew(env, cls, msg);
51 }
52
53 /* JNU_Throw common exceptions */
54
55 JNIEXPORT void JNICALL
JNU_ThrowNullPointerException(JNIEnv * env,const char * msg)56 JNU_ThrowNullPointerException(JNIEnv *env, const char *msg)
57 {
58 JNU_ThrowByName(env, "java/lang/NullPointerException", msg);
59 }
60
61 JNIEXPORT void JNICALL
JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv * env,const char * msg)62 JNU_ThrowArrayIndexOutOfBoundsException(JNIEnv *env, const char *msg)
63 {
64 JNU_ThrowByName(env, "java/lang/ArrayIndexOutOfBoundsException", msg);
65 }
66
67 JNIEXPORT void JNICALL
JNU_ThrowOutOfMemoryError(JNIEnv * env,const char * msg)68 JNU_ThrowOutOfMemoryError(JNIEnv *env, const char *msg)
69 {
70 JNU_ThrowByName(env, "java/lang/OutOfMemoryError", msg);
71 }
72
73 JNIEXPORT void JNICALL
JNU_ThrowIllegalArgumentException(JNIEnv * env,const char * msg)74 JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg)
75 {
76 JNU_ThrowByName(env, "java/lang/IllegalArgumentException", msg);
77 }
78
79 JNIEXPORT void JNICALL
JNU_ThrowIllegalAccessError(JNIEnv * env,const char * msg)80 JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg)
81 {
82 JNU_ThrowByName(env, "java/lang/IllegalAccessError", msg);
83 }
84
85 JNIEXPORT void JNICALL
JNU_ThrowIllegalAccessException(JNIEnv * env,const char * msg)86 JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg)
87 {
88 JNU_ThrowByName(env, "java/lang/IllegalAccessException", msg);
89 }
90
91 JNIEXPORT void JNICALL
JNU_ThrowInternalError(JNIEnv * env,const char * msg)92 JNU_ThrowInternalError(JNIEnv *env, const char *msg)
93 {
94 JNU_ThrowByName(env, "java/lang/InternalError", msg);
95 }
96
97 JNIEXPORT void JNICALL
JNU_ThrowNoSuchFieldException(JNIEnv * env,const char * msg)98 JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg)
99 {
100 JNU_ThrowByName(env, "java/lang/NoSuchFieldException", msg);
101 }
102
103 JNIEXPORT void JNICALL
JNU_ThrowNoSuchMethodException(JNIEnv * env,const char * msg)104 JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg)
105 {
106 JNU_ThrowByName(env, "java/lang/NoSuchMethodException", msg);
107 }
108
109 JNIEXPORT void JNICALL
JNU_ThrowClassNotFoundException(JNIEnv * env,const char * msg)110 JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg)
111 {
112 JNU_ThrowByName(env, "java/lang/ClassNotFoundException", msg);
113 }
114
115 JNIEXPORT void JNICALL
JNU_ThrowNumberFormatException(JNIEnv * env,const char * msg)116 JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg)
117 {
118 JNU_ThrowByName(env, "java/lang/NumberFormatException", msg);
119 }
120
121 JNIEXPORT void JNICALL
JNU_ThrowIOException(JNIEnv * env,const char * msg)122 JNU_ThrowIOException(JNIEnv *env, const char *msg)
123 {
124 JNU_ThrowByName(env, "java/io/IOException", msg);
125 }
126
127 JNIEXPORT void JNICALL
JNU_ThrowNoSuchFieldError(JNIEnv * env,const char * msg)128 JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg)
129 {
130 JNU_ThrowByName(env, "java/lang/NoSuchFieldError", msg);
131 }
132
133 JNIEXPORT void JNICALL
JNU_ThrowNoSuchMethodError(JNIEnv * env,const char * msg)134 JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg)
135 {
136 JNU_ThrowByName(env, "java/lang/NoSuchMethodError", msg);
137 }
138
139 JNIEXPORT void JNICALL
JNU_ThrowStringIndexOutOfBoundsException(JNIEnv * env,const char * msg)140 JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg)
141 {
142 JNU_ThrowByName(env, "java/lang/StringIndexOutOfBoundsException", msg);
143 }
144
145 JNIEXPORT void JNICALL
JNU_ThrowInstantiationException(JNIEnv * env,const char * msg)146 JNU_ThrowInstantiationException(JNIEnv *env, const char *msg)
147 {
148 JNU_ThrowByName(env, "java/lang/InstantiationException", msg);
149 }
150
151
152 /* Throw an exception by name, using the string returned by
153 * JVM_LastErrorString for the detail string. If the last-error
154 * string is NULL, use the given default detail string.
155 */
156 JNIEXPORT void JNICALL
JNU_ThrowByNameWithLastError(JNIEnv * env,const char * name,const char * defaultDetail)157 JNU_ThrowByNameWithLastError(JNIEnv *env, const char *name,
158 const char *defaultDetail)
159 {
160 char buf[256];
161 int n = JVM_GetLastErrorString(buf, sizeof(buf));
162
163 if (n > 0) {
164 jstring s = JNU_NewStringPlatform(env, buf);
165 if (s != NULL) {
166 jobject x = JNU_NewObjectByName(env, name,
167 "(Ljava/lang/String;)V", s);
168 if (x != NULL) {
169 (*env)->Throw(env, x);
170 }
171 }
172 }
173 if (!(*env)->ExceptionOccurred(env)) {
174 JNU_ThrowByName(env, name, defaultDetail);
175 }
176 }
177
178 /* Throw an IOException, using the last-error string for the detail
179 * string. If the last-error string is NULL, use the given default
180 * detail string.
181 */
182 JNIEXPORT void JNICALL
JNU_ThrowIOExceptionWithLastError(JNIEnv * env,const char * defaultDetail)183 JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail)
184 {
185 JNU_ThrowByNameWithLastError(env, "java/io/IOException", defaultDetail);
186 }
187
188
189 JNIEXPORT jvalue JNICALL
JNU_CallStaticMethodByName(JNIEnv * env,jboolean * hasException,const char * class_name,const char * name,const char * signature,...)190 JNU_CallStaticMethodByName(JNIEnv *env,
191 jboolean *hasException,
192 const char *class_name,
193 const char *name,
194 const char *signature,
195 ...)
196 {
197 jclass clazz;
198 jmethodID mid;
199 va_list args;
200 jvalue result;
201 const char *p = signature;
202
203 /* find out the return type */
204 while (*p && *p != ')')
205 p++;
206 p++;
207
208 result.i = 0;
209
210 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
211 goto done2;
212
213 clazz = (*env)->FindClass(env, class_name);
214 if (clazz == 0)
215 goto done2;
216 mid = (*env)->GetStaticMethodID(env, clazz, name, signature);
217 if (mid == 0)
218 goto done1;
219 va_start(args, signature);
220 switch (*p) {
221 case 'V':
222 (*env)->CallStaticVoidMethodV(env, clazz, mid, args);
223 break;
224 case '[':
225 case 'L':
226 result.l = (*env)->CallStaticObjectMethodV(env, clazz, mid, args);
227 break;
228 case 'Z':
229 result.z = (*env)->CallStaticBooleanMethodV(env, clazz, mid, args);
230 break;
231 case 'B':
232 result.b = (*env)->CallStaticByteMethodV(env, clazz, mid, args);
233 break;
234 case 'C':
235 result.c = (*env)->CallStaticCharMethodV(env, clazz, mid, args);
236 break;
237 case 'S':
238 result.s = (*env)->CallStaticShortMethodV(env, clazz, mid, args);
239 break;
240 case 'I':
241 result.i = (*env)->CallStaticIntMethodV(env, clazz, mid, args);
242 break;
243 case 'J':
244 result.j = (*env)->CallStaticLongMethodV(env, clazz, mid, args);
245 break;
246 case 'F':
247 result.f = (*env)->CallStaticFloatMethodV(env, clazz, mid, args);
248 break;
249 case 'D':
250 result.d = (*env)->CallStaticDoubleMethodV(env, clazz, mid, args);
251 break;
252 default:
253 (*env)->FatalError(env, "JNU_CallStaticMethodByName: illegal signature");
254 }
255 va_end(args);
256
257 done1:
258 (*env)->DeleteLocalRef(env, clazz);
259 done2:
260 if (hasException) {
261 *hasException = (*env)->ExceptionCheck(env);
262 }
263 return result;
264 }
265
266 JNIEXPORT jvalue JNICALL
JNU_CallMethodByName(JNIEnv * env,jboolean * hasException,jobject obj,const char * name,const char * signature,...)267 JNU_CallMethodByName(JNIEnv *env,
268 jboolean *hasException,
269 jobject obj,
270 const char *name,
271 const char *signature,
272 ...)
273 {
274 jvalue result;
275 va_list args;
276
277 va_start(args, signature);
278 result = JNU_CallMethodByNameV(env, hasException, obj, name, signature,
279 args);
280 va_end(args);
281
282 return result;
283 }
284
285
286 JNIEXPORT jvalue JNICALL
JNU_CallMethodByNameV(JNIEnv * env,jboolean * hasException,jobject obj,const char * name,const char * signature,va_list args)287 JNU_CallMethodByNameV(JNIEnv *env,
288 jboolean *hasException,
289 jobject obj,
290 const char *name,
291 const char *signature,
292 va_list args)
293 {
294 jclass clazz;
295 jmethodID mid;
296 jvalue result;
297 const char *p = signature;
298
299 /* find out the return type */
300 while (*p && *p != ')')
301 p++;
302 p++;
303
304 result.i = 0;
305
306 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
307 goto done2;
308
309 clazz = (*env)->GetObjectClass(env, obj);
310 mid = (*env)->GetMethodID(env, clazz, name, signature);
311 if (mid == 0)
312 goto done1;
313
314 switch (*p) {
315 case 'V':
316 (*env)->CallVoidMethodV(env, obj, mid, args);
317 break;
318 case '[':
319 case 'L':
320 result.l = (*env)->CallObjectMethodV(env, obj, mid, args);
321 break;
322 case 'Z':
323 result.z = (*env)->CallBooleanMethodV(env, obj, mid, args);
324 break;
325 case 'B':
326 result.b = (*env)->CallByteMethodV(env, obj, mid, args);
327 break;
328 case 'C':
329 result.c = (*env)->CallCharMethodV(env, obj, mid, args);
330 break;
331 case 'S':
332 result.s = (*env)->CallShortMethodV(env, obj, mid, args);
333 break;
334 case 'I':
335 result.i = (*env)->CallIntMethodV(env, obj, mid, args);
336 break;
337 case 'J':
338 result.j = (*env)->CallLongMethodV(env, obj, mid, args);
339 break;
340 case 'F':
341 result.f = (*env)->CallFloatMethodV(env, obj, mid, args);
342 break;
343 case 'D':
344 result.d = (*env)->CallDoubleMethodV(env, obj, mid, args);
345 break;
346 default:
347 (*env)->FatalError(env, "JNU_CallMethodByNameV: illegal signature");
348 }
349 done1:
350 (*env)->DeleteLocalRef(env, clazz);
351 done2:
352 if (hasException) {
353 *hasException = (*env)->ExceptionCheck(env);
354 }
355 return result;
356 }
357
358 JNIEXPORT jobject JNICALL
JNU_NewObjectByName(JNIEnv * env,const char * class_name,const char * constructor_sig,...)359 JNU_NewObjectByName(JNIEnv *env, const char *class_name,
360 const char *constructor_sig, ...)
361 {
362 jobject obj = NULL;
363
364 jclass cls = 0;
365 jmethodID cls_initMID;
366 va_list args;
367
368 if ((*env)->EnsureLocalCapacity(env, 2) < 0)
369 goto done;
370
371 cls = (*env)->FindClass(env, class_name);
372 if (cls == 0) {
373 goto done;
374 }
375 cls_initMID = (*env)->GetMethodID(env, cls,
376 "<init>", constructor_sig);
377 if (cls_initMID == NULL) {
378 goto done;
379 }
380 va_start(args, constructor_sig);
381 obj = (*env)->NewObjectV(env, cls, cls_initMID, args);
382 va_end(args);
383
384 done:
385 (*env)->DeleteLocalRef(env, cls);
386 return obj;
387 }
388
389 // Android removed: Deal solely in UTF-8
390 //
391 // /* Optimized for char set ISO_8559_1 */
392 // static jstring
393 // newString8859_1(JNIEnv *env, const char *str)
394 // {
395 // int len = (int)strlen(str);
396 // jchar buf[512];
397 // jchar *str1;
398 // jstring result;
399 // int i;
400 //
401 // if (len > 512) {
402 // str1 = (jchar *)malloc(len * sizeof(jchar));
403 // if (str1 == 0) {
404 // JNU_ThrowOutOfMemoryError(env, 0);
405 // return 0;
406 // }
407 // } else
408 // str1 = buf;
409 //
410 // for (i=0;i<len;i++)
411 // str1[i] = (unsigned char)str[i];
412 // result = (*env)->NewString(env, str1, len);
413 // if (str1 != buf)
414 // free(str1);
415 // return result;
416 // }
417 //
418 // static const char*
419 // getString8859_1Chars(JNIEnv *env, jstring jstr)
420 // {
421 // int i;
422 // char *result;
423 // jint len = (*env)->GetStringLength(env, jstr);
424 // const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
425 // if (str == 0) {
426 // return 0;
427 // }
428 //
429 // result = MALLOC_MIN4(len);
430 // if (result == 0) {
431 // (*env)->ReleaseStringCritical(env, jstr, str);
432 // JNU_ThrowOutOfMemoryError(env, 0);
433 // return 0;
434 // }
435 //
436 // for (i=0; i<len; i++) {
437 // jchar unicode = str[i];
438 // if (unicode <= 0x00ff)
439 // result[i] = (char)unicode;
440 // else
441 // result[i] = '?';
442 // }
443 //
444 // result[len] = 0;
445 // (*env)->ReleaseStringCritical(env, jstr, str);
446 // return result;
447 // }
448 //
449 //
450 // /* Optimized for char set ISO646-US (us-ascii) */
451 // static jstring
452 // newString646_US(JNIEnv *env, const char *str)
453 // {
454 // int len = strlen(str);
455 // jchar buf[512];
456 // jchar *str1;
457 // jstring result;
458 // int i;
459 //
460 // if (len > 512) {
461 // str1 = (jchar *)malloc(len * sizeof(jchar));
462 // if (str1 == 0) {
463 // JNU_ThrowOutOfMemoryError(env, 0);
464 // return 0;
465 // }
466 // } else
467 // str1 = buf;
468 //
469 // for (i=0; i<len; i++) {
470 // unsigned char c = (unsigned char)str[i];
471 // if (c <= 0x7f)
472 // str1[i] = c;
473 // else
474 // str1[i] = '?';
475 // }
476 //
477 // result = (*env)->NewString(env, str1, len);
478 // if (str1 != buf)
479 // free(str1);
480 // return result;
481 // }
482 //
483 // static const char*
484 // getString646_USChars(JNIEnv *env, jstring jstr)
485 // {
486 // int i;
487 // char *result;
488 // jint len = (*env)->GetStringLength(env, jstr);
489 // const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
490 // if (str == 0) {
491 // return 0;
492 // }
493 //
494 // result = MALLOC_MIN4(len);
495 // if (result == 0) {
496 // (*env)->ReleaseStringCritical(env, jstr, str);
497 // JNU_ThrowOutOfMemoryError(env, 0);
498 // return 0;
499 // }
500 //
501 // for (i=0; i<len; i++) {
502 // jchar unicode = str[i];
503 // if (unicode <= 0x007f )
504 // result[i] = (char)unicode;
505 // else
506 // result[i] = '?';
507 // }
508 //
509 // result[len] = 0;
510 // (*env)->ReleaseStringCritical(env, jstr, str);
511 // return result;
512 // }
513 //
514 // /* enumeration of c1 row from Cp1252 */
515 // static int cp1252c1chars[32] = {
516 // 0x20AC,0xFFFD,0x201A,0x0192,0x201E,0x2026,0x2020,0x2021,
517 // 0x02C6,0x2030,0x0160,0x2039,0x0152,0xFFFD,0x017D,0xFFFD,
518 // 0xFFFD,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014,
519 // 0x02Dc,0x2122,0x0161,0x203A,0x0153,0xFFFD,0x017E,0x0178
520 // };
521 //
522 // /* Optimized for char set Cp1252 */
523 // static jstring
524 // newStringCp1252(JNIEnv *env, const char *str)
525 // {
526 // int len = (int) strlen(str);
527 // jchar buf[512];
528 // jchar *str1;
529 // jstring result;
530 // int i;
531 // if (len > 512) {
532 // str1 = (jchar *)malloc(len * sizeof(jchar));
533 // if (str1 == 0) {
534 // JNU_ThrowOutOfMemoryError(env, 0);
535 // return 0;
536 // }
537 // } else
538 // str1 = buf;
539 //
540 // for (i=0; i<len; i++) {
541 // unsigned char c = (unsigned char)str[i];
542 // if ((c >= 0x80) && (c <= 0x9f))
543 // str1[i] = cp1252c1chars[c-128];
544 // else
545 // str1[i] = c;
546 // }
547 //
548 // result = (*env)->NewString(env, str1, len);
549 // if (str1 != buf)
550 // free(str1);
551 // return result;
552 // }
553 //
554 // static const char*
555 // getStringCp1252Chars(JNIEnv *env, jstring jstr)
556 // {
557 // int i;
558 // char *result;
559 // jint len = (*env)->GetStringLength(env, jstr);
560 // const jchar *str = (*env)->GetStringCritical(env, jstr, 0);
561 // if (str == 0) {
562 // return 0;
563 // }
564 //
565 // result = MALLOC_MIN4(len);
566 // if (result == 0) {
567 // (*env)->ReleaseStringCritical(env, jstr, str);
568 // JNU_ThrowOutOfMemoryError(env, 0);
569 // return 0;
570 // }
571 //
572 // for (i=0; i<len; i++) {
573 // jchar c = str[i];
574 // if (c < 256)
575 // result[i] = (char)c;
576 // else switch(c) {
577 // case 0x20AC: result[i] = (char)0x80; break;
578 // case 0x201A: result[i] = (char)0x82; break;
579 // case 0x0192: result[i] = (char)0x83; break;
580 // case 0x201E: result[i] = (char)0x84; break;
581 // case 0x2026: result[i] = (char)0x85; break;
582 // case 0x2020: result[i] = (char)0x86; break;
583 // case 0x2021: result[i] = (char)0x87; break;
584 // case 0x02C6: result[i] = (char)0x88; break;
585 // case 0x2030: result[i] = (char)0x89; break;
586 // case 0x0160: result[i] = (char)0x8A; break;
587 // case 0x2039: result[i] = (char)0x8B; break;
588 // case 0x0152: result[i] = (char)0x8C; break;
589 // case 0x017D: result[i] = (char)0x8E; break;
590 // case 0x2018: result[i] = (char)0x91; break;
591 // case 0x2019: result[i] = (char)0x92; break;
592 // case 0x201C: result[i] = (char)0x93; break;
593 // case 0x201D: result[i] = (char)0x94; break;
594 // case 0x2022: result[i] = (char)0x95; break;
595 // case 0x2013: result[i] = (char)0x96; break;
596 // case 0x2014: result[i] = (char)0x97; break;
597 // case 0x02DC: result[i] = (char)0x98; break;
598 // case 0x2122: result[i] = (char)0x99; break;
599 // case 0x0161: result[i] = (char)0x9A; break;
600 // case 0x203A: result[i] = (char)0x9B; break;
601 // case 0x0153: result[i] = (char)0x9C; break;
602 // case 0x017E: result[i] = (char)0x9E; break;
603 // case 0x0178: result[i] = (char)0x9F; break;
604 // default: result[i] = '?'; break;
605 // }
606 // }
607 //
608 // result[len] = 0;
609 // (*env)->ReleaseStringCritical(env, jstr, str);
610 // return result;
611 // }
612 //
613 // static int fastEncoding = NO_ENCODING_YET;
614 // static jstring jnuEncoding = NULL;
615 //
616 // /* Cached method IDs */
617 // static jmethodID String_init_ID; /* String(byte[], enc) */
618 // static jmethodID String_getBytes_ID; /* String.getBytes(enc) */
619 //
620 // int getFastEncoding() {
621 // return fastEncoding;
622 // }
623 //
624 // /* Initialize the fast encoding. If the "sun.jnu.encoding" property
625 // * has not yet been set, we leave fastEncoding == NO_ENCODING_YET.
626 // */
627 // void
628 // initializeEncoding(JNIEnv *env)
629 // {
630 // jstring propname = 0;
631 // jstring enc = 0;
632 //
633 // if ((*env)->EnsureLocalCapacity(env, 3) < 0)
634 // return;
635 //
636 // propname = (*env)->NewStringUTF(env, "sun.jnu.encoding");
637 // if (propname) {
638 // jboolean exc;
639 // enc = JNU_CallStaticMethodByName
640 // (env,
641 // &exc,
642 // "java/lang/System",
643 // "getProperty",
644 // "(Ljava/lang/String;)Ljava/lang/String;",
645 // propname).l;
646 // if (!exc) {
647 // if (enc) {
648 // const char* encname = (*env)->GetStringUTFChars(env, enc, 0);
649 // if (encname) {
650 // /*
651 // * On Solaris with nl_langinfo() called in GetJavaProperties():
652 // *
653 // * locale undefined -> NULL -> hardcoded default
654 // * "C" locale -> "" -> hardcoded default (on 2.6)
655 // * "C" locale -> "ISO646-US" (on Sol 7/8)
656 // * "en_US" locale -> "ISO8859-1"
657 // * "en_GB" locale -> "ISO8859-1" (on Sol 7/8)
658 // * "en_UK" locale -> "ISO8859-1" (on 2.6)
659 // */
660 // if ((strcmp(encname, "8859_1") == 0) ||
661 // (strcmp(encname, "ISO8859-1") == 0) ||
662 // (strcmp(encname, "ISO8859_1") == 0))
663 // fastEncoding = FAST_8859_1;
664 // else if (strcmp(encname, "ISO646-US") == 0)
665 // fastEncoding = FAST_646_US;
666 // else if (strcmp(encname, "Cp1252") == 0 ||
667 // /* This is a temporary fix until we move */
668 // /* to wide character versions of all Windows */
669 // /* calls. */
670 // strcmp(encname, "utf-16le") == 0)
671 // fastEncoding = FAST_CP1252;
672 // else {
673 // fastEncoding = NO_FAST_ENCODING;
674 // jnuEncoding = (jstring)(*env)->NewGlobalRef(env, enc);
675 // }
676 // (*env)->ReleaseStringUTFChars(env, enc, encname);
677 // }
678 // }
679 // } else {
680 // (*env)->ExceptionClear(env);
681 // }
682 // } else {
683 // (*env)->ExceptionClear(env);
684 // }
685 // (*env)->DeleteLocalRef(env, propname);
686 // (*env)->DeleteLocalRef(env, enc);
687 //
688 // /* Initialize method-id cache */
689 // String_getBytes_ID = (*env)->GetMethodID(env, JNU_ClassString(env),
690 // "getBytes", "(Ljava/lang/String;)[B");
691 // String_init_ID = (*env)->GetMethodID(env, JNU_ClassString(env),
692 // "<init>", "([BLjava/lang/String;)V");
693 // }
694 //
695 // static jboolean isJNUEncodingSupported = JNI_FALSE;
696 // static jboolean jnuEncodingSupported(JNIEnv *env) {
697 // jboolean exe;
698 // if (isJNUEncodingSupported == JNI_TRUE) {
699 // return JNI_TRUE;
700 // }
701 // isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
702 // env, &exe,
703 // "java/nio/charset/Charset",
704 // "isSupported",
705 // "(Ljava/lang/String;)Z",
706 // jnuEncoding).z;
707 // return isJNUEncodingSupported;
708 // }
709
710
711 JNIEXPORT jstring
JNU_NewStringPlatform(JNIEnv * env,const char * str)712 JNU_NewStringPlatform(JNIEnv *env, const char *str)
713 {
714 // Android-changed: Always use nativeNewStringPlatform.
715 // return JNU_NewStringPlatform(env, str);
716 return nativeNewStringPlatform(env, str);
717 }
718
719 JNIEXPORT const char *
JNU_GetStringPlatformChars(JNIEnv * env,jstring jstr,jboolean * isCopy)720 JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
721 {
722 // Android-changed: Always use nativeGetStringPlatformChars.
723 // return JNU_GetStringPlatformChars(env, jstr, isCopy);
724 return nativeGetStringPlatformChars(env, jstr, isCopy);
725 }
726
727 JNIEXPORT void JNICALL
JNU_ReleaseStringPlatformChars(JNIEnv * env,jstring jstr,const char * str)728 JNU_ReleaseStringPlatformChars(JNIEnv *env, jstring jstr, const char *str)
729 {
730 // Android changed : Use the "native" code from the platform a chance
731 // to handle this first.
732 //
733 // free((void *)str);
734 nativeReleaseStringPlatformChars(env, jstr, str);
735 }
736
737 // Android removed: Deal solely in UTF-8
738 //
739 // JNIEXPORT jstring JNICALL
740 // JNU_NewStringPlatform(JNIEnv *env, const char *str)
741 // {
742 // jstring result;
743 // result = nativeNewStringPlatform(env, str);
744 // if (result == NULL) {
745 // jbyteArray hab = 0;
746 // int len;
747 //
748 // if (fastEncoding == NO_ENCODING_YET)
749 // initializeEncoding(env);
750 //
751 // if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
752 // return newString8859_1(env, str);
753 // if (fastEncoding == FAST_646_US)
754 // return newString646_US(env, str);
755 // if (fastEncoding == FAST_CP1252)
756 // return newStringCp1252(env, str);
757 //
758 // if ((*env)->EnsureLocalCapacity(env, 2) < 0)
759 // return NULL;
760 //
761 // len = (int)strlen(str);
762 // hab = (*env)->NewByteArray(env, len);
763 // if (hab != 0) {
764 // (*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
765 // if (jnuEncodingSupported(env)) {
766 // result = (*env)->NewObject(env, JNU_ClassString(env),
767 // String_init_ID, hab, jnuEncoding);
768 // } else {
769 // /*If the encoding specified in sun.jnu.encoding is not endorsed
770 // by "Charset.isSupported" we have to fall back to use String(byte[])
771 // explicitly here without specifying the encoding name, in which the
772 // StringCoding class will pickup the iso-8859-1 as the fallback
773 // converter for us.
774 // */
775 // jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
776 // "<init>", "([B)V");
777 // result = (*env)->NewObject(env, JNU_ClassString(env), mid, hab);
778 // }
779 // (*env)->DeleteLocalRef(env, hab);
780 // return result;
781 // }
782 // }
783 // return NULL;
784 //}
785 //
786 //
787 //JNIEXPORT const char * JNICALL
788 //JNU_GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy)
789 //{
790 // char *result = nativeGetStringPlatformChars(env, jstr, isCopy);
791 // if (result == NULL) {
792 //
793 // jbyteArray hab = 0;
794 //
795 // if (isCopy)
796 // *isCopy = JNI_TRUE;
797 //
798 // if (fastEncoding == NO_ENCODING_YET)
799 // initializeEncoding(env);
800 //
801 // if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
802 // return getString8859_1Chars(env, jstr);
803 // if (fastEncoding == FAST_646_US)
804 // return getString646_USChars(env, jstr);
805 // if (fastEncoding == FAST_CP1252)
806 // return getStringCp1252Chars(env, jstr);
807 //
808 // if ((*env)->EnsureLocalCapacity(env, 2) < 0)
809 // return 0;
810 //
811 // if (jnuEncodingSupported(env)) {
812 // hab = (*env)->CallObjectMethod(env, jstr, String_getBytes_ID, jnuEncoding);
813 // } else {
814 // jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
815 // "getBytes", "()[B");
816 // hab = (*env)->CallObjectMethod(env, jstr, mid);
817 // }
818 //
819 // if (!(*env)->ExceptionCheck(env)) {
820 // jint len = (*env)->GetArrayLength(env, hab);
821 // result = MALLOC_MIN4(len);
822 // if (result == 0) {
823 // JNU_ThrowOutOfMemoryError(env, 0);
824 // (*env)->DeleteLocalRef(env, hab);
825 // return 0;
826 // }
827 // (*env)->GetByteArrayRegion(env, hab, 0, len, (jbyte *)result);
828 // result[len] = 0; /* NULL-terminate */
829 // }
830 //
831 // (*env)->DeleteLocalRef(env, hab);
832 // }
833 // return result;
834 //}
835
836
837 /*
838 * Export the platform dependent path canonicalization so that
839 * VM can find it when loading system classes.
840 *
841 */
842 // Android-changed: hidden to avoid conflict with libm (b/135018555)
843 __attribute__((visibility("hidden")))
844 extern int canonicalize(char *path, const char *out, int len);
845
846 JNIEXPORT int
Canonicalize(JNIEnv * env,char * orig,char * out,int len)847 Canonicalize(JNIEnv *env, char *orig, char *out, int len)
848 {
849 /* canonicalize an already natived path */
850 return canonicalize(orig, out, len);
851 }
852
853 JNIEXPORT jclass JNICALL
JNU_ClassString(JNIEnv * env)854 JNU_ClassString(JNIEnv *env)
855 {
856 static jclass cls = 0;
857 if (cls == 0) {
858 jclass c;
859 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
860 return 0;
861 c = (*env)->FindClass(env, "java/lang/String");
862 cls = (*env)->NewGlobalRef(env, c);
863 (*env)->DeleteLocalRef(env, c);
864 }
865 return cls;
866 }
867
868 JNIEXPORT jclass JNICALL
JNU_ClassClass(JNIEnv * env)869 JNU_ClassClass(JNIEnv *env)
870 {
871 static jclass cls = 0;
872 if (cls == 0) {
873 jclass c;
874 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
875 return 0;
876 c = (*env)->FindClass(env, "java/lang/Class");
877 cls = (*env)->NewGlobalRef(env, c);
878 (*env)->DeleteLocalRef(env, c);
879 }
880 return cls;
881 }
882
883 JNIEXPORT jclass JNICALL
JNU_ClassObject(JNIEnv * env)884 JNU_ClassObject(JNIEnv *env)
885 {
886 static jclass cls = 0;
887 if (cls == 0) {
888 jclass c;
889 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
890 return 0;
891 c = (*env)->FindClass(env, "java/lang/Object");
892 cls = (*env)->NewGlobalRef(env, c);
893 (*env)->DeleteLocalRef(env, c);
894 }
895 return cls;
896 }
897
898 JNIEXPORT jclass JNICALL
JNU_ClassThrowable(JNIEnv * env)899 JNU_ClassThrowable(JNIEnv *env)
900 {
901 static jclass cls = 0;
902 if (cls == 0) {
903 jclass c;
904 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
905 return 0;
906 c = (*env)->FindClass(env, "java/lang/Throwable");
907 cls = (*env)->NewGlobalRef(env, c);
908 (*env)->DeleteLocalRef(env, c);
909 }
910 return cls;
911 }
912
913 JNIEXPORT jint JNICALL
JNU_CopyObjectArray(JNIEnv * env,jobjectArray dst,jobjectArray src,jint count)914 JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
915 jint count)
916 {
917 int i;
918 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
919 return -1;
920 for (i=0; i<count; i++) {
921 jstring p = (*env)->GetObjectArrayElement(env, src, i);
922 (*env)->SetObjectArrayElement(env, dst, i, p);
923 (*env)->DeleteLocalRef(env, p);
924 }
925 return 0;
926 }
927
928 JNIEXPORT void * JNICALL
JNU_GetEnv(JavaVM * vm,jint version)929 JNU_GetEnv(JavaVM *vm, jint version)
930 {
931 void *env;
932 (*vm)->GetEnv(vm, &env, version);
933 return env;
934 }
935
936 JNIEXPORT jint JNICALL
JNU_IsInstanceOfByName(JNIEnv * env,jobject object,char * classname)937 JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char* classname)
938 {
939 jclass cls;
940 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
941 return JNI_ERR;
942 cls = (*env)->FindClass(env, classname);
943 if (cls != NULL) {
944 jint result = (*env)->IsInstanceOf(env, object, cls);
945 (*env)->DeleteLocalRef(env, cls);
946 return result;
947 }
948 return JNI_ERR;
949 }
950
951 JNIEXPORT jboolean JNICALL
JNU_Equals(JNIEnv * env,jobject object1,jobject object2)952 JNU_Equals(JNIEnv *env, jobject object1, jobject object2)
953 {
954 static jmethodID mid = NULL;
955 if (mid == NULL) {
956 mid = (*env)->GetMethodID(env, JNU_ClassObject(env), "equals",
957 "(Ljava/lang/Object;)Z");
958 }
959 return (*env)->CallBooleanMethod(env, object1, mid, object2);
960 }
961
962
963 /************************************************************************
964 * Thread calls
965 */
966
967 static jmethodID Object_waitMID;
968 static jmethodID Object_notifyMID;
969 static jmethodID Object_notifyAllMID;
970
971 JNIEXPORT void JNICALL
JNU_MonitorWait(JNIEnv * env,jobject object,jlong timeout)972 JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout)
973 {
974 if (object == NULL) {
975 JNU_ThrowNullPointerException(env, "JNU_MonitorWait argument");
976 return;
977 }
978 if (Object_waitMID == NULL) {
979 jclass cls = JNU_ClassObject(env);
980 if (cls == NULL) {
981 return;
982 }
983 Object_waitMID = (*env)->GetMethodID(env, cls, "wait", "(J)V");
984 if (Object_waitMID == NULL) {
985 return;
986 }
987 }
988 (*env)->CallVoidMethod(env, object, Object_waitMID, timeout);
989 }
990
991 JNIEXPORT void JNICALL
JNU_Notify(JNIEnv * env,jobject object)992 JNU_Notify(JNIEnv *env, jobject object)
993 {
994 if (object == NULL) {
995 JNU_ThrowNullPointerException(env, "JNU_Notify argument");
996 return;
997 }
998 if (Object_notifyMID == NULL) {
999 jclass cls = JNU_ClassObject(env);
1000 if (cls == NULL) {
1001 return;
1002 }
1003 Object_notifyMID = (*env)->GetMethodID(env, cls, "notify", "()V");
1004 if (Object_notifyMID == NULL) {
1005 return;
1006 }
1007 }
1008 (*env)->CallVoidMethod(env, object, Object_notifyMID);
1009 }
1010
1011 JNIEXPORT void JNICALL
JNU_NotifyAll(JNIEnv * env,jobject object)1012 JNU_NotifyAll(JNIEnv *env, jobject object)
1013 {
1014 if (object == NULL) {
1015 JNU_ThrowNullPointerException(env, "JNU_NotifyAll argument");
1016 return;
1017 }
1018 if (Object_notifyAllMID == NULL) {
1019 jclass cls = JNU_ClassObject(env);
1020 if (cls == NULL) {
1021 return;
1022 }
1023 Object_notifyAllMID = (*env)->GetMethodID(env, cls,"notifyAll", "()V");
1024 if (Object_notifyAllMID == NULL) {
1025 return;
1026 }
1027 }
1028 (*env)->CallVoidMethod(env, object, Object_notifyAllMID);
1029 }
1030
1031
1032 /************************************************************************
1033 * Debugging utilities
1034 */
1035
1036 JNIEXPORT void JNICALL
JNU_PrintString(JNIEnv * env,char * hdr,jstring string)1037 JNU_PrintString(JNIEnv *env, char *hdr, jstring string)
1038 {
1039 if (string == NULL) {
1040 fprintf(stderr, "%s: is NULL\n", hdr);
1041 } else {
1042 const char *stringPtr = JNU_GetStringPlatformChars(env, string, 0);
1043 if (stringPtr == 0)
1044 return;
1045 fprintf(stderr, "%s: %s\n", hdr, stringPtr);
1046 JNU_ReleaseStringPlatformChars(env, string, stringPtr);
1047 }
1048 }
1049
1050 JNIEXPORT void JNICALL
JNU_PrintClass(JNIEnv * env,char * hdr,jobject object)1051 JNU_PrintClass(JNIEnv *env, char* hdr, jobject object)
1052 {
1053 if (object == NULL) {
1054 fprintf(stderr, "%s: object is NULL\n", hdr);
1055 return;
1056 } else {
1057 jclass cls = (*env)->GetObjectClass(env, object);
1058 jstring clsName = JNU_ToString(env, cls);
1059 JNU_PrintString(env, hdr, clsName);
1060 (*env)->DeleteLocalRef(env, cls);
1061 (*env)->DeleteLocalRef(env, clsName);
1062 }
1063 }
1064
1065 JNIEXPORT jstring JNICALL
JNU_ToString(JNIEnv * env,jobject object)1066 JNU_ToString(JNIEnv *env, jobject object)
1067 {
1068 if (object == NULL) {
1069 return (*env)->NewStringUTF(env, "NULL");
1070 } else {
1071 return (jstring)JNU_CallMethodByName(env,
1072 NULL,
1073 object,
1074 "toString",
1075 "()Ljava/lang/String;").l;
1076 }
1077 }
1078
1079 JNIEXPORT jvalue JNICALL
JNU_GetFieldByName(JNIEnv * env,jboolean * hasException,jobject obj,const char * name,const char * signature)1080 JNU_GetFieldByName(JNIEnv *env,
1081 jboolean *hasException,
1082 jobject obj,
1083 const char *name,
1084 const char *signature)
1085 {
1086 jclass cls;
1087 jfieldID fid;
1088 jvalue result;
1089
1090 result.i = 0;
1091
1092 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1093 goto done2;
1094
1095 cls = (*env)->GetObjectClass(env, obj);
1096 fid = (*env)->GetFieldID(env, cls, name, signature);
1097 if (fid == 0)
1098 goto done1;
1099
1100 switch (*signature) {
1101 case '[':
1102 case 'L':
1103 result.l = (*env)->GetObjectField(env, obj, fid);
1104 break;
1105 case 'Z':
1106 result.z = (*env)->GetBooleanField(env, obj, fid);
1107 break;
1108 case 'B':
1109 result.b = (*env)->GetByteField(env, obj, fid);
1110 break;
1111 case 'C':
1112 result.c = (*env)->GetCharField(env, obj, fid);
1113 break;
1114 case 'S':
1115 result.s = (*env)->GetShortField(env, obj, fid);
1116 break;
1117 case 'I':
1118 result.i = (*env)->GetIntField(env, obj, fid);
1119 break;
1120 case 'J':
1121 result.j = (*env)->GetLongField(env, obj, fid);
1122 break;
1123 case 'F':
1124 result.f = (*env)->GetFloatField(env, obj, fid);
1125 break;
1126 case 'D':
1127 result.d = (*env)->GetDoubleField(env, obj, fid);
1128 break;
1129
1130 default:
1131 (*env)->FatalError(env, "JNU_GetFieldByName: illegal signature");
1132 }
1133
1134 done1:
1135 (*env)->DeleteLocalRef(env, cls);
1136 done2:
1137 if (hasException) {
1138 *hasException = (*env)->ExceptionCheck(env);
1139 }
1140 return result;
1141 }
1142
1143 JNIEXPORT void JNICALL
JNU_SetFieldByName(JNIEnv * env,jboolean * hasException,jobject obj,const char * name,const char * signature,...)1144 JNU_SetFieldByName(JNIEnv *env,
1145 jboolean *hasException,
1146 jobject obj,
1147 const char *name,
1148 const char *signature,
1149 ...)
1150 {
1151 jclass cls;
1152 jfieldID fid;
1153 va_list args;
1154
1155 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1156 goto done2;
1157
1158 cls = (*env)->GetObjectClass(env, obj);
1159 fid = (*env)->GetFieldID(env, cls, name, signature);
1160 if (fid == 0)
1161 goto done1;
1162
1163 va_start(args, signature);
1164 switch (*signature) {
1165 case '[':
1166 case 'L':
1167 (*env)->SetObjectField(env, obj, fid, va_arg(args, jobject));
1168 break;
1169 case 'Z':
1170 (*env)->SetBooleanField(env, obj, fid, (jboolean)va_arg(args, int));
1171 break;
1172 case 'B':
1173 (*env)->SetByteField(env, obj, fid, (jbyte)va_arg(args, int));
1174 break;
1175 case 'C':
1176 (*env)->SetCharField(env, obj, fid, (jchar)va_arg(args, int));
1177 break;
1178 case 'S':
1179 (*env)->SetShortField(env, obj, fid, (jshort)va_arg(args, int));
1180 break;
1181 case 'I':
1182 (*env)->SetIntField(env, obj, fid, va_arg(args, jint));
1183 break;
1184 case 'J':
1185 (*env)->SetLongField(env, obj, fid, va_arg(args, jlong));
1186 break;
1187 case 'F':
1188 (*env)->SetFloatField(env, obj, fid, (jfloat)va_arg(args, jdouble));
1189 break;
1190 case 'D':
1191 (*env)->SetDoubleField(env, obj, fid, va_arg(args, jdouble));
1192 break;
1193
1194 default:
1195 (*env)->FatalError(env, "JNU_SetFieldByName: illegal signature");
1196 }
1197 va_end(args);
1198
1199 done1:
1200 (*env)->DeleteLocalRef(env, cls);
1201 done2:
1202 if (hasException) {
1203 *hasException = (*env)->ExceptionCheck(env);
1204 }
1205 }
1206
1207 JNIEXPORT jvalue JNICALL
JNU_GetStaticFieldByName(JNIEnv * env,jboolean * hasException,const char * classname,const char * name,const char * signature)1208 JNU_GetStaticFieldByName(JNIEnv *env,
1209 jboolean *hasException,
1210 const char *classname,
1211 const char *name,
1212 const char *signature)
1213 {
1214 jclass cls;
1215 jfieldID fid;
1216 jvalue result;
1217
1218 result.i = 0;
1219
1220 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1221 goto done2;
1222
1223 cls = (*env)->FindClass(env, classname);
1224 if (cls == 0)
1225 goto done2;
1226
1227 fid = (*env)->GetStaticFieldID(env, cls, name, signature);
1228 if (fid == 0)
1229 goto done1;
1230
1231 switch (*signature) {
1232 case '[':
1233 case 'L':
1234 result.l = (*env)->GetStaticObjectField(env, cls, fid);
1235 break;
1236 case 'Z':
1237 result.z = (*env)->GetStaticBooleanField(env, cls, fid);
1238 break;
1239 case 'B':
1240 result.b = (*env)->GetStaticByteField(env, cls, fid);
1241 break;
1242 case 'C':
1243 result.c = (*env)->GetStaticCharField(env, cls, fid);
1244 break;
1245 case 'S':
1246 result.s = (*env)->GetStaticShortField(env, cls, fid);
1247 break;
1248 case 'I':
1249 result.i = (*env)->GetStaticIntField(env, cls, fid);
1250 break;
1251 case 'J':
1252 result.j = (*env)->GetStaticLongField(env, cls, fid);
1253 break;
1254 case 'F':
1255 result.f = (*env)->GetStaticFloatField(env, cls, fid);
1256 break;
1257 case 'D':
1258 result.d = (*env)->GetStaticDoubleField(env, cls, fid);
1259 break;
1260
1261 default:
1262 (*env)->FatalError(env, "JNU_GetStaticFieldByName: illegal signature");
1263 }
1264
1265 done1:
1266 (*env)->DeleteLocalRef(env, cls);
1267 done2:
1268 if (hasException) {
1269 *hasException = (*env)->ExceptionCheck(env);
1270 }
1271 return result;
1272 }
1273
1274 JNIEXPORT void JNICALL
JNU_SetStaticFieldByName(JNIEnv * env,jboolean * hasException,const char * classname,const char * name,const char * signature,...)1275 JNU_SetStaticFieldByName(JNIEnv *env,
1276 jboolean *hasException,
1277 const char *classname,
1278 const char *name,
1279 const char *signature,
1280 ...)
1281 {
1282 jclass cls;
1283 jfieldID fid;
1284 va_list args;
1285
1286 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1287 goto done2;
1288
1289 cls = (*env)->FindClass(env, classname);
1290 if (cls == 0)
1291 goto done2;
1292
1293 fid = (*env)->GetStaticFieldID(env, cls, name, signature);
1294 if (fid == 0)
1295 goto done1;
1296
1297 va_start(args, signature);
1298 switch (*signature) {
1299 case '[':
1300 case 'L':
1301 (*env)->SetStaticObjectField(env, cls, fid, va_arg(args, jobject));
1302 break;
1303 case 'Z':
1304 (*env)->SetStaticBooleanField(env, cls, fid, (jboolean)va_arg(args, int));
1305 break;
1306 case 'B':
1307 (*env)->SetStaticByteField(env, cls, fid, (jbyte)va_arg(args, int));
1308 break;
1309 case 'C':
1310 (*env)->SetStaticCharField(env, cls, fid, (jchar)va_arg(args, int));
1311 break;
1312 case 'S':
1313 (*env)->SetStaticShortField(env, cls, fid, (jshort)va_arg(args, int));
1314 break;
1315 case 'I':
1316 (*env)->SetStaticIntField(env, cls, fid, va_arg(args, jint));
1317 break;
1318 case 'J':
1319 (*env)->SetStaticLongField(env, cls, fid, va_arg(args, jlong));
1320 break;
1321 case 'F':
1322 (*env)->SetStaticFloatField(env, cls, fid, (jfloat)va_arg(args, jdouble));
1323 break;
1324 case 'D':
1325 (*env)->SetStaticDoubleField(env, cls, fid, va_arg(args, jdouble));
1326 break;
1327
1328 default:
1329 (*env)->FatalError(env, "JNU_SetStaticFieldByName: illegal signature");
1330 }
1331 va_end(args);
1332
1333 done1:
1334 (*env)->DeleteLocalRef(env, cls);
1335 done2:
1336 if (hasException) {
1337 *hasException = (*env)->ExceptionCheck(env);
1338 }
1339 }
1340