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 extern int canonicalize(char *path, const char *out, int len);
843
844 JNIEXPORT int
Canonicalize(JNIEnv * env,char * orig,char * out,int len)845 Canonicalize(JNIEnv *env, char *orig, char *out, int len)
846 {
847 /* canonicalize an already natived path */
848 return canonicalize(orig, out, len);
849 }
850
851 JNIEXPORT jclass JNICALL
JNU_ClassString(JNIEnv * env)852 JNU_ClassString(JNIEnv *env)
853 {
854 static jclass cls = 0;
855 if (cls == 0) {
856 jclass c;
857 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
858 return 0;
859 c = (*env)->FindClass(env, "java/lang/String");
860 cls = (*env)->NewGlobalRef(env, c);
861 (*env)->DeleteLocalRef(env, c);
862 }
863 return cls;
864 }
865
866 JNIEXPORT jclass JNICALL
JNU_ClassClass(JNIEnv * env)867 JNU_ClassClass(JNIEnv *env)
868 {
869 static jclass cls = 0;
870 if (cls == 0) {
871 jclass c;
872 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
873 return 0;
874 c = (*env)->FindClass(env, "java/lang/Class");
875 cls = (*env)->NewGlobalRef(env, c);
876 (*env)->DeleteLocalRef(env, c);
877 }
878 return cls;
879 }
880
881 JNIEXPORT jclass JNICALL
JNU_ClassObject(JNIEnv * env)882 JNU_ClassObject(JNIEnv *env)
883 {
884 static jclass cls = 0;
885 if (cls == 0) {
886 jclass c;
887 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
888 return 0;
889 c = (*env)->FindClass(env, "java/lang/Object");
890 cls = (*env)->NewGlobalRef(env, c);
891 (*env)->DeleteLocalRef(env, c);
892 }
893 return cls;
894 }
895
896 JNIEXPORT jclass JNICALL
JNU_ClassThrowable(JNIEnv * env)897 JNU_ClassThrowable(JNIEnv *env)
898 {
899 static jclass cls = 0;
900 if (cls == 0) {
901 jclass c;
902 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
903 return 0;
904 c = (*env)->FindClass(env, "java/lang/Throwable");
905 cls = (*env)->NewGlobalRef(env, c);
906 (*env)->DeleteLocalRef(env, c);
907 }
908 return cls;
909 }
910
911 JNIEXPORT jint JNICALL
JNU_CopyObjectArray(JNIEnv * env,jobjectArray dst,jobjectArray src,jint count)912 JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
913 jint count)
914 {
915 int i;
916 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
917 return -1;
918 for (i=0; i<count; i++) {
919 jstring p = (*env)->GetObjectArrayElement(env, src, i);
920 (*env)->SetObjectArrayElement(env, dst, i, p);
921 (*env)->DeleteLocalRef(env, p);
922 }
923 return 0;
924 }
925
926 JNIEXPORT void * JNICALL
JNU_GetEnv(JavaVM * vm,jint version)927 JNU_GetEnv(JavaVM *vm, jint version)
928 {
929 void *env;
930 (*vm)->GetEnv(vm, &env, version);
931 return env;
932 }
933
934 JNIEXPORT jint JNICALL
JNU_IsInstanceOfByName(JNIEnv * env,jobject object,char * classname)935 JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char* classname)
936 {
937 jclass cls;
938 if ((*env)->EnsureLocalCapacity(env, 1) < 0)
939 return JNI_ERR;
940 cls = (*env)->FindClass(env, classname);
941 if (cls != NULL) {
942 jint result = (*env)->IsInstanceOf(env, object, cls);
943 (*env)->DeleteLocalRef(env, cls);
944 return result;
945 }
946 return JNI_ERR;
947 }
948
949 JNIEXPORT jboolean JNICALL
JNU_Equals(JNIEnv * env,jobject object1,jobject object2)950 JNU_Equals(JNIEnv *env, jobject object1, jobject object2)
951 {
952 static jmethodID mid = NULL;
953 if (mid == NULL) {
954 mid = (*env)->GetMethodID(env, JNU_ClassObject(env), "equals",
955 "(Ljava/lang/Object;)Z");
956 }
957 return (*env)->CallBooleanMethod(env, object1, mid, object2);
958 }
959
960
961 /************************************************************************
962 * Thread calls
963 */
964
965 static jmethodID Object_waitMID;
966 static jmethodID Object_notifyMID;
967 static jmethodID Object_notifyAllMID;
968
969 JNIEXPORT void JNICALL
JNU_MonitorWait(JNIEnv * env,jobject object,jlong timeout)970 JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout)
971 {
972 if (object == NULL) {
973 JNU_ThrowNullPointerException(env, "JNU_MonitorWait argument");
974 return;
975 }
976 if (Object_waitMID == NULL) {
977 jclass cls = JNU_ClassObject(env);
978 if (cls == NULL) {
979 return;
980 }
981 Object_waitMID = (*env)->GetMethodID(env, cls, "wait", "(J)V");
982 if (Object_waitMID == NULL) {
983 return;
984 }
985 }
986 (*env)->CallVoidMethod(env, object, Object_waitMID, timeout);
987 }
988
989 JNIEXPORT void JNICALL
JNU_Notify(JNIEnv * env,jobject object)990 JNU_Notify(JNIEnv *env, jobject object)
991 {
992 if (object == NULL) {
993 JNU_ThrowNullPointerException(env, "JNU_Notify argument");
994 return;
995 }
996 if (Object_notifyMID == NULL) {
997 jclass cls = JNU_ClassObject(env);
998 if (cls == NULL) {
999 return;
1000 }
1001 Object_notifyMID = (*env)->GetMethodID(env, cls, "notify", "()V");
1002 if (Object_notifyMID == NULL) {
1003 return;
1004 }
1005 }
1006 (*env)->CallVoidMethod(env, object, Object_notifyMID);
1007 }
1008
1009 JNIEXPORT void JNICALL
JNU_NotifyAll(JNIEnv * env,jobject object)1010 JNU_NotifyAll(JNIEnv *env, jobject object)
1011 {
1012 if (object == NULL) {
1013 JNU_ThrowNullPointerException(env, "JNU_NotifyAll argument");
1014 return;
1015 }
1016 if (Object_notifyAllMID == NULL) {
1017 jclass cls = JNU_ClassObject(env);
1018 if (cls == NULL) {
1019 return;
1020 }
1021 Object_notifyAllMID = (*env)->GetMethodID(env, cls,"notifyAll", "()V");
1022 if (Object_notifyAllMID == NULL) {
1023 return;
1024 }
1025 }
1026 (*env)->CallVoidMethod(env, object, Object_notifyAllMID);
1027 }
1028
1029
1030 /************************************************************************
1031 * Debugging utilities
1032 */
1033
1034 JNIEXPORT void JNICALL
JNU_PrintString(JNIEnv * env,char * hdr,jstring string)1035 JNU_PrintString(JNIEnv *env, char *hdr, jstring string)
1036 {
1037 if (string == NULL) {
1038 fprintf(stderr, "%s: is NULL\n", hdr);
1039 } else {
1040 const char *stringPtr = JNU_GetStringPlatformChars(env, string, 0);
1041 if (stringPtr == 0)
1042 return;
1043 fprintf(stderr, "%s: %s\n", hdr, stringPtr);
1044 JNU_ReleaseStringPlatformChars(env, string, stringPtr);
1045 }
1046 }
1047
1048 JNIEXPORT void JNICALL
JNU_PrintClass(JNIEnv * env,char * hdr,jobject object)1049 JNU_PrintClass(JNIEnv *env, char* hdr, jobject object)
1050 {
1051 if (object == NULL) {
1052 fprintf(stderr, "%s: object is NULL\n", hdr);
1053 return;
1054 } else {
1055 jclass cls = (*env)->GetObjectClass(env, object);
1056 jstring clsName = JNU_ToString(env, cls);
1057 JNU_PrintString(env, hdr, clsName);
1058 (*env)->DeleteLocalRef(env, cls);
1059 (*env)->DeleteLocalRef(env, clsName);
1060 }
1061 }
1062
1063 JNIEXPORT jstring JNICALL
JNU_ToString(JNIEnv * env,jobject object)1064 JNU_ToString(JNIEnv *env, jobject object)
1065 {
1066 if (object == NULL) {
1067 return (*env)->NewStringUTF(env, "NULL");
1068 } else {
1069 return (jstring)JNU_CallMethodByName(env,
1070 NULL,
1071 object,
1072 "toString",
1073 "()Ljava/lang/String;").l;
1074 }
1075 }
1076
1077 JNIEXPORT jvalue JNICALL
JNU_GetFieldByName(JNIEnv * env,jboolean * hasException,jobject obj,const char * name,const char * signature)1078 JNU_GetFieldByName(JNIEnv *env,
1079 jboolean *hasException,
1080 jobject obj,
1081 const char *name,
1082 const char *signature)
1083 {
1084 jclass cls;
1085 jfieldID fid;
1086 jvalue result;
1087
1088 result.i = 0;
1089
1090 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1091 goto done2;
1092
1093 cls = (*env)->GetObjectClass(env, obj);
1094 fid = (*env)->GetFieldID(env, cls, name, signature);
1095 if (fid == 0)
1096 goto done1;
1097
1098 switch (*signature) {
1099 case '[':
1100 case 'L':
1101 result.l = (*env)->GetObjectField(env, obj, fid);
1102 break;
1103 case 'Z':
1104 result.z = (*env)->GetBooleanField(env, obj, fid);
1105 break;
1106 case 'B':
1107 result.b = (*env)->GetByteField(env, obj, fid);
1108 break;
1109 case 'C':
1110 result.c = (*env)->GetCharField(env, obj, fid);
1111 break;
1112 case 'S':
1113 result.s = (*env)->GetShortField(env, obj, fid);
1114 break;
1115 case 'I':
1116 result.i = (*env)->GetIntField(env, obj, fid);
1117 break;
1118 case 'J':
1119 result.j = (*env)->GetLongField(env, obj, fid);
1120 break;
1121 case 'F':
1122 result.f = (*env)->GetFloatField(env, obj, fid);
1123 break;
1124 case 'D':
1125 result.d = (*env)->GetDoubleField(env, obj, fid);
1126 break;
1127
1128 default:
1129 (*env)->FatalError(env, "JNU_GetFieldByName: illegal signature");
1130 }
1131
1132 done1:
1133 (*env)->DeleteLocalRef(env, cls);
1134 done2:
1135 if (hasException) {
1136 *hasException = (*env)->ExceptionCheck(env);
1137 }
1138 return result;
1139 }
1140
1141 JNIEXPORT void JNICALL
JNU_SetFieldByName(JNIEnv * env,jboolean * hasException,jobject obj,const char * name,const char * signature,...)1142 JNU_SetFieldByName(JNIEnv *env,
1143 jboolean *hasException,
1144 jobject obj,
1145 const char *name,
1146 const char *signature,
1147 ...)
1148 {
1149 jclass cls;
1150 jfieldID fid;
1151 va_list args;
1152
1153 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1154 goto done2;
1155
1156 cls = (*env)->GetObjectClass(env, obj);
1157 fid = (*env)->GetFieldID(env, cls, name, signature);
1158 if (fid == 0)
1159 goto done1;
1160
1161 va_start(args, signature);
1162 switch (*signature) {
1163 case '[':
1164 case 'L':
1165 (*env)->SetObjectField(env, obj, fid, va_arg(args, jobject));
1166 break;
1167 case 'Z':
1168 (*env)->SetBooleanField(env, obj, fid, (jboolean)va_arg(args, int));
1169 break;
1170 case 'B':
1171 (*env)->SetByteField(env, obj, fid, (jbyte)va_arg(args, int));
1172 break;
1173 case 'C':
1174 (*env)->SetCharField(env, obj, fid, (jchar)va_arg(args, int));
1175 break;
1176 case 'S':
1177 (*env)->SetShortField(env, obj, fid, (jshort)va_arg(args, int));
1178 break;
1179 case 'I':
1180 (*env)->SetIntField(env, obj, fid, va_arg(args, jint));
1181 break;
1182 case 'J':
1183 (*env)->SetLongField(env, obj, fid, va_arg(args, jlong));
1184 break;
1185 case 'F':
1186 (*env)->SetFloatField(env, obj, fid, (jfloat)va_arg(args, jdouble));
1187 break;
1188 case 'D':
1189 (*env)->SetDoubleField(env, obj, fid, va_arg(args, jdouble));
1190 break;
1191
1192 default:
1193 (*env)->FatalError(env, "JNU_SetFieldByName: illegal signature");
1194 }
1195 va_end(args);
1196
1197 done1:
1198 (*env)->DeleteLocalRef(env, cls);
1199 done2:
1200 if (hasException) {
1201 *hasException = (*env)->ExceptionCheck(env);
1202 }
1203 }
1204
1205 JNIEXPORT jvalue JNICALL
JNU_GetStaticFieldByName(JNIEnv * env,jboolean * hasException,const char * classname,const char * name,const char * signature)1206 JNU_GetStaticFieldByName(JNIEnv *env,
1207 jboolean *hasException,
1208 const char *classname,
1209 const char *name,
1210 const char *signature)
1211 {
1212 jclass cls;
1213 jfieldID fid;
1214 jvalue result;
1215
1216 result.i = 0;
1217
1218 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1219 goto done2;
1220
1221 cls = (*env)->FindClass(env, classname);
1222 if (cls == 0)
1223 goto done2;
1224
1225 fid = (*env)->GetStaticFieldID(env, cls, name, signature);
1226 if (fid == 0)
1227 goto done1;
1228
1229 switch (*signature) {
1230 case '[':
1231 case 'L':
1232 result.l = (*env)->GetStaticObjectField(env, cls, fid);
1233 break;
1234 case 'Z':
1235 result.z = (*env)->GetStaticBooleanField(env, cls, fid);
1236 break;
1237 case 'B':
1238 result.b = (*env)->GetStaticByteField(env, cls, fid);
1239 break;
1240 case 'C':
1241 result.c = (*env)->GetStaticCharField(env, cls, fid);
1242 break;
1243 case 'S':
1244 result.s = (*env)->GetStaticShortField(env, cls, fid);
1245 break;
1246 case 'I':
1247 result.i = (*env)->GetStaticIntField(env, cls, fid);
1248 break;
1249 case 'J':
1250 result.j = (*env)->GetStaticLongField(env, cls, fid);
1251 break;
1252 case 'F':
1253 result.f = (*env)->GetStaticFloatField(env, cls, fid);
1254 break;
1255 case 'D':
1256 result.d = (*env)->GetStaticDoubleField(env, cls, fid);
1257 break;
1258
1259 default:
1260 (*env)->FatalError(env, "JNU_GetStaticFieldByName: illegal signature");
1261 }
1262
1263 done1:
1264 (*env)->DeleteLocalRef(env, cls);
1265 done2:
1266 if (hasException) {
1267 *hasException = (*env)->ExceptionCheck(env);
1268 }
1269 return result;
1270 }
1271
1272 JNIEXPORT void JNICALL
JNU_SetStaticFieldByName(JNIEnv * env,jboolean * hasException,const char * classname,const char * name,const char * signature,...)1273 JNU_SetStaticFieldByName(JNIEnv *env,
1274 jboolean *hasException,
1275 const char *classname,
1276 const char *name,
1277 const char *signature,
1278 ...)
1279 {
1280 jclass cls;
1281 jfieldID fid;
1282 va_list args;
1283
1284 if ((*env)->EnsureLocalCapacity(env, 3) < 0)
1285 goto done2;
1286
1287 cls = (*env)->FindClass(env, classname);
1288 if (cls == 0)
1289 goto done2;
1290
1291 fid = (*env)->GetStaticFieldID(env, cls, name, signature);
1292 if (fid == 0)
1293 goto done1;
1294
1295 va_start(args, signature);
1296 switch (*signature) {
1297 case '[':
1298 case 'L':
1299 (*env)->SetStaticObjectField(env, cls, fid, va_arg(args, jobject));
1300 break;
1301 case 'Z':
1302 (*env)->SetStaticBooleanField(env, cls, fid, (jboolean)va_arg(args, int));
1303 break;
1304 case 'B':
1305 (*env)->SetStaticByteField(env, cls, fid, (jbyte)va_arg(args, int));
1306 break;
1307 case 'C':
1308 (*env)->SetStaticCharField(env, cls, fid, (jchar)va_arg(args, int));
1309 break;
1310 case 'S':
1311 (*env)->SetStaticShortField(env, cls, fid, (jshort)va_arg(args, int));
1312 break;
1313 case 'I':
1314 (*env)->SetStaticIntField(env, cls, fid, va_arg(args, jint));
1315 break;
1316 case 'J':
1317 (*env)->SetStaticLongField(env, cls, fid, va_arg(args, jlong));
1318 break;
1319 case 'F':
1320 (*env)->SetStaticFloatField(env, cls, fid, (jfloat)va_arg(args, jdouble));
1321 break;
1322 case 'D':
1323 (*env)->SetStaticDoubleField(env, cls, fid, va_arg(args, jdouble));
1324 break;
1325
1326 default:
1327 (*env)->FatalError(env, "JNU_SetStaticFieldByName: illegal signature");
1328 }
1329 va_end(args);
1330
1331 done1:
1332 (*env)->DeleteLocalRef(env, cls);
1333 done2:
1334 if (hasException) {
1335 *hasException = (*env)->ExceptionCheck(env);
1336 }
1337 }
1338