interpret.cc 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227
  1. // interpret.cc - Code for the interpreter
  2. /* Copyright (C) 1999, 2000, 2001, 2002 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. /* Author: Kresten Krab Thorup <krab@gnu.org> */
  8. #include <config.h>
  9. // Define this to get the direct-threaded interpreter. If undefined,
  10. // we revert to a basic bytecode interpreter. The former is faster
  11. // but uses more memory.
  12. #define DIRECT_THREADED
  13. #pragma implementation "java-interp.h"
  14. #include <jvm.h>
  15. #include <java-cpool.h>
  16. #include <java-interp.h>
  17. #include <java/lang/System.h>
  18. #include <java/lang/String.h>
  19. #include <java/lang/Integer.h>
  20. #include <java/lang/Long.h>
  21. #include <java/lang/StringBuffer.h>
  22. #include <java/lang/Class.h>
  23. #include <java/lang/reflect/Modifier.h>
  24. #include <java/lang/ClassCastException.h>
  25. #include <java/lang/VirtualMachineError.h>
  26. #include <java/lang/InternalError.h>
  27. #include <java/lang/NullPointerException.h>
  28. #include <java/lang/ArithmeticException.h>
  29. #include <java/lang/IncompatibleClassChangeError.h>
  30. #include <java/lang/Thread.h>
  31. #include <java-insns.h>
  32. #include <java-signal.h>
  33. #ifdef INTERPRETER
  34. #include <stdlib.h>
  35. using namespace gcj;
  36. static void throw_internal_error (char *msg)
  37. __attribute__ ((__noreturn__));
  38. static void throw_incompatible_class_change_error (jstring msg)
  39. __attribute__ ((__noreturn__));
  40. #ifndef HANDLE_SEGV
  41. static void throw_null_pointer_exception ()
  42. __attribute__ ((__noreturn__));
  43. #endif
  44. extern "C" double __ieee754_fmod (double,double);
  45. // This represents a single slot in the "compiled" form of the
  46. // bytecode.
  47. union insn_slot
  48. {
  49. // Address of code.
  50. void *insn;
  51. // An integer value used by an instruction.
  52. jint int_val;
  53. // A pointer value used by an instruction.
  54. void *datum;
  55. };
  56. // The type of the PC depends on whether we're doing direct threading
  57. // or a more ordinary bytecode interpreter.
  58. #ifdef DIRECT_THREADED
  59. typedef insn_slot *pc_t;
  60. #else
  61. typedef unsigned char *pc_t;
  62. #endif
  63. static inline void dupx (_Jv_word *sp, int n, int x)
  64. {
  65. // first "slide" n+x elements n to the right
  66. int top = n-1;
  67. for (int i = 0; i < n+x; i++)
  68. {
  69. sp[(top-i)] = sp[(top-i)-n];
  70. }
  71. // next, copy the n top elements, n+x down
  72. for (int i = 0; i < n; i++)
  73. {
  74. sp[top-(n+x)-i] = sp[top-i];
  75. }
  76. };
  77. // Used to convert from floating types to integral types.
  78. template<typename TO, typename FROM>
  79. static inline TO
  80. convert (FROM val, TO min, TO max)
  81. {
  82. TO ret;
  83. if (val >= (FROM) max)
  84. ret = max;
  85. else if (val <= (FROM) min)
  86. ret = min;
  87. else if (val != val)
  88. ret = 0;
  89. else
  90. ret = (TO) val;
  91. return ret;
  92. }
  93. #define PUSHA(V) (sp++)->o = (V)
  94. #define PUSHI(V) (sp++)->i = (V)
  95. #define PUSHF(V) (sp++)->f = (V)
  96. #if SIZEOF_VOID_P == 8
  97. # define PUSHL(V) (sp->l = (V), sp += 2)
  98. # define PUSHD(V) (sp->d = (V), sp += 2)
  99. #else
  100. # define PUSHL(V) do { _Jv_word2 w2; w2.l=(V); \
  101. (sp++)->ia[0] = w2.ia[0]; \
  102. (sp++)->ia[0] = w2.ia[1]; } while (0)
  103. # define PUSHD(V) do { _Jv_word2 w2; w2.d=(V); \
  104. (sp++)->ia[0] = w2.ia[0]; \
  105. (sp++)->ia[0] = w2.ia[1]; } while (0)
  106. #endif
  107. #define POPA() ((--sp)->o)
  108. #define POPI() ((jint) (--sp)->i) // cast since it may be promoted
  109. #define POPF() ((jfloat) (--sp)->f)
  110. #if SIZEOF_VOID_P == 8
  111. # define POPL() (sp -= 2, (jlong) sp->l)
  112. # define POPD() (sp -= 2, (jdouble) sp->d)
  113. #else
  114. # define POPL() ({ _Jv_word2 w2; \
  115. w2.ia[1] = (--sp)->ia[0]; \
  116. w2.ia[0] = (--sp)->ia[0]; w2.l; })
  117. # define POPD() ({ _Jv_word2 w2; \
  118. w2.ia[1] = (--sp)->ia[0]; \
  119. w2.ia[0] = (--sp)->ia[0]; w2.d; })
  120. #endif
  121. #define LOADA(I) (sp++)->o = locals[I].o
  122. #define LOADI(I) (sp++)->i = locals[I].i
  123. #define LOADF(I) (sp++)->f = locals[I].f
  124. #if SIZEOF_VOID_P == 8
  125. # define LOADL(I) (sp->l = locals[I].l, sp += 2)
  126. # define LOADD(I) (sp->d = locals[I].d, sp += 2)
  127. #else
  128. # define LOADL(I) do { jint __idx = (I); \
  129. (sp++)->ia[0] = locals[__idx].ia[0]; \
  130. (sp++)->ia[0] = locals[__idx+1].ia[0]; \
  131. } while (0)
  132. # define LOADD(I) LOADL(I)
  133. #endif
  134. #define STOREA(I) locals[I].o = (--sp)->o
  135. #define STOREI(I) locals[I].i = (--sp)->i
  136. #define STOREF(I) locals[I].f = (--sp)->f
  137. #if SIZEOF_VOID_P == 8
  138. # define STOREL(I) (sp -= 2, locals[I].l = sp->l)
  139. # define STORED(I) (sp -= 2, locals[I].d = sp->d)
  140. #else
  141. # define STOREL(I) do { jint __idx = (I); \
  142. locals[__idx+1].ia[0] = (--sp)->ia[0]; \
  143. locals[__idx].ia[0] = (--sp)->ia[0]; \
  144. } while (0)
  145. # define STORED(I) STOREL(I)
  146. #endif
  147. #define PEEKI(I) (locals+(I))->i
  148. #define PEEKA(I) (locals+(I))->o
  149. #define POKEI(I,V) ((locals+(I))->i = (V))
  150. #define BINOPI(OP) { \
  151. jint value2 = POPI(); \
  152. jint value1 = POPI(); \
  153. PUSHI(value1 OP value2); \
  154. }
  155. #define BINOPF(OP) { \
  156. jfloat value2 = POPF(); \
  157. jfloat value1 = POPF(); \
  158. PUSHF(value1 OP value2); \
  159. }
  160. #define BINOPL(OP) { \
  161. jlong value2 = POPL(); \
  162. jlong value1 = POPL(); \
  163. PUSHL(value1 OP value2); \
  164. }
  165. #define BINOPD(OP) { \
  166. jdouble value2 = POPD(); \
  167. jdouble value1 = POPD(); \
  168. PUSHD(value1 OP value2); \
  169. }
  170. static inline jint get1s(unsigned char* loc) {
  171. return *(signed char*)loc;
  172. }
  173. static inline jint get1u(unsigned char* loc) {
  174. return *loc;
  175. }
  176. static inline jint get2s(unsigned char* loc) {
  177. return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
  178. }
  179. static inline jint get2u(unsigned char* loc) {
  180. return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
  181. }
  182. static jint get4(unsigned char* loc) {
  183. return (((jint)(loc[0])) << 24)
  184. | (((jint)(loc[1])) << 16)
  185. | (((jint)(loc[2])) << 8)
  186. | (((jint)(loc[3])) << 0);
  187. }
  188. #ifdef HANDLE_SEGV
  189. #define NULLCHECK(X)
  190. #define NULLARRAYCHECK(X)
  191. #else
  192. #define NULLCHECK(X) \
  193. do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
  194. #define NULLARRAYCHECK(X) \
  195. do { if ((X)==NULL) { throw_null_pointer_exception (); } } while (0)
  196. #endif
  197. #define ARRAYBOUNDSCHECK(array, index) \
  198. do \
  199. { \
  200. if (((unsigned) index) >= (unsigned) (array->length)) \
  201. _Jv_ThrowBadArrayIndex (index); \
  202. } \
  203. while (0)
  204. void _Jv_InterpMethod::run_normal (ffi_cif *,
  205. void* ret,
  206. ffi_raw * args,
  207. void* __this)
  208. {
  209. _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
  210. _this->run (ret, args);
  211. }
  212. void _Jv_InterpMethod::run_synch_object (ffi_cif *,
  213. void* ret,
  214. ffi_raw * args,
  215. void* __this)
  216. {
  217. _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
  218. jobject rcv = (jobject) args[0].ptr;
  219. JvSynchronize mutex (rcv);
  220. _this->run (ret, args);
  221. }
  222. void _Jv_InterpMethod::run_synch_class (ffi_cif *,
  223. void* ret,
  224. ffi_raw * args,
  225. void* __this)
  226. {
  227. _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
  228. jclass sync = _this->defining_class;
  229. JvSynchronize mutex (sync);
  230. _this->run (ret, args);
  231. }
  232. #ifdef DIRECT_THREADED
  233. // "Compile" a method by turning it from bytecode to direct-threaded
  234. // code.
  235. void
  236. _Jv_InterpMethod::compile (const void * const *insn_targets)
  237. {
  238. insn_slot *insns = NULL;
  239. int next = 0;
  240. unsigned char *codestart = bytecode ();
  241. unsigned char *end = codestart + code_length;
  242. _Jv_word *pool_data = defining_class->constants.data;
  243. #define SET_ONE(Field, Value) \
  244. do \
  245. { \
  246. if (first_pass) \
  247. ++next; \
  248. else \
  249. insns[next++].Field = Value; \
  250. } \
  251. while (0)
  252. #define SET_INSN(Value) SET_ONE (insn, (void *) Value)
  253. #define SET_INT(Value) SET_ONE (int_val, Value)
  254. #define SET_DATUM(Value) SET_ONE (datum, Value)
  255. // Map from bytecode PC to slot in INSNS.
  256. int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
  257. for (int i = 0; i < code_length; ++i)
  258. pc_mapping[i] = -1;
  259. for (int i = 0; i < 2; ++i)
  260. {
  261. jboolean first_pass = i == 0;
  262. if (! first_pass)
  263. {
  264. insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
  265. next = 0;
  266. }
  267. unsigned char *pc = codestart;
  268. while (pc < end)
  269. {
  270. int base_pc_val = pc - codestart;
  271. if (first_pass)
  272. pc_mapping[base_pc_val] = next;
  273. java_opcode opcode = (java_opcode) *pc++;
  274. // Just elide NOPs.
  275. if (opcode == op_nop)
  276. continue;
  277. SET_INSN (insn_targets[opcode]);
  278. switch (opcode)
  279. {
  280. case op_nop:
  281. case op_aconst_null:
  282. case op_iconst_m1:
  283. case op_iconst_0:
  284. case op_iconst_1:
  285. case op_iconst_2:
  286. case op_iconst_3:
  287. case op_iconst_4:
  288. case op_iconst_5:
  289. case op_lconst_0:
  290. case op_lconst_1:
  291. case op_fconst_0:
  292. case op_fconst_1:
  293. case op_fconst_2:
  294. case op_dconst_0:
  295. case op_dconst_1:
  296. case op_iload_0:
  297. case op_iload_1:
  298. case op_iload_2:
  299. case op_iload_3:
  300. case op_lload_0:
  301. case op_lload_1:
  302. case op_lload_2:
  303. case op_lload_3:
  304. case op_fload_0:
  305. case op_fload_1:
  306. case op_fload_2:
  307. case op_fload_3:
  308. case op_dload_0:
  309. case op_dload_1:
  310. case op_dload_2:
  311. case op_dload_3:
  312. case op_aload_0:
  313. case op_aload_1:
  314. case op_aload_2:
  315. case op_aload_3:
  316. case op_iaload:
  317. case op_laload:
  318. case op_faload:
  319. case op_daload:
  320. case op_aaload:
  321. case op_baload:
  322. case op_caload:
  323. case op_saload:
  324. case op_istore_0:
  325. case op_istore_1:
  326. case op_istore_2:
  327. case op_istore_3:
  328. case op_lstore_0:
  329. case op_lstore_1:
  330. case op_lstore_2:
  331. case op_lstore_3:
  332. case op_fstore_0:
  333. case op_fstore_1:
  334. case op_fstore_2:
  335. case op_fstore_3:
  336. case op_dstore_0:
  337. case op_dstore_1:
  338. case op_dstore_2:
  339. case op_dstore_3:
  340. case op_astore_0:
  341. case op_astore_1:
  342. case op_astore_2:
  343. case op_astore_3:
  344. case op_iastore:
  345. case op_lastore:
  346. case op_fastore:
  347. case op_dastore:
  348. case op_aastore:
  349. case op_bastore:
  350. case op_castore:
  351. case op_sastore:
  352. case op_pop:
  353. case op_pop2:
  354. case op_dup:
  355. case op_dup_x1:
  356. case op_dup_x2:
  357. case op_dup2:
  358. case op_dup2_x1:
  359. case op_dup2_x2:
  360. case op_swap:
  361. case op_iadd:
  362. case op_isub:
  363. case op_imul:
  364. case op_idiv:
  365. case op_irem:
  366. case op_ishl:
  367. case op_ishr:
  368. case op_iushr:
  369. case op_iand:
  370. case op_ior:
  371. case op_ixor:
  372. case op_ladd:
  373. case op_lsub:
  374. case op_lmul:
  375. case op_ldiv:
  376. case op_lrem:
  377. case op_lshl:
  378. case op_lshr:
  379. case op_lushr:
  380. case op_land:
  381. case op_lor:
  382. case op_lxor:
  383. case op_fadd:
  384. case op_fsub:
  385. case op_fmul:
  386. case op_fdiv:
  387. case op_frem:
  388. case op_dadd:
  389. case op_dsub:
  390. case op_dmul:
  391. case op_ddiv:
  392. case op_drem:
  393. case op_ineg:
  394. case op_i2b:
  395. case op_i2c:
  396. case op_i2s:
  397. case op_lneg:
  398. case op_fneg:
  399. case op_dneg:
  400. case op_i2l:
  401. case op_i2f:
  402. case op_i2d:
  403. case op_l2i:
  404. case op_l2f:
  405. case op_l2d:
  406. case op_f2i:
  407. case op_f2l:
  408. case op_f2d:
  409. case op_d2i:
  410. case op_d2l:
  411. case op_d2f:
  412. case op_lcmp:
  413. case op_fcmpl:
  414. case op_fcmpg:
  415. case op_dcmpl:
  416. case op_dcmpg:
  417. case op_monitorenter:
  418. case op_monitorexit:
  419. case op_ireturn:
  420. case op_lreturn:
  421. case op_freturn:
  422. case op_dreturn:
  423. case op_areturn:
  424. case op_return:
  425. case op_athrow:
  426. case op_arraylength:
  427. // No argument, nothing else to do.
  428. break;
  429. case op_bipush:
  430. SET_INT (get1s (pc));
  431. ++pc;
  432. break;
  433. case op_ldc:
  434. {
  435. int index = get1u (pc);
  436. ++pc;
  437. SET_DATUM (pool_data[index].o);
  438. }
  439. break;
  440. case op_ret:
  441. case op_iload:
  442. case op_lload:
  443. case op_fload:
  444. case op_dload:
  445. case op_aload:
  446. case op_istore:
  447. case op_lstore:
  448. case op_fstore:
  449. case op_dstore:
  450. case op_astore:
  451. case op_newarray:
  452. SET_INT (get1u (pc));
  453. ++pc;
  454. break;
  455. case op_iinc:
  456. SET_INT (get1u (pc));
  457. SET_INT (get1s (pc + 1));
  458. pc += 2;
  459. break;
  460. case op_ldc_w:
  461. {
  462. int index = get2u (pc);
  463. pc += 2;
  464. SET_DATUM (pool_data[index].o);
  465. }
  466. break;
  467. case op_ldc2_w:
  468. {
  469. int index = get2u (pc);
  470. pc += 2;
  471. SET_DATUM (&pool_data[index]);
  472. }
  473. break;
  474. case op_sipush:
  475. SET_INT (get2s (pc));
  476. pc += 2;
  477. break;
  478. case op_new:
  479. case op_getstatic:
  480. case op_getfield:
  481. case op_putfield:
  482. case op_putstatic:
  483. case op_anewarray:
  484. case op_instanceof:
  485. case op_checkcast:
  486. case op_invokespecial:
  487. case op_invokestatic:
  488. case op_invokevirtual:
  489. SET_INT (get2u (pc));
  490. pc += 2;
  491. break;
  492. case op_multianewarray:
  493. SET_INT (get2u (pc));
  494. SET_INT (get1u (pc + 2));
  495. pc += 3;
  496. break;
  497. case op_jsr:
  498. case op_ifeq:
  499. case op_ifne:
  500. case op_iflt:
  501. case op_ifge:
  502. case op_ifgt:
  503. case op_ifle:
  504. case op_if_icmpeq:
  505. case op_if_icmpne:
  506. case op_if_icmplt:
  507. case op_if_icmpge:
  508. case op_if_icmpgt:
  509. case op_if_icmple:
  510. case op_if_acmpeq:
  511. case op_if_acmpne:
  512. case op_ifnull:
  513. case op_ifnonnull:
  514. case op_goto:
  515. {
  516. int offset = get2s (pc);
  517. pc += 2;
  518. int new_pc = base_pc_val + offset;
  519. bool orig_was_goto = opcode == op_goto;
  520. // Thread jumps. We limit the loop count; this lets
  521. // us avoid infinite loops if the bytecode contains
  522. // such. `10' is arbitrary.
  523. int count = 10;
  524. while (codestart[new_pc] == op_goto && count-- > 0)
  525. new_pc += get2s (&codestart[new_pc + 1]);
  526. // If the jump takes us to a `return' instruction and
  527. // the original branch was an unconditional goto, then
  528. // we hoist the return.
  529. opcode = (java_opcode) codestart[new_pc];
  530. if (orig_was_goto
  531. && (opcode == op_ireturn || opcode == op_lreturn
  532. || opcode == op_freturn || opcode == op_dreturn
  533. || opcode == op_areturn || opcode == op_return))
  534. {
  535. --next;
  536. SET_INSN (insn_targets[opcode]);
  537. }
  538. else
  539. SET_DATUM (&insns[pc_mapping[new_pc]]);
  540. }
  541. break;
  542. case op_tableswitch:
  543. {
  544. while ((pc - codestart) % 4 != 0)
  545. ++pc;
  546. jint def = get4 (pc);
  547. SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
  548. pc += 4;
  549. int low = get4 (pc);
  550. SET_INT (low);
  551. pc += 4;
  552. int high = get4 (pc);
  553. SET_INT (high);
  554. pc += 4;
  555. for (int i = low; i <= high; ++i)
  556. {
  557. SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
  558. pc += 4;
  559. }
  560. }
  561. break;
  562. case op_lookupswitch:
  563. {
  564. while ((pc - codestart) % 4 != 0)
  565. ++pc;
  566. jint def = get4 (pc);
  567. SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
  568. pc += 4;
  569. jint npairs = get4 (pc);
  570. pc += 4;
  571. SET_INT (npairs);
  572. while (npairs-- > 0)
  573. {
  574. jint match = get4 (pc);
  575. jint offset = get4 (pc + 4);
  576. SET_INT (match);
  577. SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
  578. pc += 8;
  579. }
  580. }
  581. break;
  582. case op_invokeinterface:
  583. {
  584. jint index = get2u (pc);
  585. pc += 2;
  586. // We ignore the next two bytes.
  587. pc += 2;
  588. SET_INT (index);
  589. }
  590. break;
  591. case op_wide:
  592. {
  593. opcode = (java_opcode) get1u (pc);
  594. pc += 1;
  595. jint val = get2u (pc);
  596. pc += 2;
  597. // We implement narrow and wide instructions using the
  598. // same code in the interpreter. So we rewrite the
  599. // instruction slot here.
  600. if (! first_pass)
  601. insns[next - 1].insn = (void *) insn_targets[opcode];
  602. SET_INT (val);
  603. if (opcode == op_iinc)
  604. {
  605. SET_INT (get2s (pc));
  606. pc += 2;
  607. }
  608. }
  609. break;
  610. case op_jsr_w:
  611. case op_goto_w:
  612. {
  613. jint offset = get4 (pc);
  614. pc += 4;
  615. SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
  616. }
  617. break;
  618. // Some "can't happen" cases that we include for
  619. // error-checking purposes.
  620. case op_putfield_1:
  621. case op_putfield_2:
  622. case op_putfield_4:
  623. case op_putfield_8:
  624. case op_putfield_a:
  625. case op_putstatic_1:
  626. case op_putstatic_2:
  627. case op_putstatic_4:
  628. case op_putstatic_8:
  629. case op_putstatic_a:
  630. case op_getfield_1:
  631. case op_getfield_2s:
  632. case op_getfield_2u:
  633. case op_getfield_4:
  634. case op_getfield_8:
  635. case op_getfield_a:
  636. case op_getstatic_1:
  637. case op_getstatic_2s:
  638. case op_getstatic_2u:
  639. case op_getstatic_4:
  640. case op_getstatic_8:
  641. case op_getstatic_a:
  642. default:
  643. // Fail somehow.
  644. break;
  645. }
  646. }
  647. }
  648. // Now update exceptions.
  649. _Jv_InterpException *exc = exceptions ();
  650. for (int i = 0; i < exc_count; ++i)
  651. {
  652. exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
  653. exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
  654. exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
  655. jclass handler = (_Jv_ResolvePoolEntry (defining_class,
  656. exc[i].handler_type.i)).clazz;
  657. exc[i].handler_type.p = handler;
  658. }
  659. prepared = insns;
  660. }
  661. #endif /* DIRECT_THREADED */
  662. // This function exists so that the stack-tracing code can find the
  663. // boundaries of the interpreter.
  664. void
  665. _Jv_StartOfInterpreter (void)
  666. {
  667. }
  668. void
  669. _Jv_InterpMethod::run (void *retp, ffi_raw *args)
  670. {
  671. using namespace java::lang::reflect;
  672. // FRAME_DESC registers this particular invocation as the top-most
  673. // interpreter frame. This lets the stack tracing code (for
  674. // Throwable) print information about the method being interpreted
  675. // rather than about the interpreter itself. FRAME_DESC has a
  676. // destructor so it cleans up automatically when the interpreter
  677. // returns.
  678. java::lang::Thread *thread = java::lang::Thread::currentThread();
  679. _Jv_MethodChain frame_desc (this,
  680. (_Jv_MethodChain **) &thread->interp_frame);
  681. _Jv_word stack[max_stack];
  682. _Jv_word *sp = stack;
  683. _Jv_word locals[max_locals];
  684. /* Go straight at it! the ffi raw format matches the internal
  685. stack representation exactly. At least, that's the idea.
  686. */
  687. memcpy ((void*) locals, (void*) args, args_raw_size);
  688. _Jv_word *pool_data = defining_class->constants.data;
  689. /* These three are temporaries for common code used by several
  690. instructions. */
  691. void (*fun)();
  692. _Jv_ResolvedMethod* rmeth;
  693. int tmpval;
  694. #define INSN_LABEL(op) &&insn_##op
  695. static const void *const insn_target[] =
  696. {
  697. INSN_LABEL(nop),
  698. INSN_LABEL(aconst_null),
  699. INSN_LABEL(iconst_m1),
  700. INSN_LABEL(iconst_0),
  701. INSN_LABEL(iconst_1),
  702. INSN_LABEL(iconst_2),
  703. INSN_LABEL(iconst_3),
  704. INSN_LABEL(iconst_4),
  705. INSN_LABEL(iconst_5),
  706. INSN_LABEL(lconst_0),
  707. INSN_LABEL(lconst_1),
  708. INSN_LABEL(fconst_0),
  709. INSN_LABEL(fconst_1),
  710. INSN_LABEL(fconst_2),
  711. INSN_LABEL(dconst_0),
  712. INSN_LABEL(dconst_1),
  713. INSN_LABEL(bipush),
  714. INSN_LABEL(sipush),
  715. INSN_LABEL(ldc),
  716. INSN_LABEL(ldc_w),
  717. INSN_LABEL(ldc2_w),
  718. INSN_LABEL(iload),
  719. INSN_LABEL(lload),
  720. INSN_LABEL(fload),
  721. INSN_LABEL(dload),
  722. INSN_LABEL(aload),
  723. INSN_LABEL(iload_0),
  724. INSN_LABEL(iload_1),
  725. INSN_LABEL(iload_2),
  726. INSN_LABEL(iload_3),
  727. INSN_LABEL(lload_0),
  728. INSN_LABEL(lload_1),
  729. INSN_LABEL(lload_2),
  730. INSN_LABEL(lload_3),
  731. INSN_LABEL(fload_0),
  732. INSN_LABEL(fload_1),
  733. INSN_LABEL(fload_2),
  734. INSN_LABEL(fload_3),
  735. INSN_LABEL(dload_0),
  736. INSN_LABEL(dload_1),
  737. INSN_LABEL(dload_2),
  738. INSN_LABEL(dload_3),
  739. INSN_LABEL(aload_0),
  740. INSN_LABEL(aload_1),
  741. INSN_LABEL(aload_2),
  742. INSN_LABEL(aload_3),
  743. INSN_LABEL(iaload),
  744. INSN_LABEL(laload),
  745. INSN_LABEL(faload),
  746. INSN_LABEL(daload),
  747. INSN_LABEL(aaload),
  748. INSN_LABEL(baload),
  749. INSN_LABEL(caload),
  750. INSN_LABEL(saload),
  751. INSN_LABEL(istore),
  752. INSN_LABEL(lstore),
  753. INSN_LABEL(fstore),
  754. INSN_LABEL(dstore),
  755. INSN_LABEL(astore),
  756. INSN_LABEL(istore_0),
  757. INSN_LABEL(istore_1),
  758. INSN_LABEL(istore_2),
  759. INSN_LABEL(istore_3),
  760. INSN_LABEL(lstore_0),
  761. INSN_LABEL(lstore_1),
  762. INSN_LABEL(lstore_2),
  763. INSN_LABEL(lstore_3),
  764. INSN_LABEL(fstore_0),
  765. INSN_LABEL(fstore_1),
  766. INSN_LABEL(fstore_2),
  767. INSN_LABEL(fstore_3),
  768. INSN_LABEL(dstore_0),
  769. INSN_LABEL(dstore_1),
  770. INSN_LABEL(dstore_2),
  771. INSN_LABEL(dstore_3),
  772. INSN_LABEL(astore_0),
  773. INSN_LABEL(astore_1),
  774. INSN_LABEL(astore_2),
  775. INSN_LABEL(astore_3),
  776. INSN_LABEL(iastore),
  777. INSN_LABEL(lastore),
  778. INSN_LABEL(fastore),
  779. INSN_LABEL(dastore),
  780. INSN_LABEL(aastore),
  781. INSN_LABEL(bastore),
  782. INSN_LABEL(castore),
  783. INSN_LABEL(sastore),
  784. INSN_LABEL(pop),
  785. INSN_LABEL(pop2),
  786. INSN_LABEL(dup),
  787. INSN_LABEL(dup_x1),
  788. INSN_LABEL(dup_x2),
  789. INSN_LABEL(dup2),
  790. INSN_LABEL(dup2_x1),
  791. INSN_LABEL(dup2_x2),
  792. INSN_LABEL(swap),
  793. INSN_LABEL(iadd),
  794. INSN_LABEL(ladd),
  795. INSN_LABEL(fadd),
  796. INSN_LABEL(dadd),
  797. INSN_LABEL(isub),
  798. INSN_LABEL(lsub),
  799. INSN_LABEL(fsub),
  800. INSN_LABEL(dsub),
  801. INSN_LABEL(imul),
  802. INSN_LABEL(lmul),
  803. INSN_LABEL(fmul),
  804. INSN_LABEL(dmul),
  805. INSN_LABEL(idiv),
  806. INSN_LABEL(ldiv),
  807. INSN_LABEL(fdiv),
  808. INSN_LABEL(ddiv),
  809. INSN_LABEL(irem),
  810. INSN_LABEL(lrem),
  811. INSN_LABEL(frem),
  812. INSN_LABEL(drem),
  813. INSN_LABEL(ineg),
  814. INSN_LABEL(lneg),
  815. INSN_LABEL(fneg),
  816. INSN_LABEL(dneg),
  817. INSN_LABEL(ishl),
  818. INSN_LABEL(lshl),
  819. INSN_LABEL(ishr),
  820. INSN_LABEL(lshr),
  821. INSN_LABEL(iushr),
  822. INSN_LABEL(lushr),
  823. INSN_LABEL(iand),
  824. INSN_LABEL(land),
  825. INSN_LABEL(ior),
  826. INSN_LABEL(lor),
  827. INSN_LABEL(ixor),
  828. INSN_LABEL(lxor),
  829. INSN_LABEL(iinc),
  830. INSN_LABEL(i2l),
  831. INSN_LABEL(i2f),
  832. INSN_LABEL(i2d),
  833. INSN_LABEL(l2i),
  834. INSN_LABEL(l2f),
  835. INSN_LABEL(l2d),
  836. INSN_LABEL(f2i),
  837. INSN_LABEL(f2l),
  838. INSN_LABEL(f2d),
  839. INSN_LABEL(d2i),
  840. INSN_LABEL(d2l),
  841. INSN_LABEL(d2f),
  842. INSN_LABEL(i2b),
  843. INSN_LABEL(i2c),
  844. INSN_LABEL(i2s),
  845. INSN_LABEL(lcmp),
  846. INSN_LABEL(fcmpl),
  847. INSN_LABEL(fcmpg),
  848. INSN_LABEL(dcmpl),
  849. INSN_LABEL(dcmpg),
  850. INSN_LABEL(ifeq),
  851. INSN_LABEL(ifne),
  852. INSN_LABEL(iflt),
  853. INSN_LABEL(ifge),
  854. INSN_LABEL(ifgt),
  855. INSN_LABEL(ifle),
  856. INSN_LABEL(if_icmpeq),
  857. INSN_LABEL(if_icmpne),
  858. INSN_LABEL(if_icmplt),
  859. INSN_LABEL(if_icmpge),
  860. INSN_LABEL(if_icmpgt),
  861. INSN_LABEL(if_icmple),
  862. INSN_LABEL(if_acmpeq),
  863. INSN_LABEL(if_acmpne),
  864. INSN_LABEL(goto),
  865. INSN_LABEL(jsr),
  866. INSN_LABEL(ret),
  867. INSN_LABEL(tableswitch),
  868. INSN_LABEL(lookupswitch),
  869. INSN_LABEL(ireturn),
  870. INSN_LABEL(lreturn),
  871. INSN_LABEL(freturn),
  872. INSN_LABEL(dreturn),
  873. INSN_LABEL(areturn),
  874. INSN_LABEL(return),
  875. INSN_LABEL(getstatic),
  876. INSN_LABEL(putstatic),
  877. INSN_LABEL(getfield),
  878. INSN_LABEL(putfield),
  879. INSN_LABEL(invokevirtual),
  880. INSN_LABEL(invokespecial),
  881. INSN_LABEL(invokestatic),
  882. INSN_LABEL(invokeinterface),
  883. 0, /* Unused. */
  884. INSN_LABEL(new),
  885. INSN_LABEL(newarray),
  886. INSN_LABEL(anewarray),
  887. INSN_LABEL(arraylength),
  888. INSN_LABEL(athrow),
  889. INSN_LABEL(checkcast),
  890. INSN_LABEL(instanceof),
  891. INSN_LABEL(monitorenter),
  892. INSN_LABEL(monitorexit),
  893. #ifdef DIRECT_THREADED
  894. 0, // wide
  895. #else
  896. INSN_LABEL(wide),
  897. #endif
  898. INSN_LABEL(multianewarray),
  899. INSN_LABEL(ifnull),
  900. INSN_LABEL(ifnonnull),
  901. INSN_LABEL(goto_w),
  902. INSN_LABEL(jsr_w),
  903. 0
  904. };
  905. pc_t pc;
  906. #ifdef DIRECT_THREADED
  907. #define NEXT_INSN goto *((pc++)->insn)
  908. #define INTVAL() ((pc++)->int_val)
  909. #define AVAL() ((pc++)->datum)
  910. #define GET1S() INTVAL ()
  911. #define GET2S() INTVAL ()
  912. #define GET1U() INTVAL ()
  913. #define GET2U() INTVAL ()
  914. #define AVAL1U() AVAL ()
  915. #define AVAL2U() AVAL ()
  916. #define AVAL2UP() AVAL ()
  917. #define SKIP_GOTO ++pc
  918. #define GOTO_VAL() (insn_slot *) pc->datum
  919. #define PCVAL(unionval) unionval.p
  920. #define AMPAMP(label) &&label
  921. // Compile if we must.
  922. if (prepared == NULL)
  923. compile (insn_target);
  924. pc = (insn_slot *) prepared;
  925. #else
  926. #define NEXT_INSN goto *(insn_target[*pc++])
  927. #define GET1S() get1s (pc++)
  928. #define GET2S() (pc += 2, get2s (pc- 2))
  929. #define GET1U() get1u (pc++)
  930. #define GET2U() (pc += 2, get2u (pc - 2))
  931. #define AVAL1U() ({ int index = get1u (pc++); pool_data[index].o; })
  932. #define AVAL2U() ({ int index = get2u (pc); pc += 2; pool_data[index].o; })
  933. #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
  934. #define SKIP_GOTO pc += 2
  935. #define GOTO_VAL() pc - 1 + get2s (pc)
  936. #define PCVAL(unionval) unionval.i
  937. #define AMPAMP(label) NULL
  938. pc = bytecode ();
  939. #endif /* DIRECT_THREADED */
  940. #define TAKE_GOTO pc = GOTO_VAL ()
  941. try
  942. {
  943. // We keep nop around. It is used if we're interpreting the
  944. // bytecodes and not doing direct threading.
  945. insn_nop:
  946. NEXT_INSN;
  947. /* The first few instructions here are ordered according to their
  948. frequency, in the hope that this will improve code locality a
  949. little. */
  950. insn_aload_0: // 0x2a
  951. LOADA (0);
  952. NEXT_INSN;
  953. insn_iload: // 0x15
  954. LOADI (GET1U ());
  955. NEXT_INSN;
  956. insn_iload_1: // 0x1b
  957. LOADI (1);
  958. NEXT_INSN;
  959. insn_invokevirtual: // 0xb6
  960. {
  961. int index = GET2U ();
  962. /* _Jv_ResolvePoolEntry returns immediately if the value already
  963. * is resolved. If we want to clutter up the code here to gain
  964. * a little performance, then we can check the corresponding bit
  965. * JV_CONSTANT_ResolvedFlag in the tag directly. For now, I
  966. * don't think it is worth it. */
  967. rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
  968. sp -= rmeth->stack_item_count;
  969. // We don't use NULLCHECK here because we can't rely on that
  970. // working if the method is final. So instead we do an
  971. // explicit test.
  972. if (! sp[0].o)
  973. throw new java::lang::NullPointerException;
  974. if (rmeth->vtable_index == -1)
  975. {
  976. // final methods do not appear in the vtable,
  977. // if it does not appear in the superclass.
  978. fun = (void (*)()) rmeth->method->ncode;
  979. }
  980. else
  981. {
  982. jobject rcv = sp[0].o;
  983. _Jv_VTable *table = *(_Jv_VTable**) rcv;
  984. fun = (void (*)()) table->get_method (rmeth->vtable_index);
  985. }
  986. #ifdef DIRECT_THREADED
  987. // Rewrite instruction so that we use a faster pre-resolved
  988. // method.
  989. pc[-2].insn = &&invokevirtual_resolved;
  990. pc[-1].datum = rmeth;
  991. #endif /* DIRECT_THREADED */
  992. }
  993. goto perform_invoke;
  994. #ifdef DIRECT_THREADED
  995. invokevirtual_resolved:
  996. {
  997. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  998. sp -= rmeth->stack_item_count;
  999. // We don't use NULLCHECK here because we can't rely on that
  1000. // working if the method is final. So instead we do an
  1001. // explicit test.
  1002. if (! sp[0].o)
  1003. throw new java::lang::NullPointerException;
  1004. if (rmeth->vtable_index == -1)
  1005. {
  1006. // final methods do not appear in the vtable,
  1007. // if it does not appear in the superclass.
  1008. fun = (void (*)()) rmeth->method->ncode;
  1009. }
  1010. else
  1011. {
  1012. jobject rcv = sp[0].o;
  1013. _Jv_VTable *table = *(_Jv_VTable**) rcv;
  1014. fun = (void (*)()) table->get_method (rmeth->vtable_index);
  1015. }
  1016. }
  1017. goto perform_invoke;
  1018. #endif /* DIRECT_THREADED */
  1019. perform_invoke:
  1020. {
  1021. /* here goes the magic again... */
  1022. ffi_cif *cif = &rmeth->cif;
  1023. ffi_raw *raw = (ffi_raw*) sp;
  1024. jdouble rvalue;
  1025. #if FFI_NATIVE_RAW_API
  1026. /* We assume that this is only implemented if it's correct */
  1027. /* to use it here. On a 64 bit machine, it never is. */
  1028. ffi_raw_call (cif, fun, (void*)&rvalue, raw);
  1029. #else
  1030. ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
  1031. #endif
  1032. int rtype = cif->rtype->type;
  1033. /* the likelyhood of object, int, or void return is very high,
  1034. * so those are checked before the switch */
  1035. if (rtype == FFI_TYPE_POINTER)
  1036. {
  1037. PUSHA (*(jobject*)&rvalue);
  1038. }
  1039. else if (rtype == FFI_TYPE_SINT32)
  1040. {
  1041. PUSHI (*(jint*)&rvalue);
  1042. }
  1043. else if (rtype == FFI_TYPE_VOID)
  1044. {
  1045. /* skip */
  1046. }
  1047. else
  1048. {
  1049. switch (rtype)
  1050. {
  1051. case FFI_TYPE_SINT8:
  1052. {
  1053. jbyte value = (*(jint*)&rvalue) & 0xff;
  1054. PUSHI (value);
  1055. }
  1056. break;
  1057. case FFI_TYPE_SINT16:
  1058. {
  1059. jshort value = (*(jint*)&rvalue) & 0xffff;
  1060. PUSHI (value);
  1061. }
  1062. break;
  1063. case FFI_TYPE_UINT16:
  1064. {
  1065. jint value = (*(jint*)&rvalue) & 0xffff;
  1066. PUSHI (value);
  1067. }
  1068. break;
  1069. case FFI_TYPE_FLOAT:
  1070. PUSHF (*(jfloat*)&rvalue);
  1071. break;
  1072. case FFI_TYPE_DOUBLE:
  1073. PUSHD (rvalue);
  1074. break;
  1075. case FFI_TYPE_SINT64:
  1076. PUSHL (*(jlong*)&rvalue);
  1077. break;
  1078. default:
  1079. throw_internal_error ("unknown return type in invokeXXX");
  1080. }
  1081. }
  1082. }
  1083. NEXT_INSN;
  1084. insn_aconst_null:
  1085. PUSHA (NULL);
  1086. NEXT_INSN;
  1087. insn_iconst_m1:
  1088. PUSHI (-1);
  1089. NEXT_INSN;
  1090. insn_iconst_0:
  1091. PUSHI (0);
  1092. NEXT_INSN;
  1093. insn_iconst_1:
  1094. PUSHI (1);
  1095. NEXT_INSN;
  1096. insn_iconst_2:
  1097. PUSHI (2);
  1098. NEXT_INSN;
  1099. insn_iconst_3:
  1100. PUSHI (3);
  1101. NEXT_INSN;
  1102. insn_iconst_4:
  1103. PUSHI (4);
  1104. NEXT_INSN;
  1105. insn_iconst_5:
  1106. PUSHI (5);
  1107. NEXT_INSN;
  1108. insn_lconst_0:
  1109. PUSHL (0);
  1110. NEXT_INSN;
  1111. insn_lconst_1:
  1112. PUSHL (1);
  1113. NEXT_INSN;
  1114. insn_fconst_0:
  1115. PUSHF (0);
  1116. NEXT_INSN;
  1117. insn_fconst_1:
  1118. PUSHF (1);
  1119. NEXT_INSN;
  1120. insn_fconst_2:
  1121. PUSHF (2);
  1122. NEXT_INSN;
  1123. insn_dconst_0:
  1124. PUSHD (0);
  1125. NEXT_INSN;
  1126. insn_dconst_1:
  1127. PUSHD (1);
  1128. NEXT_INSN;
  1129. insn_bipush:
  1130. // For direct threaded, bipush and sipush are the same.
  1131. #ifndef DIRECT_THREADED
  1132. PUSHI (GET1S ());
  1133. NEXT_INSN;
  1134. #endif /* DIRECT_THREADED */
  1135. insn_sipush:
  1136. PUSHI (GET2S ());
  1137. NEXT_INSN;
  1138. insn_ldc:
  1139. // For direct threaded, ldc and ldc_w are the same.
  1140. #ifndef DIRECT_THREADED
  1141. PUSHA ((jobject) AVAL1U ());
  1142. NEXT_INSN;
  1143. #endif /* DIRECT_THREADED */
  1144. insn_ldc_w:
  1145. PUSHA ((jobject) AVAL2U ());
  1146. NEXT_INSN;
  1147. insn_ldc2_w:
  1148. {
  1149. void *where = AVAL2UP ();
  1150. memcpy (sp, where, 2*sizeof (_Jv_word));
  1151. sp += 2;
  1152. }
  1153. NEXT_INSN;
  1154. insn_lload:
  1155. LOADL (GET1U ());
  1156. NEXT_INSN;
  1157. insn_fload:
  1158. LOADF (GET1U ());
  1159. NEXT_INSN;
  1160. insn_dload:
  1161. LOADD (GET1U ());
  1162. NEXT_INSN;
  1163. insn_aload:
  1164. LOADA (GET1U ());
  1165. NEXT_INSN;
  1166. insn_iload_0:
  1167. LOADI (0);
  1168. NEXT_INSN;
  1169. insn_iload_2:
  1170. LOADI (2);
  1171. NEXT_INSN;
  1172. insn_iload_3:
  1173. LOADI (3);
  1174. NEXT_INSN;
  1175. insn_lload_0:
  1176. LOADL (0);
  1177. NEXT_INSN;
  1178. insn_lload_1:
  1179. LOADL (1);
  1180. NEXT_INSN;
  1181. insn_lload_2:
  1182. LOADL (2);
  1183. NEXT_INSN;
  1184. insn_lload_3:
  1185. LOADL (3);
  1186. NEXT_INSN;
  1187. insn_fload_0:
  1188. LOADF (0);
  1189. NEXT_INSN;
  1190. insn_fload_1:
  1191. LOADF (1);
  1192. NEXT_INSN;
  1193. insn_fload_2:
  1194. LOADF (2);
  1195. NEXT_INSN;
  1196. insn_fload_3:
  1197. LOADF (3);
  1198. NEXT_INSN;
  1199. insn_dload_0:
  1200. LOADD (0);
  1201. NEXT_INSN;
  1202. insn_dload_1:
  1203. LOADD (1);
  1204. NEXT_INSN;
  1205. insn_dload_2:
  1206. LOADD (2);
  1207. NEXT_INSN;
  1208. insn_dload_3:
  1209. LOADD (3);
  1210. NEXT_INSN;
  1211. insn_aload_1:
  1212. LOADA(1);
  1213. NEXT_INSN;
  1214. insn_aload_2:
  1215. LOADA(2);
  1216. NEXT_INSN;
  1217. insn_aload_3:
  1218. LOADA(3);
  1219. NEXT_INSN;
  1220. insn_iaload:
  1221. {
  1222. jint index = POPI();
  1223. jintArray arr = (jintArray) POPA();
  1224. NULLARRAYCHECK (arr);
  1225. ARRAYBOUNDSCHECK (arr, index);
  1226. PUSHI( elements(arr)[index] );
  1227. }
  1228. NEXT_INSN;
  1229. insn_laload:
  1230. {
  1231. jint index = POPI();
  1232. jlongArray arr = (jlongArray) POPA();
  1233. NULLARRAYCHECK (arr);
  1234. ARRAYBOUNDSCHECK (arr, index);
  1235. PUSHL( elements(arr)[index] );
  1236. }
  1237. NEXT_INSN;
  1238. insn_faload:
  1239. {
  1240. jint index = POPI();
  1241. jfloatArray arr = (jfloatArray) POPA();
  1242. NULLARRAYCHECK (arr);
  1243. ARRAYBOUNDSCHECK (arr, index);
  1244. PUSHF( elements(arr)[index] );
  1245. }
  1246. NEXT_INSN;
  1247. insn_daload:
  1248. {
  1249. jint index = POPI();
  1250. jdoubleArray arr = (jdoubleArray) POPA();
  1251. NULLARRAYCHECK (arr);
  1252. ARRAYBOUNDSCHECK (arr, index);
  1253. PUSHD( elements(arr)[index] );
  1254. }
  1255. NEXT_INSN;
  1256. insn_aaload:
  1257. {
  1258. jint index = POPI();
  1259. jobjectArray arr = (jobjectArray) POPA();
  1260. NULLARRAYCHECK (arr);
  1261. ARRAYBOUNDSCHECK (arr, index);
  1262. PUSHA( elements(arr)[index] );
  1263. }
  1264. NEXT_INSN;
  1265. insn_baload:
  1266. {
  1267. jint index = POPI();
  1268. jbyteArray arr = (jbyteArray) POPA();
  1269. NULLARRAYCHECK (arr);
  1270. ARRAYBOUNDSCHECK (arr, index);
  1271. PUSHI( elements(arr)[index] );
  1272. }
  1273. NEXT_INSN;
  1274. insn_caload:
  1275. {
  1276. jint index = POPI();
  1277. jcharArray arr = (jcharArray) POPA();
  1278. NULLARRAYCHECK (arr);
  1279. ARRAYBOUNDSCHECK (arr, index);
  1280. PUSHI( elements(arr)[index] );
  1281. }
  1282. NEXT_INSN;
  1283. insn_saload:
  1284. {
  1285. jint index = POPI();
  1286. jshortArray arr = (jshortArray) POPA();
  1287. NULLARRAYCHECK (arr);
  1288. ARRAYBOUNDSCHECK (arr, index);
  1289. PUSHI( elements(arr)[index] );
  1290. }
  1291. NEXT_INSN;
  1292. insn_istore:
  1293. STOREI (GET1U ());
  1294. NEXT_INSN;
  1295. insn_lstore:
  1296. STOREL (GET1U ());
  1297. NEXT_INSN;
  1298. insn_fstore:
  1299. STOREF (GET1U ());
  1300. NEXT_INSN;
  1301. insn_dstore:
  1302. STORED (GET1U ());
  1303. NEXT_INSN;
  1304. insn_astore:
  1305. STOREA (GET1U ());
  1306. NEXT_INSN;
  1307. insn_istore_0:
  1308. STOREI (0);
  1309. NEXT_INSN;
  1310. insn_istore_1:
  1311. STOREI (1);
  1312. NEXT_INSN;
  1313. insn_istore_2:
  1314. STOREI (2);
  1315. NEXT_INSN;
  1316. insn_istore_3:
  1317. STOREI (3);
  1318. NEXT_INSN;
  1319. insn_lstore_0:
  1320. STOREL (0);
  1321. NEXT_INSN;
  1322. insn_lstore_1:
  1323. STOREL (1);
  1324. NEXT_INSN;
  1325. insn_lstore_2:
  1326. STOREL (2);
  1327. NEXT_INSN;
  1328. insn_lstore_3:
  1329. STOREL (3);
  1330. NEXT_INSN;
  1331. insn_fstore_0:
  1332. STOREF (0);
  1333. NEXT_INSN;
  1334. insn_fstore_1:
  1335. STOREF (1);
  1336. NEXT_INSN;
  1337. insn_fstore_2:
  1338. STOREF (2);
  1339. NEXT_INSN;
  1340. insn_fstore_3:
  1341. STOREF (3);
  1342. NEXT_INSN;
  1343. insn_dstore_0:
  1344. STORED (0);
  1345. NEXT_INSN;
  1346. insn_dstore_1:
  1347. STORED (1);
  1348. NEXT_INSN;
  1349. insn_dstore_2:
  1350. STORED (2);
  1351. NEXT_INSN;
  1352. insn_dstore_3:
  1353. STORED (3);
  1354. NEXT_INSN;
  1355. insn_astore_0:
  1356. STOREA(0);
  1357. NEXT_INSN;
  1358. insn_astore_1:
  1359. STOREA(1);
  1360. NEXT_INSN;
  1361. insn_astore_2:
  1362. STOREA(2);
  1363. NEXT_INSN;
  1364. insn_astore_3:
  1365. STOREA(3);
  1366. NEXT_INSN;
  1367. insn_iastore:
  1368. {
  1369. jint value = POPI();
  1370. jint index = POPI();
  1371. jintArray arr = (jintArray) POPA();
  1372. NULLARRAYCHECK (arr);
  1373. ARRAYBOUNDSCHECK (arr, index);
  1374. elements(arr)[index] = value;
  1375. }
  1376. NEXT_INSN;
  1377. insn_lastore:
  1378. {
  1379. jlong value = POPL();
  1380. jint index = POPI();
  1381. jlongArray arr = (jlongArray) POPA();
  1382. NULLARRAYCHECK (arr);
  1383. ARRAYBOUNDSCHECK (arr, index);
  1384. elements(arr)[index] = value;
  1385. }
  1386. NEXT_INSN;
  1387. insn_fastore:
  1388. {
  1389. jfloat value = POPF();
  1390. jint index = POPI();
  1391. jfloatArray arr = (jfloatArray) POPA();
  1392. NULLARRAYCHECK (arr);
  1393. ARRAYBOUNDSCHECK (arr, index);
  1394. elements(arr)[index] = value;
  1395. }
  1396. NEXT_INSN;
  1397. insn_dastore:
  1398. {
  1399. jdouble value = POPD();
  1400. jint index = POPI();
  1401. jdoubleArray arr = (jdoubleArray) POPA();
  1402. NULLARRAYCHECK (arr);
  1403. ARRAYBOUNDSCHECK (arr, index);
  1404. elements(arr)[index] = value;
  1405. }
  1406. NEXT_INSN;
  1407. insn_aastore:
  1408. {
  1409. jobject value = POPA();
  1410. jint index = POPI();
  1411. jobjectArray arr = (jobjectArray) POPA();
  1412. NULLARRAYCHECK (arr);
  1413. ARRAYBOUNDSCHECK (arr, index);
  1414. _Jv_CheckArrayStore (arr, value);
  1415. elements(arr)[index] = value;
  1416. }
  1417. NEXT_INSN;
  1418. insn_bastore:
  1419. {
  1420. jbyte value = (jbyte) POPI();
  1421. jint index = POPI();
  1422. jbyteArray arr = (jbyteArray) POPA();
  1423. NULLARRAYCHECK (arr);
  1424. ARRAYBOUNDSCHECK (arr, index);
  1425. elements(arr)[index] = value;
  1426. }
  1427. NEXT_INSN;
  1428. insn_castore:
  1429. {
  1430. jchar value = (jchar) POPI();
  1431. jint index = POPI();
  1432. jcharArray arr = (jcharArray) POPA();
  1433. NULLARRAYCHECK (arr);
  1434. ARRAYBOUNDSCHECK (arr, index);
  1435. elements(arr)[index] = value;
  1436. }
  1437. NEXT_INSN;
  1438. insn_sastore:
  1439. {
  1440. jshort value = (jshort) POPI();
  1441. jint index = POPI();
  1442. jshortArray arr = (jshortArray) POPA();
  1443. NULLARRAYCHECK (arr);
  1444. ARRAYBOUNDSCHECK (arr, index);
  1445. elements(arr)[index] = value;
  1446. }
  1447. NEXT_INSN;
  1448. insn_pop:
  1449. sp -= 1;
  1450. NEXT_INSN;
  1451. insn_pop2:
  1452. sp -= 2;
  1453. NEXT_INSN;
  1454. insn_dup:
  1455. sp[0] = sp[-1];
  1456. sp += 1;
  1457. NEXT_INSN;
  1458. insn_dup_x1:
  1459. dupx (sp, 1, 1); sp+=1;
  1460. NEXT_INSN;
  1461. insn_dup_x2:
  1462. dupx (sp, 1, 2); sp+=1;
  1463. NEXT_INSN;
  1464. insn_dup2:
  1465. sp[0] = sp[-2];
  1466. sp[1] = sp[-1];
  1467. sp += 2;
  1468. NEXT_INSN;
  1469. insn_dup2_x1:
  1470. dupx (sp, 2, 1); sp+=2;
  1471. NEXT_INSN;
  1472. insn_dup2_x2:
  1473. dupx (sp, 2, 2); sp+=2;
  1474. NEXT_INSN;
  1475. insn_swap:
  1476. {
  1477. jobject tmp1 = POPA();
  1478. jobject tmp2 = POPA();
  1479. PUSHA (tmp1);
  1480. PUSHA (tmp2);
  1481. }
  1482. NEXT_INSN;
  1483. insn_iadd:
  1484. BINOPI(+);
  1485. NEXT_INSN;
  1486. insn_ladd:
  1487. BINOPL(+);
  1488. NEXT_INSN;
  1489. insn_fadd:
  1490. BINOPF(+);
  1491. NEXT_INSN;
  1492. insn_dadd:
  1493. BINOPD(+);
  1494. NEXT_INSN;
  1495. insn_isub:
  1496. BINOPI(-);
  1497. NEXT_INSN;
  1498. insn_lsub:
  1499. BINOPL(-);
  1500. NEXT_INSN;
  1501. insn_fsub:
  1502. BINOPF(-);
  1503. NEXT_INSN;
  1504. insn_dsub:
  1505. BINOPD(-);
  1506. NEXT_INSN;
  1507. insn_imul:
  1508. BINOPI(*);
  1509. NEXT_INSN;
  1510. insn_lmul:
  1511. BINOPL(*);
  1512. NEXT_INSN;
  1513. insn_fmul:
  1514. BINOPF(*);
  1515. NEXT_INSN;
  1516. insn_dmul:
  1517. BINOPD(*);
  1518. NEXT_INSN;
  1519. insn_idiv:
  1520. {
  1521. jint value2 = POPI();
  1522. jint value1 = POPI();
  1523. jint res = _Jv_divI (value1, value2);
  1524. PUSHI (res);
  1525. }
  1526. NEXT_INSN;
  1527. insn_ldiv:
  1528. {
  1529. jlong value2 = POPL();
  1530. jlong value1 = POPL();
  1531. jlong res = _Jv_divJ (value1, value2);
  1532. PUSHL (res);
  1533. }
  1534. NEXT_INSN;
  1535. insn_fdiv:
  1536. {
  1537. jfloat value2 = POPF();
  1538. jfloat value1 = POPF();
  1539. jfloat res = value1 / value2;
  1540. PUSHF (res);
  1541. }
  1542. NEXT_INSN;
  1543. insn_ddiv:
  1544. {
  1545. jdouble value2 = POPD();
  1546. jdouble value1 = POPD();
  1547. jdouble res = value1 / value2;
  1548. PUSHD (res);
  1549. }
  1550. NEXT_INSN;
  1551. insn_irem:
  1552. {
  1553. jint value2 = POPI();
  1554. jint value1 = POPI();
  1555. jint res = _Jv_remI (value1, value2);
  1556. PUSHI (res);
  1557. }
  1558. NEXT_INSN;
  1559. insn_lrem:
  1560. {
  1561. jlong value2 = POPL();
  1562. jlong value1 = POPL();
  1563. jlong res = _Jv_remJ (value1, value2);
  1564. PUSHL (res);
  1565. }
  1566. NEXT_INSN;
  1567. insn_frem:
  1568. {
  1569. jfloat value2 = POPF();
  1570. jfloat value1 = POPF();
  1571. jfloat res = __ieee754_fmod (value1, value2);
  1572. PUSHF (res);
  1573. }
  1574. NEXT_INSN;
  1575. insn_drem:
  1576. {
  1577. jdouble value2 = POPD();
  1578. jdouble value1 = POPD();
  1579. jdouble res = __ieee754_fmod (value1, value2);
  1580. PUSHD (res);
  1581. }
  1582. NEXT_INSN;
  1583. insn_ineg:
  1584. {
  1585. jint value = POPI();
  1586. PUSHI (value * -1);
  1587. }
  1588. NEXT_INSN;
  1589. insn_lneg:
  1590. {
  1591. jlong value = POPL();
  1592. PUSHL (value * -1);
  1593. }
  1594. NEXT_INSN;
  1595. insn_fneg:
  1596. {
  1597. jfloat value = POPF();
  1598. PUSHF (value * -1);
  1599. }
  1600. NEXT_INSN;
  1601. insn_dneg:
  1602. {
  1603. jdouble value = POPD();
  1604. PUSHD (value * -1);
  1605. }
  1606. NEXT_INSN;
  1607. insn_ishl:
  1608. {
  1609. jint shift = (POPI() & 0x1f);
  1610. jint value = POPI();
  1611. PUSHI (value << shift);
  1612. }
  1613. NEXT_INSN;
  1614. insn_lshl:
  1615. {
  1616. jint shift = (POPI() & 0x3f);
  1617. jlong value = POPL();
  1618. PUSHL (value << shift);
  1619. }
  1620. NEXT_INSN;
  1621. insn_ishr:
  1622. {
  1623. jint shift = (POPI() & 0x1f);
  1624. jint value = POPI();
  1625. PUSHI (value >> shift);
  1626. }
  1627. NEXT_INSN;
  1628. insn_lshr:
  1629. {
  1630. jint shift = (POPI() & 0x3f);
  1631. jlong value = POPL();
  1632. PUSHL (value >> shift);
  1633. }
  1634. NEXT_INSN;
  1635. insn_iushr:
  1636. {
  1637. jint shift = (POPI() & 0x1f);
  1638. UINT32 value = (UINT32) POPI();
  1639. PUSHI ((jint) (value >> shift));
  1640. }
  1641. NEXT_INSN;
  1642. insn_lushr:
  1643. {
  1644. jint shift = (POPI() & 0x3f);
  1645. UINT64 value = (UINT64) POPL();
  1646. PUSHL ((value >> shift));
  1647. }
  1648. NEXT_INSN;
  1649. insn_iand:
  1650. BINOPI (&);
  1651. NEXT_INSN;
  1652. insn_land:
  1653. BINOPL (&);
  1654. NEXT_INSN;
  1655. insn_ior:
  1656. BINOPI (|);
  1657. NEXT_INSN;
  1658. insn_lor:
  1659. BINOPL (|);
  1660. NEXT_INSN;
  1661. insn_ixor:
  1662. BINOPI (^);
  1663. NEXT_INSN;
  1664. insn_lxor:
  1665. BINOPL (^);
  1666. NEXT_INSN;
  1667. insn_iinc:
  1668. {
  1669. jint index = GET1U ();
  1670. jint amount = GET1S ();
  1671. locals[index].i += amount;
  1672. }
  1673. NEXT_INSN;
  1674. insn_i2l:
  1675. {jlong value = POPI(); PUSHL (value);}
  1676. NEXT_INSN;
  1677. insn_i2f:
  1678. {jfloat value = POPI(); PUSHF (value);}
  1679. NEXT_INSN;
  1680. insn_i2d:
  1681. {jdouble value = POPI(); PUSHD (value);}
  1682. NEXT_INSN;
  1683. insn_l2i:
  1684. {jint value = POPL(); PUSHI (value);}
  1685. NEXT_INSN;
  1686. insn_l2f:
  1687. {jfloat value = POPL(); PUSHF (value);}
  1688. NEXT_INSN;
  1689. insn_l2d:
  1690. {jdouble value = POPL(); PUSHD (value);}
  1691. NEXT_INSN;
  1692. insn_f2i:
  1693. {
  1694. using namespace java::lang;
  1695. jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
  1696. PUSHI(value);
  1697. }
  1698. NEXT_INSN;
  1699. insn_f2l:
  1700. {
  1701. using namespace java::lang;
  1702. jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
  1703. PUSHL(value);
  1704. }
  1705. NEXT_INSN;
  1706. insn_f2d:
  1707. { jdouble value = POPF (); PUSHD(value); }
  1708. NEXT_INSN;
  1709. insn_d2i:
  1710. {
  1711. using namespace java::lang;
  1712. jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
  1713. PUSHI(value);
  1714. }
  1715. NEXT_INSN;
  1716. insn_d2l:
  1717. {
  1718. using namespace java::lang;
  1719. jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
  1720. PUSHL(value);
  1721. }
  1722. NEXT_INSN;
  1723. insn_d2f:
  1724. { jfloat value = POPD (); PUSHF(value); }
  1725. NEXT_INSN;
  1726. insn_i2b:
  1727. { jbyte value = POPI (); PUSHI(value); }
  1728. NEXT_INSN;
  1729. insn_i2c:
  1730. { jchar value = POPI (); PUSHI(value); }
  1731. NEXT_INSN;
  1732. insn_i2s:
  1733. { jshort value = POPI (); PUSHI(value); }
  1734. NEXT_INSN;
  1735. insn_lcmp:
  1736. {
  1737. jlong value2 = POPL ();
  1738. jlong value1 = POPL ();
  1739. if (value1 > value2)
  1740. { PUSHI (1); }
  1741. else if (value1 == value2)
  1742. { PUSHI (0); }
  1743. else
  1744. { PUSHI (-1); }
  1745. }
  1746. NEXT_INSN;
  1747. insn_fcmpl:
  1748. tmpval = -1;
  1749. goto fcmp;
  1750. insn_fcmpg:
  1751. tmpval = 1;
  1752. fcmp:
  1753. {
  1754. jfloat value2 = POPF ();
  1755. jfloat value1 = POPF ();
  1756. if (value1 > value2)
  1757. PUSHI (1);
  1758. else if (value1 == value2)
  1759. PUSHI (0);
  1760. else if (value1 < value2)
  1761. PUSHI (-1);
  1762. else
  1763. PUSHI (tmpval);
  1764. }
  1765. NEXT_INSN;
  1766. insn_dcmpl:
  1767. tmpval = 1;
  1768. goto dcmp;
  1769. insn_dcmpg:
  1770. tmpval = -1;
  1771. dcmp:
  1772. {
  1773. jdouble value2 = POPD ();
  1774. jdouble value1 = POPD ();
  1775. if (value1 > value2)
  1776. PUSHI (1);
  1777. else if (value1 == value2)
  1778. PUSHI (0);
  1779. else if (value1 < value2)
  1780. PUSHI (-1);
  1781. else
  1782. PUSHI (tmpval);
  1783. }
  1784. NEXT_INSN;
  1785. insn_ifeq:
  1786. {
  1787. if (POPI() == 0)
  1788. TAKE_GOTO;
  1789. else
  1790. SKIP_GOTO;
  1791. }
  1792. NEXT_INSN;
  1793. insn_ifne:
  1794. {
  1795. if (POPI() != 0)
  1796. TAKE_GOTO;
  1797. else
  1798. SKIP_GOTO;
  1799. }
  1800. NEXT_INSN;
  1801. insn_iflt:
  1802. {
  1803. if (POPI() < 0)
  1804. TAKE_GOTO;
  1805. else
  1806. SKIP_GOTO;
  1807. }
  1808. NEXT_INSN;
  1809. insn_ifge:
  1810. {
  1811. if (POPI() >= 0)
  1812. TAKE_GOTO;
  1813. else
  1814. SKIP_GOTO;
  1815. }
  1816. NEXT_INSN;
  1817. insn_ifgt:
  1818. {
  1819. if (POPI() > 0)
  1820. TAKE_GOTO;
  1821. else
  1822. SKIP_GOTO;
  1823. }
  1824. NEXT_INSN;
  1825. insn_ifle:
  1826. {
  1827. if (POPI() <= 0)
  1828. TAKE_GOTO;
  1829. else
  1830. SKIP_GOTO;
  1831. }
  1832. NEXT_INSN;
  1833. insn_if_icmpeq:
  1834. {
  1835. jint value2 = POPI();
  1836. jint value1 = POPI();
  1837. if (value1 == value2)
  1838. TAKE_GOTO;
  1839. else
  1840. SKIP_GOTO;
  1841. }
  1842. NEXT_INSN;
  1843. insn_if_icmpne:
  1844. {
  1845. jint value2 = POPI();
  1846. jint value1 = POPI();
  1847. if (value1 != value2)
  1848. TAKE_GOTO;
  1849. else
  1850. SKIP_GOTO;
  1851. }
  1852. NEXT_INSN;
  1853. insn_if_icmplt:
  1854. {
  1855. jint value2 = POPI();
  1856. jint value1 = POPI();
  1857. if (value1 < value2)
  1858. TAKE_GOTO;
  1859. else
  1860. SKIP_GOTO;
  1861. }
  1862. NEXT_INSN;
  1863. insn_if_icmpge:
  1864. {
  1865. jint value2 = POPI();
  1866. jint value1 = POPI();
  1867. if (value1 >= value2)
  1868. TAKE_GOTO;
  1869. else
  1870. SKIP_GOTO;
  1871. }
  1872. NEXT_INSN;
  1873. insn_if_icmpgt:
  1874. {
  1875. jint value2 = POPI();
  1876. jint value1 = POPI();
  1877. if (value1 > value2)
  1878. TAKE_GOTO;
  1879. else
  1880. SKIP_GOTO;
  1881. }
  1882. NEXT_INSN;
  1883. insn_if_icmple:
  1884. {
  1885. jint value2 = POPI();
  1886. jint value1 = POPI();
  1887. if (value1 <= value2)
  1888. TAKE_GOTO;
  1889. else
  1890. SKIP_GOTO;
  1891. }
  1892. NEXT_INSN;
  1893. insn_if_acmpeq:
  1894. {
  1895. jobject value2 = POPA();
  1896. jobject value1 = POPA();
  1897. if (value1 == value2)
  1898. TAKE_GOTO;
  1899. else
  1900. SKIP_GOTO;
  1901. }
  1902. NEXT_INSN;
  1903. insn_if_acmpne:
  1904. {
  1905. jobject value2 = POPA();
  1906. jobject value1 = POPA();
  1907. if (value1 != value2)
  1908. TAKE_GOTO;
  1909. else
  1910. SKIP_GOTO;
  1911. }
  1912. NEXT_INSN;
  1913. insn_goto_w:
  1914. #ifndef DIRECT_THREADED
  1915. // For direct threaded, goto and goto_w are the same.
  1916. pc = pc - 1 + get4 (pc);
  1917. NEXT_INSN;
  1918. #endif /* DIRECT_THREADED */
  1919. insn_goto:
  1920. TAKE_GOTO;
  1921. NEXT_INSN;
  1922. insn_jsr_w:
  1923. #ifndef DIRECT_THREADED
  1924. // For direct threaded, jsr and jsr_w are the same.
  1925. {
  1926. pc_t next = pc - 1 + get4 (pc);
  1927. pc += 4;
  1928. PUSHA ((jobject) pc);
  1929. pc = next;
  1930. }
  1931. NEXT_INSN;
  1932. #endif /* DIRECT_THREADED */
  1933. insn_jsr:
  1934. {
  1935. pc_t next = GOTO_VAL();
  1936. SKIP_GOTO;
  1937. PUSHA ((jobject) pc);
  1938. pc = next;
  1939. }
  1940. NEXT_INSN;
  1941. insn_ret:
  1942. {
  1943. jint index = GET1U ();
  1944. pc = (pc_t) PEEKA (index);
  1945. }
  1946. NEXT_INSN;
  1947. insn_tableswitch:
  1948. {
  1949. #ifdef DIRECT_THREADED
  1950. void *def = (pc++)->datum;
  1951. int index = POPI();
  1952. jint low = INTVAL ();
  1953. jint high = INTVAL ();
  1954. if (index < low || index > high)
  1955. pc = (insn_slot *) def;
  1956. else
  1957. pc = (insn_slot *) ((pc + index - low)->datum);
  1958. #else
  1959. pc_t base_pc = pc - 1;
  1960. int index = POPI ();
  1961. pc_t base = (pc_t) bytecode ();
  1962. while ((pc - base) % 4 != 0)
  1963. ++pc;
  1964. jint def = get4 (pc);
  1965. jint low = get4 (pc + 4);
  1966. jint high = get4 (pc + 8);
  1967. if (index < low || index > high)
  1968. pc = base_pc + def;
  1969. else
  1970. pc = base_pc + get4 (pc + 4 * (index - low + 3));
  1971. #endif /* DIRECT_THREADED */
  1972. }
  1973. NEXT_INSN;
  1974. insn_lookupswitch:
  1975. {
  1976. #ifdef DIRECT_THREADED
  1977. void *def = (pc++)->insn;
  1978. int index = POPI();
  1979. jint npairs = INTVAL ();
  1980. int max = npairs - 1;
  1981. int min = 0;
  1982. // Simple binary search...
  1983. while (min < max)
  1984. {
  1985. int half = (min + max) / 2;
  1986. int match = pc[2 * half].int_val;
  1987. if (index == match)
  1988. {
  1989. // Found it.
  1990. pc = (insn_slot *) pc[2 * half + 1].datum;
  1991. NEXT_INSN;
  1992. }
  1993. else if (index < match)
  1994. // We can use HALF - 1 here because we check again on
  1995. // loop exit.
  1996. max = half - 1;
  1997. else
  1998. // We can use HALF + 1 here because we check again on
  1999. // loop exit.
  2000. min = half + 1;
  2001. }
  2002. if (index == pc[2 * min].int_val)
  2003. pc = (insn_slot *) pc[2 * min + 1].datum;
  2004. else
  2005. pc = (insn_slot *) def;
  2006. #else
  2007. unsigned char *base_pc = pc-1;
  2008. int index = POPI();
  2009. unsigned char* base = bytecode ();
  2010. while ((pc-base) % 4 != 0)
  2011. ++pc;
  2012. jint def = get4 (pc);
  2013. jint npairs = get4 (pc+4);
  2014. int max = npairs-1;
  2015. int min = 0;
  2016. // Simple binary search...
  2017. while (min < max)
  2018. {
  2019. int half = (min+max)/2;
  2020. int match = get4 (pc+ 4*(2 + 2*half));
  2021. if (index == match)
  2022. min = max = half;
  2023. else if (index < match)
  2024. // We can use HALF - 1 here because we check again on
  2025. // loop exit.
  2026. max = half - 1;
  2027. else
  2028. // We can use HALF + 1 here because we check again on
  2029. // loop exit.
  2030. min = half + 1;
  2031. }
  2032. if (index == get4 (pc+ 4*(2 + 2*min)))
  2033. pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
  2034. else
  2035. pc = base_pc + def;
  2036. #endif /* DIRECT_THREADED */
  2037. }
  2038. NEXT_INSN;
  2039. insn_areturn:
  2040. *(jobject *) retp = POPA ();
  2041. return;
  2042. insn_lreturn:
  2043. *(jlong *) retp = POPL ();
  2044. return;
  2045. insn_freturn:
  2046. *(jfloat *) retp = POPF ();
  2047. return;
  2048. insn_dreturn:
  2049. *(jdouble *) retp = POPD ();
  2050. return;
  2051. insn_ireturn:
  2052. *(jint *) retp = POPI ();
  2053. return;
  2054. insn_return:
  2055. return;
  2056. insn_getstatic:
  2057. {
  2058. jint fieldref_index = GET2U ();
  2059. _Jv_ResolvePoolEntry (defining_class, fieldref_index);
  2060. _Jv_Field *field = pool_data[fieldref_index].field;
  2061. if ((field->flags & Modifier::STATIC) == 0)
  2062. throw_incompatible_class_change_error
  2063. (JvNewStringLatin1 ("field no longer static"));
  2064. jclass type = field->type;
  2065. // We rewrite the instruction once we discover what it refers
  2066. // to.
  2067. void *newinsn = NULL;
  2068. if (type->isPrimitive ())
  2069. {
  2070. switch (type->size_in_bytes)
  2071. {
  2072. case 1:
  2073. PUSHI (*(jbyte*) (field->u.addr));
  2074. newinsn = AMPAMP (getstatic_resolved_1);
  2075. break;
  2076. case 2:
  2077. if (type == JvPrimClass (char))
  2078. {
  2079. PUSHI(*(jchar*) (field->u.addr));
  2080. newinsn = AMPAMP (getstatic_resolved_char);
  2081. }
  2082. else
  2083. {
  2084. PUSHI(*(jshort*) (field->u.addr));
  2085. newinsn = AMPAMP (getstatic_resolved_short);
  2086. }
  2087. break;
  2088. case 4:
  2089. PUSHI(*(jint*) (field->u.addr));
  2090. newinsn = AMPAMP (getstatic_resolved_4);
  2091. break;
  2092. case 8:
  2093. PUSHL(*(jlong*) (field->u.addr));
  2094. newinsn = AMPAMP (getstatic_resolved_8);
  2095. break;
  2096. }
  2097. }
  2098. else
  2099. {
  2100. PUSHA(*(jobject*) (field->u.addr));
  2101. newinsn = AMPAMP (getstatic_resolved_obj);
  2102. }
  2103. #ifdef DIRECT_THREADED
  2104. pc[-2].insn = newinsn;
  2105. pc[-1].datum = field->u.addr;
  2106. #endif /* DIRECT_THREADED */
  2107. }
  2108. NEXT_INSN;
  2109. #ifdef DIRECT_THREADED
  2110. getstatic_resolved_1:
  2111. PUSHI (*(jbyte *) AVAL ());
  2112. NEXT_INSN;
  2113. getstatic_resolved_char:
  2114. PUSHI (*(jchar *) AVAL ());
  2115. NEXT_INSN;
  2116. getstatic_resolved_short:
  2117. PUSHI (*(jshort *) AVAL ());
  2118. NEXT_INSN;
  2119. getstatic_resolved_4:
  2120. PUSHI (*(jint *) AVAL ());
  2121. NEXT_INSN;
  2122. getstatic_resolved_8:
  2123. PUSHL (*(jlong *) AVAL ());
  2124. NEXT_INSN;
  2125. getstatic_resolved_obj:
  2126. PUSHA (*(jobject *) AVAL ());
  2127. NEXT_INSN;
  2128. #endif /* DIRECT_THREADED */
  2129. insn_getfield:
  2130. {
  2131. jint fieldref_index = GET2U ();
  2132. _Jv_ResolvePoolEntry (defining_class, fieldref_index);
  2133. _Jv_Field *field = pool_data[fieldref_index].field;
  2134. if ((field->flags & Modifier::STATIC) != 0)
  2135. throw_incompatible_class_change_error
  2136. (JvNewStringLatin1 ("field is static"));
  2137. jclass type = field->type;
  2138. jint field_offset = field->u.boffset;
  2139. if (field_offset > 0xffff)
  2140. throw new java::lang::VirtualMachineError;
  2141. jobject obj = POPA();
  2142. NULLCHECK(obj);
  2143. void *newinsn = NULL;
  2144. if (type->isPrimitive ())
  2145. {
  2146. switch (type->size_in_bytes)
  2147. {
  2148. case 1:
  2149. PUSHI (*(jbyte*) ((char*)obj + field_offset));
  2150. newinsn = AMPAMP (getfield_resolved_1);
  2151. break;
  2152. case 2:
  2153. if (type == JvPrimClass (char))
  2154. {
  2155. PUSHI (*(jchar*) ((char*)obj + field_offset));
  2156. newinsn = AMPAMP (getfield_resolved_char);
  2157. }
  2158. else
  2159. {
  2160. PUSHI (*(jshort*) ((char*)obj + field_offset));
  2161. newinsn = AMPAMP (getfield_resolved_short);
  2162. }
  2163. break;
  2164. case 4:
  2165. PUSHI (*(jint*) ((char*)obj + field_offset));
  2166. newinsn = AMPAMP (getfield_resolved_4);
  2167. break;
  2168. case 8:
  2169. PUSHL(*(jlong*) ((char*)obj + field_offset));
  2170. newinsn = AMPAMP (getfield_resolved_8);
  2171. break;
  2172. }
  2173. }
  2174. else
  2175. {
  2176. PUSHA(*(jobject*) ((char*)obj + field_offset));
  2177. newinsn = AMPAMP (getfield_resolved_obj);
  2178. }
  2179. #ifdef DIRECT_THREADED
  2180. pc[-2].insn = newinsn;
  2181. pc[-1].int_val = field_offset;
  2182. #endif /* DIRECT_THREADED */
  2183. }
  2184. NEXT_INSN;
  2185. #ifdef DIRECT_THREADED
  2186. getfield_resolved_1:
  2187. {
  2188. char *obj = (char *) POPA ();
  2189. NULLCHECK (obj);
  2190. PUSHI (*(jbyte *) (obj + INTVAL ()));
  2191. }
  2192. NEXT_INSN;
  2193. getfield_resolved_char:
  2194. {
  2195. char *obj = (char *) POPA ();
  2196. NULLCHECK (obj);
  2197. PUSHI (*(jchar *) (obj + INTVAL ()));
  2198. }
  2199. NEXT_INSN;
  2200. getfield_resolved_short:
  2201. {
  2202. char *obj = (char *) POPA ();
  2203. NULLCHECK (obj);
  2204. PUSHI (*(jshort *) (obj + INTVAL ()));
  2205. }
  2206. NEXT_INSN;
  2207. getfield_resolved_4:
  2208. {
  2209. char *obj = (char *) POPA ();
  2210. NULLCHECK (obj);
  2211. PUSHI (*(jint *) (obj + INTVAL ()));
  2212. }
  2213. NEXT_INSN;
  2214. getfield_resolved_8:
  2215. {
  2216. char *obj = (char *) POPA ();
  2217. NULLCHECK (obj);
  2218. PUSHL (*(jlong *) (obj + INTVAL ()));
  2219. }
  2220. NEXT_INSN;
  2221. getfield_resolved_obj:
  2222. {
  2223. char *obj = (char *) POPA ();
  2224. NULLCHECK (obj);
  2225. PUSHA (*(jobject *) (obj + INTVAL ()));
  2226. }
  2227. NEXT_INSN;
  2228. #endif /* DIRECT_THREADED */
  2229. insn_putstatic:
  2230. {
  2231. jint fieldref_index = GET2U ();
  2232. _Jv_ResolvePoolEntry (defining_class, fieldref_index);
  2233. _Jv_Field *field = pool_data[fieldref_index].field;
  2234. jclass type = field->type;
  2235. // ResolvePoolEntry cannot check this
  2236. if ((field->flags & Modifier::STATIC) == 0)
  2237. throw_incompatible_class_change_error
  2238. (JvNewStringLatin1 ("field no longer static"));
  2239. void *newinsn = NULL;
  2240. if (type->isPrimitive ())
  2241. {
  2242. switch (type->size_in_bytes)
  2243. {
  2244. case 1:
  2245. {
  2246. jint value = POPI();
  2247. *(jbyte*) (field->u.addr) = value;
  2248. newinsn = AMPAMP (putstatic_resolved_1);
  2249. break;
  2250. }
  2251. case 2:
  2252. {
  2253. jint value = POPI();
  2254. *(jchar*) (field->u.addr) = value;
  2255. newinsn = AMPAMP (putstatic_resolved_2);
  2256. break;
  2257. }
  2258. case 4:
  2259. {
  2260. jint value = POPI();
  2261. *(jint*) (field->u.addr) = value;
  2262. newinsn = AMPAMP (putstatic_resolved_4);
  2263. break;
  2264. }
  2265. case 8:
  2266. {
  2267. jlong value = POPL();
  2268. *(jlong*) (field->u.addr) = value;
  2269. newinsn = AMPAMP (putstatic_resolved_8);
  2270. break;
  2271. }
  2272. }
  2273. }
  2274. else
  2275. {
  2276. jobject value = POPA();
  2277. *(jobject*) (field->u.addr) = value;
  2278. newinsn = AMPAMP (putstatic_resolved_obj);
  2279. }
  2280. #ifdef DIRECT_THREADED
  2281. pc[-2].insn = newinsn;
  2282. pc[-1].datum = field->u.addr;
  2283. #endif /* DIRECT_THREADED */
  2284. }
  2285. NEXT_INSN;
  2286. #ifdef DIRECT_THREADED
  2287. putstatic_resolved_1:
  2288. *(jbyte *) AVAL () = POPI ();
  2289. NEXT_INSN;
  2290. putstatic_resolved_2:
  2291. *(jchar *) AVAL () = POPI ();
  2292. NEXT_INSN;
  2293. putstatic_resolved_4:
  2294. *(jint *) AVAL () = POPI ();
  2295. NEXT_INSN;
  2296. putstatic_resolved_8:
  2297. *(jlong *) AVAL () = POPL ();
  2298. NEXT_INSN;
  2299. putstatic_resolved_obj:
  2300. *(jobject *) AVAL () = POPA ();
  2301. NEXT_INSN;
  2302. #endif /* DIRECT_THREADED */
  2303. insn_putfield:
  2304. {
  2305. jint fieldref_index = GET2U ();
  2306. _Jv_ResolvePoolEntry (defining_class, fieldref_index);
  2307. _Jv_Field *field = pool_data[fieldref_index].field;
  2308. jclass type = field->type;
  2309. if ((field->flags & Modifier::STATIC) != 0)
  2310. throw_incompatible_class_change_error
  2311. (JvNewStringLatin1 ("field is static"));
  2312. jint field_offset = field->u.boffset;
  2313. if (field_offset > 0xffff)
  2314. throw new java::lang::VirtualMachineError;
  2315. void *newinsn = NULL;
  2316. if (type->isPrimitive ())
  2317. {
  2318. switch (type->size_in_bytes)
  2319. {
  2320. case 1:
  2321. {
  2322. jint value = POPI();
  2323. jobject obj = POPA();
  2324. NULLCHECK(obj);
  2325. *(jbyte*) ((char*)obj + field_offset) = value;
  2326. newinsn = AMPAMP (putfield_resolved_1);
  2327. break;
  2328. }
  2329. case 2:
  2330. {
  2331. jint value = POPI();
  2332. jobject obj = POPA();
  2333. NULLCHECK(obj);
  2334. *(jchar*) ((char*)obj + field_offset) = value;
  2335. newinsn = AMPAMP (putfield_resolved_2);
  2336. break;
  2337. }
  2338. case 4:
  2339. {
  2340. jint value = POPI();
  2341. jobject obj = POPA();
  2342. NULLCHECK(obj);
  2343. *(jint*) ((char*)obj + field_offset) = value;
  2344. newinsn = AMPAMP (putfield_resolved_4);
  2345. break;
  2346. }
  2347. case 8:
  2348. {
  2349. jlong value = POPL();
  2350. jobject obj = POPA();
  2351. NULLCHECK(obj);
  2352. *(jlong*) ((char*)obj + field_offset) = value;
  2353. newinsn = AMPAMP (putfield_resolved_8);
  2354. break;
  2355. }
  2356. }
  2357. }
  2358. else
  2359. {
  2360. jobject value = POPA();
  2361. jobject obj = POPA();
  2362. NULLCHECK(obj);
  2363. *(jobject*) ((char*)obj + field_offset) = value;
  2364. newinsn = AMPAMP (putfield_resolved_obj);
  2365. }
  2366. #ifdef DIRECT_THREADED
  2367. pc[-2].insn = newinsn;
  2368. pc[-1].int_val = field_offset;
  2369. #endif /* DIRECT_THREADED */
  2370. }
  2371. NEXT_INSN;
  2372. #ifdef DIRECT_THREADED
  2373. putfield_resolved_1:
  2374. {
  2375. jint val = POPI ();
  2376. char *obj = (char *) POPA ();
  2377. NULLCHECK (obj);
  2378. *(jbyte *) (obj + INTVAL ()) = val;
  2379. }
  2380. NEXT_INSN;
  2381. putfield_resolved_2:
  2382. {
  2383. jint val = POPI ();
  2384. char *obj = (char *) POPA ();
  2385. NULLCHECK (obj);
  2386. *(jchar *) (obj + INTVAL ()) = val;
  2387. }
  2388. NEXT_INSN;
  2389. putfield_resolved_4:
  2390. {
  2391. jint val = POPI ();
  2392. char *obj = (char *) POPA ();
  2393. NULLCHECK (obj);
  2394. *(jint *) (obj + INTVAL ()) = val;
  2395. }
  2396. NEXT_INSN;
  2397. putfield_resolved_8:
  2398. {
  2399. jlong val = POPL ();
  2400. char *obj = (char *) POPA ();
  2401. NULLCHECK (obj);
  2402. *(jlong *) (obj + INTVAL ()) = val;
  2403. }
  2404. NEXT_INSN;
  2405. putfield_resolved_obj:
  2406. {
  2407. jobject val = POPA ();
  2408. char *obj = (char *) POPA ();
  2409. NULLCHECK (obj);
  2410. *(jobject *) (obj + INTVAL ()) = val;
  2411. }
  2412. NEXT_INSN;
  2413. #endif /* DIRECT_THREADED */
  2414. insn_invokespecial:
  2415. {
  2416. int index = GET2U ();
  2417. rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
  2418. sp -= rmeth->stack_item_count;
  2419. // We don't use NULLCHECK here because we can't rely on that
  2420. // working for <init>. So instead we do an explicit test.
  2421. if (! sp[0].o)
  2422. throw new java::lang::NullPointerException;
  2423. fun = (void (*)()) rmeth->method->ncode;
  2424. #ifdef DIRECT_THREADED
  2425. // Rewrite instruction so that we use a faster pre-resolved
  2426. // method.
  2427. pc[-2].insn = &&invokespecial_resolved;
  2428. pc[-1].datum = rmeth;
  2429. #endif /* DIRECT_THREADED */
  2430. }
  2431. goto perform_invoke;
  2432. #ifdef DIRECT_THREADED
  2433. invokespecial_resolved:
  2434. {
  2435. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  2436. sp -= rmeth->stack_item_count;
  2437. // We don't use NULLCHECK here because we can't rely on that
  2438. // working for <init>. So instead we do an explicit test.
  2439. if (! sp[0].o)
  2440. throw new java::lang::NullPointerException;
  2441. fun = (void (*)()) rmeth->method->ncode;
  2442. }
  2443. goto perform_invoke;
  2444. #endif /* DIRECT_THREADED */
  2445. insn_invokestatic:
  2446. {
  2447. int index = GET2U ();
  2448. rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
  2449. sp -= rmeth->stack_item_count;
  2450. _Jv_InitClass (rmeth->klass);
  2451. fun = (void (*)()) rmeth->method->ncode;
  2452. #ifdef DIRECT_THREADED
  2453. // Rewrite instruction so that we use a faster pre-resolved
  2454. // method.
  2455. pc[-2].insn = &&invokestatic_resolved;
  2456. pc[-1].datum = rmeth;
  2457. #endif /* DIRECT_THREADED */
  2458. }
  2459. goto perform_invoke;
  2460. #ifdef DIRECT_THREADED
  2461. invokestatic_resolved:
  2462. {
  2463. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  2464. sp -= rmeth->stack_item_count;
  2465. fun = (void (*)()) rmeth->method->ncode;
  2466. }
  2467. goto perform_invoke;
  2468. #endif /* DIRECT_THREADED */
  2469. insn_invokeinterface:
  2470. {
  2471. int index = GET2U ();
  2472. rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
  2473. sp -= rmeth->stack_item_count;
  2474. jobject rcv = sp[0].o;
  2475. NULLCHECK (rcv);
  2476. fun = (void (*)())
  2477. _Jv_LookupInterfaceMethod (rcv->getClass (),
  2478. rmeth->method->name,
  2479. rmeth->method->signature);
  2480. #ifdef DIRECT_THREADED
  2481. // Rewrite instruction so that we use a faster pre-resolved
  2482. // method.
  2483. pc[-2].insn = &&invokeinterface_resolved;
  2484. pc[-1].datum = rmeth;
  2485. #else
  2486. // Skip dummy bytes.
  2487. pc += 2;
  2488. #endif /* DIRECT_THREADED */
  2489. }
  2490. goto perform_invoke;
  2491. #ifdef DIRECT_THREADED
  2492. invokeinterface_resolved:
  2493. {
  2494. rmeth = (_Jv_ResolvedMethod *) AVAL ();
  2495. sp -= rmeth->stack_item_count;
  2496. jobject rcv = sp[0].o;
  2497. NULLCHECK (rcv);
  2498. fun = (void (*)())
  2499. _Jv_LookupInterfaceMethod (rcv->getClass (),
  2500. rmeth->method->name,
  2501. rmeth->method->signature);
  2502. }
  2503. goto perform_invoke;
  2504. #endif /* DIRECT_THREADED */
  2505. insn_new:
  2506. {
  2507. int index = GET2U ();
  2508. jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
  2509. _Jv_InitClass (klass);
  2510. jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
  2511. PUSHA (res);
  2512. #ifdef DIRECT_THREADED
  2513. pc[-2].insn = &&new_resolved;
  2514. pc[-1].datum = klass;
  2515. #endif /* DIRECT_THREADED */
  2516. }
  2517. NEXT_INSN;
  2518. #ifdef DIRECT_THREADED
  2519. new_resolved:
  2520. {
  2521. jclass klass = (jclass) AVAL ();
  2522. jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
  2523. PUSHA (res);
  2524. }
  2525. NEXT_INSN;
  2526. #endif /* DIRECT_THREADED */
  2527. insn_newarray:
  2528. {
  2529. int atype = GET1U ();
  2530. int size = POPI();
  2531. jobject result = _Jv_NewArray (atype, size);
  2532. PUSHA (result);
  2533. }
  2534. NEXT_INSN;
  2535. insn_anewarray:
  2536. {
  2537. int index = GET2U ();
  2538. jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
  2539. int size = POPI();
  2540. _Jv_InitClass (klass);
  2541. jobject result = _Jv_NewObjectArray (size, klass, 0);
  2542. PUSHA (result);
  2543. #ifdef DIRECT_THREADED
  2544. pc[-2].insn = &&anewarray_resolved;
  2545. pc[-1].datum = klass;
  2546. #endif /* DIRECT_THREADED */
  2547. }
  2548. NEXT_INSN;
  2549. #ifdef DIRECT_THREADED
  2550. anewarray_resolved:
  2551. {
  2552. jclass klass = (jclass) AVAL ();
  2553. int size = POPI ();
  2554. jobject result = _Jv_NewObjectArray (size, klass, 0);
  2555. PUSHA (result);
  2556. }
  2557. NEXT_INSN;
  2558. #endif /* DIRECT_THREADED */
  2559. insn_arraylength:
  2560. {
  2561. __JArray *arr = (__JArray*)POPA();
  2562. NULLARRAYCHECK (arr);
  2563. PUSHI (arr->length);
  2564. }
  2565. NEXT_INSN;
  2566. insn_athrow:
  2567. {
  2568. jobject value = POPA();
  2569. throw static_cast<jthrowable>(value);
  2570. }
  2571. NEXT_INSN;
  2572. insn_checkcast:
  2573. {
  2574. jobject value = POPA();
  2575. jint index = GET2U ();
  2576. jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
  2577. if (value != NULL && ! to->isInstance (value))
  2578. throw new java::lang::ClassCastException (to->getName());
  2579. PUSHA (value);
  2580. #ifdef DIRECT_THREADED
  2581. pc[-2].insn = &&checkcast_resolved;
  2582. pc[-1].datum = to;
  2583. #endif /* DIRECT_THREADED */
  2584. }
  2585. NEXT_INSN;
  2586. #ifdef DIRECT_THREADED
  2587. checkcast_resolved:
  2588. {
  2589. jobject value = POPA ();
  2590. jclass to = (jclass) AVAL ();
  2591. if (value != NULL && ! to->isInstance (value))
  2592. throw new java::lang::ClassCastException (to->getName());
  2593. PUSHA (value);
  2594. }
  2595. NEXT_INSN;
  2596. #endif /* DIRECT_THREADED */
  2597. insn_instanceof:
  2598. {
  2599. jobject value = POPA();
  2600. jint index = GET2U ();
  2601. jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
  2602. PUSHI (to->isInstance (value));
  2603. #ifdef DIRECT_THREADED
  2604. pc[-2].insn = &&instanceof_resolved;
  2605. pc[-1].datum = to;
  2606. #endif /* DIRECT_THREADED */
  2607. }
  2608. NEXT_INSN;
  2609. #ifdef DIRECT_THREADED
  2610. instanceof_resolved:
  2611. {
  2612. jobject value = POPA ();
  2613. jclass to = (jclass) AVAL ();
  2614. PUSHI (to->isInstance (value));
  2615. }
  2616. NEXT_INSN;
  2617. #endif /* DIRECT_THREADED */
  2618. insn_monitorenter:
  2619. {
  2620. jobject value = POPA();
  2621. NULLCHECK(value);
  2622. _Jv_MonitorEnter (value);
  2623. }
  2624. NEXT_INSN;
  2625. insn_monitorexit:
  2626. {
  2627. jobject value = POPA();
  2628. NULLCHECK(value);
  2629. _Jv_MonitorExit (value);
  2630. }
  2631. NEXT_INSN;
  2632. insn_ifnull:
  2633. {
  2634. jobject val = POPA();
  2635. if (val == NULL)
  2636. TAKE_GOTO;
  2637. else
  2638. SKIP_GOTO;
  2639. }
  2640. NEXT_INSN;
  2641. insn_ifnonnull:
  2642. {
  2643. jobject val = POPA();
  2644. if (val != NULL)
  2645. TAKE_GOTO;
  2646. else
  2647. SKIP_GOTO;
  2648. }
  2649. NEXT_INSN;
  2650. insn_multianewarray:
  2651. {
  2652. int kind_index = GET2U ();
  2653. int dim = GET1U ();
  2654. jclass type
  2655. = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
  2656. _Jv_InitClass (type);
  2657. jint *sizes = (jint*) __builtin_alloca (sizeof (jint)*dim);
  2658. for (int i = dim - 1; i >= 0; i--)
  2659. {
  2660. sizes[i] = POPI ();
  2661. }
  2662. jobject res = _Jv_NewMultiArray (type,dim, sizes);
  2663. PUSHA (res);
  2664. }
  2665. NEXT_INSN;
  2666. #ifndef DIRECT_THREADED
  2667. insn_wide:
  2668. {
  2669. jint the_mod_op = get1u (pc++);
  2670. jint wide = get2u (pc); pc += 2;
  2671. switch (the_mod_op)
  2672. {
  2673. case op_istore:
  2674. STOREI (wide);
  2675. NEXT_INSN;
  2676. case op_fstore:
  2677. STOREF (wide);
  2678. NEXT_INSN;
  2679. case op_astore:
  2680. STOREA (wide);
  2681. NEXT_INSN;
  2682. case op_lload:
  2683. LOADL (wide);
  2684. NEXT_INSN;
  2685. case op_dload:
  2686. LOADD (wide);
  2687. NEXT_INSN;
  2688. case op_iload:
  2689. LOADI (wide);
  2690. NEXT_INSN;
  2691. case op_aload:
  2692. LOADA (wide);
  2693. NEXT_INSN;
  2694. case op_lstore:
  2695. STOREL (wide);
  2696. NEXT_INSN;
  2697. case op_dstore:
  2698. STORED (wide);
  2699. NEXT_INSN;
  2700. case op_ret:
  2701. pc = (unsigned char*) PEEKA (wide);
  2702. NEXT_INSN;
  2703. case op_iinc:
  2704. {
  2705. jint amount = get2s (pc); pc += 2;
  2706. jint value = PEEKI (wide);
  2707. POKEI (wide, value+amount);
  2708. }
  2709. NEXT_INSN;
  2710. default:
  2711. throw_internal_error ("illegal bytecode modified by wide");
  2712. }
  2713. }
  2714. #endif /* DIRECT_THREADED */
  2715. }
  2716. catch (java::lang::Throwable *ex)
  2717. {
  2718. #ifdef DIRECT_THREADED
  2719. void *logical_pc = (void *) ((insn_slot *) pc - 1);
  2720. #else
  2721. int logical_pc = pc - 1 - bytecode ();
  2722. #endif
  2723. _Jv_InterpException *exc = exceptions ();
  2724. jclass exc_class = ex->getClass ();
  2725. for (int i = 0; i < exc_count; i++)
  2726. {
  2727. if (PCVAL (exc[i].start_pc) <= logical_pc
  2728. && logical_pc < PCVAL (exc[i].end_pc))
  2729. {
  2730. #ifdef DIRECT_THREADED
  2731. jclass handler = (jclass) exc[i].handler_type.p;
  2732. #else
  2733. jclass handler = NULL;
  2734. if (exc[i].handler_type.i != 0)
  2735. handler = (_Jv_ResolvePoolEntry (defining_class,
  2736. exc[i].handler_type.i)).clazz;
  2737. #endif /* DIRECT_THREADED */
  2738. if (handler == NULL || handler->isAssignableFrom (exc_class))
  2739. {
  2740. #ifdef DIRECT_THREADED
  2741. pc = (insn_slot *) exc[i].handler_pc.p;
  2742. #else
  2743. pc = bytecode () + exc[i].handler_pc.i;
  2744. #endif /* DIRECT_THREADED */
  2745. sp = stack;
  2746. sp++->o = ex; // Push exception.
  2747. NEXT_INSN;
  2748. }
  2749. }
  2750. }
  2751. // No handler, so re-throw.
  2752. throw ex;
  2753. }
  2754. }
  2755. // This function exists so that the stack-tracing code can find the
  2756. // boundaries of the interpreter.
  2757. void
  2758. _Jv_EndOfInterpreter (void)
  2759. {
  2760. }
  2761. static void
  2762. throw_internal_error (char *msg)
  2763. {
  2764. throw new java::lang::InternalError (JvNewStringLatin1 (msg));
  2765. }
  2766. static void
  2767. throw_incompatible_class_change_error (jstring msg)
  2768. {
  2769. throw new java::lang::IncompatibleClassChangeError (msg);
  2770. }
  2771. #ifndef HANDLE_SEGV
  2772. static java::lang::NullPointerException *null_pointer_exc;
  2773. static void
  2774. throw_null_pointer_exception ()
  2775. {
  2776. if (null_pointer_exc == NULL)
  2777. null_pointer_exc = new java::lang::NullPointerException;
  2778. throw null_pointer_exc;
  2779. }
  2780. #endif
  2781. #endif // INTERPRETER