natMethod.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. // natMethod.cc - Native code for Method class.
  2. /* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005, 2006 Free Software Foundation
  3. This file is part of libgcj.
  4. This software is copyrighted work licensed under the terms of the
  5. Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
  6. details. */
  7. #include <config.h>
  8. #include <gcj/cni.h>
  9. #include <jvm.h>
  10. #include <jni.h>
  11. #include <java-stack.h>
  12. #include <java/lang/reflect/Method.h>
  13. #include <java/lang/reflect/Constructor.h>
  14. #include <java/lang/reflect/InvocationTargetException.h>
  15. #include <java/lang/reflect/Modifier.h>
  16. #include <java/lang/Void.h>
  17. #include <java/lang/Byte.h>
  18. #include <java/lang/Boolean.h>
  19. #include <java/lang/Character.h>
  20. #include <java/lang/Short.h>
  21. #include <java/lang/Integer.h>
  22. #include <java/lang/Long.h>
  23. #include <java/lang/Float.h>
  24. #include <java/lang/Double.h>
  25. #include <java/lang/IllegalAccessException.h>
  26. #include <java/lang/IllegalArgumentException.h>
  27. #include <java/lang/IncompatibleClassChangeError.h>
  28. #include <java/lang/NullPointerException.h>
  29. #include <java/lang/ArrayIndexOutOfBoundsException.h>
  30. #include <java/lang/VirtualMachineError.h>
  31. #include <java/lang/Class.h>
  32. #include <gcj/method.h>
  33. #include <gnu/gcj/RawData.h>
  34. #include <java/lang/NoClassDefFoundError.h>
  35. #include <stdlib.h>
  36. #if USE_LIBFFI
  37. #include <ffi.h>
  38. #else
  39. #include <java/lang/UnsupportedOperationException.h>
  40. #endif
  41. typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
  42. typedef JArray< JArray< ::java::lang::annotation::Annotation * > *> * anno_aa_t;
  43. struct cpair
  44. {
  45. jclass prim;
  46. jclass wrap;
  47. };
  48. // This is used to determine when a primitive widening conversion is
  49. // allowed.
  50. static cpair primitives[] =
  51. {
  52. #define BOOLEAN 0
  53. { JvPrimClass (boolean), &java::lang::Boolean::class$ },
  54. { JvPrimClass (byte), &java::lang::Byte::class$ },
  55. #define SHORT 2
  56. { JvPrimClass (short), &java::lang::Short::class$ },
  57. #define CHAR 3
  58. { JvPrimClass (char), &java::lang::Character::class$ },
  59. { JvPrimClass (int), &java::lang::Integer::class$ },
  60. { JvPrimClass (long), &java::lang::Long::class$ },
  61. { JvPrimClass (float), &java::lang::Float::class$ },
  62. { JvPrimClass (double), &java::lang::Double::class$ },
  63. { NULL, NULL }
  64. };
  65. static inline jboolean
  66. can_widen (jclass from, jclass to)
  67. {
  68. int fromx = -1, tox = -1;
  69. for (int i = 0; primitives[i].prim; ++i)
  70. {
  71. if (primitives[i].wrap == from)
  72. fromx = i;
  73. if (primitives[i].prim == to)
  74. tox = i;
  75. }
  76. // Can't handle a miss.
  77. if (fromx == -1 || tox == -1)
  78. return false;
  79. // Boolean arguments may not be widened.
  80. if (fromx == BOOLEAN && tox != BOOLEAN)
  81. return false;
  82. // Nothing promotes to char.
  83. if (tox == CHAR && fromx != CHAR)
  84. return false;
  85. return fromx <= tox;
  86. }
  87. #ifdef USE_LIBFFI
  88. static inline ffi_type *
  89. get_ffi_type (jclass klass)
  90. {
  91. // A special case.
  92. if (klass == NULL)
  93. return &ffi_type_pointer;
  94. ffi_type *r;
  95. if (klass == JvPrimClass (byte))
  96. r = &ffi_type_sint8;
  97. else if (klass == JvPrimClass (short))
  98. r = &ffi_type_sint16;
  99. else if (klass == JvPrimClass (int))
  100. r = &ffi_type_sint32;
  101. else if (klass == JvPrimClass (long))
  102. r = &ffi_type_sint64;
  103. else if (klass == JvPrimClass (float))
  104. r = &ffi_type_float;
  105. else if (klass == JvPrimClass (double))
  106. r = &ffi_type_double;
  107. else if (klass == JvPrimClass (boolean))
  108. {
  109. // On some platforms a bool is a byte, on others an int.
  110. if (sizeof (jboolean) == sizeof (jbyte))
  111. r = &ffi_type_sint8;
  112. else
  113. {
  114. JvAssert (sizeof (jboolean) == sizeof (jint));
  115. r = &ffi_type_sint32;
  116. }
  117. }
  118. else if (klass == JvPrimClass (char))
  119. r = &ffi_type_uint16;
  120. else
  121. {
  122. JvAssert (! klass->isPrimitive());
  123. r = &ffi_type_pointer;
  124. }
  125. return r;
  126. }
  127. #endif // USE_LIBFFI
  128. jobject
  129. java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
  130. {
  131. using namespace java::lang::reflect;
  132. jclass iface = NULL;
  133. if (parameter_types == NULL)
  134. getType ();
  135. jmethodID meth = _Jv_FromReflectedMethod (this);
  136. if (Modifier::isStatic(meth->accflags))
  137. {
  138. // We have to initialize a static class. It is safe to do this
  139. // here and not in _Jv_CallAnyMethodA because JNI initializes a
  140. // class whenever a method lookup is done.
  141. _Jv_InitClass (declaringClass);
  142. }
  143. else
  144. {
  145. jclass objClass = JV_CLASS (obj);
  146. if (! _Jv_IsAssignableFrom (objClass, declaringClass))
  147. throw new java::lang::IllegalArgumentException;
  148. }
  149. // Check accessibility, if required.
  150. if (! this->isAccessible())
  151. {
  152. if (! (Modifier::isPublic (meth->accflags)))
  153. {
  154. Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
  155. if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
  156. throw new IllegalAccessException;
  157. }
  158. else
  159. // Method is public, check to see if class is accessible.
  160. {
  161. jint flags = (declaringClass->accflags
  162. & (Modifier::PUBLIC
  163. | Modifier::PROTECTED
  164. | Modifier::PRIVATE));
  165. if (flags == 0) // i.e. class is package private
  166. {
  167. Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
  168. if (! _Jv_ClassNameSamePackage (caller->name,
  169. declaringClass->name))
  170. throw new IllegalAccessException;
  171. }
  172. }
  173. }
  174. if (declaringClass->isInterface())
  175. iface = declaringClass;
  176. return _Jv_CallAnyMethodA (obj, return_type, meth, false,
  177. parameter_types, args, iface);
  178. }
  179. jint
  180. java::lang::reflect::Method::getModifiersInternal ()
  181. {
  182. return _Jv_FromReflectedMethod (this)->accflags;
  183. }
  184. jstring
  185. java::lang::reflect::Method::getSignature()
  186. {
  187. return declaringClass->getReflectionSignature (this);
  188. }
  189. jobject
  190. java::lang::reflect::Method::getDefaultValue()
  191. {
  192. return declaringClass->getMethodDefaultValue(this);
  193. }
  194. anno_a_t
  195. java::lang::reflect::Method::getDeclaredAnnotationsInternal()
  196. {
  197. return (anno_a_t) declaringClass->getDeclaredAnnotations(this, false);
  198. }
  199. anno_aa_t
  200. java::lang::reflect::Method::getParameterAnnotationsInternal()
  201. {
  202. return (anno_aa_t) declaringClass->getDeclaredAnnotations(this, true);
  203. }
  204. jstring
  205. java::lang::reflect::Method::getName ()
  206. {
  207. if (name == NULL)
  208. name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);
  209. return name;
  210. }
  211. /* Internal method to set return_type and parameter_types fields. */
  212. void
  213. java::lang::reflect::Method::getType ()
  214. {
  215. _Jv_Method *method = _Jv_FromReflectedMethod (this);
  216. _Jv_GetTypesFromSignature (method,
  217. declaringClass,
  218. &parameter_types,
  219. &return_type);
  220. int count = 0;
  221. if (method->throws != NULL)
  222. {
  223. while (method->throws[count] != NULL)
  224. ++count;
  225. }
  226. exception_types
  227. = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
  228. NULL);
  229. jclass *elts = elements (exception_types);
  230. for (int i = 0; i < count; ++i)
  231. elts[i] = _Jv_FindClass (method->throws[i],
  232. declaringClass->getClassLoaderInternal ());
  233. }
  234. void
  235. _Jv_GetTypesFromSignature (jmethodID method,
  236. jclass declaringClass,
  237. JArray<jclass> **arg_types_out,
  238. jclass *return_type_out)
  239. {
  240. _Jv_Utf8Const* sig = method->signature;
  241. java::lang::ClassLoader *loader = declaringClass->getClassLoaderInternal();
  242. char *ptr = sig->chars();
  243. int numArgs = 0;
  244. /* First just count the number of parameters. */
  245. // FIXME: should do some validation here, e.g., that there is only
  246. // one return type.
  247. for (; ; ptr++)
  248. {
  249. switch (*ptr)
  250. {
  251. case 0:
  252. case ')':
  253. case 'V':
  254. break;
  255. case '[':
  256. case '(':
  257. continue;
  258. case 'B':
  259. case 'C':
  260. case 'D':
  261. case 'F':
  262. case 'S':
  263. case 'I':
  264. case 'J':
  265. case 'Z':
  266. numArgs++;
  267. continue;
  268. case 'L':
  269. numArgs++;
  270. do
  271. ptr++;
  272. while (*ptr != ';' && ptr[1] != '\0');
  273. continue;
  274. }
  275. break;
  276. }
  277. JArray<jclass> *args = (JArray<jclass> *)
  278. JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL);
  279. jclass* argPtr = elements (args);
  280. for (ptr = sig->chars(); *ptr != '\0'; ptr++)
  281. {
  282. if (*ptr == '(')
  283. continue;
  284. if (*ptr == ')')
  285. {
  286. argPtr = return_type_out;
  287. continue;
  288. }
  289. char *end_ptr;
  290. jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);
  291. if (type == NULL)
  292. // FIXME: This isn't ideal.
  293. throw new java::lang::NoClassDefFoundError (sig->toString());
  294. // ARGPTR can be NULL if we are processing the return value of a
  295. // call from Constructor.
  296. if (argPtr)
  297. *argPtr++ = type;
  298. ptr = end_ptr;
  299. }
  300. *arg_types_out = args;
  301. }
  302. // This is a very rough analog of the JNI CallNonvirtual<type>MethodA
  303. // functions. It handles both Methods and Constructors, and it can
  304. // handle any return type. In the Constructor case, the `obj'
  305. // argument is unused and should be NULL; also, the `return_type' is
  306. // the class that the constructor will construct. RESULT is a pointer
  307. // to a `jvalue' (see jni.h); for a void method this should be NULL.
  308. // This function returns an exception (if one was thrown), or NULL if
  309. // the call went ok.
  310. void
  311. _Jv_CallAnyMethodA (jobject obj,
  312. jclass return_type,
  313. jmethodID meth,
  314. jboolean is_constructor,
  315. jboolean is_virtual_call,
  316. JArray<jclass> *parameter_types,
  317. const jvalue *args,
  318. jvalue *result,
  319. jboolean is_jni_call,
  320. jclass iface)
  321. {
  322. using namespace java::lang::reflect;
  323. #ifdef USE_LIBFFI
  324. JvAssert (! is_constructor || ! obj);
  325. JvAssert (! is_constructor || return_type);
  326. // See whether call needs an object as the first argument. A
  327. // constructor does need a `this' argument, but it is one we create.
  328. jboolean needs_this = false;
  329. if (is_constructor
  330. || ! Modifier::isStatic(meth->accflags))
  331. needs_this = true;
  332. int param_count = parameter_types->length;
  333. if (needs_this)
  334. ++param_count;
  335. ffi_type *rtype;
  336. // A constructor itself always returns void.
  337. if (is_constructor || return_type == JvPrimClass (void))
  338. rtype = &ffi_type_void;
  339. else
  340. rtype = get_ffi_type (return_type);
  341. ffi_type **argtypes = (ffi_type **) __builtin_alloca (param_count
  342. * sizeof (ffi_type *));
  343. jclass *paramelts = elements (parameter_types);
  344. // Special case for the `this' argument of a constructor. Note that
  345. // the JDK 1.2 docs specify that the new object must be allocated
  346. // before argument conversions are done.
  347. if (is_constructor)
  348. obj = _Jv_AllocObject (return_type);
  349. const int size_per_arg = sizeof(jvalue);
  350. ffi_cif cif;
  351. char *p = (char *) __builtin_alloca (param_count * size_per_arg);
  352. // Overallocate to get correct alignment.
  353. void **values = (void **)
  354. __builtin_alloca (param_count * sizeof (void *));
  355. int i = 0;
  356. if (needs_this)
  357. {
  358. // The `NULL' type is `Object'.
  359. argtypes[i] = get_ffi_type (NULL);
  360. values[i] = p;
  361. memcpy (p, &obj, sizeof (jobject));
  362. p += size_per_arg;
  363. ++i;
  364. }
  365. for (int arg = 0; i < param_count; ++i, ++arg)
  366. {
  367. int tsize;
  368. argtypes[i] = get_ffi_type (paramelts[arg]);
  369. if (paramelts[arg]->isPrimitive())
  370. tsize = paramelts[arg]->size();
  371. else
  372. tsize = sizeof (jobject);
  373. // Copy appropriate bits from the jvalue into the ffi array.
  374. // FIXME: we could do this copying all in one loop, above, by
  375. // over-allocating a bit.
  376. // How do we do this without breaking big-endian platforms?
  377. values[i] = p;
  378. memcpy (p, &args[arg], tsize);
  379. p += size_per_arg;
  380. }
  381. ffi_abi cabi = FFI_DEFAULT_ABI;
  382. #if defined (X86_WIN32) && !defined (__CYGWIN__)
  383. if (needs_this)
  384. cabi = FFI_THISCALL;
  385. #endif
  386. if (ffi_prep_cif (&cif, cabi, param_count,
  387. rtype, argtypes) != FFI_OK)
  388. throw new java::lang::VirtualMachineError(JvNewStringLatin1("internal error: ffi_prep_cif failed"));
  389. using namespace java::lang;
  390. using namespace java::lang::reflect;
  391. union
  392. {
  393. ffi_arg i;
  394. jobject o;
  395. jlong l;
  396. jfloat f;
  397. jdouble d;
  398. } ffi_result;
  399. switch (rtype->type)
  400. {
  401. case FFI_TYPE_VOID:
  402. break;
  403. case FFI_TYPE_SINT8:
  404. result->b = 0;
  405. break;
  406. case FFI_TYPE_SINT16:
  407. result->s = 0;
  408. break;
  409. case FFI_TYPE_UINT16:
  410. result->c = 0;
  411. break;
  412. case FFI_TYPE_SINT32:
  413. result->i = 0;
  414. break;
  415. case FFI_TYPE_SINT64:
  416. result->j = 0;
  417. break;
  418. case FFI_TYPE_FLOAT:
  419. result->f = 0;
  420. break;
  421. case FFI_TYPE_DOUBLE:
  422. result->d = 0;
  423. break;
  424. case FFI_TYPE_POINTER:
  425. result->l = 0;
  426. break;
  427. default:
  428. JvFail ("Unknown ffi_call return type");
  429. break;
  430. }
  431. void *ncode;
  432. // FIXME: If a vtable index is -1 at this point it is invalid, so we
  433. // have to use the ncode.
  434. //
  435. // This can happen because methods in final classes don't have
  436. // vtable entries, but _Jv_isVirtualMethod() doesn't know that. We
  437. // could solve this problem by allocating a vtable index for methods
  438. // in final classes.
  439. if (is_virtual_call
  440. && ! Modifier::isFinal (meth->accflags)
  441. && (_Jv_ushort)-1 != meth->index)
  442. {
  443. _Jv_VTable *vtable = *(_Jv_VTable **) obj;
  444. if (iface == NULL)
  445. {
  446. if (is_jni_call && Modifier::isAbstract (meth->accflags))
  447. {
  448. // With JNI we don't know if this is an interface call
  449. // or a call to an abstract method. Look up the method
  450. // by name, the slow way.
  451. _Jv_Method *concrete_meth
  452. = _Jv_LookupDeclaredMethod (vtable->clas,
  453. meth->name,
  454. meth->signature,
  455. NULL);
  456. if (concrete_meth == NULL
  457. || concrete_meth->ncode == NULL
  458. || Modifier::isAbstract(concrete_meth->accflags))
  459. throw new java::lang::IncompatibleClassChangeError
  460. (_Jv_GetMethodString (vtable->clas, meth));
  461. ncode = concrete_meth->ncode;
  462. }
  463. else
  464. ncode = vtable->get_method (meth->index);
  465. }
  466. else
  467. ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface,
  468. meth->index);
  469. }
  470. else
  471. {
  472. ncode = meth->ncode;
  473. }
  474. try
  475. {
  476. ffi_call (&cif, (void (*)()) ncode, &ffi_result, values);
  477. }
  478. catch (Throwable *ex)
  479. {
  480. // For JNI we just throw the real error. For reflection, we
  481. // wrap the underlying method's exception in an
  482. // InvocationTargetException.
  483. if (! is_jni_call)
  484. ex = new InvocationTargetException (ex);
  485. throw ex;
  486. }
  487. // Since ffi_call returns integer values promoted to a word, use
  488. // a narrowing conversion for jbyte, jchar, etc. results.
  489. // Note that boolean is handled either by the FFI_TYPE_SINT8 or
  490. // FFI_TYPE_SINT32 case.
  491. if (is_constructor)
  492. result->l = obj;
  493. else
  494. {
  495. switch (rtype->type)
  496. {
  497. case FFI_TYPE_VOID:
  498. break;
  499. case FFI_TYPE_SINT8:
  500. result->b = (jbyte)ffi_result.i;
  501. break;
  502. case FFI_TYPE_SINT16:
  503. result->s = (jshort)ffi_result.i;
  504. break;
  505. case FFI_TYPE_UINT16:
  506. result->c = (jchar)ffi_result.i;
  507. break;
  508. case FFI_TYPE_SINT32:
  509. result->i = (jint)ffi_result.i;
  510. break;
  511. case FFI_TYPE_SINT64:
  512. result->j = (jlong)ffi_result.l;
  513. break;
  514. case FFI_TYPE_FLOAT:
  515. result->f = (jfloat)ffi_result.f;
  516. break;
  517. case FFI_TYPE_DOUBLE:
  518. result->d = (jdouble)ffi_result.d;
  519. break;
  520. case FFI_TYPE_POINTER:
  521. result->l = (jobject)ffi_result.o;
  522. break;
  523. default:
  524. JvFail ("Unknown ffi_call return type");
  525. break;
  526. }
  527. }
  528. #else
  529. throw new java::lang::UnsupportedOperationException(JvNewStringLatin1("reflection not available in this build"));
  530. #endif // USE_LIBFFI
  531. }
  532. // This is another version of _Jv_CallAnyMethodA, but this one does
  533. // more checking and is used by the reflection (and not JNI) code.
  534. jobject
  535. _Jv_CallAnyMethodA (jobject obj,
  536. jclass return_type,
  537. jmethodID meth,
  538. jboolean is_constructor,
  539. JArray<jclass> *parameter_types,
  540. jobjectArray args,
  541. jclass iface)
  542. {
  543. if (parameter_types->length == 0 && args == NULL)
  544. {
  545. // The JDK accepts this, so we do too.
  546. }
  547. else if (parameter_types->length != args->length)
  548. throw new java::lang::IllegalArgumentException;
  549. int param_count = parameter_types->length;
  550. jclass *paramelts = elements (parameter_types);
  551. jobject *argelts = args == NULL ? NULL : elements (args);
  552. jvalue argvals[param_count];
  553. #define COPY(Where, What, Type) \
  554. do { \
  555. Type val = (What); \
  556. memcpy ((Where), &val, sizeof (Type)); \
  557. } while (0)
  558. for (int i = 0; i < param_count; ++i)
  559. {
  560. jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
  561. if (paramelts[i]->isPrimitive())
  562. {
  563. if (! argelts[i]
  564. || ! k
  565. || ! can_widen (k, paramelts[i]))
  566. throw new java::lang::IllegalArgumentException;
  567. if (paramelts[i] == JvPrimClass (boolean))
  568. COPY (&argvals[i],
  569. ((java::lang::Boolean *) argelts[i])->booleanValue(),
  570. jboolean);
  571. else if (paramelts[i] == JvPrimClass (char))
  572. COPY (&argvals[i],
  573. ((java::lang::Character *) argelts[i])->charValue(),
  574. jchar);
  575. else
  576. {
  577. java::lang::Number *num = (java::lang::Number *) argelts[i];
  578. if (paramelts[i] == JvPrimClass (byte))
  579. COPY (&argvals[i], num->byteValue(), jbyte);
  580. else if (paramelts[i] == JvPrimClass (short))
  581. COPY (&argvals[i], num->shortValue(), jshort);
  582. else if (paramelts[i] == JvPrimClass (int))
  583. COPY (&argvals[i], num->intValue(), jint);
  584. else if (paramelts[i] == JvPrimClass (long))
  585. COPY (&argvals[i], num->longValue(), jlong);
  586. else if (paramelts[i] == JvPrimClass (float))
  587. COPY (&argvals[i], num->floatValue(), jfloat);
  588. else if (paramelts[i] == JvPrimClass (double))
  589. COPY (&argvals[i], num->doubleValue(), jdouble);
  590. }
  591. }
  592. else
  593. {
  594. if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
  595. throw new java::lang::IllegalArgumentException;
  596. COPY (&argvals[i], argelts[i], jobject);
  597. }
  598. }
  599. jvalue ret_value;
  600. _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
  601. _Jv_isVirtualMethod (meth),
  602. parameter_types, argvals, &ret_value,
  603. false, iface);
  604. jobject r;
  605. #define VAL(Wrapper, Field) (new Wrapper (ret_value.Field))
  606. if (is_constructor)
  607. r = ret_value.l;
  608. else if (return_type == JvPrimClass (byte))
  609. r = VAL (java::lang::Byte, b);
  610. else if (return_type == JvPrimClass (short))
  611. r = VAL (java::lang::Short, s);
  612. else if (return_type == JvPrimClass (int))
  613. r = VAL (java::lang::Integer, i);
  614. else if (return_type == JvPrimClass (long))
  615. r = VAL (java::lang::Long, j);
  616. else if (return_type == JvPrimClass (float))
  617. r = VAL (java::lang::Float, f);
  618. else if (return_type == JvPrimClass (double))
  619. r = VAL (java::lang::Double, d);
  620. else if (return_type == JvPrimClass (boolean))
  621. r = VAL (java::lang::Boolean, z);
  622. else if (return_type == JvPrimClass (char))
  623. r = VAL (java::lang::Character, c);
  624. else if (return_type == JvPrimClass (void))
  625. r = NULL;
  626. else
  627. {
  628. JvAssert (return_type == NULL || ! return_type->isPrimitive());
  629. r = ret_value.l;
  630. }
  631. return r;
  632. }