interpret-run.cc 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697
  1. // interpret-run.cc - Code to interpret bytecode
  2. /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 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. /* This file is meant only to be included in interpret.cc, it should not be
  8. * compiled directly. */
  9. using namespace java::lang::reflect;
  10. pc_t pc = NULL;
  11. // FRAME_DESC registers this particular invocation as the top-most
  12. // interpreter frame. This lets the stack tracing code (for
  13. // Throwable) print information about the method being interpreted
  14. // rather than about the interpreter itself. FRAME_DESC has a
  15. // destructor so it cleans up automatically when the interpreter
  16. // returns.
  17. java::lang::Thread *thread = java::lang::Thread::currentThread();
  18. #ifdef __GCJ_DEBUG
  19. _Jv_InterpFrame frame_desc (meth, thread, NULL, &pc);
  20. #else
  21. _Jv_InterpFrame frame_desc (meth, thread);
  22. #endif
  23. #ifdef DIRECT_THREADED
  24. ThreadCountAdjuster adj (meth, &frame_desc);
  25. #endif // DIRECT_THREADED
  26. _Jv_word stack[meth->max_stack];
  27. _Jv_word *sp = stack;
  28. _Jv_word locals[meth->max_locals];
  29. #ifdef __GCJ_DEBUG
  30. // This is the information needed to get and set local variables with
  31. // proper type checking.
  32. frame_desc.locals = locals;
  33. char locals_type[meth->max_locals];
  34. frame_desc.locals_type = locals_type;
  35. // Set all slots as invalid until they are written to.
  36. memset (locals_type, 'x', meth->max_locals);
  37. // We need to set the local variable types for the method arguments since
  38. // they are valid at invocation.
  39. _Jv_Method *method = meth->get_method ();
  40. int type_ctr = 0;
  41. // If the method is non-static, we need to set the type for the "this" pointer.
  42. if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
  43. {
  44. if (args)
  45. {
  46. // Set the "this" pointer for this frame.
  47. _Jv_word *this_ptr = reinterpret_cast<_Jv_word *> (args);
  48. frame_desc.obj_ptr = this_ptr[0].o;
  49. }
  50. frame_desc.locals_type[0] = 'o';
  51. type_ctr++;
  52. }
  53. // Now parse the method signature to set the types of the other arguments.
  54. int sig_len = method->signature->len ();
  55. char *signature = method->signature->chars ();
  56. for (int i = 1; signature[i] != ')' && i <= sig_len; i++)
  57. {
  58. if (signature[i] == 'Z' || signature[i] == 'B' || signature[i] == 'C'
  59. || signature[i] == 'S' || signature[i] == 'I')
  60. {
  61. frame_desc.locals_type[type_ctr] = 'i';
  62. type_ctr++;
  63. continue;
  64. }
  65. else if (signature[i] == 'F')
  66. {
  67. frame_desc.locals_type[type_ctr] = 'f';
  68. type_ctr++;
  69. continue;
  70. }
  71. else if (signature[i] == 'J')
  72. {
  73. frame_desc.locals_type[type_ctr] = 'l';
  74. frame_desc.locals_type[type_ctr+1] = 'x';
  75. type_ctr += 2;
  76. continue;
  77. }
  78. else if (signature[i] == 'D')
  79. {
  80. frame_desc.locals_type[type_ctr] = 'd';
  81. frame_desc.locals_type[type_ctr+1] = 'x';
  82. type_ctr += 2;
  83. continue;
  84. }
  85. else if (signature[i] == 'L')
  86. {
  87. frame_desc.locals_type[type_ctr] = 'o';
  88. type_ctr++;
  89. while (signature[i] != ';')
  90. i++;
  91. continue;
  92. }
  93. else if (signature[i] == '[')
  94. {
  95. frame_desc.locals_type[type_ctr] = 'o';
  96. type_ctr++;
  97. // Ignore multi-dimensional arrays.
  98. while (signature[i] == '[')
  99. i++;
  100. // Check for an object array
  101. if (signature[i] == 'L')
  102. {
  103. while (signature[i] != ';')
  104. i++;
  105. }
  106. continue;
  107. }
  108. }
  109. #endif /* __GCJ_DEBUG */
  110. #define INSN_LABEL(op) &&insn_##op
  111. static const void *const insn_target[] =
  112. {
  113. INSN_LABEL(nop),
  114. INSN_LABEL(aconst_null),
  115. INSN_LABEL(iconst_m1),
  116. INSN_LABEL(iconst_0),
  117. INSN_LABEL(iconst_1),
  118. INSN_LABEL(iconst_2),
  119. INSN_LABEL(iconst_3),
  120. INSN_LABEL(iconst_4),
  121. INSN_LABEL(iconst_5),
  122. INSN_LABEL(lconst_0),
  123. INSN_LABEL(lconst_1),
  124. INSN_LABEL(fconst_0),
  125. INSN_LABEL(fconst_1),
  126. INSN_LABEL(fconst_2),
  127. INSN_LABEL(dconst_0),
  128. INSN_LABEL(dconst_1),
  129. INSN_LABEL(bipush),
  130. INSN_LABEL(sipush),
  131. INSN_LABEL(ldc),
  132. INSN_LABEL(ldc_w),
  133. INSN_LABEL(ldc2_w),
  134. INSN_LABEL(iload),
  135. INSN_LABEL(lload),
  136. INSN_LABEL(fload),
  137. INSN_LABEL(dload),
  138. INSN_LABEL(aload),
  139. INSN_LABEL(iload_0),
  140. INSN_LABEL(iload_1),
  141. INSN_LABEL(iload_2),
  142. INSN_LABEL(iload_3),
  143. INSN_LABEL(lload_0),
  144. INSN_LABEL(lload_1),
  145. INSN_LABEL(lload_2),
  146. INSN_LABEL(lload_3),
  147. INSN_LABEL(fload_0),
  148. INSN_LABEL(fload_1),
  149. INSN_LABEL(fload_2),
  150. INSN_LABEL(fload_3),
  151. INSN_LABEL(dload_0),
  152. INSN_LABEL(dload_1),
  153. INSN_LABEL(dload_2),
  154. INSN_LABEL(dload_3),
  155. INSN_LABEL(aload_0),
  156. INSN_LABEL(aload_1),
  157. INSN_LABEL(aload_2),
  158. INSN_LABEL(aload_3),
  159. INSN_LABEL(iaload),
  160. INSN_LABEL(laload),
  161. INSN_LABEL(faload),
  162. INSN_LABEL(daload),
  163. INSN_LABEL(aaload),
  164. INSN_LABEL(baload),
  165. INSN_LABEL(caload),
  166. INSN_LABEL(saload),
  167. INSN_LABEL(istore),
  168. INSN_LABEL(lstore),
  169. INSN_LABEL(fstore),
  170. INSN_LABEL(dstore),
  171. INSN_LABEL(astore),
  172. INSN_LABEL(istore_0),
  173. INSN_LABEL(istore_1),
  174. INSN_LABEL(istore_2),
  175. INSN_LABEL(istore_3),
  176. INSN_LABEL(lstore_0),
  177. INSN_LABEL(lstore_1),
  178. INSN_LABEL(lstore_2),
  179. INSN_LABEL(lstore_3),
  180. INSN_LABEL(fstore_0),
  181. INSN_LABEL(fstore_1),
  182. INSN_LABEL(fstore_2),
  183. INSN_LABEL(fstore_3),
  184. INSN_LABEL(dstore_0),
  185. INSN_LABEL(dstore_1),
  186. INSN_LABEL(dstore_2),
  187. INSN_LABEL(dstore_3),
  188. INSN_LABEL(astore_0),
  189. INSN_LABEL(astore_1),
  190. INSN_LABEL(astore_2),
  191. INSN_LABEL(astore_3),
  192. INSN_LABEL(iastore),
  193. INSN_LABEL(lastore),
  194. INSN_LABEL(fastore),
  195. INSN_LABEL(dastore),
  196. INSN_LABEL(aastore),
  197. INSN_LABEL(bastore),
  198. INSN_LABEL(castore),
  199. INSN_LABEL(sastore),
  200. INSN_LABEL(pop),
  201. INSN_LABEL(pop2),
  202. INSN_LABEL(dup),
  203. INSN_LABEL(dup_x1),
  204. INSN_LABEL(dup_x2),
  205. INSN_LABEL(dup2),
  206. INSN_LABEL(dup2_x1),
  207. INSN_LABEL(dup2_x2),
  208. INSN_LABEL(swap),
  209. INSN_LABEL(iadd),
  210. INSN_LABEL(ladd),
  211. INSN_LABEL(fadd),
  212. INSN_LABEL(dadd),
  213. INSN_LABEL(isub),
  214. INSN_LABEL(lsub),
  215. INSN_LABEL(fsub),
  216. INSN_LABEL(dsub),
  217. INSN_LABEL(imul),
  218. INSN_LABEL(lmul),
  219. INSN_LABEL(fmul),
  220. INSN_LABEL(dmul),
  221. INSN_LABEL(idiv),
  222. INSN_LABEL(ldiv),
  223. INSN_LABEL(fdiv),
  224. INSN_LABEL(ddiv),
  225. INSN_LABEL(irem),
  226. INSN_LABEL(lrem),
  227. INSN_LABEL(frem),
  228. INSN_LABEL(drem),
  229. INSN_LABEL(ineg),
  230. INSN_LABEL(lneg),
  231. INSN_LABEL(fneg),
  232. INSN_LABEL(dneg),
  233. INSN_LABEL(ishl),
  234. INSN_LABEL(lshl),
  235. INSN_LABEL(ishr),
  236. INSN_LABEL(lshr),
  237. INSN_LABEL(iushr),
  238. INSN_LABEL(lushr),
  239. INSN_LABEL(iand),
  240. INSN_LABEL(land),
  241. INSN_LABEL(ior),
  242. INSN_LABEL(lor),
  243. INSN_LABEL(ixor),
  244. INSN_LABEL(lxor),
  245. INSN_LABEL(iinc),
  246. INSN_LABEL(i2l),
  247. INSN_LABEL(i2f),
  248. INSN_LABEL(i2d),
  249. INSN_LABEL(l2i),
  250. INSN_LABEL(l2f),
  251. INSN_LABEL(l2d),
  252. INSN_LABEL(f2i),
  253. INSN_LABEL(f2l),
  254. INSN_LABEL(f2d),
  255. INSN_LABEL(d2i),
  256. INSN_LABEL(d2l),
  257. INSN_LABEL(d2f),
  258. INSN_LABEL(i2b),
  259. INSN_LABEL(i2c),
  260. INSN_LABEL(i2s),
  261. INSN_LABEL(lcmp),
  262. INSN_LABEL(fcmpl),
  263. INSN_LABEL(fcmpg),
  264. INSN_LABEL(dcmpl),
  265. INSN_LABEL(dcmpg),
  266. INSN_LABEL(ifeq),
  267. INSN_LABEL(ifne),
  268. INSN_LABEL(iflt),
  269. INSN_LABEL(ifge),
  270. INSN_LABEL(ifgt),
  271. INSN_LABEL(ifle),
  272. INSN_LABEL(if_icmpeq),
  273. INSN_LABEL(if_icmpne),
  274. INSN_LABEL(if_icmplt),
  275. INSN_LABEL(if_icmpge),
  276. INSN_LABEL(if_icmpgt),
  277. INSN_LABEL(if_icmple),
  278. INSN_LABEL(if_acmpeq),
  279. INSN_LABEL(if_acmpne),
  280. INSN_LABEL(goto),
  281. INSN_LABEL(jsr),
  282. INSN_LABEL(ret),
  283. INSN_LABEL(tableswitch),
  284. INSN_LABEL(lookupswitch),
  285. INSN_LABEL(ireturn),
  286. INSN_LABEL(lreturn),
  287. INSN_LABEL(freturn),
  288. INSN_LABEL(dreturn),
  289. INSN_LABEL(areturn),
  290. INSN_LABEL(return),
  291. INSN_LABEL(getstatic),
  292. INSN_LABEL(putstatic),
  293. INSN_LABEL(getfield),
  294. INSN_LABEL(putfield),
  295. INSN_LABEL(invokevirtual),
  296. INSN_LABEL(invokespecial),
  297. INSN_LABEL(invokestatic),
  298. INSN_LABEL(invokeinterface),
  299. INSN_LABEL(breakpoint),
  300. INSN_LABEL(new),
  301. INSN_LABEL(newarray),
  302. INSN_LABEL(anewarray),
  303. INSN_LABEL(arraylength),
  304. INSN_LABEL(athrow),
  305. INSN_LABEL(checkcast),
  306. INSN_LABEL(instanceof),
  307. INSN_LABEL(monitorenter),
  308. INSN_LABEL(monitorexit),
  309. #ifdef DIRECT_THREADED
  310. 0, // wide
  311. #else
  312. INSN_LABEL(wide),
  313. #endif
  314. INSN_LABEL(multianewarray),
  315. INSN_LABEL(ifnull),
  316. INSN_LABEL(ifnonnull),
  317. INSN_LABEL(goto_w),
  318. INSN_LABEL(jsr_w),
  319. #ifdef DIRECT_THREADED
  320. INSN_LABEL (ldc_class)
  321. #else
  322. 0
  323. #endif
  324. };
  325. #ifdef DIRECT_THREADED
  326. #ifdef __GCJ_DEBUG
  327. #undef NEXT_INSN
  328. #define NEXT_INSN \
  329. do \
  330. { \
  331. pc_t insn = pc++; \
  332. if (JVMTI_REQUESTED_EVENT (SingleStep)) \
  333. { \
  334. JNIEnv *env = _Jv_GetCurrentJNIEnv (); \
  335. jmethodID method = meth->self; \
  336. jlocation loc = meth->insn_index (insn); \
  337. _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread, \
  338. env, method, loc); \
  339. } \
  340. goto *(insn->insn); \
  341. } \
  342. while (0)
  343. // We fail to rewrite a breakpoint if there is another thread
  344. // currently executing this method. This is a bug, but there's
  345. // nothing else we can do that doesn't cause a data race.
  346. #undef REWRITE_INSN
  347. #define REWRITE_INSN(INSN,SLOT,VALUE) \
  348. do \
  349. { \
  350. _Jv_MutexLock (&rewrite_insn_mutex); \
  351. if (meth->thread_count <= 1) \
  352. { \
  353. if (pc[-2].insn == breakpoint_insn->insn) \
  354. { \
  355. using namespace ::gnu::gcj::jvmti; \
  356. jlocation location = meth->insn_index (pc - 2); \
  357. _Jv_RewriteBreakpointInsn (meth->self, location, (pc_t) INSN); \
  358. } \
  359. else \
  360. pc[-2].insn = INSN; \
  361. \
  362. pc[-1].SLOT = VALUE; \
  363. } \
  364. _Jv_MutexUnlock (&rewrite_insn_mutex); \
  365. } \
  366. while (0)
  367. #undef INTERP_REPORT_EXCEPTION
  368. #define INTERP_REPORT_EXCEPTION(Jthrowable) REPORT_EXCEPTION (Jthrowable)
  369. #else // !__GCJ_DEBUG
  370. #undef NEXT_INSN
  371. #define NEXT_INSN goto *((pc++)->insn)
  372. // Rewriting a multi-word instruction in the presence of multiple
  373. // threads is a data race if a thread reads part of an instruction
  374. // while some other thread is rewriting that instruction. We detect
  375. // more than one thread executing a method and don't rewrite the
  376. // instruction. A thread entering a method blocks on
  377. // rewrite_insn_mutex until the write is complete.
  378. #define REWRITE_INSN(INSN,SLOT,VALUE) \
  379. do { \
  380. _Jv_MutexLock (&rewrite_insn_mutex); \
  381. if (meth->thread_count <= 1) \
  382. { \
  383. pc[-2].insn = INSN; \
  384. pc[-1].SLOT = VALUE; \
  385. } \
  386. _Jv_MutexUnlock (&rewrite_insn_mutex); \
  387. } \
  388. while (0)
  389. #undef INTERP_REPORT_EXCEPTION
  390. #define INTERP_REPORT_EXCEPTION(Jthrowable) /* not needed when not debugging */
  391. #endif // !__GCJ_DEBUG
  392. #define INTVAL() ((pc++)->int_val)
  393. #define AVAL() ((pc++)->datum)
  394. #define GET1S() INTVAL ()
  395. #define GET2S() INTVAL ()
  396. #define GET1U() INTVAL ()
  397. #define GET2U() INTVAL ()
  398. #define AVAL1U() AVAL ()
  399. #define AVAL2U() AVAL ()
  400. #define AVAL2UP() AVAL ()
  401. #define SKIP_GOTO ++pc
  402. #define GOTO_VAL() (insn_slot *) pc->datum
  403. #define PCVAL(unionval) unionval.p
  404. #define AMPAMP(label) &&label
  405. // Compile if we must. NOTE: Double-check locking.
  406. if (meth->prepared == NULL)
  407. {
  408. _Jv_MutexLock (&compile_mutex);
  409. if (meth->prepared == NULL)
  410. meth->compile (insn_target);
  411. _Jv_MutexUnlock (&compile_mutex);
  412. }
  413. // If we're only compiling, stop here
  414. if (args == NULL)
  415. return;
  416. pc = (insn_slot *) meth->prepared;
  417. #else
  418. #ifdef __GCJ_DEBUG
  419. #define NEXT_INSN \
  420. do \
  421. { \
  422. if (JVMTI_REQUESTED_EVENT (SingleStep)) \
  423. { \
  424. JNIEnv *env = _Jv_GetCurrentJNIEnv (); \
  425. jmethodID method = meth->self; \
  426. jlocation loc = meth->insn_index (pc); \
  427. _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread, \
  428. env, method, loc); \
  429. } \
  430. goto *(insn_target[*pc++])
  431. #else
  432. #define NEXT_INSN goto *(insn_target[*pc++])
  433. #endif
  434. #define GET1S() get1s (pc++)
  435. #define GET2S() (pc += 2, get2s (pc- 2))
  436. #define GET1U() get1u (pc++)
  437. #define GET2U() (pc += 2, get2u (pc - 2))
  438. // Note that these could be more efficient when not handling 'ldc
  439. // class'.
  440. #define AVAL1U() \
  441. ({ int index = get1u (pc++); \
  442. _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
  443. #define AVAL2U() \
  444. ({ int index = get2u (pc); pc += 2; \
  445. _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
  446. // Note that we don't need to resolve the pool entry here as class
  447. // constants are never wide.
  448. #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
  449. #define SKIP_GOTO pc += 2
  450. #define GOTO_VAL() pc - 1 + get2s (pc)
  451. #define PCVAL(unionval) unionval.i
  452. #define AMPAMP(label) NULL
  453. pc = meth->bytecode ();
  454. #endif /* DIRECT_THREADED */
  455. #define TAKE_GOTO pc = GOTO_VAL ()
  456. /* Go straight at it! the ffi raw format matches the internal
  457. stack representation exactly. At least, that's the idea.
  458. */
  459. memcpy ((void*) locals, (void*) args, meth->args_raw_size);
  460. _Jv_word *pool_data = meth->defining_class->constants.data;
  461. /* These three are temporaries for common code used by several
  462. instructions. */
  463. void (*fun)();
  464. _Jv_ResolvedMethod* rmeth;
  465. int tmpval;
  466. try
  467. {
  468. // We keep nop around. It is used if we're interpreting the
  469. // bytecodes and not doing direct threading.
  470. insn_nop:
  471. NEXT_INSN;
  472. /* The first few instructions here are ordered according to their
  473. frequency, in the hope that this will improve code locality a
  474. little. */
  475. insn_aload_0: // 0x2a
  476. LOADA (0);
  477. NEXT_INSN;
  478. insn_iload: // 0x15
  479. LOADI (GET1U ());
  480. NEXT_INSN;
  481. insn_iload_1: // 0x1b
  482. LOADI (1);
  483. NEXT_INSN;
  484. insn_invokevirtual: // 0xb6
  485. {
  486. SAVE_PC();
  487. int index = GET2U ();
  488. /* _Jv_Linker::resolve_pool_entry returns immediately if the
  489. * value already is resolved. If we want to clutter up the
  490. * code here to gain a little performance, then we can check
  491. * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
  492. * directly. For now, I don't think it is worth it. */
  493. rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  494. index)).rmethod;
  495. sp -= rmeth->stack_item_count;
  496. if (rmeth->method->accflags & Modifier::FINAL)
  497. {
  498. // We can't rely on NULLCHECK working if the method is final.
  499. if (! sp[0].o)
  500. throw_null_pointer_exception ();
  501. // Final methods might not appear in the vtable.
  502. fun = (void (*)()) rmeth->method->ncode;
  503. }
  504. else
  505. {
  506. NULLCHECK (sp[0].o);
  507. jobject rcv = sp[0].o;
  508. _Jv_VTable *table = *(_Jv_VTable**) rcv;
  509. fun = (void (*)()) table->get_method (rmeth->method->index);
  510. }
  511. #ifdef DIRECT_THREADED
  512. // Rewrite instruction so that we use a faster pre-resolved
  513. // method.
  514. REWRITE_INSN (&&invokevirtual_resolved, datum, rmeth);
  515. #endif /* DIRECT_THREADED */
  516. }
  517. goto perform_invoke;
  518. #ifdef DIRECT_THREADED
  519. invokevirtual_resolved:
  520. {
  521. SAVE_PC();
  522. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  523. sp -= rmeth->stack_item_count;
  524. if (rmeth->method->accflags & Modifier::FINAL)
  525. {
  526. // We can't rely on NULLCHECK working if the method is final.
  527. if (! sp[0].o)
  528. throw_null_pointer_exception ();
  529. // Final methods might not appear in the vtable.
  530. fun = (void (*)()) rmeth->method->ncode;
  531. }
  532. else
  533. {
  534. NULLCHECK (sp[0].o);
  535. jobject rcv = sp[0].o;
  536. _Jv_VTable *table = *(_Jv_VTable**) rcv;
  537. fun = (void (*)()) table->get_method (rmeth->method->index);
  538. }
  539. }
  540. goto perform_invoke;
  541. #endif /* DIRECT_THREADED */
  542. perform_invoke:
  543. {
  544. /* here goes the magic again... */
  545. ffi_cif *cif = &rmeth->cif;
  546. INTERP_FFI_RAW_TYPE *raw = (INTERP_FFI_RAW_TYPE *) sp;
  547. _Jv_value rvalue;
  548. #if FFI_NATIVE_RAW_API
  549. /* We assume that this is only implemented if it's correct */
  550. /* to use it here. On a 64 bit machine, it never is. */
  551. ffi_raw_call (cif, fun, (void*)&rvalue, raw);
  552. #else
  553. ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
  554. #endif
  555. int rtype = cif->rtype->type;
  556. /* the likelyhood of object, int, or void return is very high,
  557. * so those are checked before the switch */
  558. if (rtype == FFI_TYPE_POINTER)
  559. {
  560. PUSHA (rvalue.object_value);
  561. }
  562. else if (rtype == FFI_TYPE_SINT32)
  563. {
  564. PUSHI (rvalue.int_value);
  565. }
  566. else if (rtype == FFI_TYPE_VOID)
  567. {
  568. /* skip */
  569. }
  570. else
  571. {
  572. switch (rtype)
  573. {
  574. case FFI_TYPE_SINT8:
  575. PUSHI ((jbyte)(rvalue.int_value & 0xff));
  576. break;
  577. case FFI_TYPE_SINT16:
  578. PUSHI ((jshort)(rvalue.int_value & 0xffff));
  579. break;
  580. case FFI_TYPE_UINT16:
  581. PUSHI (rvalue.int_value & 0xffff);
  582. break;
  583. case FFI_TYPE_FLOAT:
  584. PUSHF (rvalue.float_value);
  585. break;
  586. case FFI_TYPE_DOUBLE:
  587. PUSHD (rvalue.double_value);
  588. break;
  589. case FFI_TYPE_SINT64:
  590. PUSHL (rvalue.long_value);
  591. break;
  592. default:
  593. throw_internal_error ("unknown return type in invokeXXX");
  594. }
  595. }
  596. }
  597. NEXT_INSN;
  598. insn_aconst_null:
  599. PUSHA (NULL);
  600. NEXT_INSN;
  601. insn_iconst_m1:
  602. PUSHI (-1);
  603. NEXT_INSN;
  604. insn_iconst_0:
  605. PUSHI (0);
  606. NEXT_INSN;
  607. insn_iconst_1:
  608. PUSHI (1);
  609. NEXT_INSN;
  610. insn_iconst_2:
  611. PUSHI (2);
  612. NEXT_INSN;
  613. insn_iconst_3:
  614. PUSHI (3);
  615. NEXT_INSN;
  616. insn_iconst_4:
  617. PUSHI (4);
  618. NEXT_INSN;
  619. insn_iconst_5:
  620. PUSHI (5);
  621. NEXT_INSN;
  622. insn_lconst_0:
  623. PUSHL (0);
  624. NEXT_INSN;
  625. insn_lconst_1:
  626. PUSHL (1);
  627. NEXT_INSN;
  628. insn_fconst_0:
  629. PUSHF (0);
  630. NEXT_INSN;
  631. insn_fconst_1:
  632. PUSHF (1);
  633. NEXT_INSN;
  634. insn_fconst_2:
  635. PUSHF (2);
  636. NEXT_INSN;
  637. insn_dconst_0:
  638. PUSHD (0);
  639. NEXT_INSN;
  640. insn_dconst_1:
  641. PUSHD (1);
  642. NEXT_INSN;
  643. insn_bipush:
  644. // For direct threaded, bipush and sipush are the same.
  645. #ifndef DIRECT_THREADED
  646. PUSHI (GET1S ());
  647. NEXT_INSN;
  648. #endif /* DIRECT_THREADED */
  649. insn_sipush:
  650. PUSHI (GET2S ());
  651. NEXT_INSN;
  652. insn_ldc:
  653. // For direct threaded, ldc and ldc_w are the same.
  654. #ifndef DIRECT_THREADED
  655. PUSHA ((jobject) AVAL1U ());
  656. NEXT_INSN;
  657. #endif /* DIRECT_THREADED */
  658. insn_ldc_w:
  659. PUSHA ((jobject) AVAL2U ());
  660. NEXT_INSN;
  661. #ifdef DIRECT_THREADED
  662. // For direct threaded we have a separate 'ldc class' operation.
  663. insn_ldc_class:
  664. {
  665. SAVE_PC();
  666. // We could rewrite the instruction at this point.
  667. int index = INTVAL ();
  668. jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  669. index)).o;
  670. PUSHA (k);
  671. }
  672. NEXT_INSN;
  673. #endif /* DIRECT_THREADED */
  674. insn_ldc2_w:
  675. {
  676. void *where = AVAL2UP ();
  677. memcpy (sp, where, 2*sizeof (_Jv_word));
  678. sp += 2;
  679. }
  680. NEXT_INSN;
  681. insn_lload:
  682. LOADL (GET1U ());
  683. NEXT_INSN;
  684. insn_fload:
  685. LOADF (GET1U ());
  686. NEXT_INSN;
  687. insn_dload:
  688. LOADD (GET1U ());
  689. NEXT_INSN;
  690. insn_aload:
  691. LOADA (GET1U ());
  692. NEXT_INSN;
  693. insn_iload_0:
  694. LOADI (0);
  695. NEXT_INSN;
  696. insn_iload_2:
  697. LOADI (2);
  698. NEXT_INSN;
  699. insn_iload_3:
  700. LOADI (3);
  701. NEXT_INSN;
  702. insn_lload_0:
  703. LOADL (0);
  704. NEXT_INSN;
  705. insn_lload_1:
  706. LOADL (1);
  707. NEXT_INSN;
  708. insn_lload_2:
  709. LOADL (2);
  710. NEXT_INSN;
  711. insn_lload_3:
  712. LOADL (3);
  713. NEXT_INSN;
  714. insn_fload_0:
  715. LOADF (0);
  716. NEXT_INSN;
  717. insn_fload_1:
  718. LOADF (1);
  719. NEXT_INSN;
  720. insn_fload_2:
  721. LOADF (2);
  722. NEXT_INSN;
  723. insn_fload_3:
  724. LOADF (3);
  725. NEXT_INSN;
  726. insn_dload_0:
  727. LOADD (0);
  728. NEXT_INSN;
  729. insn_dload_1:
  730. LOADD (1);
  731. NEXT_INSN;
  732. insn_dload_2:
  733. LOADD (2);
  734. NEXT_INSN;
  735. insn_dload_3:
  736. LOADD (3);
  737. NEXT_INSN;
  738. insn_aload_1:
  739. LOADA(1);
  740. NEXT_INSN;
  741. insn_aload_2:
  742. LOADA(2);
  743. NEXT_INSN;
  744. insn_aload_3:
  745. LOADA(3);
  746. NEXT_INSN;
  747. insn_iaload:
  748. {
  749. jint index = POPI();
  750. jintArray arr = (jintArray) POPA();
  751. NULLARRAYCHECK (arr);
  752. ARRAYBOUNDSCHECK (arr, index);
  753. PUSHI( elements(arr)[index] );
  754. }
  755. NEXT_INSN;
  756. insn_laload:
  757. {
  758. jint index = POPI();
  759. jlongArray arr = (jlongArray) POPA();
  760. NULLARRAYCHECK (arr);
  761. ARRAYBOUNDSCHECK (arr, index);
  762. PUSHL( elements(arr)[index] );
  763. }
  764. NEXT_INSN;
  765. insn_faload:
  766. {
  767. jint index = POPI();
  768. jfloatArray arr = (jfloatArray) POPA();
  769. NULLARRAYCHECK (arr);
  770. ARRAYBOUNDSCHECK (arr, index);
  771. PUSHF( elements(arr)[index] );
  772. }
  773. NEXT_INSN;
  774. insn_daload:
  775. {
  776. jint index = POPI();
  777. jdoubleArray arr = (jdoubleArray) POPA();
  778. NULLARRAYCHECK (arr);
  779. ARRAYBOUNDSCHECK (arr, index);
  780. PUSHD( elements(arr)[index] );
  781. }
  782. NEXT_INSN;
  783. insn_aaload:
  784. {
  785. jint index = POPI();
  786. jobjectArray arr = (jobjectArray) POPA();
  787. NULLARRAYCHECK (arr);
  788. ARRAYBOUNDSCHECK (arr, index);
  789. PUSHA( elements(arr)[index] );
  790. }
  791. NEXT_INSN;
  792. insn_baload:
  793. {
  794. jint index = POPI();
  795. jbyteArray arr = (jbyteArray) POPA();
  796. NULLARRAYCHECK (arr);
  797. ARRAYBOUNDSCHECK (arr, index);
  798. PUSHI( elements(arr)[index] );
  799. }
  800. NEXT_INSN;
  801. insn_caload:
  802. {
  803. jint index = POPI();
  804. jcharArray arr = (jcharArray) POPA();
  805. NULLARRAYCHECK (arr);
  806. ARRAYBOUNDSCHECK (arr, index);
  807. PUSHI( elements(arr)[index] );
  808. }
  809. NEXT_INSN;
  810. insn_saload:
  811. {
  812. jint index = POPI();
  813. jshortArray arr = (jshortArray) POPA();
  814. NULLARRAYCHECK (arr);
  815. ARRAYBOUNDSCHECK (arr, index);
  816. PUSHI( elements(arr)[index] );
  817. }
  818. NEXT_INSN;
  819. insn_istore:
  820. STOREI (GET1U ());
  821. NEXT_INSN;
  822. insn_lstore:
  823. STOREL (GET1U ());
  824. NEXT_INSN;
  825. insn_fstore:
  826. STOREF (GET1U ());
  827. NEXT_INSN;
  828. insn_dstore:
  829. STORED (GET1U ());
  830. NEXT_INSN;
  831. insn_astore:
  832. STOREA (GET1U ());
  833. NEXT_INSN;
  834. insn_istore_0:
  835. STOREI (0);
  836. NEXT_INSN;
  837. insn_istore_1:
  838. STOREI (1);
  839. NEXT_INSN;
  840. insn_istore_2:
  841. STOREI (2);
  842. NEXT_INSN;
  843. insn_istore_3:
  844. STOREI (3);
  845. NEXT_INSN;
  846. insn_lstore_0:
  847. STOREL (0);
  848. NEXT_INSN;
  849. insn_lstore_1:
  850. STOREL (1);
  851. NEXT_INSN;
  852. insn_lstore_2:
  853. STOREL (2);
  854. NEXT_INSN;
  855. insn_lstore_3:
  856. STOREL (3);
  857. NEXT_INSN;
  858. insn_fstore_0:
  859. STOREF (0);
  860. NEXT_INSN;
  861. insn_fstore_1:
  862. STOREF (1);
  863. NEXT_INSN;
  864. insn_fstore_2:
  865. STOREF (2);
  866. NEXT_INSN;
  867. insn_fstore_3:
  868. STOREF (3);
  869. NEXT_INSN;
  870. insn_dstore_0:
  871. STORED (0);
  872. NEXT_INSN;
  873. insn_dstore_1:
  874. STORED (1);
  875. NEXT_INSN;
  876. insn_dstore_2:
  877. STORED (2);
  878. NEXT_INSN;
  879. insn_dstore_3:
  880. STORED (3);
  881. NEXT_INSN;
  882. insn_astore_0:
  883. STOREA(0);
  884. NEXT_INSN;
  885. insn_astore_1:
  886. STOREA(1);
  887. NEXT_INSN;
  888. insn_astore_2:
  889. STOREA(2);
  890. NEXT_INSN;
  891. insn_astore_3:
  892. STOREA(3);
  893. NEXT_INSN;
  894. insn_iastore:
  895. {
  896. jint value = POPI();
  897. jint index = POPI();
  898. jintArray arr = (jintArray) POPA();
  899. NULLARRAYCHECK (arr);
  900. ARRAYBOUNDSCHECK (arr, index);
  901. elements(arr)[index] = value;
  902. }
  903. NEXT_INSN;
  904. insn_lastore:
  905. {
  906. jlong value = POPL();
  907. jint index = POPI();
  908. jlongArray arr = (jlongArray) POPA();
  909. NULLARRAYCHECK (arr);
  910. ARRAYBOUNDSCHECK (arr, index);
  911. elements(arr)[index] = value;
  912. }
  913. NEXT_INSN;
  914. insn_fastore:
  915. {
  916. jfloat value = POPF();
  917. jint index = POPI();
  918. jfloatArray arr = (jfloatArray) POPA();
  919. NULLARRAYCHECK (arr);
  920. ARRAYBOUNDSCHECK (arr, index);
  921. elements(arr)[index] = value;
  922. }
  923. NEXT_INSN;
  924. insn_dastore:
  925. {
  926. jdouble value = POPD();
  927. jint index = POPI();
  928. jdoubleArray arr = (jdoubleArray) POPA();
  929. NULLARRAYCHECK (arr);
  930. ARRAYBOUNDSCHECK (arr, index);
  931. elements(arr)[index] = value;
  932. }
  933. NEXT_INSN;
  934. insn_aastore:
  935. {
  936. jobject value = POPA();
  937. jint index = POPI();
  938. jobjectArray arr = (jobjectArray) POPA();
  939. NULLARRAYCHECK (arr);
  940. ARRAYBOUNDSCHECK (arr, index);
  941. _Jv_CheckArrayStore (arr, value);
  942. elements(arr)[index] = value;
  943. }
  944. NEXT_INSN;
  945. insn_bastore:
  946. {
  947. jbyte value = (jbyte) POPI();
  948. jint index = POPI();
  949. jbyteArray arr = (jbyteArray) POPA();
  950. NULLARRAYCHECK (arr);
  951. ARRAYBOUNDSCHECK (arr, index);
  952. elements(arr)[index] = value;
  953. }
  954. NEXT_INSN;
  955. insn_castore:
  956. {
  957. jchar value = (jchar) POPI();
  958. jint index = POPI();
  959. jcharArray arr = (jcharArray) POPA();
  960. NULLARRAYCHECK (arr);
  961. ARRAYBOUNDSCHECK (arr, index);
  962. elements(arr)[index] = value;
  963. }
  964. NEXT_INSN;
  965. insn_sastore:
  966. {
  967. jshort value = (jshort) POPI();
  968. jint index = POPI();
  969. jshortArray arr = (jshortArray) POPA();
  970. NULLARRAYCHECK (arr);
  971. ARRAYBOUNDSCHECK (arr, index);
  972. elements(arr)[index] = value;
  973. }
  974. NEXT_INSN;
  975. insn_pop:
  976. sp -= 1;
  977. NEXT_INSN;
  978. insn_pop2:
  979. sp -= 2;
  980. NEXT_INSN;
  981. insn_dup:
  982. sp[0] = sp[-1];
  983. sp += 1;
  984. NEXT_INSN;
  985. insn_dup_x1:
  986. dupx (sp, 1, 1); sp+=1;
  987. NEXT_INSN;
  988. insn_dup_x2:
  989. dupx (sp, 1, 2); sp+=1;
  990. NEXT_INSN;
  991. insn_dup2:
  992. sp[0] = sp[-2];
  993. sp[1] = sp[-1];
  994. sp += 2;
  995. NEXT_INSN;
  996. insn_dup2_x1:
  997. dupx (sp, 2, 1); sp+=2;
  998. NEXT_INSN;
  999. insn_dup2_x2:
  1000. dupx (sp, 2, 2); sp+=2;
  1001. NEXT_INSN;
  1002. insn_swap:
  1003. {
  1004. jobject tmp1 = POPA();
  1005. jobject tmp2 = POPA();
  1006. PUSHA (tmp1);
  1007. PUSHA (tmp2);
  1008. }
  1009. NEXT_INSN;
  1010. insn_iadd:
  1011. BINOPI(+);
  1012. NEXT_INSN;
  1013. insn_ladd:
  1014. BINOPL(+);
  1015. NEXT_INSN;
  1016. insn_fadd:
  1017. BINOPF(+);
  1018. NEXT_INSN;
  1019. insn_dadd:
  1020. BINOPD(+);
  1021. NEXT_INSN;
  1022. insn_isub:
  1023. BINOPI(-);
  1024. NEXT_INSN;
  1025. insn_lsub:
  1026. BINOPL(-);
  1027. NEXT_INSN;
  1028. insn_fsub:
  1029. BINOPF(-);
  1030. NEXT_INSN;
  1031. insn_dsub:
  1032. BINOPD(-);
  1033. NEXT_INSN;
  1034. insn_imul:
  1035. BINOPI(*);
  1036. NEXT_INSN;
  1037. insn_lmul:
  1038. BINOPL(*);
  1039. NEXT_INSN;
  1040. insn_fmul:
  1041. BINOPF(*);
  1042. NEXT_INSN;
  1043. insn_dmul:
  1044. BINOPD(*);
  1045. NEXT_INSN;
  1046. insn_idiv:
  1047. {
  1048. SAVE_PC();
  1049. jint value2 = POPI();
  1050. jint value1 = POPI();
  1051. jint res = _Jv_divI (value1, value2);
  1052. PUSHI (res);
  1053. }
  1054. NEXT_INSN;
  1055. insn_ldiv:
  1056. {
  1057. SAVE_PC();
  1058. jlong value2 = POPL();
  1059. jlong value1 = POPL();
  1060. jlong res = _Jv_divJ (value1, value2);
  1061. PUSHL (res);
  1062. }
  1063. NEXT_INSN;
  1064. insn_fdiv:
  1065. {
  1066. jfloat value2 = POPF();
  1067. jfloat value1 = POPF();
  1068. jfloat res = value1 / value2;
  1069. PUSHF (res);
  1070. }
  1071. NEXT_INSN;
  1072. insn_ddiv:
  1073. {
  1074. jdouble value2 = POPD();
  1075. jdouble value1 = POPD();
  1076. jdouble res = value1 / value2;
  1077. PUSHD (res);
  1078. }
  1079. NEXT_INSN;
  1080. insn_irem:
  1081. {
  1082. SAVE_PC();
  1083. jint value2 = POPI();
  1084. jint value1 = POPI();
  1085. jint res = _Jv_remI (value1, value2);
  1086. PUSHI (res);
  1087. }
  1088. NEXT_INSN;
  1089. insn_lrem:
  1090. {
  1091. SAVE_PC();
  1092. jlong value2 = POPL();
  1093. jlong value1 = POPL();
  1094. jlong res = _Jv_remJ (value1, value2);
  1095. PUSHL (res);
  1096. }
  1097. NEXT_INSN;
  1098. insn_frem:
  1099. {
  1100. jfloat value2 = POPF();
  1101. jfloat value1 = POPF();
  1102. jfloat res = __ieee754_fmod (value1, value2);
  1103. PUSHF (res);
  1104. }
  1105. NEXT_INSN;
  1106. insn_drem:
  1107. {
  1108. jdouble value2 = POPD();
  1109. jdouble value1 = POPD();
  1110. jdouble res = __ieee754_fmod (value1, value2);
  1111. PUSHD (res);
  1112. }
  1113. NEXT_INSN;
  1114. insn_ineg:
  1115. {
  1116. jint value = POPI();
  1117. PUSHI (value * -1);
  1118. }
  1119. NEXT_INSN;
  1120. insn_lneg:
  1121. {
  1122. jlong value = POPL();
  1123. PUSHL (value * -1);
  1124. }
  1125. NEXT_INSN;
  1126. insn_fneg:
  1127. {
  1128. jfloat value = POPF();
  1129. PUSHF (value * -1);
  1130. }
  1131. NEXT_INSN;
  1132. insn_dneg:
  1133. {
  1134. jdouble value = POPD();
  1135. PUSHD (value * -1);
  1136. }
  1137. NEXT_INSN;
  1138. insn_ishl:
  1139. {
  1140. jint shift = (POPI() & 0x1f);
  1141. jint value = POPI();
  1142. PUSHI (value << shift);
  1143. }
  1144. NEXT_INSN;
  1145. insn_lshl:
  1146. {
  1147. jint shift = (POPI() & 0x3f);
  1148. jlong value = POPL();
  1149. PUSHL (value << shift);
  1150. }
  1151. NEXT_INSN;
  1152. insn_ishr:
  1153. {
  1154. jint shift = (POPI() & 0x1f);
  1155. jint value = POPI();
  1156. PUSHI (value >> shift);
  1157. }
  1158. NEXT_INSN;
  1159. insn_lshr:
  1160. {
  1161. jint shift = (POPI() & 0x3f);
  1162. jlong value = POPL();
  1163. PUSHL (value >> shift);
  1164. }
  1165. NEXT_INSN;
  1166. insn_iushr:
  1167. {
  1168. jint shift = (POPI() & 0x1f);
  1169. _Jv_uint value = (_Jv_uint) POPI();
  1170. PUSHI ((jint) (value >> shift));
  1171. }
  1172. NEXT_INSN;
  1173. insn_lushr:
  1174. {
  1175. jint shift = (POPI() & 0x3f);
  1176. _Jv_ulong value = (_Jv_ulong) POPL();
  1177. PUSHL ((jlong) (value >> shift));
  1178. }
  1179. NEXT_INSN;
  1180. insn_iand:
  1181. BINOPI (&);
  1182. NEXT_INSN;
  1183. insn_land:
  1184. BINOPL (&);
  1185. NEXT_INSN;
  1186. insn_ior:
  1187. BINOPI (|);
  1188. NEXT_INSN;
  1189. insn_lor:
  1190. BINOPL (|);
  1191. NEXT_INSN;
  1192. insn_ixor:
  1193. BINOPI (^);
  1194. NEXT_INSN;
  1195. insn_lxor:
  1196. BINOPL (^);
  1197. NEXT_INSN;
  1198. insn_iinc:
  1199. {
  1200. jint index = GET1U ();
  1201. jint amount = GET1S ();
  1202. locals[index].i += amount;
  1203. }
  1204. NEXT_INSN;
  1205. insn_i2l:
  1206. {jlong value = POPI(); PUSHL (value);}
  1207. NEXT_INSN;
  1208. insn_i2f:
  1209. {jfloat value = POPI(); PUSHF (value);}
  1210. NEXT_INSN;
  1211. insn_i2d:
  1212. {jdouble value = POPI(); PUSHD (value);}
  1213. NEXT_INSN;
  1214. insn_l2i:
  1215. {jint value = POPL(); PUSHI (value);}
  1216. NEXT_INSN;
  1217. insn_l2f:
  1218. {jfloat value = POPL(); PUSHF (value);}
  1219. NEXT_INSN;
  1220. insn_l2d:
  1221. {jdouble value = POPL(); PUSHD (value);}
  1222. NEXT_INSN;
  1223. insn_f2i:
  1224. {
  1225. using namespace java::lang;
  1226. jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
  1227. PUSHI(value);
  1228. }
  1229. NEXT_INSN;
  1230. insn_f2l:
  1231. {
  1232. using namespace java::lang;
  1233. jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
  1234. PUSHL(value);
  1235. }
  1236. NEXT_INSN;
  1237. insn_f2d:
  1238. { jdouble value = POPF (); PUSHD(value); }
  1239. NEXT_INSN;
  1240. insn_d2i:
  1241. {
  1242. using namespace java::lang;
  1243. jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
  1244. PUSHI(value);
  1245. }
  1246. NEXT_INSN;
  1247. insn_d2l:
  1248. {
  1249. using namespace java::lang;
  1250. jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
  1251. PUSHL(value);
  1252. }
  1253. NEXT_INSN;
  1254. insn_d2f:
  1255. { jfloat value = POPD (); PUSHF(value); }
  1256. NEXT_INSN;
  1257. insn_i2b:
  1258. { jbyte value = POPI (); PUSHI(value); }
  1259. NEXT_INSN;
  1260. insn_i2c:
  1261. { jchar value = POPI (); PUSHI(value); }
  1262. NEXT_INSN;
  1263. insn_i2s:
  1264. { jshort value = POPI (); PUSHI(value); }
  1265. NEXT_INSN;
  1266. insn_lcmp:
  1267. {
  1268. jlong value2 = POPL ();
  1269. jlong value1 = POPL ();
  1270. if (value1 > value2)
  1271. { PUSHI (1); }
  1272. else if (value1 == value2)
  1273. { PUSHI (0); }
  1274. else
  1275. { PUSHI (-1); }
  1276. }
  1277. NEXT_INSN;
  1278. insn_fcmpl:
  1279. tmpval = -1;
  1280. goto fcmp;
  1281. insn_fcmpg:
  1282. tmpval = 1;
  1283. fcmp:
  1284. {
  1285. jfloat value2 = POPF ();
  1286. jfloat value1 = POPF ();
  1287. if (value1 > value2)
  1288. PUSHI (1);
  1289. else if (value1 == value2)
  1290. PUSHI (0);
  1291. else if (value1 < value2)
  1292. PUSHI (-1);
  1293. else
  1294. PUSHI (tmpval);
  1295. }
  1296. NEXT_INSN;
  1297. insn_dcmpl:
  1298. tmpval = -1;
  1299. goto dcmp;
  1300. insn_dcmpg:
  1301. tmpval = 1;
  1302. dcmp:
  1303. {
  1304. jdouble value2 = POPD ();
  1305. jdouble value1 = POPD ();
  1306. if (value1 > value2)
  1307. PUSHI (1);
  1308. else if (value1 == value2)
  1309. PUSHI (0);
  1310. else if (value1 < value2)
  1311. PUSHI (-1);
  1312. else
  1313. PUSHI (tmpval);
  1314. }
  1315. NEXT_INSN;
  1316. insn_ifeq:
  1317. {
  1318. if (POPI() == 0)
  1319. TAKE_GOTO;
  1320. else
  1321. SKIP_GOTO;
  1322. }
  1323. NEXT_INSN;
  1324. insn_ifne:
  1325. {
  1326. if (POPI() != 0)
  1327. TAKE_GOTO;
  1328. else
  1329. SKIP_GOTO;
  1330. }
  1331. NEXT_INSN;
  1332. insn_iflt:
  1333. {
  1334. if (POPI() < 0)
  1335. TAKE_GOTO;
  1336. else
  1337. SKIP_GOTO;
  1338. }
  1339. NEXT_INSN;
  1340. insn_ifge:
  1341. {
  1342. if (POPI() >= 0)
  1343. TAKE_GOTO;
  1344. else
  1345. SKIP_GOTO;
  1346. }
  1347. NEXT_INSN;
  1348. insn_ifgt:
  1349. {
  1350. if (POPI() > 0)
  1351. TAKE_GOTO;
  1352. else
  1353. SKIP_GOTO;
  1354. }
  1355. NEXT_INSN;
  1356. insn_ifle:
  1357. {
  1358. if (POPI() <= 0)
  1359. TAKE_GOTO;
  1360. else
  1361. SKIP_GOTO;
  1362. }
  1363. NEXT_INSN;
  1364. insn_if_icmpeq:
  1365. {
  1366. jint value2 = POPI();
  1367. jint value1 = POPI();
  1368. if (value1 == value2)
  1369. TAKE_GOTO;
  1370. else
  1371. SKIP_GOTO;
  1372. }
  1373. NEXT_INSN;
  1374. insn_if_icmpne:
  1375. {
  1376. jint value2 = POPI();
  1377. jint value1 = POPI();
  1378. if (value1 != value2)
  1379. TAKE_GOTO;
  1380. else
  1381. SKIP_GOTO;
  1382. }
  1383. NEXT_INSN;
  1384. insn_if_icmplt:
  1385. {
  1386. jint value2 = POPI();
  1387. jint value1 = POPI();
  1388. if (value1 < value2)
  1389. TAKE_GOTO;
  1390. else
  1391. SKIP_GOTO;
  1392. }
  1393. NEXT_INSN;
  1394. insn_if_icmpge:
  1395. {
  1396. jint value2 = POPI();
  1397. jint value1 = POPI();
  1398. if (value1 >= value2)
  1399. TAKE_GOTO;
  1400. else
  1401. SKIP_GOTO;
  1402. }
  1403. NEXT_INSN;
  1404. insn_if_icmpgt:
  1405. {
  1406. jint value2 = POPI();
  1407. jint value1 = POPI();
  1408. if (value1 > value2)
  1409. TAKE_GOTO;
  1410. else
  1411. SKIP_GOTO;
  1412. }
  1413. NEXT_INSN;
  1414. insn_if_icmple:
  1415. {
  1416. jint value2 = POPI();
  1417. jint value1 = POPI();
  1418. if (value1 <= value2)
  1419. TAKE_GOTO;
  1420. else
  1421. SKIP_GOTO;
  1422. }
  1423. NEXT_INSN;
  1424. insn_if_acmpeq:
  1425. {
  1426. jobject value2 = POPA();
  1427. jobject value1 = POPA();
  1428. if (value1 == value2)
  1429. TAKE_GOTO;
  1430. else
  1431. SKIP_GOTO;
  1432. }
  1433. NEXT_INSN;
  1434. insn_if_acmpne:
  1435. {
  1436. jobject value2 = POPA();
  1437. jobject value1 = POPA();
  1438. if (value1 != value2)
  1439. TAKE_GOTO;
  1440. else
  1441. SKIP_GOTO;
  1442. }
  1443. NEXT_INSN;
  1444. insn_goto_w:
  1445. #ifndef DIRECT_THREADED
  1446. // For direct threaded, goto and goto_w are the same.
  1447. pc = pc - 1 + get4 (pc);
  1448. NEXT_INSN;
  1449. #endif /* DIRECT_THREADED */
  1450. insn_goto:
  1451. TAKE_GOTO;
  1452. NEXT_INSN;
  1453. insn_jsr_w:
  1454. #ifndef DIRECT_THREADED
  1455. // For direct threaded, jsr and jsr_w are the same.
  1456. {
  1457. pc_t next = pc - 1 + get4 (pc);
  1458. pc += 4;
  1459. PUSHA ((jobject) pc);
  1460. pc = next;
  1461. }
  1462. NEXT_INSN;
  1463. #endif /* DIRECT_THREADED */
  1464. insn_jsr:
  1465. {
  1466. pc_t next = GOTO_VAL();
  1467. SKIP_GOTO;
  1468. PUSHA ((jobject) pc);
  1469. pc = next;
  1470. }
  1471. NEXT_INSN;
  1472. insn_ret:
  1473. {
  1474. jint index = GET1U ();
  1475. pc = (pc_t) PEEKA (index);
  1476. }
  1477. NEXT_INSN;
  1478. insn_tableswitch:
  1479. {
  1480. #ifdef DIRECT_THREADED
  1481. void *def = (pc++)->datum;
  1482. int index = POPI();
  1483. jint low = INTVAL ();
  1484. jint high = INTVAL ();
  1485. if (index < low || index > high)
  1486. pc = (insn_slot *) def;
  1487. else
  1488. pc = (insn_slot *) ((pc + index - low)->datum);
  1489. #else
  1490. pc_t base_pc = pc - 1;
  1491. int index = POPI ();
  1492. pc_t base = (pc_t) meth->bytecode ();
  1493. while ((pc - base) % 4 != 0)
  1494. ++pc;
  1495. jint def = get4 (pc);
  1496. jint low = get4 (pc + 4);
  1497. jint high = get4 (pc + 8);
  1498. if (index < low || index > high)
  1499. pc = base_pc + def;
  1500. else
  1501. pc = base_pc + get4 (pc + 4 * (index - low + 3));
  1502. #endif /* DIRECT_THREADED */
  1503. }
  1504. NEXT_INSN;
  1505. insn_lookupswitch:
  1506. {
  1507. #ifdef DIRECT_THREADED
  1508. void *def = (pc++)->insn;
  1509. int index = POPI();
  1510. jint npairs = INTVAL ();
  1511. int max = npairs - 1;
  1512. int min = 0;
  1513. // Simple binary search...
  1514. while (min < max)
  1515. {
  1516. int half = (min + max) / 2;
  1517. int match = pc[2 * half].int_val;
  1518. if (index == match)
  1519. {
  1520. // Found it.
  1521. pc = (insn_slot *) pc[2 * half + 1].datum;
  1522. NEXT_INSN;
  1523. }
  1524. else if (index < match)
  1525. // We can use HALF - 1 here because we check again on
  1526. // loop exit.
  1527. max = half - 1;
  1528. else
  1529. // We can use HALF + 1 here because we check again on
  1530. // loop exit.
  1531. min = half + 1;
  1532. }
  1533. if (index == pc[2 * min].int_val)
  1534. pc = (insn_slot *) pc[2 * min + 1].datum;
  1535. else
  1536. pc = (insn_slot *) def;
  1537. #else
  1538. unsigned char *base_pc = pc-1;
  1539. int index = POPI();
  1540. unsigned char* base = meth->bytecode ();
  1541. while ((pc-base) % 4 != 0)
  1542. ++pc;
  1543. jint def = get4 (pc);
  1544. jint npairs = get4 (pc+4);
  1545. int max = npairs-1;
  1546. int min = 0;
  1547. // Simple binary search...
  1548. while (min < max)
  1549. {
  1550. int half = (min+max)/2;
  1551. int match = get4 (pc+ 4*(2 + 2*half));
  1552. if (index == match)
  1553. min = max = half;
  1554. else if (index < match)
  1555. // We can use HALF - 1 here because we check again on
  1556. // loop exit.
  1557. max = half - 1;
  1558. else
  1559. // We can use HALF + 1 here because we check again on
  1560. // loop exit.
  1561. min = half + 1;
  1562. }
  1563. if (index == get4 (pc+ 4*(2 + 2*min)))
  1564. pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
  1565. else
  1566. pc = base_pc + def;
  1567. #endif /* DIRECT_THREADED */
  1568. }
  1569. NEXT_INSN;
  1570. insn_areturn:
  1571. *(jobject *) retp = POPA ();
  1572. return;
  1573. insn_lreturn:
  1574. *(jlong *) retp = POPL ();
  1575. return;
  1576. insn_freturn:
  1577. *(jfloat *) retp = POPF ();
  1578. return;
  1579. insn_dreturn:
  1580. *(jdouble *) retp = POPD ();
  1581. return;
  1582. insn_ireturn:
  1583. *(jint *) retp = POPI ();
  1584. return;
  1585. insn_return:
  1586. return;
  1587. insn_getstatic:
  1588. {
  1589. jint fieldref_index = GET2U ();
  1590. SAVE_PC(); // Constant pool resolution could throw.
  1591. _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
  1592. _Jv_Field *field = pool_data[fieldref_index].field;
  1593. if ((field->flags & Modifier::STATIC) == 0)
  1594. throw_incompatible_class_change_error
  1595. (JvNewStringLatin1 ("field no longer static"));
  1596. jclass type = field->type;
  1597. // We rewrite the instruction once we discover what it refers
  1598. // to.
  1599. void *newinsn = NULL;
  1600. if (type->isPrimitive ())
  1601. {
  1602. switch (type->size_in_bytes)
  1603. {
  1604. case 1:
  1605. PUSHI (*field->u.byte_addr);
  1606. newinsn = AMPAMP (getstatic_resolved_1);
  1607. break;
  1608. case 2:
  1609. if (type == JvPrimClass (char))
  1610. {
  1611. PUSHI (*field->u.char_addr);
  1612. newinsn = AMPAMP (getstatic_resolved_char);
  1613. }
  1614. else
  1615. {
  1616. PUSHI (*field->u.short_addr);
  1617. newinsn = AMPAMP (getstatic_resolved_short);
  1618. }
  1619. break;
  1620. case 4:
  1621. PUSHI(*field->u.int_addr);
  1622. newinsn = AMPAMP (getstatic_resolved_4);
  1623. break;
  1624. case 8:
  1625. PUSHL(*field->u.long_addr);
  1626. newinsn = AMPAMP (getstatic_resolved_8);
  1627. break;
  1628. }
  1629. }
  1630. else
  1631. {
  1632. PUSHA(*field->u.object_addr);
  1633. newinsn = AMPAMP (getstatic_resolved_obj);
  1634. }
  1635. #ifdef DIRECT_THREADED
  1636. REWRITE_INSN (newinsn, datum, field->u.addr);
  1637. #endif /* DIRECT_THREADED */
  1638. }
  1639. NEXT_INSN;
  1640. #ifdef DIRECT_THREADED
  1641. getstatic_resolved_1:
  1642. PUSHI (*(jbyte *) AVAL ());
  1643. NEXT_INSN;
  1644. getstatic_resolved_char:
  1645. PUSHI (*(jchar *) AVAL ());
  1646. NEXT_INSN;
  1647. getstatic_resolved_short:
  1648. PUSHI (*(jshort *) AVAL ());
  1649. NEXT_INSN;
  1650. getstatic_resolved_4:
  1651. PUSHI (*(jint *) AVAL ());
  1652. NEXT_INSN;
  1653. getstatic_resolved_8:
  1654. PUSHL (*(jlong *) AVAL ());
  1655. NEXT_INSN;
  1656. getstatic_resolved_obj:
  1657. PUSHA (*(jobject *) AVAL ());
  1658. NEXT_INSN;
  1659. #endif /* DIRECT_THREADED */
  1660. insn_getfield:
  1661. {
  1662. SAVE_PC();
  1663. jint fieldref_index = GET2U ();
  1664. _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
  1665. _Jv_Field *field = pool_data[fieldref_index].field;
  1666. if ((field->flags & Modifier::STATIC) != 0)
  1667. throw_incompatible_class_change_error
  1668. (JvNewStringLatin1 ("field is static"));
  1669. jclass type = field->type;
  1670. jint field_offset = field->u.boffset;
  1671. jobject obj = POPA();
  1672. NULLCHECK(obj);
  1673. void *newinsn = NULL;
  1674. _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
  1675. if (type->isPrimitive ())
  1676. {
  1677. switch (type->size_in_bytes)
  1678. {
  1679. case 1:
  1680. PUSHI (val->byte_value);
  1681. newinsn = AMPAMP (getfield_resolved_1);
  1682. break;
  1683. case 2:
  1684. if (type == JvPrimClass (char))
  1685. {
  1686. PUSHI (val->char_value);
  1687. newinsn = AMPAMP (getfield_resolved_char);
  1688. }
  1689. else
  1690. {
  1691. PUSHI (val->short_value);
  1692. newinsn = AMPAMP (getfield_resolved_short);
  1693. }
  1694. break;
  1695. case 4:
  1696. PUSHI (val->int_value);
  1697. newinsn = AMPAMP (getfield_resolved_4);
  1698. break;
  1699. case 8:
  1700. PUSHL (val->long_value);
  1701. newinsn = AMPAMP (getfield_resolved_8);
  1702. break;
  1703. }
  1704. }
  1705. else
  1706. {
  1707. PUSHA (val->object_value);
  1708. newinsn = AMPAMP (getfield_resolved_obj);
  1709. }
  1710. #ifdef DIRECT_THREADED
  1711. REWRITE_INSN (newinsn, int_val, field_offset);
  1712. #endif /* DIRECT_THREADED */
  1713. }
  1714. NEXT_INSN;
  1715. #ifdef DIRECT_THREADED
  1716. getfield_resolved_1:
  1717. {
  1718. char *obj = (char *) POPA ();
  1719. NULLCHECK (obj);
  1720. PUSHI (*(jbyte *) (obj + INTVAL ()));
  1721. }
  1722. NEXT_INSN;
  1723. getfield_resolved_char:
  1724. {
  1725. char *obj = (char *) POPA ();
  1726. NULLCHECK (obj);
  1727. PUSHI (*(jchar *) (obj + INTVAL ()));
  1728. }
  1729. NEXT_INSN;
  1730. getfield_resolved_short:
  1731. {
  1732. char *obj = (char *) POPA ();
  1733. NULLCHECK (obj);
  1734. PUSHI (*(jshort *) (obj + INTVAL ()));
  1735. }
  1736. NEXT_INSN;
  1737. getfield_resolved_4:
  1738. {
  1739. char *obj = (char *) POPA ();
  1740. NULLCHECK (obj);
  1741. PUSHI (*(jint *) (obj + INTVAL ()));
  1742. }
  1743. NEXT_INSN;
  1744. getfield_resolved_8:
  1745. {
  1746. char *obj = (char *) POPA ();
  1747. NULLCHECK (obj);
  1748. PUSHL (*(jlong *) (obj + INTVAL ()));
  1749. }
  1750. NEXT_INSN;
  1751. getfield_resolved_obj:
  1752. {
  1753. char *obj = (char *) POPA ();
  1754. NULLCHECK (obj);
  1755. PUSHA (*(jobject *) (obj + INTVAL ()));
  1756. }
  1757. NEXT_INSN;
  1758. #endif /* DIRECT_THREADED */
  1759. insn_putstatic:
  1760. {
  1761. SAVE_PC();
  1762. jint fieldref_index = GET2U ();
  1763. _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
  1764. _Jv_Field *field = pool_data[fieldref_index].field;
  1765. jclass type = field->type;
  1766. // ResolvePoolEntry cannot check this
  1767. if ((field->flags & Modifier::STATIC) == 0)
  1768. throw_incompatible_class_change_error
  1769. (JvNewStringLatin1 ("field no longer static"));
  1770. void *newinsn = NULL;
  1771. if (type->isPrimitive ())
  1772. {
  1773. switch (type->size_in_bytes)
  1774. {
  1775. case 1:
  1776. {
  1777. jint value = POPI();
  1778. *field->u.byte_addr = value;
  1779. newinsn = AMPAMP (putstatic_resolved_1);
  1780. break;
  1781. }
  1782. case 2:
  1783. {
  1784. jint value = POPI();
  1785. *field->u.char_addr = value;
  1786. newinsn = AMPAMP (putstatic_resolved_2);
  1787. break;
  1788. }
  1789. case 4:
  1790. {
  1791. jint value = POPI();
  1792. *field->u.int_addr = value;
  1793. newinsn = AMPAMP (putstatic_resolved_4);
  1794. break;
  1795. }
  1796. case 8:
  1797. {
  1798. jlong value = POPL();
  1799. *field->u.long_addr = value;
  1800. newinsn = AMPAMP (putstatic_resolved_8);
  1801. break;
  1802. }
  1803. }
  1804. }
  1805. else
  1806. {
  1807. jobject value = POPA();
  1808. *field->u.object_addr = value;
  1809. newinsn = AMPAMP (putstatic_resolved_obj);
  1810. }
  1811. #ifdef DIRECT_THREADED
  1812. REWRITE_INSN (newinsn, datum, field->u.addr);
  1813. #endif /* DIRECT_THREADED */
  1814. }
  1815. NEXT_INSN;
  1816. #ifdef DIRECT_THREADED
  1817. putstatic_resolved_1:
  1818. *(jbyte *) AVAL () = POPI ();
  1819. NEXT_INSN;
  1820. putstatic_resolved_2:
  1821. *(jchar *) AVAL () = POPI ();
  1822. NEXT_INSN;
  1823. putstatic_resolved_4:
  1824. *(jint *) AVAL () = POPI ();
  1825. NEXT_INSN;
  1826. putstatic_resolved_8:
  1827. *(jlong *) AVAL () = POPL ();
  1828. NEXT_INSN;
  1829. putstatic_resolved_obj:
  1830. *(jobject *) AVAL () = POPA ();
  1831. NEXT_INSN;
  1832. #endif /* DIRECT_THREADED */
  1833. insn_putfield:
  1834. {
  1835. SAVE_PC();
  1836. jint fieldref_index = GET2U ();
  1837. _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
  1838. _Jv_Field *field = pool_data[fieldref_index].field;
  1839. jclass type = field->type;
  1840. if ((field->flags & Modifier::STATIC) != 0)
  1841. throw_incompatible_class_change_error
  1842. (JvNewStringLatin1 ("field is static"));
  1843. jint field_offset = field->u.boffset;
  1844. void *newinsn = NULL;
  1845. if (type->isPrimitive ())
  1846. {
  1847. switch (type->size_in_bytes)
  1848. {
  1849. case 1:
  1850. {
  1851. jint value = POPI();
  1852. jobject obj = POPA();
  1853. NULLCHECK(obj);
  1854. *(jbyte*) ((char*)obj + field_offset) = value;
  1855. newinsn = AMPAMP (putfield_resolved_1);
  1856. break;
  1857. }
  1858. case 2:
  1859. {
  1860. jint value = POPI();
  1861. jobject obj = POPA();
  1862. NULLCHECK(obj);
  1863. *(jchar*) ((char*)obj + field_offset) = value;
  1864. newinsn = AMPAMP (putfield_resolved_2);
  1865. break;
  1866. }
  1867. case 4:
  1868. {
  1869. jint value = POPI();
  1870. jobject obj = POPA();
  1871. NULLCHECK(obj);
  1872. *(jint*) ((char*)obj + field_offset) = value;
  1873. newinsn = AMPAMP (putfield_resolved_4);
  1874. break;
  1875. }
  1876. case 8:
  1877. {
  1878. jlong value = POPL();
  1879. jobject obj = POPA();
  1880. NULLCHECK(obj);
  1881. *(jlong*) ((char*)obj + field_offset) = value;
  1882. newinsn = AMPAMP (putfield_resolved_8);
  1883. break;
  1884. }
  1885. }
  1886. }
  1887. else
  1888. {
  1889. jobject value = POPA();
  1890. jobject obj = POPA();
  1891. NULLCHECK(obj);
  1892. *(jobject*) ((char*)obj + field_offset) = value;
  1893. newinsn = AMPAMP (putfield_resolved_obj);
  1894. }
  1895. #ifdef DIRECT_THREADED
  1896. REWRITE_INSN (newinsn, int_val, field_offset);
  1897. #endif /* DIRECT_THREADED */
  1898. }
  1899. NEXT_INSN;
  1900. #ifdef DIRECT_THREADED
  1901. putfield_resolved_1:
  1902. {
  1903. jint val = POPI ();
  1904. char *obj = (char *) POPA ();
  1905. NULLCHECK (obj);
  1906. *(jbyte *) (obj + INTVAL ()) = val;
  1907. }
  1908. NEXT_INSN;
  1909. putfield_resolved_2:
  1910. {
  1911. jint val = POPI ();
  1912. char *obj = (char *) POPA ();
  1913. NULLCHECK (obj);
  1914. *(jchar *) (obj + INTVAL ()) = val;
  1915. }
  1916. NEXT_INSN;
  1917. putfield_resolved_4:
  1918. {
  1919. jint val = POPI ();
  1920. char *obj = (char *) POPA ();
  1921. NULLCHECK (obj);
  1922. *(jint *) (obj + INTVAL ()) = val;
  1923. }
  1924. NEXT_INSN;
  1925. putfield_resolved_8:
  1926. {
  1927. jlong val = POPL ();
  1928. char *obj = (char *) POPA ();
  1929. NULLCHECK (obj);
  1930. *(jlong *) (obj + INTVAL ()) = val;
  1931. }
  1932. NEXT_INSN;
  1933. putfield_resolved_obj:
  1934. {
  1935. jobject val = POPA ();
  1936. char *obj = (char *) POPA ();
  1937. NULLCHECK (obj);
  1938. *(jobject *) (obj + INTVAL ()) = val;
  1939. }
  1940. NEXT_INSN;
  1941. #endif /* DIRECT_THREADED */
  1942. insn_invokespecial:
  1943. {
  1944. SAVE_PC();
  1945. int index = GET2U ();
  1946. rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  1947. index)).rmethod;
  1948. sp -= rmeth->stack_item_count;
  1949. // We don't use NULLCHECK here because we can't rely on that
  1950. // working for <init>. So instead we do an explicit test.
  1951. if (! sp[0].o)
  1952. {
  1953. SAVE_PC();
  1954. throw_null_pointer_exception ();
  1955. }
  1956. fun = (void (*)()) rmeth->method->ncode;
  1957. #ifdef DIRECT_THREADED
  1958. // Rewrite instruction so that we use a faster pre-resolved
  1959. // method.
  1960. REWRITE_INSN (&&invokespecial_resolved, datum, rmeth);
  1961. #endif /* DIRECT_THREADED */
  1962. }
  1963. goto perform_invoke;
  1964. #ifdef DIRECT_THREADED
  1965. invokespecial_resolved:
  1966. {
  1967. SAVE_PC();
  1968. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  1969. sp -= rmeth->stack_item_count;
  1970. // We don't use NULLCHECK here because we can't rely on that
  1971. // working for <init>. So instead we do an explicit test.
  1972. if (! sp[0].o)
  1973. {
  1974. throw_null_pointer_exception ();
  1975. }
  1976. fun = (void (*)()) rmeth->method->ncode;
  1977. }
  1978. goto perform_invoke;
  1979. #endif /* DIRECT_THREADED */
  1980. insn_invokestatic:
  1981. {
  1982. SAVE_PC();
  1983. int index = GET2U ();
  1984. rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  1985. index)).rmethod;
  1986. sp -= rmeth->stack_item_count;
  1987. fun = (void (*)()) rmeth->method->ncode;
  1988. #ifdef DIRECT_THREADED
  1989. // Rewrite instruction so that we use a faster pre-resolved
  1990. // method.
  1991. REWRITE_INSN (&&invokestatic_resolved, datum, rmeth);
  1992. #endif /* DIRECT_THREADED */
  1993. }
  1994. goto perform_invoke;
  1995. #ifdef DIRECT_THREADED
  1996. invokestatic_resolved:
  1997. {
  1998. SAVE_PC();
  1999. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  2000. sp -= rmeth->stack_item_count;
  2001. fun = (void (*)()) rmeth->method->ncode;
  2002. }
  2003. goto perform_invoke;
  2004. #endif /* DIRECT_THREADED */
  2005. insn_invokeinterface:
  2006. {
  2007. SAVE_PC();
  2008. int index = GET2U ();
  2009. rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  2010. index)).rmethod;
  2011. sp -= rmeth->stack_item_count;
  2012. jobject rcv = sp[0].o;
  2013. NULLCHECK (rcv);
  2014. fun = (void (*)())
  2015. _Jv_LookupInterfaceMethod (rcv->getClass (),
  2016. rmeth->method->name,
  2017. rmeth->method->signature);
  2018. #ifdef DIRECT_THREADED
  2019. // Rewrite instruction so that we use a faster pre-resolved
  2020. // method.
  2021. REWRITE_INSN (&&invokeinterface_resolved, datum, rmeth);
  2022. #else
  2023. // Skip dummy bytes.
  2024. pc += 2;
  2025. #endif /* DIRECT_THREADED */
  2026. }
  2027. goto perform_invoke;
  2028. #ifdef DIRECT_THREADED
  2029. invokeinterface_resolved:
  2030. {
  2031. SAVE_PC();
  2032. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  2033. sp -= rmeth->stack_item_count;
  2034. jobject rcv = sp[0].o;
  2035. NULLCHECK (rcv);
  2036. fun = (void (*)())
  2037. _Jv_LookupInterfaceMethod (rcv->getClass (),
  2038. rmeth->method->name,
  2039. rmeth->method->signature);
  2040. }
  2041. goto perform_invoke;
  2042. #endif /* DIRECT_THREADED */
  2043. insn_new:
  2044. {
  2045. SAVE_PC();
  2046. int index = GET2U ();
  2047. jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  2048. index)).clazz;
  2049. /* VM spec, section 3.11.5 */
  2050. if ((klass->getModifiers() & Modifier::ABSTRACT)
  2051. || klass->isInterface())
  2052. {
  2053. jthrowable t = new java::lang::InstantiationException;
  2054. INTERP_REPORT_EXCEPTION (t);
  2055. throw t;
  2056. }
  2057. jobject res = _Jv_AllocObject (klass);
  2058. PUSHA (res);
  2059. #ifdef DIRECT_THREADED
  2060. REWRITE_INSN (&&new_resolved, datum, klass);
  2061. #endif /* DIRECT_THREADED */
  2062. }
  2063. NEXT_INSN;
  2064. #ifdef DIRECT_THREADED
  2065. new_resolved:
  2066. {
  2067. jclass klass = (jclass) AVAL ();
  2068. jobject res = _Jv_AllocObject (klass);
  2069. PUSHA (res);
  2070. }
  2071. NEXT_INSN;
  2072. #endif /* DIRECT_THREADED */
  2073. insn_newarray:
  2074. {
  2075. int atype = GET1U ();
  2076. int size = POPI();
  2077. jobject result = _Jv_NewArray (atype, size);
  2078. PUSHA (result);
  2079. }
  2080. NEXT_INSN;
  2081. insn_anewarray:
  2082. {
  2083. SAVE_PC();
  2084. int index = GET2U ();
  2085. jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  2086. index)).clazz;
  2087. int size = POPI();
  2088. jobject result = _Jv_NewObjectArray (size, klass, 0);
  2089. PUSHA (result);
  2090. #ifdef DIRECT_THREADED
  2091. REWRITE_INSN (&&anewarray_resolved, datum, klass);
  2092. #endif /* DIRECT_THREADED */
  2093. }
  2094. NEXT_INSN;
  2095. #ifdef DIRECT_THREADED
  2096. anewarray_resolved:
  2097. {
  2098. jclass klass = (jclass) AVAL ();
  2099. int size = POPI ();
  2100. jobject result = _Jv_NewObjectArray (size, klass, 0);
  2101. PUSHA (result);
  2102. }
  2103. NEXT_INSN;
  2104. #endif /* DIRECT_THREADED */
  2105. insn_arraylength:
  2106. {
  2107. __JArray *arr = (__JArray*)POPA();
  2108. NULLARRAYCHECK (arr);
  2109. PUSHI (arr->length);
  2110. }
  2111. NEXT_INSN;
  2112. insn_athrow:
  2113. {
  2114. jobject value = POPA();
  2115. jthrowable t = static_cast<jthrowable> (value);
  2116. INTERP_REPORT_EXCEPTION (t);
  2117. throw t;
  2118. }
  2119. NEXT_INSN;
  2120. insn_checkcast:
  2121. {
  2122. SAVE_PC();
  2123. jobject value = POPA();
  2124. jint index = GET2U ();
  2125. jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  2126. index)).clazz;
  2127. value = (jobject) _Jv_CheckCast (to, value);
  2128. PUSHA (value);
  2129. #ifdef DIRECT_THREADED
  2130. REWRITE_INSN (&&checkcast_resolved, datum, to);
  2131. #endif /* DIRECT_THREADED */
  2132. }
  2133. NEXT_INSN;
  2134. #ifdef DIRECT_THREADED
  2135. checkcast_resolved:
  2136. {
  2137. SAVE_PC();
  2138. jobject value = POPA ();
  2139. jclass to = (jclass) AVAL ();
  2140. value = (jobject) _Jv_CheckCast (to, value);
  2141. PUSHA (value);
  2142. }
  2143. NEXT_INSN;
  2144. #endif /* DIRECT_THREADED */
  2145. insn_instanceof:
  2146. {
  2147. SAVE_PC();
  2148. jobject value = POPA();
  2149. jint index = GET2U ();
  2150. jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  2151. index)).clazz;
  2152. PUSHI (to->isInstance (value));
  2153. #ifdef DIRECT_THREADED
  2154. REWRITE_INSN (&&instanceof_resolved, datum, to);
  2155. #endif /* DIRECT_THREADED */
  2156. }
  2157. NEXT_INSN;
  2158. #ifdef DIRECT_THREADED
  2159. instanceof_resolved:
  2160. {
  2161. jobject value = POPA ();
  2162. jclass to = (jclass) AVAL ();
  2163. PUSHI (to->isInstance (value));
  2164. }
  2165. NEXT_INSN;
  2166. #endif /* DIRECT_THREADED */
  2167. insn_monitorenter:
  2168. {
  2169. jobject value = POPA();
  2170. NULLCHECK(value);
  2171. _Jv_MonitorEnter (value);
  2172. }
  2173. NEXT_INSN;
  2174. insn_monitorexit:
  2175. {
  2176. jobject value = POPA();
  2177. NULLCHECK(value);
  2178. _Jv_MonitorExit (value);
  2179. }
  2180. NEXT_INSN;
  2181. insn_ifnull:
  2182. {
  2183. jobject val = POPA();
  2184. if (val == NULL)
  2185. TAKE_GOTO;
  2186. else
  2187. SKIP_GOTO;
  2188. }
  2189. NEXT_INSN;
  2190. insn_ifnonnull:
  2191. {
  2192. jobject val = POPA();
  2193. if (val != NULL)
  2194. TAKE_GOTO;
  2195. else
  2196. SKIP_GOTO;
  2197. }
  2198. NEXT_INSN;
  2199. insn_multianewarray:
  2200. {
  2201. SAVE_PC();
  2202. int kind_index = GET2U ();
  2203. int dim = GET1U ();
  2204. jclass type
  2205. = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
  2206. kind_index)).clazz;
  2207. jint *sizes = (jint*) __builtin_alloca (sizeof (jint)*dim);
  2208. for (int i = dim - 1; i >= 0; i--)
  2209. {
  2210. sizes[i] = POPI ();
  2211. }
  2212. jobject res = _Jv_NewMultiArray (type,dim, sizes);
  2213. PUSHA (res);
  2214. }
  2215. NEXT_INSN;
  2216. #ifndef DIRECT_THREADED
  2217. insn_wide:
  2218. {
  2219. jint the_mod_op = get1u (pc++);
  2220. jint wide = get2u (pc); pc += 2;
  2221. switch (the_mod_op)
  2222. {
  2223. case op_istore:
  2224. STOREI (wide);
  2225. NEXT_INSN;
  2226. case op_fstore:
  2227. STOREF (wide);
  2228. NEXT_INSN;
  2229. case op_astore:
  2230. STOREA (wide);
  2231. NEXT_INSN;
  2232. case op_lload:
  2233. LOADL (wide);
  2234. NEXT_INSN;
  2235. case op_dload:
  2236. LOADD (wide);
  2237. NEXT_INSN;
  2238. case op_iload:
  2239. LOADI (wide);
  2240. NEXT_INSN;
  2241. case op_fload:
  2242. LOADF (wide);
  2243. NEXT_INSN;
  2244. case op_aload:
  2245. LOADA (wide);
  2246. NEXT_INSN;
  2247. case op_lstore:
  2248. STOREL (wide);
  2249. NEXT_INSN;
  2250. case op_dstore:
  2251. STORED (wide);
  2252. NEXT_INSN;
  2253. case op_ret:
  2254. pc = (unsigned char*) PEEKA (wide);
  2255. NEXT_INSN;
  2256. case op_iinc:
  2257. {
  2258. jint amount = get2s (pc); pc += 2;
  2259. jint value = PEEKI (wide);
  2260. POKEI (wide, value+amount);
  2261. }
  2262. NEXT_INSN;
  2263. default:
  2264. throw_internal_error ("illegal bytecode modified by wide");
  2265. }
  2266. }
  2267. #endif /* DIRECT_THREADED */
  2268. insn_breakpoint:
  2269. {
  2270. using namespace ::java::lang;
  2271. jmethodID method = meth->self;
  2272. jlocation location = meth->insn_index (pc - 1);
  2273. using namespace gnu::gcj::jvmti;
  2274. Breakpoint *bp
  2275. = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
  2276. location);
  2277. JvAssert (bp != NULL);
  2278. // Save the insn here since the breakpoint could be removed
  2279. // before the JVMTI notification returns.
  2280. pc_t opc = reinterpret_cast<pc_t> (bp->getInsn ());
  2281. bp->execute ();
  2282. // Continue execution
  2283. #ifdef DIRECT_THREADED
  2284. goto *(opc->insn);
  2285. #else
  2286. goto *(insn_target[*opc]);
  2287. #endif
  2288. }
  2289. }
  2290. catch (java::lang::Throwable *ex)
  2291. {
  2292. // Check if the exception is handled and, if so, set the pc to the start
  2293. // of the appropriate catch block.
  2294. if (meth->check_handler (&pc, meth, ex))
  2295. {
  2296. sp = stack;
  2297. sp++->o = ex; // Push exception.
  2298. #ifdef __GCJ_DEBUG
  2299. if (JVMTI_REQUESTED_EVENT (ExceptionCatch))
  2300. {
  2301. using namespace gnu::gcj::jvmti;
  2302. jlong catch_meth = reinterpret_cast<jlong> (meth->get_method ());
  2303. jlong catch_loc = meth->insn_index (pc);
  2304. _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, thread,
  2305. _Jv_GetCurrentJNIEnv (), catch_meth,
  2306. catch_loc, ex);
  2307. }
  2308. #endif
  2309. NEXT_INSN;
  2310. }
  2311. // No handler, so re-throw.
  2312. throw ex;
  2313. }