jni.cc 73 KB

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