jni.cc 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905
  1. // jni.cc - JNI implementation, including the jump table.
  2. /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
  3. Free Software Foundation
  4. This file is part of libgcj.
  5. This software is copyrighted work licensed under the terms of the
  6. Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
  7. details. */
  8. #include <config.h>
  9. #include <stdio.h>
  10. #include <stddef.h>
  11. #include <string.h>
  12. #include <gcj/cni.h>
  13. #include <jvm.h>
  14. #include <java-assert.h>
  15. #include <jni.h>
  16. #ifdef ENABLE_JVMPI
  17. #include <jvmpi.h>
  18. #endif
  19. #ifdef INTERPRETER
  20. #include <jvmti.h>
  21. #include "jvmti-int.h"
  22. #endif
  23. #include <java/lang/Class.h>
  24. #include <java/lang/ClassLoader.h>
  25. #include <java/lang/Throwable.h>
  26. #include <java/lang/ArrayIndexOutOfBoundsException.h>
  27. #include <java/lang/StringIndexOutOfBoundsException.h>
  28. #include <java/lang/StringBuffer.h>
  29. #include <java/lang/UnsatisfiedLinkError.h>
  30. #include <java/lang/InstantiationException.h>
  31. #include <java/lang/NoSuchFieldError.h>
  32. #include <java/lang/NoSuchMethodError.h>
  33. #include <java/lang/reflect/Constructor.h>
  34. #include <java/lang/reflect/Method.h>
  35. #include <java/lang/reflect/Modifier.h>
  36. #include <java/lang/OutOfMemoryError.h>
  37. #include <java/lang/Integer.h>
  38. #include <java/lang/ThreadGroup.h>
  39. #include <java/lang/Thread.h>
  40. #include <java/lang/IllegalAccessError.h>
  41. #include <java/nio/Buffer.h>
  42. #include <java/nio/DirectByteBufferImpl.h>
  43. #include <java/nio/DirectByteBufferImpl$ReadWrite.h>
  44. #include <java/util/IdentityHashMap.h>
  45. #include <gnu/gcj/RawData.h>
  46. #include <java/lang/ClassNotFoundException.h>
  47. #include <gcj/method.h>
  48. #include <gcj/field.h>
  49. #include <java-interp.h>
  50. #include <java-threads.h>
  51. using namespace gcj;
  52. // This enum is used to select different template instantiations in
  53. // the invocation code.
  54. enum invocation_type
  55. {
  56. normal,
  57. nonvirtual,
  58. static_type,
  59. constructor
  60. };
  61. // Forward declarations.
  62. extern struct JNINativeInterface_ _Jv_JNIFunctions;
  63. extern struct JNIInvokeInterface_ _Jv_JNI_InvokeFunctions;
  64. // Number of slots in the default frame. The VM must allow at least
  65. // 16.
  66. #define FRAME_SIZE 16
  67. // Mark value indicating this is an overflow frame.
  68. #define MARK_NONE 0
  69. // Mark value indicating this is a user frame.
  70. #define MARK_USER 1
  71. // Mark value indicating this is a system frame.
  72. #define MARK_SYSTEM 2
  73. // This structure is used to keep track of local references.
  74. struct _Jv_JNI_LocalFrame
  75. {
  76. // This is one of the MARK_ constants.
  77. unsigned char marker;
  78. // Flag to indicate some locals were allocated.
  79. bool allocated_p;
  80. // Number of elements in frame.
  81. int size;
  82. // The class loader of the JNI method that allocated this frame.
  83. ::java::lang::ClassLoader *loader;
  84. // Next frame in chain.
  85. _Jv_JNI_LocalFrame *next;
  86. // The elements. These are allocated using the C "struct hack".
  87. jobject vec[0];
  88. };
  89. // This holds a reference count for all local references.
  90. static java::util::IdentityHashMap *local_ref_table;
  91. // This holds a reference count for all global references.
  92. static java::util::IdentityHashMap *global_ref_table;
  93. // The only VM.
  94. JavaVM *_Jv_the_vm;
  95. #ifdef ENABLE_JVMPI
  96. // The only JVMPI interface description.
  97. static JVMPI_Interface _Jv_JVMPI_Interface;
  98. static jint
  99. jvmpiEnableEvent (jint event_type, void *)
  100. {
  101. switch (event_type)
  102. {
  103. case JVMPI_EVENT_OBJECT_ALLOC:
  104. _Jv_JVMPI_Notify_OBJECT_ALLOC = _Jv_JVMPI_Interface.NotifyEvent;
  105. break;
  106. case JVMPI_EVENT_THREAD_START:
  107. _Jv_JVMPI_Notify_THREAD_START = _Jv_JVMPI_Interface.NotifyEvent;
  108. break;
  109. case JVMPI_EVENT_THREAD_END:
  110. _Jv_JVMPI_Notify_THREAD_END = _Jv_JVMPI_Interface.NotifyEvent;
  111. break;
  112. default:
  113. return JVMPI_NOT_AVAILABLE;
  114. }
  115. return JVMPI_SUCCESS;
  116. }
  117. static jint
  118. jvmpiDisableEvent (jint event_type, void *)
  119. {
  120. switch (event_type)
  121. {
  122. case JVMPI_EVENT_OBJECT_ALLOC:
  123. _Jv_JVMPI_Notify_OBJECT_ALLOC = NULL;
  124. break;
  125. default:
  126. return JVMPI_NOT_AVAILABLE;
  127. }
  128. return JVMPI_SUCCESS;
  129. }
  130. #endif
  131. void
  132. _Jv_JNI_Init (void)
  133. {
  134. local_ref_table = new java::util::IdentityHashMap;
  135. global_ref_table = new java::util::IdentityHashMap;
  136. #ifdef ENABLE_JVMPI
  137. _Jv_JVMPI_Interface.version = 1;
  138. _Jv_JVMPI_Interface.EnableEvent = &jvmpiEnableEvent;
  139. _Jv_JVMPI_Interface.DisableEvent = &jvmpiDisableEvent;
  140. _Jv_JVMPI_Interface.EnableGC = &_Jv_EnableGC;
  141. _Jv_JVMPI_Interface.DisableGC = &_Jv_DisableGC;
  142. _Jv_JVMPI_Interface.RunGC = &_Jv_RunGC;
  143. #endif
  144. }
  145. // Tell the GC that a certain pointer is live.
  146. static void
  147. mark_for_gc (jobject obj, java::util::IdentityHashMap *ref_table)
  148. {
  149. JvSynchronize sync (ref_table);
  150. using namespace java::lang;
  151. Integer *refcount = (Integer *) ref_table->get (obj);
  152. jint val = (refcount == NULL) ? 0 : refcount->intValue ();
  153. // FIXME: what about out of memory error?
  154. ref_table->put (obj, new Integer (val + 1));
  155. }
  156. // Unmark a pointer.
  157. static void
  158. unmark_for_gc (jobject obj, java::util::IdentityHashMap *ref_table)
  159. {
  160. JvSynchronize sync (ref_table);
  161. using namespace java::lang;
  162. Integer *refcount = (Integer *) ref_table->get (obj);
  163. JvAssert (refcount);
  164. jint val = refcount->intValue () - 1;
  165. JvAssert (val >= 0);
  166. if (val == 0)
  167. ref_table->remove (obj);
  168. else
  169. // FIXME: what about out of memory error?
  170. ref_table->put (obj, new Integer (val));
  171. }
  172. // "Unwrap" some random non-reference type. This exists to simplify
  173. // other template functions.
  174. template<typename T>
  175. static T
  176. unwrap (T val)
  177. {
  178. return val;
  179. }
  180. // Unwrap a weak reference, if required.
  181. template<typename T>
  182. static T *
  183. unwrap (T *obj)
  184. {
  185. using namespace gnu::gcj::runtime;
  186. // We can compare the class directly because JNIWeakRef is `final'.
  187. // Doing it this way is much faster.
  188. if (obj == NULL || obj->getClass () != &JNIWeakRef::class$)
  189. return obj;
  190. JNIWeakRef *wr = reinterpret_cast<JNIWeakRef *> (obj);
  191. return reinterpret_cast<T *> (wr->get ());
  192. }
  193. jobject
  194. _Jv_UnwrapJNIweakReference (jobject obj)
  195. {
  196. return unwrap (obj);
  197. }
  198. static jobject JNICALL
  199. _Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj)
  200. {
  201. // This seems weird but I think it is correct.
  202. obj = unwrap (obj);
  203. mark_for_gc (obj, global_ref_table);
  204. return obj;
  205. }
  206. static void JNICALL
  207. _Jv_JNI_DeleteGlobalRef (JNIEnv *, jobject obj)
  208. {
  209. // This seems weird but I think it is correct.
  210. obj = unwrap (obj);
  211. // NULL is ok here -- the JNI specification doesn't say so, but this
  212. // is a no-op.
  213. if (! obj)
  214. return;
  215. unmark_for_gc (obj, global_ref_table);
  216. }
  217. static void JNICALL
  218. _Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj)
  219. {
  220. _Jv_JNI_LocalFrame *frame;
  221. // This seems weird but I think it is correct.
  222. obj = unwrap (obj);
  223. // NULL is ok here -- the JNI specification doesn't say so, but this
  224. // is a no-op.
  225. if (! obj)
  226. return;
  227. for (frame = env->locals; frame != NULL; frame = frame->next)
  228. {
  229. for (int i = 0; i < frame->size; ++i)
  230. {
  231. if (frame->vec[i] == obj)
  232. {
  233. frame->vec[i] = NULL;
  234. unmark_for_gc (obj, local_ref_table);
  235. return;
  236. }
  237. }
  238. // Don't go past a marked frame.
  239. JvAssert (frame->marker == MARK_NONE);
  240. }
  241. JvAssert (0);
  242. }
  243. static jint JNICALL
  244. _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
  245. {
  246. // It is easier to just always allocate a new frame of the requested
  247. // size. This isn't the most efficient thing, but for now we don't
  248. // care. Note that _Jv_JNI_PushLocalFrame relies on this right now.
  249. _Jv_JNI_LocalFrame *frame;
  250. try
  251. {
  252. frame = (_Jv_JNI_LocalFrame *) _Jv_Malloc (sizeof (_Jv_JNI_LocalFrame)
  253. + size * sizeof (jobject));
  254. }
  255. catch (jthrowable t)
  256. {
  257. env->ex = t;
  258. return JNI_ERR;
  259. }
  260. frame->marker = MARK_NONE;
  261. frame->size = size;
  262. frame->allocated_p = false;
  263. memset (&frame->vec[0], 0, size * sizeof (jobject));
  264. frame->loader = env->locals->loader;
  265. frame->next = env->locals;
  266. env->locals = frame;
  267. return 0;
  268. }
  269. static jint JNICALL
  270. _Jv_JNI_PushLocalFrame (JNIEnv *env, jint size)
  271. {
  272. jint r = _Jv_JNI_EnsureLocalCapacity (env, size);
  273. if (r < 0)
  274. return r;
  275. // The new frame is on top.
  276. env->locals->marker = MARK_USER;
  277. return 0;
  278. }
  279. static jobject JNICALL
  280. _Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
  281. {
  282. // This seems weird but I think it is correct.
  283. obj = unwrap (obj);
  284. // Try to find an open slot somewhere in the topmost frame.
  285. _Jv_JNI_LocalFrame *frame = env->locals;
  286. bool done = false, set = false;
  287. for (; frame != NULL && ! done; frame = frame->next)
  288. {
  289. for (int i = 0; i < frame->size; ++i)
  290. {
  291. if (frame->vec[i] == NULL)
  292. {
  293. set = true;
  294. done = true;
  295. frame->vec[i] = obj;
  296. frame->allocated_p = true;
  297. break;
  298. }
  299. }
  300. // If we found a slot, or if the frame we just searched is the
  301. // mark frame, then we are done.
  302. if (done || frame == NULL || frame->marker != MARK_NONE)
  303. break;
  304. }
  305. if (! set)
  306. {
  307. // No slots, so we allocate a new frame. According to the spec
  308. // we could just die here. FIXME: return value.
  309. _Jv_JNI_EnsureLocalCapacity (env, 16);
  310. // We know the first element of the new frame will be ok.
  311. env->locals->vec[0] = obj;
  312. env->locals->allocated_p = true;
  313. }
  314. mark_for_gc (obj, local_ref_table);
  315. return obj;
  316. }
  317. static jobject JNICALL
  318. _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result, int stop)
  319. {
  320. _Jv_JNI_LocalFrame *rf = env->locals;
  321. bool done = false;
  322. while (rf != NULL && ! done)
  323. {
  324. for (int i = 0; i < rf->size; ++i)
  325. if (rf->vec[i] != NULL)
  326. unmark_for_gc (rf->vec[i], local_ref_table);
  327. // If the frame we just freed is the marker frame, we are done.
  328. done = (rf->marker == stop);
  329. _Jv_JNI_LocalFrame *n = rf->next;
  330. // When N==NULL, we've reached the reusable bottom_locals, and we must
  331. // not free it. However, we must be sure to clear all its elements.
  332. if (n == NULL)
  333. {
  334. if (rf->allocated_p)
  335. memset (&rf->vec[0], 0, rf->size * sizeof (jobject));
  336. rf->allocated_p = false;
  337. rf = NULL;
  338. break;
  339. }
  340. _Jv_Free (rf);
  341. rf = n;
  342. }
  343. // Update the local frame information.
  344. env->locals = rf;
  345. return result == NULL ? NULL : _Jv_JNI_NewLocalRef (env, result);
  346. }
  347. static jobject JNICALL
  348. _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
  349. {
  350. return _Jv_JNI_PopLocalFrame (env, result, MARK_USER);
  351. }
  352. // Make sure an array's type is compatible with the type of the
  353. // destination.
  354. template<typename T>
  355. static bool
  356. _Jv_JNI_check_types (JNIEnv *env, JArray<T> *array, jclass K)
  357. {
  358. jclass klass = array->getClass()->getComponentType();
  359. if (__builtin_expect (klass != K, false))
  360. {
  361. env->ex = new java::lang::IllegalAccessError ();
  362. return false;
  363. }
  364. else
  365. return true;
  366. }
  367. // Pop a `system' frame from the stack. This is `extern "C"' as it is
  368. // used by the compiler.
  369. extern "C" void
  370. _Jv_JNI_PopSystemFrame (JNIEnv *env)
  371. {
  372. // Only enter slow path when we're not at the bottom, or there have been
  373. // allocations. Usually this is false and we can just null out the locals
  374. // field.
  375. if (__builtin_expect ((env->locals->next
  376. || env->locals->allocated_p), false))
  377. _Jv_JNI_PopLocalFrame (env, NULL, MARK_SYSTEM);
  378. else
  379. env->locals = NULL;
  380. #ifdef INTERPRETER
  381. if (__builtin_expect (env->ex != NULL, false))
  382. {
  383. jthrowable t = env->ex;
  384. env->ex = NULL;
  385. if (JVMTI_REQUESTED_EVENT (Exception))
  386. _Jv_ReportJVMTIExceptionThrow (t);
  387. throw t;
  388. }
  389. #endif
  390. }
  391. template<typename T> T extract_from_jvalue(jvalue const & t);
  392. template<> jboolean extract_from_jvalue(jvalue const & jv) { return jv.z; }
  393. template<> jbyte extract_from_jvalue(jvalue const & jv) { return jv.b; }
  394. template<> jchar extract_from_jvalue(jvalue const & jv) { return jv.c; }
  395. template<> jshort extract_from_jvalue(jvalue const & jv) { return jv.s; }
  396. template<> jint extract_from_jvalue(jvalue const & jv) { return jv.i; }
  397. template<> jlong extract_from_jvalue(jvalue const & jv) { return jv.j; }
  398. template<> jfloat extract_from_jvalue(jvalue const & jv) { return jv.f; }
  399. template<> jdouble extract_from_jvalue(jvalue const & jv) { return jv.d; }
  400. template<> jobject extract_from_jvalue(jvalue const & jv) { return jv.l; }
  401. // This function is used from other template functions. It wraps the
  402. // return value appropriately; we specialize it so that object returns
  403. // are turned into local references.
  404. template<typename T>
  405. static T
  406. wrap_value (JNIEnv *, T value)
  407. {
  408. return value;
  409. }
  410. // This specialization is used for jobject, jclass, jstring, jarray,
  411. // etc.
  412. template<typename R, typename T>
  413. static T *
  414. wrap_value (JNIEnv *env, T *value)
  415. {
  416. return (value == NULL
  417. ? value
  418. : (T *) _Jv_JNI_NewLocalRef (env, (jobject) value));
  419. }
  420. static jint JNICALL
  421. _Jv_JNI_GetVersion (JNIEnv *)
  422. {
  423. return JNI_VERSION_1_4;
  424. }
  425. static jclass JNICALL
  426. _Jv_JNI_DefineClass (JNIEnv *env, const char *name, jobject loader,
  427. const jbyte *buf, jsize bufLen)
  428. {
  429. try
  430. {
  431. loader = unwrap (loader);
  432. jstring sname = JvNewStringUTF (name);
  433. jbyteArray bytes = JvNewByteArray (bufLen);
  434. jbyte *elts = elements (bytes);
  435. memcpy (elts, buf, bufLen * sizeof (jbyte));
  436. java::lang::ClassLoader *l
  437. = reinterpret_cast<java::lang::ClassLoader *> (loader);
  438. jclass result = l->defineClass (sname, bytes, 0, bufLen);
  439. return (jclass) wrap_value (env, result);
  440. }
  441. catch (jthrowable t)
  442. {
  443. env->ex = t;
  444. return NULL;
  445. }
  446. }
  447. static jclass JNICALL
  448. _Jv_JNI_FindClass (JNIEnv *env, const char *name)
  449. {
  450. // FIXME: assume that NAME isn't too long.
  451. int len = strlen (name);
  452. char s[len + 1];
  453. for (int i = 0; i <= len; ++i)
  454. s[i] = (name[i] == '/') ? '.' : name[i];
  455. jclass r = NULL;
  456. try
  457. {
  458. // This might throw an out of memory exception.
  459. jstring n = JvNewStringUTF (s);
  460. java::lang::ClassLoader *loader = NULL;
  461. if (env->locals->loader != NULL)
  462. loader = env->locals->loader;
  463. if (loader == NULL)
  464. {
  465. // FIXME: should use getBaseClassLoader, but we don't have that
  466. // yet.
  467. loader = java::lang::ClassLoader::getSystemClassLoader ();
  468. }
  469. r = loader->loadClass (n);
  470. _Jv_InitClass (r);
  471. }
  472. catch (jthrowable t)
  473. {
  474. env->ex = t;
  475. }
  476. return (jclass) wrap_value (env, r);
  477. }
  478. static jclass JNICALL
  479. _Jv_JNI_GetSuperclass (JNIEnv *env, jclass clazz)
  480. {
  481. return (jclass) wrap_value (env, unwrap (clazz)->getSuperclass ());
  482. }
  483. static jboolean JNICALL
  484. _Jv_JNI_IsAssignableFrom (JNIEnv *, jclass clazz1, jclass clazz2)
  485. {
  486. return unwrap (clazz2)->isAssignableFrom (unwrap (clazz1));
  487. }
  488. static jint JNICALL
  489. _Jv_JNI_Throw (JNIEnv *env, jthrowable obj)
  490. {
  491. // We check in case the user did some funky cast.
  492. obj = unwrap (obj);
  493. JvAssert (obj != NULL && java::lang::Throwable::class$.isInstance (obj));
  494. env->ex = obj;
  495. return 0;
  496. }
  497. static jint JNICALL
  498. _Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
  499. {
  500. using namespace java::lang::reflect;
  501. clazz = unwrap (clazz);
  502. JvAssert (java::lang::Throwable::class$.isAssignableFrom (clazz));
  503. int r = JNI_OK;
  504. try
  505. {
  506. JArray<jclass> *argtypes
  507. = (JArray<jclass> *) JvNewObjectArray (1, &java::lang::Class::class$,
  508. NULL);
  509. jclass *elts = elements (argtypes);
  510. elts[0] = &java::lang::String::class$;
  511. Constructor *cons = clazz->getConstructor (argtypes);
  512. jobjectArray values = JvNewObjectArray (1, &java::lang::String::class$,
  513. NULL);
  514. jobject *velts = elements (values);
  515. velts[0] = JvNewStringUTF (message);
  516. jobject obj = cons->newInstance (values);
  517. env->ex = reinterpret_cast<jthrowable> (obj);
  518. }
  519. catch (jthrowable t)
  520. {
  521. env->ex = t;
  522. r = JNI_ERR;
  523. }
  524. return r;
  525. }
  526. static jthrowable JNICALL
  527. _Jv_JNI_ExceptionOccurred (JNIEnv *env)
  528. {
  529. return (jthrowable) wrap_value (env, env->ex);
  530. }
  531. static void JNICALL
  532. _Jv_JNI_ExceptionDescribe (JNIEnv *env)
  533. {
  534. if (env->ex != NULL)
  535. env->ex->printStackTrace();
  536. }
  537. static void JNICALL
  538. _Jv_JNI_ExceptionClear (JNIEnv *env)
  539. {
  540. env->ex = NULL;
  541. }
  542. static jboolean JNICALL
  543. _Jv_JNI_ExceptionCheck (JNIEnv *env)
  544. {
  545. return env->ex != NULL;
  546. }
  547. static void JNICALL
  548. _Jv_JNI_FatalError (JNIEnv *, const char *message)
  549. {
  550. JvFail (message);
  551. }
  552. static jboolean JNICALL
  553. _Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2)
  554. {
  555. return unwrap (obj1) == unwrap (obj2);
  556. }
  557. static jobject JNICALL
  558. _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
  559. {
  560. jobject obj = NULL;
  561. using namespace java::lang::reflect;
  562. try
  563. {
  564. clazz = unwrap (clazz);
  565. JvAssert (clazz && ! clazz->isArray ());
  566. if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
  567. env->ex = new java::lang::InstantiationException ();
  568. else
  569. obj = _Jv_AllocObject (clazz);
  570. }
  571. catch (jthrowable t)
  572. {
  573. env->ex = t;
  574. }
  575. return wrap_value (env, obj);
  576. }
  577. static jclass JNICALL
  578. _Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj)
  579. {
  580. obj = unwrap (obj);
  581. JvAssert (obj);
  582. return (jclass) wrap_value (env, obj->getClass());
  583. }
  584. static jboolean JNICALL
  585. _Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz)
  586. {
  587. return unwrap (clazz)->isInstance(unwrap (obj));
  588. }
  589. //
  590. // This section concerns method invocation.
  591. //
  592. template<jboolean is_static>
  593. static jmethodID JNICALL
  594. _Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
  595. const char *name, const char *sig)
  596. {
  597. try
  598. {
  599. clazz = unwrap (clazz);
  600. _Jv_InitClass (clazz);
  601. _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
  602. // FIXME: assume that SIG isn't too long.
  603. int len = strlen (sig);
  604. char s[len + 1];
  605. for (int i = 0; i <= len; ++i)
  606. s[i] = (sig[i] == '/') ? '.' : sig[i];
  607. _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) s, -1);
  608. JvAssert (! clazz->isPrimitive());
  609. using namespace java::lang::reflect;
  610. while (clazz != NULL)
  611. {
  612. jint count = JvNumMethods (clazz);
  613. jmethodID meth = JvGetFirstMethod (clazz);
  614. for (jint i = 0; i < count; ++i)
  615. {
  616. if (((is_static && Modifier::isStatic (meth->accflags))
  617. || (! is_static && ! Modifier::isStatic (meth->accflags)))
  618. && _Jv_equalUtf8Consts (meth->name, name_u)
  619. && _Jv_equalUtf8Consts (meth->signature, sig_u))
  620. return meth;
  621. meth = meth->getNextMethod();
  622. }
  623. clazz = clazz->getSuperclass ();
  624. }
  625. java::lang::StringBuffer *name_sig =
  626. new java::lang::StringBuffer (JvNewStringUTF (name));
  627. name_sig->append ((jchar) ' ');
  628. name_sig->append (JvNewStringUTF (s));
  629. env->ex = new java::lang::NoSuchMethodError (name_sig->toString ());
  630. }
  631. catch (jthrowable t)
  632. {
  633. env->ex = t;
  634. }
  635. return NULL;
  636. }
  637. // This is a helper function which turns a va_list into an array of
  638. // `jvalue's. It needs signature information in order to do its work.
  639. // The array of values must already be allocated.
  640. static void
  641. array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs)
  642. {
  643. jclass *arg_elts = elements (arg_types);
  644. for (int i = 0; i < arg_types->length; ++i)
  645. {
  646. // Here we assume that sizeof(int) >= sizeof(jint), because we
  647. // use `int' when decoding the varargs. Likewise for
  648. // float, and double. Also we assume that sizeof(jlong) >=
  649. // sizeof(int), i.e. that jlong values are not further
  650. // promoted.
  651. JvAssert (sizeof (int) >= sizeof (jint));
  652. JvAssert (sizeof (jlong) >= sizeof (int));
  653. JvAssert (sizeof (double) >= sizeof (jfloat));
  654. JvAssert (sizeof (double) >= sizeof (jdouble));
  655. if (arg_elts[i] == JvPrimClass (byte))
  656. values[i].b = (jbyte) va_arg (vargs, int);
  657. else if (arg_elts[i] == JvPrimClass (short))
  658. values[i].s = (jshort) va_arg (vargs, int);
  659. else if (arg_elts[i] == JvPrimClass (int))
  660. values[i].i = (jint) va_arg (vargs, int);
  661. else if (arg_elts[i] == JvPrimClass (long))
  662. values[i].j = (jlong) va_arg (vargs, jlong);
  663. else if (arg_elts[i] == JvPrimClass (float))
  664. values[i].f = (jfloat) va_arg (vargs, double);
  665. else if (arg_elts[i] == JvPrimClass (double))
  666. values[i].d = (jdouble) va_arg (vargs, double);
  667. else if (arg_elts[i] == JvPrimClass (boolean))
  668. values[i].z = (jboolean) va_arg (vargs, int);
  669. else if (arg_elts[i] == JvPrimClass (char))
  670. values[i].c = (jchar) va_arg (vargs, int);
  671. else
  672. {
  673. // An object.
  674. values[i].l = unwrap (va_arg (vargs, jobject));
  675. }
  676. }
  677. }
  678. // This can call any sort of method: virtual, "nonvirtual", static, or
  679. // constructor.
  680. template<typename T, invocation_type style>
  681. static T JNICALL
  682. _Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
  683. jmethodID id, va_list vargs)
  684. {
  685. obj = unwrap (obj);
  686. klass = unwrap (klass);
  687. jclass decl_class = klass ? klass : obj->getClass ();
  688. JvAssert (decl_class != NULL);
  689. jclass return_type;
  690. JArray<jclass> *arg_types;
  691. try
  692. {
  693. _Jv_GetTypesFromSignature (id, decl_class,
  694. &arg_types, &return_type);
  695. jvalue args[arg_types->length];
  696. array_from_valist (args, arg_types, vargs);
  697. // For constructors we need to pass the Class we are instantiating.
  698. if (style == constructor)
  699. return_type = klass;
  700. jvalue result;
  701. _Jv_CallAnyMethodA (obj, return_type, id,
  702. style == constructor,
  703. style == normal,
  704. arg_types, args, &result);
  705. return wrap_value (env, extract_from_jvalue<T>(result));
  706. }
  707. catch (jthrowable t)
  708. {
  709. env->ex = t;
  710. }
  711. return wrap_value (env, (T) 0);
  712. }
  713. template<typename T, invocation_type style>
  714. static T JNICALL
  715. _Jv_JNI_CallAnyMethod (JNIEnv *env, jobject obj, jclass klass,
  716. jmethodID method, ...)
  717. {
  718. va_list args;
  719. T result;
  720. va_start (args, method);
  721. result = _Jv_JNI_CallAnyMethodV<T, style> (env, obj, klass, method, args);
  722. va_end (args);
  723. return result;
  724. }
  725. template<typename T, invocation_type style>
  726. static T JNICALL
  727. _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
  728. jmethodID id, const jvalue *args)
  729. {
  730. obj = unwrap (obj);
  731. klass = unwrap (klass);
  732. jclass decl_class = klass ? klass : obj->getClass ();
  733. JvAssert (decl_class != NULL);
  734. jclass return_type;
  735. JArray<jclass> *arg_types;
  736. try
  737. {
  738. _Jv_GetTypesFromSignature (id, decl_class,
  739. &arg_types, &return_type);
  740. // For constructors we need to pass the Class we are instantiating.
  741. if (style == constructor)
  742. return_type = klass;
  743. // Unwrap arguments as required. Eww.
  744. jclass *type_elts = elements (arg_types);
  745. jvalue arg_copy[arg_types->length];
  746. for (int i = 0; i < arg_types->length; ++i)
  747. {
  748. if (type_elts[i]->isPrimitive ())
  749. arg_copy[i] = args[i];
  750. else
  751. arg_copy[i].l = unwrap (args[i].l);
  752. }
  753. jvalue result;
  754. _Jv_CallAnyMethodA (obj, return_type, id,
  755. style == constructor,
  756. style == normal,
  757. arg_types, arg_copy, &result);
  758. return wrap_value (env, extract_from_jvalue<T>(result));
  759. }
  760. catch (jthrowable t)
  761. {
  762. env->ex = t;
  763. }
  764. return wrap_value (env, (T) 0);
  765. }
  766. template<invocation_type style>
  767. static void JNICALL
  768. _Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
  769. jmethodID id, va_list vargs)
  770. {
  771. obj = unwrap (obj);
  772. klass = unwrap (klass);
  773. jclass decl_class = klass ? klass : obj->getClass ();
  774. JvAssert (decl_class != NULL);
  775. jclass return_type;
  776. JArray<jclass> *arg_types;
  777. try
  778. {
  779. _Jv_GetTypesFromSignature (id, decl_class,
  780. &arg_types, &return_type);
  781. jvalue args[arg_types->length];
  782. array_from_valist (args, arg_types, vargs);
  783. // For constructors we need to pass the Class we are instantiating.
  784. if (style == constructor)
  785. return_type = klass;
  786. _Jv_CallAnyMethodA (obj, return_type, id,
  787. style == constructor,
  788. style == normal,
  789. arg_types, args, NULL);
  790. }
  791. catch (jthrowable t)
  792. {
  793. env->ex = t;
  794. }
  795. }
  796. template<invocation_type style>
  797. static void JNICALL
  798. _Jv_JNI_CallAnyVoidMethod (JNIEnv *env, jobject obj, jclass klass,
  799. jmethodID method, ...)
  800. {
  801. va_list args;
  802. va_start (args, method);
  803. _Jv_JNI_CallAnyVoidMethodV<style> (env, obj, klass, method, args);
  804. va_end (args);
  805. }
  806. template<invocation_type style>
  807. static void JNICALL
  808. _Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
  809. jmethodID id, const jvalue *args)
  810. {
  811. jclass decl_class = klass ? klass : obj->getClass ();
  812. JvAssert (decl_class != NULL);
  813. jclass return_type;
  814. JArray<jclass> *arg_types;
  815. try
  816. {
  817. _Jv_GetTypesFromSignature (id, decl_class,
  818. &arg_types, &return_type);
  819. // Unwrap arguments as required. Eww.
  820. jclass *type_elts = elements (arg_types);
  821. jvalue arg_copy[arg_types->length];
  822. for (int i = 0; i < arg_types->length; ++i)
  823. {
  824. if (type_elts[i]->isPrimitive ())
  825. arg_copy[i] = args[i];
  826. else
  827. arg_copy[i].l = unwrap (args[i].l);
  828. }
  829. _Jv_CallAnyMethodA (obj, return_type, id,
  830. style == constructor,
  831. style == normal,
  832. arg_types, args, NULL);
  833. }
  834. catch (jthrowable t)
  835. {
  836. env->ex = t;
  837. }
  838. }
  839. // Functions with this signature are used to implement functions in
  840. // the CallMethod family.
  841. template<typename T>
  842. static T JNICALL
  843. _Jv_JNI_CallMethodV (JNIEnv *env, jobject obj,
  844. jmethodID id, va_list args)
  845. {
  846. return _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
  847. }
  848. // Functions with this signature are used to implement functions in
  849. // the CallMethod family.
  850. template<typename T>
  851. static T JNICALL
  852. _Jv_JNI_CallMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
  853. {
  854. va_list args;
  855. T result;
  856. va_start (args, id);
  857. result = _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
  858. va_end (args);
  859. return result;
  860. }
  861. // Functions with this signature are used to implement functions in
  862. // the CallMethod family.
  863. template<typename T>
  864. static T JNICALL
  865. _Jv_JNI_CallMethodA (JNIEnv *env, jobject obj,
  866. jmethodID id, const jvalue *args)
  867. {
  868. return _Jv_JNI_CallAnyMethodA<T, normal> (env, obj, NULL, id, args);
  869. }
  870. static void JNICALL
  871. _Jv_JNI_CallVoidMethodV (JNIEnv *env, jobject obj,
  872. jmethodID id, va_list args)
  873. {
  874. _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
  875. }
  876. static void JNICALL
  877. _Jv_JNI_CallVoidMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
  878. {
  879. va_list args;
  880. va_start (args, id);
  881. _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
  882. va_end (args);
  883. }
  884. static void JNICALL
  885. _Jv_JNI_CallVoidMethodA (JNIEnv *env, jobject obj,
  886. jmethodID id, const jvalue *args)
  887. {
  888. _Jv_JNI_CallAnyVoidMethodA<normal> (env, obj, NULL, id, args);
  889. }
  890. // Functions with this signature are used to implement functions in
  891. // the CallStaticMethod family.
  892. template<typename T>
  893. static T JNICALL
  894. _Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass,
  895. jmethodID id, va_list args)
  896. {
  897. JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
  898. JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));
  899. return _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, id, args);
  900. }
  901. // Functions with this signature are used to implement functions in
  902. // the CallStaticMethod family.
  903. template<typename T>
  904. static T JNICALL
  905. _Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass,
  906. jmethodID id, ...)
  907. {
  908. va_list args;
  909. T result;
  910. JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
  911. JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));
  912. va_start (args, id);
  913. result = _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass,
  914. id, args);
  915. va_end (args);
  916. return result;
  917. }
  918. // Functions with this signature are used to implement functions in
  919. // the CallStaticMethod family.
  920. template<typename T>
  921. static T JNICALL
  922. _Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id,
  923. const jvalue *args)
  924. {
  925. JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
  926. JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));
  927. return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args);
  928. }
  929. static void JNICALL
  930. _Jv_JNI_CallStaticVoidMethodV (JNIEnv *env, jclass klass,
  931. jmethodID id, va_list args)
  932. {
  933. _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
  934. }
  935. static void JNICALL
  936. _Jv_JNI_CallStaticVoidMethod (JNIEnv *env, jclass klass,
  937. jmethodID id, ...)
  938. {
  939. va_list args;
  940. va_start (args, id);
  941. _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
  942. va_end (args);
  943. }
  944. static void JNICALL
  945. _Jv_JNI_CallStaticVoidMethodA (JNIEnv *env, jclass klass,
  946. jmethodID id, const jvalue *args)
  947. {
  948. _Jv_JNI_CallAnyVoidMethodA<static_type> (env, NULL, klass, id, args);
  949. }
  950. static jobject JNICALL
  951. _Jv_JNI_NewObjectV (JNIEnv *env, jclass klass,
  952. jmethodID id, va_list args)
  953. {
  954. JvAssert (klass && ! klass->isArray ());
  955. JvAssert (! strcmp (id->name->chars(), "<init>")
  956. && id->signature->len() > 2
  957. && id->signature->chars()[0] == '('
  958. && ! strcmp (&id->signature->chars()[id->signature->len() - 2],
  959. ")V"));
  960. return _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
  961. id, args);
  962. }
  963. static jobject JNICALL
  964. _Jv_JNI_NewObject (JNIEnv *env, jclass klass, jmethodID id, ...)
  965. {
  966. JvAssert (klass && ! klass->isArray ());
  967. JvAssert (! strcmp (id->name->chars(), "<init>")
  968. && id->signature->len() > 2
  969. && id->signature->chars()[0] == '('
  970. && ! strcmp (&id->signature->chars()[id->signature->len() - 2],
  971. ")V"));
  972. va_list args;
  973. jobject result;
  974. va_start (args, id);
  975. result = _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
  976. id, args);
  977. va_end (args);
  978. return result;
  979. }
  980. static jobject JNICALL
  981. _Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id,
  982. const jvalue *args)
  983. {
  984. JvAssert (klass && ! klass->isArray ());
  985. JvAssert (! strcmp (id->name->chars(), "<init>")
  986. && id->signature->len() > 2
  987. && id->signature->chars()[0] == '('
  988. && ! strcmp (&id->signature->chars()[id->signature->len() - 2],
  989. ")V"));
  990. return _Jv_JNI_CallAnyMethodA<jobject, constructor> (env, NULL, klass,
  991. id, args);
  992. }
  993. template<typename T>
  994. static T JNICALL
  995. _Jv_JNI_GetField (JNIEnv *env, jobject obj, jfieldID field)
  996. {
  997. obj = unwrap (obj);
  998. JvAssert (obj);
  999. T *ptr = (T *) ((char *) obj + field->getOffset ());
  1000. return wrap_value (env, *ptr);
  1001. }
  1002. template<typename T>
  1003. static void JNICALL
  1004. _Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value)
  1005. {
  1006. obj = unwrap (obj);
  1007. value = unwrap (value);
  1008. JvAssert (obj);
  1009. T *ptr = (T *) ((char *) obj + field->getOffset ());
  1010. *ptr = value;
  1011. }
  1012. template<jboolean is_static>
  1013. static jfieldID JNICALL
  1014. _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
  1015. const char *name, const char *sig)
  1016. {
  1017. try
  1018. {
  1019. clazz = unwrap (clazz);
  1020. _Jv_InitClass (clazz);
  1021. _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
  1022. // FIXME: assume that SIG isn't too long.
  1023. int len = strlen (sig);
  1024. char s[len + 1];
  1025. for (int i = 0; i <= len; ++i)
  1026. s[i] = (sig[i] == '/') ? '.' : sig[i];
  1027. java::lang::ClassLoader *loader = clazz->getClassLoaderInternal ();
  1028. jclass field_class = _Jv_FindClassFromSignature ((char *) s, loader);
  1029. if (! field_class)
  1030. throw new java::lang::ClassNotFoundException(JvNewStringUTF(s));
  1031. while (clazz != NULL)
  1032. {
  1033. // We acquire the class lock so that fields aren't resolved
  1034. // while we are running.
  1035. JvSynchronize sync (clazz);
  1036. jint count = (is_static
  1037. ? JvNumStaticFields (clazz)
  1038. : JvNumInstanceFields (clazz));
  1039. jfieldID field = (is_static
  1040. ? JvGetFirstStaticField (clazz)
  1041. : JvGetFirstInstanceField (clazz));
  1042. for (jint i = 0; i < count; ++i)
  1043. {
  1044. _Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz);
  1045. // The field might be resolved or it might not be. It
  1046. // is much simpler to always resolve it.
  1047. _Jv_Linker::resolve_field (field, loader);
  1048. if (_Jv_equalUtf8Consts (f_name, a_name)
  1049. && field->getClass() == field_class)
  1050. return field;
  1051. field = field->getNextField ();
  1052. }
  1053. clazz = clazz->getSuperclass ();
  1054. }
  1055. env->ex = new java::lang::NoSuchFieldError ();
  1056. }
  1057. catch (jthrowable t)
  1058. {
  1059. env->ex = t;
  1060. }
  1061. return NULL;
  1062. }
  1063. template<typename T>
  1064. static T JNICALL
  1065. _Jv_JNI_GetStaticField (JNIEnv *env, jclass, jfieldID field)
  1066. {
  1067. T *ptr = (T *) field->u.addr;
  1068. return wrap_value (env, *ptr);
  1069. }
  1070. template<typename T>
  1071. static void JNICALL
  1072. _Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
  1073. {
  1074. value = unwrap (value);
  1075. T *ptr = (T *) field->u.addr;
  1076. *ptr = value;
  1077. }
  1078. static jstring JNICALL
  1079. _Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len)
  1080. {
  1081. try
  1082. {
  1083. jstring r = _Jv_NewString (unichars, len);
  1084. return (jstring) wrap_value (env, r);
  1085. }
  1086. catch (jthrowable t)
  1087. {
  1088. env->ex = t;
  1089. return NULL;
  1090. }
  1091. }
  1092. static jsize JNICALL
  1093. _Jv_JNI_GetStringLength (JNIEnv *, jstring string)
  1094. {
  1095. return unwrap (string)->length();
  1096. }
  1097. static const jchar * JNICALL
  1098. _Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
  1099. {
  1100. string = unwrap (string);
  1101. jchar *result = _Jv_GetStringChars (string);
  1102. mark_for_gc (string, global_ref_table);
  1103. if (isCopy)
  1104. *isCopy = false;
  1105. return (const jchar *) result;
  1106. }
  1107. static void JNICALL
  1108. _Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *)
  1109. {
  1110. unmark_for_gc (unwrap (string), global_ref_table);
  1111. }
  1112. static jstring JNICALL
  1113. _Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes)
  1114. {
  1115. try
  1116. {
  1117. // For compatibility with the JDK.
  1118. if (!bytes)
  1119. return NULL;
  1120. jstring result = JvNewStringUTF (bytes);
  1121. return (jstring) wrap_value (env, result);
  1122. }
  1123. catch (jthrowable t)
  1124. {
  1125. env->ex = t;
  1126. return NULL;
  1127. }
  1128. }
  1129. static jsize JNICALL
  1130. _Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string)
  1131. {
  1132. return JvGetStringUTFLength (unwrap (string));
  1133. }
  1134. static const char * JNICALL
  1135. _Jv_JNI_GetStringUTFChars (JNIEnv *env, jstring string,
  1136. jboolean *isCopy)
  1137. {
  1138. try
  1139. {
  1140. string = unwrap (string);
  1141. if (string == NULL)
  1142. return NULL;
  1143. jsize len = JvGetStringUTFLength (string);
  1144. char *r = (char *) _Jv_Malloc (len + 1);
  1145. JvGetStringUTFRegion (string, 0, string->length(), r);
  1146. r[len] = '\0';
  1147. if (isCopy)
  1148. *isCopy = true;
  1149. return (const char *) r;
  1150. }
  1151. catch (jthrowable t)
  1152. {
  1153. env->ex = t;
  1154. return NULL;
  1155. }
  1156. }
  1157. static void JNICALL
  1158. _Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf)
  1159. {
  1160. _Jv_Free ((void *) utf);
  1161. }
  1162. static void JNICALL
  1163. _Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start,
  1164. jsize len, jchar *buf)
  1165. {
  1166. string = unwrap (string);
  1167. jchar *result = _Jv_GetStringChars (string);
  1168. if (start < 0 || start > string->length ()
  1169. || len < 0 || start + len > string->length ())
  1170. {
  1171. try
  1172. {
  1173. env->ex = new java::lang::StringIndexOutOfBoundsException ();
  1174. }
  1175. catch (jthrowable t)
  1176. {
  1177. env->ex = t;
  1178. }
  1179. }
  1180. else
  1181. memcpy (buf, &result[start], len * sizeof (jchar));
  1182. }
  1183. static void JNICALL
  1184. _Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
  1185. jsize len, char *buf)
  1186. {
  1187. str = unwrap (str);
  1188. if (start < 0 || start > str->length ()
  1189. || len < 0 || start + len > str->length ())
  1190. {
  1191. try
  1192. {
  1193. env->ex = new java::lang::StringIndexOutOfBoundsException ();
  1194. }
  1195. catch (jthrowable t)
  1196. {
  1197. env->ex = t;
  1198. }
  1199. }
  1200. else
  1201. _Jv_GetStringUTFRegion (str, start, len, buf);
  1202. }
  1203. static const jchar * JNICALL
  1204. _Jv_JNI_GetStringCritical (JNIEnv *, jstring str, jboolean *isCopy)
  1205. {
  1206. jchar *result = _Jv_GetStringChars (unwrap (str));
  1207. if (isCopy)
  1208. *isCopy = false;
  1209. return result;
  1210. }
  1211. static void JNICALL
  1212. _Jv_JNI_ReleaseStringCritical (JNIEnv *, jstring, const jchar *)
  1213. {
  1214. // Nothing.
  1215. }
  1216. static jsize JNICALL
  1217. _Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
  1218. {
  1219. return unwrap (array)->length;
  1220. }
  1221. static jobjectArray JNICALL
  1222. _Jv_JNI_NewObjectArray (JNIEnv *env, jsize length,
  1223. jclass elementClass, jobject init)
  1224. {
  1225. try
  1226. {
  1227. elementClass = unwrap (elementClass);
  1228. init = unwrap (init);
  1229. _Jv_CheckCast (elementClass, init);
  1230. jarray result = JvNewObjectArray (length, elementClass, init);
  1231. return (jobjectArray) wrap_value (env, result);
  1232. }
  1233. catch (jthrowable t)
  1234. {
  1235. env->ex = t;
  1236. return NULL;
  1237. }
  1238. }
  1239. static jobject JNICALL
  1240. _Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array,
  1241. jsize index)
  1242. {
  1243. if ((unsigned) index >= (unsigned) array->length)
  1244. _Jv_ThrowBadArrayIndex (index);
  1245. jobject *elts = elements (unwrap (array));
  1246. return wrap_value (env, elts[index]);
  1247. }
  1248. static void JNICALL
  1249. _Jv_JNI_SetObjectArrayElement (JNIEnv *env, jobjectArray array,
  1250. jsize index, jobject value)
  1251. {
  1252. try
  1253. {
  1254. array = unwrap (array);
  1255. value = unwrap (value);
  1256. _Jv_CheckArrayStore (array, value);
  1257. if ((unsigned) index >= (unsigned) array->length)
  1258. _Jv_ThrowBadArrayIndex (index);
  1259. jobject *elts = elements (array);
  1260. elts[index] = value;
  1261. }
  1262. catch (jthrowable t)
  1263. {
  1264. env->ex = t;
  1265. }
  1266. }
  1267. template<typename T, jclass K>
  1268. static JArray<T> * JNICALL
  1269. _Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length)
  1270. {
  1271. try
  1272. {
  1273. return (JArray<T> *) wrap_value (env, _Jv_NewPrimArray (K, length));
  1274. }
  1275. catch (jthrowable t)
  1276. {
  1277. env->ex = t;
  1278. return NULL;
  1279. }
  1280. }
  1281. template<typename T, jclass K>
  1282. static T * JNICALL
  1283. _Jv_JNI_GetPrimitiveArrayElements (JNIEnv *env, JArray<T> *array,
  1284. jboolean *isCopy)
  1285. {
  1286. array = unwrap (array);
  1287. if (! _Jv_JNI_check_types (env, array, K))
  1288. return NULL;
  1289. T *elts = elements (array);
  1290. if (isCopy)
  1291. {
  1292. // We elect never to copy.
  1293. *isCopy = false;
  1294. }
  1295. mark_for_gc (array, global_ref_table);
  1296. return elts;
  1297. }
  1298. template<typename T, jclass K>
  1299. static void JNICALL
  1300. _Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *env, JArray<T> *array,
  1301. T *, jint /* mode */)
  1302. {
  1303. array = unwrap (array);
  1304. _Jv_JNI_check_types (env, array, K);
  1305. // Note that we ignore MODE. We can do this because we never copy
  1306. // the array elements. My reading of the JNI documentation is that
  1307. // this is an option for the implementor.
  1308. unmark_for_gc (array, global_ref_table);
  1309. }
  1310. template<typename T, jclass K>
  1311. static void JNICALL
  1312. _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
  1313. jsize start, jsize len,
  1314. T *buf)
  1315. {
  1316. array = unwrap (array);
  1317. if (! _Jv_JNI_check_types (env, array, K))
  1318. return;
  1319. // The cast to unsigned lets us save a comparison.
  1320. if (start < 0 || len < 0
  1321. || (unsigned long) (start + len) > (unsigned long) array->length)
  1322. {
  1323. try
  1324. {
  1325. // FIXME: index.
  1326. env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
  1327. }
  1328. catch (jthrowable t)
  1329. {
  1330. // Could have thown out of memory error.
  1331. env->ex = t;
  1332. }
  1333. }
  1334. else
  1335. {
  1336. T *elts = elements (array) + start;
  1337. memcpy (buf, elts, len * sizeof (T));
  1338. }
  1339. }
  1340. template<typename T, jclass K>
  1341. static void JNICALL
  1342. _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
  1343. jsize start, jsize len, const T *buf)
  1344. {
  1345. array = unwrap (array);
  1346. if (! _Jv_JNI_check_types (env, array, K))
  1347. return;
  1348. // The cast to unsigned lets us save a comparison.
  1349. if (start < 0 || len < 0
  1350. || (unsigned long) (start + len) > (unsigned long) array->length)
  1351. {
  1352. try
  1353. {
  1354. // FIXME: index.
  1355. env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
  1356. }
  1357. catch (jthrowable t)
  1358. {
  1359. env->ex = t;
  1360. }
  1361. }
  1362. else
  1363. {
  1364. T *elts = elements (array) + start;
  1365. memcpy (elts, buf, len * sizeof (T));
  1366. }
  1367. }
  1368. static void * JNICALL
  1369. _Jv_JNI_GetPrimitiveArrayCritical (JNIEnv *, jarray array,
  1370. jboolean *isCopy)
  1371. {
  1372. array = unwrap (array);
  1373. // FIXME: does this work?
  1374. jclass klass = array->getClass()->getComponentType();
  1375. JvAssert (klass->isPrimitive ());
  1376. char *r = _Jv_GetArrayElementFromElementType (array, klass);
  1377. if (isCopy)
  1378. *isCopy = false;
  1379. return r;
  1380. }
  1381. static void JNICALL
  1382. _Jv_JNI_ReleasePrimitiveArrayCritical (JNIEnv *, jarray, void *, jint)
  1383. {
  1384. // Nothing.
  1385. }
  1386. static jint JNICALL
  1387. _Jv_JNI_MonitorEnter (JNIEnv *env, jobject obj)
  1388. {
  1389. try
  1390. {
  1391. _Jv_MonitorEnter (unwrap (obj));
  1392. return 0;
  1393. }
  1394. catch (jthrowable t)
  1395. {
  1396. env->ex = t;
  1397. }
  1398. return JNI_ERR;
  1399. }
  1400. static jint JNICALL
  1401. _Jv_JNI_MonitorExit (JNIEnv *env, jobject obj)
  1402. {
  1403. try
  1404. {
  1405. _Jv_MonitorExit (unwrap (obj));
  1406. return 0;
  1407. }
  1408. catch (jthrowable t)
  1409. {
  1410. env->ex = t;
  1411. }
  1412. return JNI_ERR;
  1413. }
  1414. // JDK 1.2
  1415. jobject JNICALL
  1416. _Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID,
  1417. jboolean)
  1418. {
  1419. try
  1420. {
  1421. cls = unwrap (cls);
  1422. java::lang::reflect::Field *field = new java::lang::reflect::Field();
  1423. field->declaringClass = cls;
  1424. field->offset = (char*) fieldID - (char *) cls->fields;
  1425. field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls));
  1426. return wrap_value (env, field);
  1427. }
  1428. catch (jthrowable t)
  1429. {
  1430. env->ex = t;
  1431. }
  1432. return NULL;
  1433. }
  1434. // JDK 1.2
  1435. static jfieldID JNICALL
  1436. _Jv_JNI_FromReflectedField (JNIEnv *, jobject f)
  1437. {
  1438. using namespace java::lang::reflect;
  1439. f = unwrap (f);
  1440. Field *field = reinterpret_cast<Field *> (f);
  1441. return _Jv_FromReflectedField (field);
  1442. }
  1443. jobject JNICALL
  1444. _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
  1445. jboolean)
  1446. {
  1447. using namespace java::lang::reflect;
  1448. jobject result = NULL;
  1449. klass = unwrap (klass);
  1450. try
  1451. {
  1452. if (_Jv_equalUtf8Consts (id->name, init_name))
  1453. {
  1454. // A constructor.
  1455. Constructor *cons = new Constructor ();
  1456. cons->offset = (char *) id - (char *) &klass->methods;
  1457. cons->declaringClass = klass;
  1458. result = cons;
  1459. }
  1460. else
  1461. {
  1462. Method *meth = new Method ();
  1463. meth->offset = (char *) id - (char *) &klass->methods;
  1464. meth->declaringClass = klass;
  1465. result = meth;
  1466. }
  1467. }
  1468. catch (jthrowable t)
  1469. {
  1470. env->ex = t;
  1471. }
  1472. return wrap_value (env, result);
  1473. }
  1474. static jmethodID JNICALL
  1475. _Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
  1476. {
  1477. using namespace java::lang::reflect;
  1478. method = unwrap (method);
  1479. if (Method::class$.isInstance (method))
  1480. return _Jv_FromReflectedMethod (reinterpret_cast<Method *> (method));
  1481. return
  1482. _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
  1483. }
  1484. // JDK 1.2.
  1485. jweak JNICALL
  1486. _Jv_JNI_NewWeakGlobalRef (JNIEnv *env, jobject obj)
  1487. {
  1488. using namespace gnu::gcj::runtime;
  1489. JNIWeakRef *ref = NULL;
  1490. try
  1491. {
  1492. // This seems weird but I think it is correct.
  1493. obj = unwrap (obj);
  1494. ref = new JNIWeakRef (obj);
  1495. mark_for_gc (ref, global_ref_table);
  1496. }
  1497. catch (jthrowable t)
  1498. {
  1499. env->ex = t;
  1500. }
  1501. return reinterpret_cast<jweak> (ref);
  1502. }
  1503. void JNICALL
  1504. _Jv_JNI_DeleteWeakGlobalRef (JNIEnv *, jweak obj)
  1505. {
  1506. // JDK compatibility.
  1507. if (obj == NULL)
  1508. return;
  1509. using namespace gnu::gcj::runtime;
  1510. JNIWeakRef *ref = reinterpret_cast<JNIWeakRef *> (obj);
  1511. unmark_for_gc (ref, global_ref_table);
  1512. ref->clear ();
  1513. }
  1514. // Direct byte buffers.
  1515. static jobject JNICALL
  1516. _Jv_JNI_NewDirectByteBuffer (JNIEnv *, void *address, jlong length)
  1517. {
  1518. using namespace gnu::gcj;
  1519. using namespace java::nio;
  1520. return new DirectByteBufferImpl$ReadWrite
  1521. (reinterpret_cast<RawData *> (address), length);
  1522. }
  1523. static void * JNICALL
  1524. _Jv_JNI_GetDirectBufferAddress (JNIEnv *, jobject buffer)
  1525. {
  1526. using namespace java::nio;
  1527. if (! _Jv_IsInstanceOf (buffer, &Buffer::class$))
  1528. return NULL;
  1529. Buffer *tmp = static_cast<Buffer *> (buffer);
  1530. return reinterpret_cast<void *> (tmp->address);
  1531. }
  1532. static jlong JNICALL
  1533. _Jv_JNI_GetDirectBufferCapacity (JNIEnv *, jobject buffer)
  1534. {
  1535. using namespace java::nio;
  1536. if (! _Jv_IsInstanceOf (buffer, &Buffer::class$))
  1537. return -1;
  1538. Buffer *tmp = static_cast<Buffer *> (buffer);
  1539. if (tmp->address == NULL)
  1540. return -1;
  1541. return tmp->capacity();
  1542. }
  1543. static jobjectRefType JNICALL
  1544. _Jv_JNI_GetObjectRefType (JNIEnv *, MAYBE_UNUSED jobject object)
  1545. {
  1546. JvFail("GetObjectRefType not implemented");
  1547. return JNIInvalidRefType;
  1548. }
  1549. struct NativeMethodCacheEntry : public JNINativeMethod
  1550. {
  1551. char *className;
  1552. };
  1553. // Hash table of native methods.
  1554. static NativeMethodCacheEntry *nathash;
  1555. // Number of slots used.
  1556. static int nathash_count = 0;
  1557. // Number of slots available. Must be power of 2.
  1558. static int nathash_size = 0;
  1559. #define DELETED_ENTRY ((char *) (~0))
  1560. // Compute a hash value for a native method descriptor.
  1561. static int
  1562. hash (const NativeMethodCacheEntry *method)
  1563. {
  1564. char *ptr;
  1565. int hash = 0;
  1566. ptr = method->className;
  1567. while (*ptr)
  1568. hash = (31 * hash) + *ptr++;
  1569. ptr = method->name;
  1570. while (*ptr)
  1571. hash = (31 * hash) + *ptr++;
  1572. ptr = method->signature;
  1573. while (*ptr)
  1574. hash = (31 * hash) + *ptr++;
  1575. return hash;
  1576. }
  1577. // Find the slot where a native method goes.
  1578. static NativeMethodCacheEntry *
  1579. nathash_find_slot (const NativeMethodCacheEntry *method)
  1580. {
  1581. jint h = hash (method);
  1582. int step = (h ^ (h >> 16)) | 1;
  1583. int w = h & (nathash_size - 1);
  1584. int del = -1;
  1585. for (;;)
  1586. {
  1587. NativeMethodCacheEntry *slotp = &nathash[w];
  1588. if (slotp->name == NULL)
  1589. {
  1590. if (del >= 0)
  1591. return &nathash[del];
  1592. else
  1593. return slotp;
  1594. }
  1595. else if (slotp->name == DELETED_ENTRY)
  1596. del = w;
  1597. else if (! strcmp (slotp->name, method->name)
  1598. && ! strcmp (slotp->signature, method->signature)
  1599. && ! strcmp (slotp->className, method->className))
  1600. return slotp;
  1601. w = (w + step) & (nathash_size - 1);
  1602. }
  1603. }
  1604. // Find a method. Return NULL if it isn't in the hash table.
  1605. static void *
  1606. nathash_find (NativeMethodCacheEntry *method)
  1607. {
  1608. if (nathash == NULL)
  1609. return NULL;
  1610. NativeMethodCacheEntry *slot = nathash_find_slot (method);
  1611. if (slot->name == NULL || slot->name == DELETED_ENTRY)
  1612. return NULL;
  1613. return slot->fnPtr;
  1614. }
  1615. static void
  1616. natrehash ()
  1617. {
  1618. if (nathash == NULL)
  1619. {
  1620. nathash_size = 1024;
  1621. nathash =
  1622. (NativeMethodCacheEntry *) _Jv_AllocBytes (nathash_size
  1623. * sizeof (NativeMethodCacheEntry));
  1624. }
  1625. else
  1626. {
  1627. int savesize = nathash_size;
  1628. NativeMethodCacheEntry *savehash = nathash;
  1629. nathash_size *= 2;
  1630. nathash =
  1631. (NativeMethodCacheEntry *) _Jv_AllocBytes (nathash_size
  1632. * sizeof (NativeMethodCacheEntry));
  1633. for (int i = 0; i < savesize; ++i)
  1634. {
  1635. if (savehash[i].name != NULL && savehash[i].name != DELETED_ENTRY)
  1636. {
  1637. NativeMethodCacheEntry *slot = nathash_find_slot (&savehash[i]);
  1638. *slot = savehash[i];
  1639. }
  1640. }
  1641. }
  1642. }
  1643. static void
  1644. nathash_add (const NativeMethodCacheEntry *method)
  1645. {
  1646. if (3 * nathash_count >= 2 * nathash_size)
  1647. natrehash ();
  1648. NativeMethodCacheEntry *slot = nathash_find_slot (method);
  1649. // If the slot has a real entry in it, then there is no work to do.
  1650. if (slot->name != NULL && slot->name != DELETED_ENTRY)
  1651. return;
  1652. // FIXME: memory leak?
  1653. slot->name = strdup (method->name);
  1654. slot->className = strdup (method->className);
  1655. // This was already strduped in _Jv_JNI_RegisterNatives.
  1656. slot->signature = method->signature;
  1657. slot->fnPtr = method->fnPtr;
  1658. }
  1659. static jint JNICALL
  1660. _Jv_JNI_RegisterNatives (JNIEnv *env, jclass klass,
  1661. const JNINativeMethod *methods,
  1662. jint nMethods)
  1663. {
  1664. // Synchronize while we do the work. This must match
  1665. // synchronization in some other functions that manipulate or use
  1666. // the nathash table.
  1667. JvSynchronize sync (global_ref_table);
  1668. NativeMethodCacheEntry dottedMethod;
  1669. // Look at each descriptor given us, and find the corresponding
  1670. // method in the class.
  1671. for (int j = 0; j < nMethods; ++j)
  1672. {
  1673. bool found = false;
  1674. _Jv_Method *imeths = JvGetFirstMethod (klass);
  1675. for (int i = 0; i < JvNumMethods (klass); ++i)
  1676. {
  1677. _Jv_Method *self = &imeths[i];
  1678. // Copy this JNINativeMethod and do a slash to dot
  1679. // conversion on the signature.
  1680. dottedMethod.name = methods[j].name;
  1681. // FIXME: we leak a little memory here if the method
  1682. // is not found.
  1683. dottedMethod.signature = strdup (methods[j].signature);
  1684. dottedMethod.fnPtr = methods[j].fnPtr;
  1685. dottedMethod.className = _Jv_GetClassNameUtf8 (klass)->chars();
  1686. char *c = dottedMethod.signature;
  1687. while (*c)
  1688. {
  1689. if (*c == '/')
  1690. *c = '.';
  1691. c++;
  1692. }
  1693. if (! strcmp (self->name->chars (), dottedMethod.name)
  1694. && ! strcmp (self->signature->chars (), dottedMethod.signature))
  1695. {
  1696. if (! (self->accflags & java::lang::reflect::Modifier::NATIVE))
  1697. break;
  1698. // Found a match that is native.
  1699. found = true;
  1700. nathash_add (&dottedMethod);
  1701. break;
  1702. }
  1703. }
  1704. if (! found)
  1705. {
  1706. jstring m = JvNewStringUTF (methods[j].name);
  1707. try
  1708. {
  1709. env->ex = new java::lang::NoSuchMethodError (m);
  1710. }
  1711. catch (jthrowable t)
  1712. {
  1713. env->ex = t;
  1714. }
  1715. return JNI_ERR;
  1716. }
  1717. }
  1718. return JNI_OK;
  1719. }
  1720. static jint JNICALL
  1721. _Jv_JNI_UnregisterNatives (JNIEnv *, jclass)
  1722. {
  1723. // FIXME -- we could implement this.
  1724. return JNI_ERR;
  1725. }
  1726. // Add a character to the buffer, encoding properly.
  1727. static void
  1728. add_char (char *buf, jchar c, int *here)
  1729. {
  1730. if (c == '_')
  1731. {
  1732. buf[(*here)++] = '_';
  1733. buf[(*here)++] = '1';
  1734. }
  1735. else if (c == ';')
  1736. {
  1737. buf[(*here)++] = '_';
  1738. buf[(*here)++] = '2';
  1739. }
  1740. else if (c == '[')
  1741. {
  1742. buf[(*here)++] = '_';
  1743. buf[(*here)++] = '3';
  1744. }
  1745. // Also check for `.' here because we might be passed an internal
  1746. // qualified class name like `foo.bar'.
  1747. else if (c == '/' || c == '.')
  1748. buf[(*here)++] = '_';
  1749. else if ((c >= '0' && c <= '9')
  1750. || (c >= 'a' && c <= 'z')
  1751. || (c >= 'A' && c <= 'Z'))
  1752. buf[(*here)++] = (char) c;
  1753. else
  1754. {
  1755. // "Unicode" character.
  1756. buf[(*here)++] = '_';
  1757. buf[(*here)++] = '0';
  1758. for (int i = 0; i < 4; ++i)
  1759. {
  1760. int val = c & 0x0f;
  1761. buf[(*here) + 3 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
  1762. c >>= 4;
  1763. }
  1764. *here += 4;
  1765. }
  1766. }
  1767. // Compute a mangled name for a native function. This computes the
  1768. // long name, and also returns an index which indicates where a NUL
  1769. // can be placed to create the short name. This function assumes that
  1770. // the buffer is large enough for its results.
  1771. static void
  1772. mangled_name (jclass klass, _Jv_Utf8Const *func_name,
  1773. _Jv_Utf8Const *signature, char *buf, int *long_start)
  1774. {
  1775. strcpy (buf, "Java_");
  1776. int here = 5;
  1777. // Add fully qualified class name.
  1778. jchar *chars = _Jv_GetStringChars (klass->getName ());
  1779. jint len = klass->getName ()->length ();
  1780. for (int i = 0; i < len; ++i)
  1781. add_char (buf, chars[i], &here);
  1782. // Don't use add_char because we need a literal `_'.
  1783. buf[here++] = '_';
  1784. const unsigned char *fn = (const unsigned char *) func_name->chars ();
  1785. const unsigned char *limit = fn + func_name->len ();
  1786. for (int i = 0; ; ++i)
  1787. {
  1788. int ch = UTF8_GET (fn, limit);
  1789. if (ch < 0)
  1790. break;
  1791. add_char (buf, ch, &here);
  1792. }
  1793. // This is where the long signature begins.
  1794. *long_start = here;
  1795. buf[here++] = '_';
  1796. buf[here++] = '_';
  1797. const unsigned char *sig = (const unsigned char *) signature->chars ();
  1798. limit = sig + signature->len ();
  1799. JvAssert (sig[0] == '(');
  1800. ++sig;
  1801. while (1)
  1802. {
  1803. int ch = UTF8_GET (sig, limit);
  1804. if (ch == ')' || ch < 0)
  1805. break;
  1806. add_char (buf, ch, &here);
  1807. }
  1808. buf[here] = '\0';
  1809. }
  1810. JNIEnv *
  1811. _Jv_GetJNIEnvNewFrameWithLoader (::java::lang::ClassLoader *loader)
  1812. {
  1813. JNIEnv *env = _Jv_GetCurrentJNIEnv ();
  1814. if (__builtin_expect (env == NULL, false))
  1815. {
  1816. env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
  1817. env->functions = &_Jv_JNIFunctions;
  1818. env->locals = NULL;
  1819. // We set env->ex below.
  1820. // Set up the bottom, reusable frame.
  1821. env->bottom_locals = (_Jv_JNI_LocalFrame *)
  1822. _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
  1823. + (FRAME_SIZE
  1824. * sizeof (jobject)));
  1825. env->bottom_locals->marker = MARK_SYSTEM;
  1826. env->bottom_locals->size = FRAME_SIZE;
  1827. env->bottom_locals->next = NULL;
  1828. env->bottom_locals->allocated_p = false;
  1829. // We set the klass field below.
  1830. memset (&env->bottom_locals->vec[0], 0,
  1831. env->bottom_locals->size * sizeof (jobject));
  1832. _Jv_SetCurrentJNIEnv (env);
  1833. }
  1834. // If we're in a simple JNI call (non-nested), we can just reuse the
  1835. // locals frame we allocated many calls ago, back when the env was first
  1836. // built, above.
  1837. if (__builtin_expect (env->locals == NULL, true))
  1838. {
  1839. env->locals = env->bottom_locals;
  1840. env->locals->loader = loader;
  1841. }
  1842. else
  1843. {
  1844. // Alternatively, we might be re-entering JNI, in which case we can't
  1845. // reuse the bottom_locals frame, because it is already underneath
  1846. // us. So we need to make a new one.
  1847. _Jv_JNI_LocalFrame *frame
  1848. = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
  1849. + (FRAME_SIZE
  1850. * sizeof (jobject)));
  1851. frame->marker = MARK_SYSTEM;
  1852. frame->size = FRAME_SIZE;
  1853. frame->allocated_p = false;
  1854. frame->next = env->locals;
  1855. frame->loader = loader;
  1856. memset (&frame->vec[0], 0,
  1857. frame->size * sizeof (jobject));
  1858. env->locals = frame;
  1859. }
  1860. env->ex = NULL;
  1861. return env;
  1862. }
  1863. // Return the current thread's JNIEnv; if one does not exist, create
  1864. // it. Also create a new system frame for use. This is `extern "C"'
  1865. // because the compiler calls it.
  1866. extern "C" JNIEnv *
  1867. _Jv_GetJNIEnvNewFrame (jclass klass)
  1868. {
  1869. return _Jv_GetJNIEnvNewFrameWithLoader (klass->getClassLoaderInternal());
  1870. }
  1871. // Destroy the env's reusable resources. This is called from the thread
  1872. // destructor "finalize_native" in natThread.cc
  1873. void
  1874. _Jv_FreeJNIEnv (_Jv_JNIEnv *env)
  1875. {
  1876. if (env == NULL)
  1877. return;
  1878. if (env->bottom_locals != NULL)
  1879. _Jv_Free (env->bottom_locals);
  1880. _Jv_Free (env);
  1881. }
  1882. // Return the function which implements a particular JNI method. If
  1883. // we can't find the function, we throw the appropriate exception.
  1884. // This is `extern "C"' because the compiler uses it.
  1885. extern "C" void *
  1886. _Jv_LookupJNIMethod (jclass klass, _Jv_Utf8Const *name,
  1887. _Jv_Utf8Const *signature, MAYBE_UNUSED int args_size)
  1888. {
  1889. int name_length = name->len();
  1890. int sig_length = signature->len();
  1891. char buf[10 + 6 * (name_length + sig_length) + 12];
  1892. int long_start;
  1893. void *function;
  1894. // Synchronize on something convenient. Right now we use the hash.
  1895. JvSynchronize sync (global_ref_table);
  1896. // First see if we have an override in the hash table.
  1897. strncpy (buf, name->chars (), name_length);
  1898. buf[name_length] = '\0';
  1899. strncpy (buf + name_length + 1, signature->chars (), sig_length);
  1900. buf[name_length + sig_length + 1] = '\0';
  1901. NativeMethodCacheEntry meth;
  1902. meth.name = buf;
  1903. meth.signature = buf + name_length + 1;
  1904. meth.className = _Jv_GetClassNameUtf8(klass)->chars();
  1905. function = nathash_find (&meth);
  1906. if (function != NULL)
  1907. return function;
  1908. // If there was no override, then look in the symbol table.
  1909. buf[0] = '_';
  1910. mangled_name (klass, name, signature, buf + 1, &long_start);
  1911. char c = buf[long_start + 1];
  1912. buf[long_start + 1] = '\0';
  1913. function = _Jv_FindSymbolInExecutable (buf + 1);
  1914. #ifdef WIN32
  1915. // On Win32, we use the "stdcall" calling convention (see JNICALL
  1916. // in jni.h).
  1917. //
  1918. // For a function named 'fooBar' that takes 'nn' bytes as arguments,
  1919. // by default, MinGW GCC exports it as 'fooBar@nn', MSVC exports it
  1920. // as '_fooBar@nn' and Borland C exports it as 'fooBar'. We try to
  1921. // take care of all these variations here.
  1922. char asz_buf[12]; /* '@' + '2147483647' (32-bit INT_MAX) + '\0' */
  1923. char long_nm_sv[11]; /* Ditto, except for the '\0'. */
  1924. if (function == NULL)
  1925. {
  1926. // We have tried searching for the 'fooBar' form (BCC) - now
  1927. // try the others.
  1928. // First, save the part of the long name that will be damaged
  1929. // by appending '@nn'.
  1930. memcpy (long_nm_sv, (buf + long_start + 1 + 1), sizeof (long_nm_sv));
  1931. sprintf (asz_buf, "@%d", args_size);
  1932. strcat (buf, asz_buf);
  1933. // Search for the '_fooBar@nn' form (MSVC).
  1934. function = _Jv_FindSymbolInExecutable (buf);
  1935. if (function == NULL)
  1936. {
  1937. // Search for the 'fooBar@nn' form (MinGW GCC).
  1938. function = _Jv_FindSymbolInExecutable (buf + 1);
  1939. }
  1940. }
  1941. #endif /* WIN32 */
  1942. if (function == NULL)
  1943. {
  1944. buf[long_start + 1] = c;
  1945. #ifdef WIN32
  1946. // Restore the part of the long name that was damaged by
  1947. // appending the '@nn'.
  1948. memcpy ((buf + long_start + 1 + 1), long_nm_sv, sizeof (long_nm_sv));
  1949. #endif /* WIN32 */
  1950. function = _Jv_FindSymbolInExecutable (buf + 1);
  1951. if (function == NULL)
  1952. {
  1953. #ifdef WIN32
  1954. strcat (buf, asz_buf);
  1955. function = _Jv_FindSymbolInExecutable (buf);
  1956. if (function == NULL)
  1957. function = _Jv_FindSymbolInExecutable (buf + 1);
  1958. if (function == NULL)
  1959. #endif /* WIN32 */
  1960. {
  1961. jstring str = JvNewStringUTF (name->chars ());
  1962. throw new java::lang::UnsatisfiedLinkError (str);
  1963. }
  1964. }
  1965. }
  1966. return function;
  1967. }
  1968. #ifdef INTERPRETER
  1969. // This function is the stub which is used to turn an ordinary (CNI)
  1970. // method call into a JNI call.
  1971. void
  1972. _Jv_JNIMethod::call (ffi_cif *, void *ret, INTERP_FFI_RAW_TYPE *args,
  1973. void *__this)
  1974. {
  1975. _Jv_JNIMethod* _this = (_Jv_JNIMethod *) __this;
  1976. JNIEnv *env = _Jv_GetJNIEnvNewFrame (_this->defining_class);
  1977. // FIXME: we should mark every reference parameter as a local. For
  1978. // now we assume a conservative GC, and we assume that the
  1979. // references are on the stack somewhere.
  1980. // We cache the value that we find, of course, but if we don't find
  1981. // a value we don't cache that fact -- we might subsequently load a
  1982. // library which finds the function in question.
  1983. {
  1984. // Synchronize on a convenient object to ensure sanity in case two
  1985. // threads reach this point for the same function at the same
  1986. // time.
  1987. JvSynchronize sync (global_ref_table);
  1988. if (_this->function == NULL)
  1989. {
  1990. int args_size = sizeof (JNIEnv *) + _this->args_raw_size;
  1991. if (_this->self->accflags & java::lang::reflect::Modifier::STATIC)
  1992. args_size += sizeof (_this->defining_class);
  1993. _this->function = _Jv_LookupJNIMethod (_this->defining_class,
  1994. _this->self->name,
  1995. _this->self->signature,
  1996. args_size);
  1997. }
  1998. }
  1999. JvAssert (_this->args_raw_size % sizeof (INTERP_FFI_RAW_TYPE) == 0);
  2000. INTERP_FFI_RAW_TYPE
  2001. real_args[2 + _this->args_raw_size / sizeof (INTERP_FFI_RAW_TYPE)];
  2002. int offset = 0;
  2003. // First argument is always the environment pointer.
  2004. real_args[offset++].ptr = env;
  2005. // For a static method, we pass in the Class. For non-static
  2006. // methods, the `this' argument is already handled.
  2007. if ((_this->self->accflags & java::lang::reflect::Modifier::STATIC))
  2008. real_args[offset++].ptr = _this->defining_class;
  2009. // In libgcj, the callee synchronizes.
  2010. jobject sync = NULL;
  2011. if ((_this->self->accflags & java::lang::reflect::Modifier::SYNCHRONIZED))
  2012. {
  2013. if ((_this->self->accflags & java::lang::reflect::Modifier::STATIC))
  2014. sync = _this->defining_class;
  2015. else
  2016. sync = (jobject) args[0].ptr;
  2017. _Jv_MonitorEnter (sync);
  2018. }
  2019. // Copy over passed-in arguments.
  2020. memcpy (&real_args[offset], args, _this->args_raw_size);
  2021. // Add a frame to the composite (interpreted + JNI) call stack
  2022. java::lang::Thread *thread = java::lang::Thread::currentThread();
  2023. _Jv_NativeFrame nat_frame (_this, thread);
  2024. // The actual call to the JNI function.
  2025. #if FFI_NATIVE_RAW_API
  2026. ffi_raw_call (&_this->jni_cif, (void (*)()) _this->function,
  2027. ret, real_args);
  2028. #else
  2029. ffi_java_raw_call (&_this->jni_cif, (void (*)()) _this->function,
  2030. ret, real_args);
  2031. #endif
  2032. // We might need to unwrap a JNI weak reference here.
  2033. if (_this->jni_cif.rtype == &ffi_type_pointer)
  2034. {
  2035. _Jv_value *val = (_Jv_value *) ret;
  2036. val->object_value = unwrap (val->object_value);
  2037. }
  2038. if (sync != NULL)
  2039. _Jv_MonitorExit (sync);
  2040. _Jv_JNI_PopSystemFrame (env);
  2041. }
  2042. #endif /* INTERPRETER */
  2043. //
  2044. // Invocation API.
  2045. //
  2046. // An internal helper function.
  2047. static jint
  2048. _Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv,
  2049. void *args, jboolean is_daemon)
  2050. {
  2051. JavaVMAttachArgs *attach = reinterpret_cast<JavaVMAttachArgs *> (args);
  2052. java::lang::ThreadGroup *group = NULL;
  2053. if (attach)
  2054. {
  2055. // FIXME: do we really want to support 1.1?
  2056. if (attach->version != JNI_VERSION_1_4
  2057. && attach->version != JNI_VERSION_1_2
  2058. && attach->version != JNI_VERSION_1_1)
  2059. return JNI_EVERSION;
  2060. JvAssert (java::lang::ThreadGroup::class$.isInstance (attach->group));
  2061. group = reinterpret_cast<java::lang::ThreadGroup *> (attach->group);
  2062. }
  2063. // Attaching an already-attached thread is a no-op.
  2064. JNIEnv *env = _Jv_GetCurrentJNIEnv ();
  2065. if (env != NULL)
  2066. {
  2067. *penv = reinterpret_cast<void *> (env);
  2068. return 0;
  2069. }
  2070. env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
  2071. if (env == NULL)
  2072. return JNI_ERR;
  2073. env->functions = &_Jv_JNIFunctions;
  2074. env->ex = NULL;
  2075. env->bottom_locals
  2076. = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
  2077. + (FRAME_SIZE
  2078. * sizeof (jobject)));
  2079. env->locals = env->bottom_locals;
  2080. if (env->locals == NULL)
  2081. {
  2082. _Jv_Free (env);
  2083. return JNI_ERR;
  2084. }
  2085. env->locals->allocated_p = false;
  2086. env->locals->marker = MARK_SYSTEM;
  2087. env->locals->size = FRAME_SIZE;
  2088. env->locals->loader = NULL;
  2089. env->locals->next = NULL;
  2090. for (int i = 0; i < env->locals->size; ++i)
  2091. env->locals->vec[i] = NULL;
  2092. *penv = reinterpret_cast<void *> (env);
  2093. // This thread might already be a Java thread -- this function might
  2094. // have been called simply to set the new JNIEnv.
  2095. if (_Jv_ThreadCurrent () == NULL)
  2096. {
  2097. try
  2098. {
  2099. if (is_daemon)
  2100. _Jv_AttachCurrentThreadAsDaemon (name, group);
  2101. else
  2102. _Jv_AttachCurrentThread (name, group);
  2103. }
  2104. catch (jthrowable t)
  2105. {
  2106. return JNI_ERR;
  2107. }
  2108. }
  2109. _Jv_SetCurrentJNIEnv (env);
  2110. return 0;
  2111. }
  2112. // This is the one actually used by JNI.
  2113. jint JNICALL
  2114. _Jv_JNI_AttachCurrentThread (JavaVM *vm, void **penv, void *args)
  2115. {
  2116. return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args, false);
  2117. }
  2118. static jint JNICALL
  2119. _Jv_JNI_AttachCurrentThreadAsDaemon (JavaVM *vm, void **penv,
  2120. void *args)
  2121. {
  2122. return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args, true);
  2123. }
  2124. static jint JNICALL
  2125. _Jv_JNI_DestroyJavaVM (JavaVM *vm)
  2126. {
  2127. JvAssert (_Jv_the_vm && vm == _Jv_the_vm);
  2128. union
  2129. {
  2130. JNIEnv *env;
  2131. void *env_p;
  2132. };
  2133. if (_Jv_ThreadCurrent () != NULL)
  2134. {
  2135. jstring main_name;
  2136. // This sucks.
  2137. try
  2138. {
  2139. main_name = JvNewStringLatin1 ("main");
  2140. }
  2141. catch (jthrowable t)
  2142. {
  2143. return JNI_ERR;
  2144. }
  2145. jint r = _Jv_JNI_AttachCurrentThread (vm, main_name, &env_p,
  2146. NULL, false);
  2147. if (r < 0)
  2148. return r;
  2149. }
  2150. else
  2151. env = _Jv_GetCurrentJNIEnv ();
  2152. _Jv_ThreadWait ();
  2153. // Docs say that this always returns an error code.
  2154. return JNI_ERR;
  2155. }
  2156. jint JNICALL
  2157. _Jv_JNI_DetachCurrentThread (JavaVM *)
  2158. {
  2159. jint code = _Jv_DetachCurrentThread ();
  2160. return code ? JNI_EDETACHED : 0;
  2161. }
  2162. static jint JNICALL
  2163. _Jv_JNI_GetEnv (JavaVM *, void **penv, jint version)
  2164. {
  2165. if (_Jv_ThreadCurrent () == NULL)
  2166. {
  2167. *penv = NULL;
  2168. return JNI_EDETACHED;
  2169. }
  2170. #ifdef ENABLE_JVMPI
  2171. // Handle JVMPI requests.
  2172. if (version == JVMPI_VERSION_1)
  2173. {
  2174. *penv = (void *) &_Jv_JVMPI_Interface;
  2175. return 0;
  2176. }
  2177. #endif
  2178. #ifdef INTERPRETER
  2179. // Handle JVMTI requests
  2180. if (version == JVMTI_VERSION_1_0)
  2181. {
  2182. *penv = (void *) _Jv_GetJVMTIEnv ();
  2183. return 0;
  2184. }
  2185. #endif
  2186. // FIXME: do we really want to support 1.1?
  2187. if (version != JNI_VERSION_1_4 && version != JNI_VERSION_1_2
  2188. && version != JNI_VERSION_1_1)
  2189. {
  2190. *penv = NULL;
  2191. return JNI_EVERSION;
  2192. }
  2193. *penv = (void *) _Jv_GetCurrentJNIEnv ();
  2194. return 0;
  2195. }
  2196. JavaVM *
  2197. _Jv_GetJavaVM ()
  2198. {
  2199. // FIXME: synchronize
  2200. if (! _Jv_the_vm)
  2201. {
  2202. JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
  2203. if (nvm != NULL)
  2204. nvm->functions = &_Jv_JNI_InvokeFunctions;
  2205. _Jv_the_vm = nvm;
  2206. }
  2207. // If this is a Java thread, we want to make sure it has an
  2208. // associated JNIEnv.
  2209. if (_Jv_ThreadCurrent () != NULL)
  2210. {
  2211. void *ignore;
  2212. _Jv_JNI_AttachCurrentThread (_Jv_the_vm, &ignore, NULL);
  2213. }
  2214. return _Jv_the_vm;
  2215. }
  2216. static jint JNICALL
  2217. _Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm)
  2218. {
  2219. *vm = _Jv_GetJavaVM ();
  2220. return *vm == NULL ? JNI_ERR : JNI_OK;
  2221. }
  2222. #define RESERVED NULL
  2223. struct JNINativeInterface_ _Jv_JNIFunctions =
  2224. {
  2225. RESERVED,
  2226. RESERVED,
  2227. RESERVED,
  2228. RESERVED,
  2229. _Jv_JNI_GetVersion, // GetVersion
  2230. _Jv_JNI_DefineClass, // DefineClass
  2231. _Jv_JNI_FindClass, // FindClass
  2232. _Jv_JNI_FromReflectedMethod, // FromReflectedMethod
  2233. _Jv_JNI_FromReflectedField, // FromReflectedField
  2234. _Jv_JNI_ToReflectedMethod, // ToReflectedMethod
  2235. _Jv_JNI_GetSuperclass, // GetSuperclass
  2236. _Jv_JNI_IsAssignableFrom, // IsAssignableFrom
  2237. _Jv_JNI_ToReflectedField, // ToReflectedField
  2238. _Jv_JNI_Throw, // Throw
  2239. _Jv_JNI_ThrowNew, // ThrowNew
  2240. _Jv_JNI_ExceptionOccurred, // ExceptionOccurred
  2241. _Jv_JNI_ExceptionDescribe, // ExceptionDescribe
  2242. _Jv_JNI_ExceptionClear, // ExceptionClear
  2243. _Jv_JNI_FatalError, // FatalError
  2244. _Jv_JNI_PushLocalFrame, // PushLocalFrame
  2245. _Jv_JNI_PopLocalFrame, // PopLocalFrame
  2246. _Jv_JNI_NewGlobalRef, // NewGlobalRef
  2247. _Jv_JNI_DeleteGlobalRef, // DeleteGlobalRef
  2248. _Jv_JNI_DeleteLocalRef, // DeleteLocalRef
  2249. _Jv_JNI_IsSameObject, // IsSameObject
  2250. _Jv_JNI_NewLocalRef, // NewLocalRef
  2251. _Jv_JNI_EnsureLocalCapacity, // EnsureLocalCapacity
  2252. _Jv_JNI_AllocObject, // AllocObject
  2253. _Jv_JNI_NewObject, // NewObject
  2254. _Jv_JNI_NewObjectV, // NewObjectV
  2255. _Jv_JNI_NewObjectA, // NewObjectA
  2256. _Jv_JNI_GetObjectClass, // GetObjectClass
  2257. _Jv_JNI_IsInstanceOf, // IsInstanceOf
  2258. _Jv_JNI_GetAnyMethodID<false>, // GetMethodID
  2259. _Jv_JNI_CallMethod<jobject>, // CallObjectMethod
  2260. _Jv_JNI_CallMethodV<jobject>, // CallObjectMethodV
  2261. _Jv_JNI_CallMethodA<jobject>, // CallObjectMethodA
  2262. _Jv_JNI_CallMethod<jboolean>, // CallBooleanMethod
  2263. _Jv_JNI_CallMethodV<jboolean>, // CallBooleanMethodV
  2264. _Jv_JNI_CallMethodA<jboolean>, // CallBooleanMethodA
  2265. _Jv_JNI_CallMethod<jbyte>, // CallByteMethod
  2266. _Jv_JNI_CallMethodV<jbyte>, // CallByteMethodV
  2267. _Jv_JNI_CallMethodA<jbyte>, // CallByteMethodA
  2268. _Jv_JNI_CallMethod<jchar>, // CallCharMethod
  2269. _Jv_JNI_CallMethodV<jchar>, // CallCharMethodV
  2270. _Jv_JNI_CallMethodA<jchar>, // CallCharMethodA
  2271. _Jv_JNI_CallMethod<jshort>, // CallShortMethod
  2272. _Jv_JNI_CallMethodV<jshort>, // CallShortMethodV
  2273. _Jv_JNI_CallMethodA<jshort>, // CallShortMethodA
  2274. _Jv_JNI_CallMethod<jint>, // CallIntMethod
  2275. _Jv_JNI_CallMethodV<jint>, // CallIntMethodV
  2276. _Jv_JNI_CallMethodA<jint>, // CallIntMethodA
  2277. _Jv_JNI_CallMethod<jlong>, // CallLongMethod
  2278. _Jv_JNI_CallMethodV<jlong>, // CallLongMethodV
  2279. _Jv_JNI_CallMethodA<jlong>, // CallLongMethodA
  2280. _Jv_JNI_CallMethod<jfloat>, // CallFloatMethod
  2281. _Jv_JNI_CallMethodV<jfloat>, // CallFloatMethodV
  2282. _Jv_JNI_CallMethodA<jfloat>, // CallFloatMethodA
  2283. _Jv_JNI_CallMethod<jdouble>, // CallDoubleMethod
  2284. _Jv_JNI_CallMethodV<jdouble>, // CallDoubleMethodV
  2285. _Jv_JNI_CallMethodA<jdouble>, // CallDoubleMethodA
  2286. _Jv_JNI_CallVoidMethod, // CallVoidMethod
  2287. _Jv_JNI_CallVoidMethodV, // CallVoidMethodV
  2288. _Jv_JNI_CallVoidMethodA, // CallVoidMethodA
  2289. // Nonvirtual method invocation functions follow.
  2290. _Jv_JNI_CallAnyMethod<jobject, nonvirtual>, // CallNonvirtualObjectMethod
  2291. _Jv_JNI_CallAnyMethodV<jobject, nonvirtual>, // CallNonvirtualObjectMethodV
  2292. _Jv_JNI_CallAnyMethodA<jobject, nonvirtual>, // CallNonvirtualObjectMethodA
  2293. _Jv_JNI_CallAnyMethod<jboolean, nonvirtual>, // CallNonvirtualBooleanMethod
  2294. _Jv_JNI_CallAnyMethodV<jboolean, nonvirtual>, // CallNonvirtualBooleanMethodV
  2295. _Jv_JNI_CallAnyMethodA<jboolean, nonvirtual>, // CallNonvirtualBooleanMethodA
  2296. _Jv_JNI_CallAnyMethod<jbyte, nonvirtual>, // CallNonvirtualByteMethod
  2297. _Jv_JNI_CallAnyMethodV<jbyte, nonvirtual>, // CallNonvirtualByteMethodV
  2298. _Jv_JNI_CallAnyMethodA<jbyte, nonvirtual>, // CallNonvirtualByteMethodA
  2299. _Jv_JNI_CallAnyMethod<jchar, nonvirtual>, // CallNonvirtualCharMethod
  2300. _Jv_JNI_CallAnyMethodV<jchar, nonvirtual>, // CallNonvirtualCharMethodV
  2301. _Jv_JNI_CallAnyMethodA<jchar, nonvirtual>, // CallNonvirtualCharMethodA
  2302. _Jv_JNI_CallAnyMethod<jshort, nonvirtual>, // CallNonvirtualShortMethod
  2303. _Jv_JNI_CallAnyMethodV<jshort, nonvirtual>, // CallNonvirtualShortMethodV
  2304. _Jv_JNI_CallAnyMethodA<jshort, nonvirtual>, // CallNonvirtualShortMethodA
  2305. _Jv_JNI_CallAnyMethod<jint, nonvirtual>, // CallNonvirtualIntMethod
  2306. _Jv_JNI_CallAnyMethodV<jint, nonvirtual>, // CallNonvirtualIntMethodV
  2307. _Jv_JNI_CallAnyMethodA<jint, nonvirtual>, // CallNonvirtualIntMethodA
  2308. _Jv_JNI_CallAnyMethod<jlong, nonvirtual>, // CallNonvirtualLongMethod
  2309. _Jv_JNI_CallAnyMethodV<jlong, nonvirtual>, // CallNonvirtualLongMethodV
  2310. _Jv_JNI_CallAnyMethodA<jlong, nonvirtual>, // CallNonvirtualLongMethodA
  2311. _Jv_JNI_CallAnyMethod<jfloat, nonvirtual>, // CallNonvirtualFloatMethod
  2312. _Jv_JNI_CallAnyMethodV<jfloat, nonvirtual>, // CallNonvirtualFloatMethodV
  2313. _Jv_JNI_CallAnyMethodA<jfloat, nonvirtual>, // CallNonvirtualFloatMethodA
  2314. _Jv_JNI_CallAnyMethod<jdouble, nonvirtual>, // CallNonvirtualDoubleMethod
  2315. _Jv_JNI_CallAnyMethodV<jdouble, nonvirtual>, // CallNonvirtualDoubleMethodV
  2316. _Jv_JNI_CallAnyMethodA<jdouble, nonvirtual>, // CallNonvirtualDoubleMethodA
  2317. _Jv_JNI_CallAnyVoidMethod<nonvirtual>, // CallNonvirtualVoidMethod
  2318. _Jv_JNI_CallAnyVoidMethodV<nonvirtual>, // CallNonvirtualVoidMethodV
  2319. _Jv_JNI_CallAnyVoidMethodA<nonvirtual>, // CallNonvirtualVoidMethodA
  2320. _Jv_JNI_GetAnyFieldID<false>, // GetFieldID
  2321. _Jv_JNI_GetField<jobject>, // GetObjectField
  2322. _Jv_JNI_GetField<jboolean>, // GetBooleanField
  2323. _Jv_JNI_GetField<jbyte>, // GetByteField
  2324. _Jv_JNI_GetField<jchar>, // GetCharField
  2325. _Jv_JNI_GetField<jshort>, // GetShortField
  2326. _Jv_JNI_GetField<jint>, // GetIntField
  2327. _Jv_JNI_GetField<jlong>, // GetLongField
  2328. _Jv_JNI_GetField<jfloat>, // GetFloatField
  2329. _Jv_JNI_GetField<jdouble>, // GetDoubleField
  2330. _Jv_JNI_SetField, // SetObjectField
  2331. _Jv_JNI_SetField, // SetBooleanField
  2332. _Jv_JNI_SetField, // SetByteField
  2333. _Jv_JNI_SetField, // SetCharField
  2334. _Jv_JNI_SetField, // SetShortField
  2335. _Jv_JNI_SetField, // SetIntField
  2336. _Jv_JNI_SetField, // SetLongField
  2337. _Jv_JNI_SetField, // SetFloatField
  2338. _Jv_JNI_SetField, // SetDoubleField
  2339. _Jv_JNI_GetAnyMethodID<true>, // GetStaticMethodID
  2340. _Jv_JNI_CallStaticMethod<jobject>, // CallStaticObjectMethod
  2341. _Jv_JNI_CallStaticMethodV<jobject>, // CallStaticObjectMethodV
  2342. _Jv_JNI_CallStaticMethodA<jobject>, // CallStaticObjectMethodA
  2343. _Jv_JNI_CallStaticMethod<jboolean>, // CallStaticBooleanMethod
  2344. _Jv_JNI_CallStaticMethodV<jboolean>, // CallStaticBooleanMethodV
  2345. _Jv_JNI_CallStaticMethodA<jboolean>, // CallStaticBooleanMethodA
  2346. _Jv_JNI_CallStaticMethod<jbyte>, // CallStaticByteMethod
  2347. _Jv_JNI_CallStaticMethodV<jbyte>, // CallStaticByteMethodV
  2348. _Jv_JNI_CallStaticMethodA<jbyte>, // CallStaticByteMethodA
  2349. _Jv_JNI_CallStaticMethod<jchar>, // CallStaticCharMethod
  2350. _Jv_JNI_CallStaticMethodV<jchar>, // CallStaticCharMethodV
  2351. _Jv_JNI_CallStaticMethodA<jchar>, // CallStaticCharMethodA
  2352. _Jv_JNI_CallStaticMethod<jshort>, // CallStaticShortMethod
  2353. _Jv_JNI_CallStaticMethodV<jshort>, // CallStaticShortMethodV
  2354. _Jv_JNI_CallStaticMethodA<jshort>, // CallStaticShortMethodA
  2355. _Jv_JNI_CallStaticMethod<jint>, // CallStaticIntMethod
  2356. _Jv_JNI_CallStaticMethodV<jint>, // CallStaticIntMethodV
  2357. _Jv_JNI_CallStaticMethodA<jint>, // CallStaticIntMethodA
  2358. _Jv_JNI_CallStaticMethod<jlong>, // CallStaticLongMethod
  2359. _Jv_JNI_CallStaticMethodV<jlong>, // CallStaticLongMethodV
  2360. _Jv_JNI_CallStaticMethodA<jlong>, // CallStaticLongMethodA
  2361. _Jv_JNI_CallStaticMethod<jfloat>, // CallStaticFloatMethod
  2362. _Jv_JNI_CallStaticMethodV<jfloat>, // CallStaticFloatMethodV
  2363. _Jv_JNI_CallStaticMethodA<jfloat>, // CallStaticFloatMethodA
  2364. _Jv_JNI_CallStaticMethod<jdouble>, // CallStaticDoubleMethod
  2365. _Jv_JNI_CallStaticMethodV<jdouble>, // CallStaticDoubleMethodV
  2366. _Jv_JNI_CallStaticMethodA<jdouble>, // CallStaticDoubleMethodA
  2367. _Jv_JNI_CallStaticVoidMethod, // CallStaticVoidMethod
  2368. _Jv_JNI_CallStaticVoidMethodV, // CallStaticVoidMethodV
  2369. _Jv_JNI_CallStaticVoidMethodA, // CallStaticVoidMethodA
  2370. _Jv_JNI_GetAnyFieldID<true>, // GetStaticFieldID
  2371. _Jv_JNI_GetStaticField<jobject>, // GetStaticObjectField
  2372. _Jv_JNI_GetStaticField<jboolean>, // GetStaticBooleanField
  2373. _Jv_JNI_GetStaticField<jbyte>, // GetStaticByteField
  2374. _Jv_JNI_GetStaticField<jchar>, // GetStaticCharField
  2375. _Jv_JNI_GetStaticField<jshort>, // GetStaticShortField
  2376. _Jv_JNI_GetStaticField<jint>, // GetStaticIntField
  2377. _Jv_JNI_GetStaticField<jlong>, // GetStaticLongField
  2378. _Jv_JNI_GetStaticField<jfloat>, // GetStaticFloatField
  2379. _Jv_JNI_GetStaticField<jdouble>, // GetStaticDoubleField
  2380. _Jv_JNI_SetStaticField, // SetStaticObjectField
  2381. _Jv_JNI_SetStaticField, // SetStaticBooleanField
  2382. _Jv_JNI_SetStaticField, // SetStaticByteField
  2383. _Jv_JNI_SetStaticField, // SetStaticCharField
  2384. _Jv_JNI_SetStaticField, // SetStaticShortField
  2385. _Jv_JNI_SetStaticField, // SetStaticIntField
  2386. _Jv_JNI_SetStaticField, // SetStaticLongField
  2387. _Jv_JNI_SetStaticField, // SetStaticFloatField
  2388. _Jv_JNI_SetStaticField, // SetStaticDoubleField
  2389. _Jv_JNI_NewString, // NewString
  2390. _Jv_JNI_GetStringLength, // GetStringLength
  2391. _Jv_JNI_GetStringChars, // GetStringChars
  2392. _Jv_JNI_ReleaseStringChars, // ReleaseStringChars
  2393. _Jv_JNI_NewStringUTF, // NewStringUTF
  2394. _Jv_JNI_GetStringUTFLength, // GetStringUTFLength
  2395. _Jv_JNI_GetStringUTFChars, // GetStringUTFChars
  2396. _Jv_JNI_ReleaseStringUTFChars, // ReleaseStringUTFChars
  2397. _Jv_JNI_GetArrayLength, // GetArrayLength
  2398. _Jv_JNI_NewObjectArray, // NewObjectArray
  2399. _Jv_JNI_GetObjectArrayElement, // GetObjectArrayElement
  2400. _Jv_JNI_SetObjectArrayElement, // SetObjectArrayElement
  2401. _Jv_JNI_NewPrimitiveArray<jboolean, JvPrimClass (boolean)>,
  2402. // NewBooleanArray
  2403. _Jv_JNI_NewPrimitiveArray<jbyte, JvPrimClass (byte)>, // NewByteArray
  2404. _Jv_JNI_NewPrimitiveArray<jchar, JvPrimClass (char)>, // NewCharArray
  2405. _Jv_JNI_NewPrimitiveArray<jshort, JvPrimClass (short)>, // NewShortArray
  2406. _Jv_JNI_NewPrimitiveArray<jint, JvPrimClass (int)>, // NewIntArray
  2407. _Jv_JNI_NewPrimitiveArray<jlong, JvPrimClass (long)>, // NewLongArray
  2408. _Jv_JNI_NewPrimitiveArray<jfloat, JvPrimClass (float)>, // NewFloatArray
  2409. _Jv_JNI_NewPrimitiveArray<jdouble, JvPrimClass (double)>, // NewDoubleArray
  2410. _Jv_JNI_GetPrimitiveArrayElements<jboolean, JvPrimClass (boolean)>,
  2411. // GetBooleanArrayElements
  2412. _Jv_JNI_GetPrimitiveArrayElements<jbyte, JvPrimClass (byte)>,
  2413. // GetByteArrayElements
  2414. _Jv_JNI_GetPrimitiveArrayElements<jchar, JvPrimClass (char)>,
  2415. // GetCharArrayElements
  2416. _Jv_JNI_GetPrimitiveArrayElements<jshort, JvPrimClass (short)>,
  2417. // GetShortArrayElements
  2418. _Jv_JNI_GetPrimitiveArrayElements<jint, JvPrimClass (int)>,
  2419. // GetIntArrayElements
  2420. _Jv_JNI_GetPrimitiveArrayElements<jlong, JvPrimClass (long)>,
  2421. // GetLongArrayElements
  2422. _Jv_JNI_GetPrimitiveArrayElements<jfloat, JvPrimClass (float)>,
  2423. // GetFloatArrayElements
  2424. _Jv_JNI_GetPrimitiveArrayElements<jdouble, JvPrimClass (double)>,
  2425. // GetDoubleArrayElements
  2426. _Jv_JNI_ReleasePrimitiveArrayElements<jboolean, JvPrimClass (boolean)>,
  2427. // ReleaseBooleanArrayElements
  2428. _Jv_JNI_ReleasePrimitiveArrayElements<jbyte, JvPrimClass (byte)>,
  2429. // ReleaseByteArrayElements
  2430. _Jv_JNI_ReleasePrimitiveArrayElements<jchar, JvPrimClass (char)>,
  2431. // ReleaseCharArrayElements
  2432. _Jv_JNI_ReleasePrimitiveArrayElements<jshort, JvPrimClass (short)>,
  2433. // ReleaseShortArrayElements
  2434. _Jv_JNI_ReleasePrimitiveArrayElements<jint, JvPrimClass (int)>,
  2435. // ReleaseIntArrayElements
  2436. _Jv_JNI_ReleasePrimitiveArrayElements<jlong, JvPrimClass (long)>,
  2437. // ReleaseLongArrayElements
  2438. _Jv_JNI_ReleasePrimitiveArrayElements<jfloat, JvPrimClass (float)>,
  2439. // ReleaseFloatArrayElements
  2440. _Jv_JNI_ReleasePrimitiveArrayElements<jdouble, JvPrimClass (double)>,
  2441. // ReleaseDoubleArrayElements
  2442. _Jv_JNI_GetPrimitiveArrayRegion<jboolean, JvPrimClass (boolean)>,
  2443. // GetBooleanArrayRegion
  2444. _Jv_JNI_GetPrimitiveArrayRegion<jbyte, JvPrimClass (byte)>,
  2445. // GetByteArrayRegion
  2446. _Jv_JNI_GetPrimitiveArrayRegion<jchar, JvPrimClass (char)>,
  2447. // GetCharArrayRegion
  2448. _Jv_JNI_GetPrimitiveArrayRegion<jshort, JvPrimClass (short)>,
  2449. // GetShortArrayRegion
  2450. _Jv_JNI_GetPrimitiveArrayRegion<jint, JvPrimClass (int)>,
  2451. // GetIntArrayRegion
  2452. _Jv_JNI_GetPrimitiveArrayRegion<jlong, JvPrimClass (long)>,
  2453. // GetLongArrayRegion
  2454. _Jv_JNI_GetPrimitiveArrayRegion<jfloat, JvPrimClass (float)>,
  2455. // GetFloatArrayRegion
  2456. _Jv_JNI_GetPrimitiveArrayRegion<jdouble, JvPrimClass (double)>,
  2457. // GetDoubleArrayRegion
  2458. _Jv_JNI_SetPrimitiveArrayRegion<jboolean, JvPrimClass (boolean)>,
  2459. // SetBooleanArrayRegion
  2460. _Jv_JNI_SetPrimitiveArrayRegion<jbyte, JvPrimClass (byte)>,
  2461. // SetByteArrayRegion
  2462. _Jv_JNI_SetPrimitiveArrayRegion<jchar, JvPrimClass (char)>,
  2463. // SetCharArrayRegion
  2464. _Jv_JNI_SetPrimitiveArrayRegion<jshort, JvPrimClass (short)>,
  2465. // SetShortArrayRegion
  2466. _Jv_JNI_SetPrimitiveArrayRegion<jint, JvPrimClass (int)>,
  2467. // SetIntArrayRegion
  2468. _Jv_JNI_SetPrimitiveArrayRegion<jlong, JvPrimClass (long)>,
  2469. // SetLongArrayRegion
  2470. _Jv_JNI_SetPrimitiveArrayRegion<jfloat, JvPrimClass (float)>,
  2471. // SetFloatArrayRegion
  2472. _Jv_JNI_SetPrimitiveArrayRegion<jdouble, JvPrimClass (double)>,
  2473. // SetDoubleArrayRegion
  2474. _Jv_JNI_RegisterNatives, // RegisterNatives
  2475. _Jv_JNI_UnregisterNatives, // UnregisterNatives
  2476. _Jv_JNI_MonitorEnter, // MonitorEnter
  2477. _Jv_JNI_MonitorExit, // MonitorExit
  2478. _Jv_JNI_GetJavaVM, // GetJavaVM
  2479. _Jv_JNI_GetStringRegion, // GetStringRegion
  2480. _Jv_JNI_GetStringUTFRegion, // GetStringUTFRegion
  2481. _Jv_JNI_GetPrimitiveArrayCritical, // GetPrimitiveArrayCritical
  2482. _Jv_JNI_ReleasePrimitiveArrayCritical, // ReleasePrimitiveArrayCritical
  2483. _Jv_JNI_GetStringCritical, // GetStringCritical
  2484. _Jv_JNI_ReleaseStringCritical, // ReleaseStringCritical
  2485. _Jv_JNI_NewWeakGlobalRef, // NewWeakGlobalRef
  2486. _Jv_JNI_DeleteWeakGlobalRef, // DeleteWeakGlobalRef
  2487. _Jv_JNI_ExceptionCheck, // ExceptionCheck
  2488. _Jv_JNI_NewDirectByteBuffer, // NewDirectByteBuffer
  2489. _Jv_JNI_GetDirectBufferAddress, // GetDirectBufferAddress
  2490. _Jv_JNI_GetDirectBufferCapacity, // GetDirectBufferCapacity
  2491. _Jv_JNI_GetObjectRefType // GetObjectRefType
  2492. };
  2493. struct JNIInvokeInterface_ _Jv_JNI_InvokeFunctions =
  2494. {
  2495. RESERVED,
  2496. RESERVED,
  2497. RESERVED,
  2498. _Jv_JNI_DestroyJavaVM,
  2499. _Jv_JNI_AttachCurrentThread,
  2500. _Jv_JNI_DetachCurrentThread,
  2501. _Jv_JNI_GetEnv,
  2502. _Jv_JNI_AttachCurrentThreadAsDaemon
  2503. };