wasm_interp_fast.c 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_interp.h"
  6. #include "bh_log.h"
  7. #include "wasm_runtime.h"
  8. #include "wasm_opcode.h"
  9. #include "wasm_loader.h"
  10. #include "../common/wasm_exec_env.h"
  11. typedef int32 CellType_I32;
  12. typedef int64 CellType_I64;
  13. typedef float32 CellType_F32;
  14. typedef float64 CellType_F64;
  15. #define BR_TABLE_TMP_BUF_LEN 32
  16. /* 64-bit Memory accessors. */
  17. #if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
  18. #define PUT_I64_TO_ADDR(addr, value) do { \
  19. *(int64*)(addr) = (int64)(value); \
  20. } while (0)
  21. #define PUT_F64_TO_ADDR(addr, value) do { \
  22. *(float64*)(addr) = (float64)(value); \
  23. } while (0)
  24. #define GET_I64_FROM_ADDR(addr) (*(int64*)(addr))
  25. #define GET_F64_FROM_ADDR(addr) (*(float64*)(addr))
  26. /* For STORE opcodes */
  27. #define STORE_I64 PUT_I64_TO_ADDR
  28. #define STORE_U32(addr, value) do { \
  29. *(uint32*)(addr) = (uint32)(value); \
  30. } while (0)
  31. #define STORE_U16(addr, value) do { \
  32. *(uint16*)(addr) = (uint16)(value); \
  33. } while (0)
  34. /* For LOAD opcodes */
  35. #define LOAD_I64(addr) (*(int64*)(addr))
  36. #define LOAD_F64(addr) (*(float64*)(addr))
  37. #define LOAD_F32(addr) (*(float32*)(addr))
  38. #define LOAD_I32(addr) (*(int32*)(addr))
  39. #define LOAD_U32(addr) (*(uint32*)(addr))
  40. #define LOAD_I16(addr) (*(int16*)(addr))
  41. #define LOAD_U16(addr) (*(uint16*)(addr))
  42. #else /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
  43. #define PUT_I64_TO_ADDR(addr, value) do { \
  44. union { int64 val; uint32 parts[2]; } u; \
  45. u.val = (int64)(value); \
  46. (addr)[0] = u.parts[0]; \
  47. (addr)[1] = u.parts[1]; \
  48. } while (0)
  49. #define PUT_F64_TO_ADDR(addr, value) do { \
  50. union { float64 val; uint32 parts[2]; } u; \
  51. u.val = (value); \
  52. (addr)[0] = u.parts[0]; \
  53. (addr)[1] = u.parts[1]; \
  54. } while (0)
  55. static inline int64
  56. GET_I64_FROM_ADDR(uint32 *addr)
  57. {
  58. union { int64 val; uint32 parts[2]; } u;
  59. u.parts[0] = addr[0];
  60. u.parts[1] = addr[1];
  61. return u.val;
  62. }
  63. static inline float64
  64. GET_F64_FROM_ADDR (uint32 *addr)
  65. {
  66. union { float64 val; uint32 parts[2]; } u;
  67. u.parts[0] = addr[0];
  68. u.parts[1] = addr[1];
  69. return u.val;
  70. }
  71. /* For STORE opcodes */
  72. #define STORE_I64(addr, value) do { \
  73. uintptr_t addr1 = (uintptr_t)(addr); \
  74. union { int64 val; uint32 u32[2]; \
  75. uint16 u16[4]; uint8 u8[8]; } u; \
  76. if ((addr1 & (uintptr_t)7) == 0) \
  77. *(int64*)(addr) = (int64)(value); \
  78. else { \
  79. u.val = (int64)(value); \
  80. if ((addr1 & (uintptr_t)3) == 0) { \
  81. ((uint32*)(addr))[0] = u.u32[0]; \
  82. ((uint32*)(addr))[1] = u.u32[1]; \
  83. } \
  84. else if ((addr1 & (uintptr_t)1) == 0) { \
  85. ((uint16*)(addr))[0] = u.u16[0]; \
  86. ((uint16*)(addr))[1] = u.u16[1]; \
  87. ((uint16*)(addr))[2] = u.u16[2]; \
  88. ((uint16*)(addr))[3] = u.u16[3]; \
  89. } \
  90. else { \
  91. int32 t; \
  92. for (t = 0; t < 8; t++) \
  93. ((uint8*)(addr))[t] = u.u8[t]; \
  94. } \
  95. } \
  96. } while (0)
  97. #define STORE_U32(addr, value) do { \
  98. uintptr_t addr1 = (uintptr_t)(addr); \
  99. union { uint32 val; \
  100. uint16 u16[2]; uint8 u8[4]; } u; \
  101. if ((addr1 & (uintptr_t)3) == 0) \
  102. *(uint32*)(addr) = (uint32)(value); \
  103. else { \
  104. u.val = (uint32)(value); \
  105. if ((addr1 & (uintptr_t)1) == 0) { \
  106. ((uint16*)(addr))[0] = u.u16[0]; \
  107. ((uint16*)(addr))[1] = u.u16[1]; \
  108. } \
  109. else { \
  110. ((uint8*)(addr))[0] = u.u8[0]; \
  111. ((uint8*)(addr))[1] = u.u8[1]; \
  112. ((uint8*)(addr))[2] = u.u8[2]; \
  113. ((uint8*)(addr))[3] = u.u8[3]; \
  114. } \
  115. } \
  116. } while (0)
  117. #define STORE_U16(addr, value) do { \
  118. union { uint16 val; uint8 u8[2]; } u; \
  119. u.val = (uint16)(value); \
  120. ((uint8*)(addr))[0] = u.u8[0]; \
  121. ((uint8*)(addr))[1] = u.u8[1]; \
  122. } while (0)
  123. /* For LOAD opcodes */
  124. static inline int64
  125. LOAD_I64(void *addr)
  126. {
  127. uintptr_t addr1 = (uintptr_t)addr;
  128. union { int64 val; uint32 u32[2];
  129. uint16 u16[4]; uint8 u8[8]; } u;
  130. if ((addr1 & (uintptr_t)7) == 0)
  131. return *(int64*)addr;
  132. if ((addr1 & (uintptr_t)3) == 0) {
  133. u.u32[0] = ((uint32*)addr)[0];
  134. u.u32[1] = ((uint32*)addr)[1];
  135. }
  136. else if ((addr1 & (uintptr_t)1) == 0) {
  137. u.u16[0] = ((uint16*)addr)[0];
  138. u.u16[1] = ((uint16*)addr)[1];
  139. u.u16[2] = ((uint16*)addr)[2];
  140. u.u16[3] = ((uint16*)addr)[3];
  141. }
  142. else {
  143. int32 t;
  144. for (t = 0; t < 8; t++)
  145. u.u8[t] = ((uint8*)addr)[t];
  146. }
  147. return u.val;
  148. }
  149. static inline float64
  150. LOAD_F64(void *addr)
  151. {
  152. uintptr_t addr1 = (uintptr_t)addr;
  153. union { float64 val; uint32 u32[2];
  154. uint16 u16[4]; uint8 u8[8]; } u;
  155. if ((addr1 & (uintptr_t)7) == 0)
  156. return *(float64*)addr;
  157. if ((addr1 & (uintptr_t)3) == 0) {
  158. u.u32[0] = ((uint32*)addr)[0];
  159. u.u32[1] = ((uint32*)addr)[1];
  160. }
  161. else if ((addr1 & (uintptr_t)1) == 0) {
  162. u.u16[0] = ((uint16*)addr)[0];
  163. u.u16[1] = ((uint16*)addr)[1];
  164. u.u16[2] = ((uint16*)addr)[2];
  165. u.u16[3] = ((uint16*)addr)[3];
  166. }
  167. else {
  168. int32 t;
  169. for (t = 0; t < 8; t++)
  170. u.u8[t] = ((uint8*)addr)[t];
  171. }
  172. return u.val;
  173. }
  174. static inline int32
  175. LOAD_I32(void *addr)
  176. {
  177. uintptr_t addr1 = (uintptr_t)addr;
  178. union { int32 val; uint16 u16[2]; uint8 u8[4]; } u;
  179. if ((addr1 & (uintptr_t)3) == 0)
  180. return *(int32*)addr;
  181. if ((addr1 & (uintptr_t)1) == 0) {
  182. u.u16[0] = ((uint16*)addr)[0];
  183. u.u16[1] = ((uint16*)addr)[1];
  184. }
  185. else {
  186. u.u8[0] = ((uint8*)addr)[0];
  187. u.u8[1] = ((uint8*)addr)[1];
  188. u.u8[2] = ((uint8*)addr)[2];
  189. u.u8[3] = ((uint8*)addr)[3];
  190. }
  191. return u.val;
  192. }
  193. static inline int16
  194. LOAD_I16(void *addr)
  195. {
  196. union { int16 val; uint8 u8[2]; } u;
  197. u.u8[0] = ((uint8*)addr)[0];
  198. u.u8[1] = ((uint8*)addr)[1];
  199. return u.val;
  200. }
  201. #define LOAD_U32(addr) ((uint32)LOAD_I32(addr))
  202. #define LOAD_U16(addr) ((uint16)LOAD_I16(addr))
  203. #define LOAD_F32(addr) ((float32)LOAD_I32(addr))
  204. #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
  205. #define CHECK_MEMORY_OVERFLOW(bytes) do { \
  206. int64 offset1 = (int64)(uint32)offset + (int64)(int32)addr; \
  207. if (heap_base_offset <= offset1 \
  208. && offset1 <= (int64)linear_mem_size - bytes) \
  209. /* If offset1 is in valid range, maddr must also be in valid range,\
  210. no need to check it again. */ \
  211. maddr = memory->memory_data + offset1; \
  212. else \
  213. goto out_of_bounds; \
  214. } while (0)
  215. #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) do { \
  216. uint64 offset1 = (int32)(start); \
  217. if (offset1 + bytes <= linear_mem_size) \
  218. /* App heap space is not valid space for bulk memory operation */ \
  219. maddr = memory->memory_data + offset1; \
  220. else \
  221. goto out_of_bounds; \
  222. } while (0)
  223. static inline uint32
  224. rotl32(uint32 n, uint32 c)
  225. {
  226. const uint32 mask = (31);
  227. c = c % 32;
  228. c &= mask;
  229. return (n<<c) | (n>>( (-c)&mask ));
  230. }
  231. static inline uint32
  232. rotr32(uint32 n, uint32 c)
  233. {
  234. const uint32 mask = (31);
  235. c = c % 32;
  236. c &= mask;
  237. return (n>>c) | (n<<( (-c)&mask ));
  238. }
  239. static inline uint64
  240. rotl64(uint64 n, uint64 c)
  241. {
  242. const uint64 mask = (63);
  243. c = c % 64;
  244. c &= mask;
  245. return (n<<c) | (n>>( (-c)&mask ));
  246. }
  247. static inline uint64
  248. rotr64(uint64 n, uint64 c)
  249. {
  250. const uint64 mask = (63);
  251. c = c % 64;
  252. c &= mask;
  253. return (n>>c) | (n<<( (-c)&mask ));
  254. }
  255. static inline double
  256. wa_fmax(double a, double b)
  257. {
  258. double c = fmax(a, b);
  259. if (c==0 && a==b)
  260. return signbit(a) ? b : a;
  261. return c;
  262. }
  263. static inline double
  264. wa_fmin(double a, double b)
  265. {
  266. double c = fmin(a, b);
  267. if (c==0 && a==b)
  268. return signbit(a) ? a : b;
  269. return c;
  270. }
  271. static inline uint32
  272. clz32(uint32 type)
  273. {
  274. uint32 num = 0;
  275. if (type == 0)
  276. return 32;
  277. while (!(type & 0x80000000)) {
  278. num++;
  279. type <<= 1;
  280. }
  281. return num;
  282. }
  283. static inline uint32
  284. clz64(uint64 type)
  285. {
  286. uint32 num = 0;
  287. if (type == 0)
  288. return 64;
  289. while (!(type & 0x8000000000000000LL)) {
  290. num++;
  291. type <<= 1;
  292. }
  293. return num;
  294. }
  295. static inline uint32
  296. ctz32(uint32 type)
  297. {
  298. uint32 num = 0;
  299. if (type == 0)
  300. return 32;
  301. while (!(type & 1)) {
  302. num++;
  303. type >>= 1;
  304. }
  305. return num;
  306. }
  307. static inline uint32
  308. ctz64(uint64 type)
  309. {
  310. uint32 num = 0;
  311. if (type == 0)
  312. return 64;
  313. while (!(type & 1)) {
  314. num++;
  315. type >>= 1;
  316. }
  317. return num;
  318. }
  319. static inline uint32
  320. popcount32(uint32 u)
  321. {
  322. uint32 ret = 0;
  323. while (u) {
  324. u = (u & (u - 1));
  325. ret++;
  326. }
  327. return ret;
  328. }
  329. static inline uint32
  330. popcount64(uint64 u)
  331. {
  332. uint32 ret = 0;
  333. while (u) {
  334. u = (u & (u - 1));
  335. ret++;
  336. }
  337. return ret;
  338. }
  339. static uint64
  340. read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
  341. {
  342. uint64 result = 0;
  343. uint32 shift = 0;
  344. uint32 bcnt = 0;
  345. uint64 byte;
  346. while (true) {
  347. byte = buf[*p_offset];
  348. *p_offset += 1;
  349. result |= ((byte & 0x7f) << shift);
  350. shift += 7;
  351. if ((byte & 0x80) == 0) {
  352. break;
  353. }
  354. bcnt += 1;
  355. }
  356. if (sign && (shift < maxbits) && (byte & 0x40)) {
  357. /* Sign extend */
  358. result |= - ((uint64)1 << shift);
  359. }
  360. return result;
  361. }
  362. #define read_leb_uint32(p, p_end, res) do { \
  363. uint8 _val = *p; \
  364. if (!(_val & 0x80)) { \
  365. res = _val; \
  366. p++; \
  367. break; \
  368. } \
  369. uint32 _off = 0; \
  370. res = (uint32)read_leb(p, &_off, 32, false); \
  371. p += _off; \
  372. } while (0)
  373. #define read_uint32(p) (p += sizeof(uint32), *(uint32 *)(p - sizeof(uint32)))
  374. #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() do { \
  375. uint32 param_count = cur_func->param_count; \
  376. read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
  377. bh_assert(local_idx < param_count + cur_func->local_count); \
  378. local_offset = cur_func->local_offsets[local_idx]; \
  379. if (local_idx < param_count) \
  380. local_type = cur_func->param_types[local_idx]; \
  381. else \
  382. local_type = cur_func->local_types[local_idx - param_count]; \
  383. } while (0)
  384. #define GET_OFFSET() (frame_ip += 2, *(int16 *)(frame_ip - 2))
  385. #define SET_OPERAND(type, off, value) \
  386. (*(type*)(frame_lp + *(int16*)(frame_ip + off))) = value
  387. #define GET_OPERAND(type, off) (*(type*)(frame_lp + *(int16*)(frame_ip + off)))
  388. #define PUSH_I32(value) do { \
  389. *(int32*)(frame_lp + GET_OFFSET()) = value; \
  390. } while (0)
  391. #define PUSH_F32(value) do { \
  392. *(float32*)(frame_lp + GET_OFFSET()) = value; \
  393. } while (0)
  394. #define PUSH_I64(value) do { \
  395. *(int64*)(frame_lp + GET_OFFSET()) = value; \
  396. } while (0)
  397. #define PUSH_F64(value) do { \
  398. *(float64*)(frame_lp + GET_OFFSET()) = value; \
  399. } while (0)
  400. #define POP_I32() (*(int32*)(frame_lp + GET_OFFSET()))
  401. #define POP_F32() (*(float32*)(frame_lp + GET_OFFSET()))
  402. #define POP_I64() (*(int64*)(frame_lp + GET_OFFSET()))
  403. #define POP_F64() (*(float64*)(frame_lp + GET_OFFSET()))
  404. #define SYNC_ALL_TO_FRAME() do { \
  405. frame->ip = frame_ip; \
  406. } while (0)
  407. #define UPDATE_ALL_FROM_FRAME() do { \
  408. frame_ip = frame->ip; \
  409. } while (0)
  410. #define RECOVER_CONTEXT(new_frame) do { \
  411. frame = (new_frame); \
  412. cur_func = frame->function; \
  413. prev_frame = frame->prev_frame; \
  414. frame_ip = frame->ip; \
  415. frame_lp = frame->lp; \
  416. } while (0)
  417. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  418. #define GET_OPCODE() opcode = *(frame_ip++);
  419. #else
  420. #define GET_OPCODE() (void)0
  421. #endif
  422. #define DEF_OP_EQZ(ctype, src_op_type) do { \
  423. SET_OPERAND(int32, 2, (GET_OPERAND(ctype, 0) == 0)); \
  424. frame_ip += 4; \
  425. } while (0)
  426. #define DEF_OP_CMP(src_type, src_op_type, cond) do { \
  427. SET_OPERAND(uint32, 4, GET_OPERAND(src_type, 2) cond \
  428. GET_OPERAND(src_type, 0)); \
  429. frame_ip += 6; \
  430. } while (0)
  431. #define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
  432. SET_OPERAND(src_type, 2, \
  433. (src_type)operation(GET_OPERAND(src_type, 0))); \
  434. frame_ip += 4; \
  435. } while (0)
  436. #define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) do { \
  437. SET_OPERAND(src_type1, 4, (GET_OPERAND(src_type1, 2) \
  438. operation GET_OPERAND(src_type1, 0))); \
  439. frame_ip += 6; \
  440. } while (0)
  441. #if defined(BUILD_TARGET_X86_32)
  442. #define DEF_OP_REINTERPRET(src_type) do { \
  443. void *src = frame_lp + GET_OFFSET(); \
  444. void *dst = frame_lp + GET_OFFSET(); \
  445. bh_memcpy_s(dst, sizeof(src_type), src, sizeof(src_type)); \
  446. } while (0)
  447. #else
  448. #define DEF_OP_REINTERPRET(src_type) do { \
  449. SET_OPERAND(src_type, 2, GET_OPERAND(src_type, 0)); \
  450. frame_ip += 4; \
  451. } while (0)
  452. #endif
  453. #if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
  454. #define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC
  455. #else
  456. #define DEF_OP_NUMERIC_64(src_type1, src_type2, src_op_type, operation) do { \
  457. src_type1 val1; \
  458. src_type2 val2; \
  459. val1 = \
  460. (src_type1)GET_##src_op_type##_FROM_ADDR(frame_lp + (*(int16*)(frame_ip + 2))); \
  461. val2 = \
  462. (src_type2)GET_##src_op_type##_FROM_ADDR(frame_lp + (*(int16*)(frame_ip))); \
  463. val1 operation##= val2; \
  464. PUT_##src_op_type##_TO_ADDR(frame_lp + (*(int16*)(frame_ip + 4)), val1); \
  465. frame_ip += 6; \
  466. } while (0)
  467. #endif
  468. #define DEF_OP_NUMERIC2(src_type1, src_type2, src_op_type, operation) do { \
  469. SET_OPERAND(src_type1, 4, (GET_OPERAND(src_type1, 2) \
  470. operation (GET_OPERAND(src_type1, 0) % 32))); \
  471. frame_ip += 6; \
  472. } while (0)
  473. #define DEF_OP_NUMERIC2_64(src_type1, src_type2, src_op_type, operation) do { \
  474. SET_OPERAND(src_type1, 4, (GET_OPERAND(src_type1, 2) \
  475. operation (GET_OPERAND(src_type1, 0) % 64))); \
  476. frame_ip += 6; \
  477. } while (0)
  478. #define DEF_OP_MATH(src_type, src_op_type, method) do { \
  479. SET_OPERAND(src_type, 2, method(GET_OPERAND(src_type, 0))); \
  480. frame_ip += 4; \
  481. } while (0)
  482. #define TRUNC_FUNCTION(func_name, src_type, dst_type, signed_type) \
  483. static dst_type \
  484. func_name(src_type src_value, src_type src_min, src_type src_max, \
  485. dst_type dst_min, dst_type dst_max, bool is_sign) \
  486. { \
  487. dst_type dst_value = 0; \
  488. if (!isnan(src_value)) { \
  489. if (src_value <= src_min) \
  490. dst_value = dst_min; \
  491. else if (src_value >= src_max) \
  492. dst_value = dst_max; \
  493. else { \
  494. if (is_sign) \
  495. dst_value = (dst_type)(signed_type)src_value; \
  496. else \
  497. dst_value = (dst_type)src_value; \
  498. } \
  499. } \
  500. return dst_value; \
  501. }
  502. TRUNC_FUNCTION(trunc_f32_to_i32, float32, uint32, int32)
  503. TRUNC_FUNCTION(trunc_f32_to_i64, float32, uint64, int64)
  504. TRUNC_FUNCTION(trunc_f64_to_i32, float64, uint32, int32)
  505. TRUNC_FUNCTION(trunc_f64_to_i64, float64, uint64, int64)
  506. static bool
  507. trunc_f32_to_int(WASMModuleInstance *module,
  508. uint8 *frame_ip, uint32 *frame_lp,
  509. float32 src_min, float32 src_max,
  510. bool saturating, bool is_i32, bool is_sign)
  511. {
  512. float32 src_value = GET_OPERAND(float32, 0);
  513. uint64 dst_value_i64;
  514. uint32 dst_value_i32;
  515. if (!saturating) {
  516. if (isnan(src_value)) {
  517. wasm_set_exception(module, "invalid conversion to integer");
  518. return true;
  519. }
  520. else if (src_value <= src_min || src_value >= src_max) {
  521. wasm_set_exception(module, "integer overflow");
  522. return true;
  523. }
  524. }
  525. if (is_i32) {
  526. uint32 dst_min = is_sign ? INT32_MIN : 0;
  527. uint32 dst_max = is_sign ? INT32_MAX : UINT32_MAX;
  528. dst_value_i32 = trunc_f32_to_i32(src_value, src_min, src_max,
  529. dst_min, dst_max, is_sign);
  530. SET_OPERAND(uint32, 2, dst_value_i32);
  531. }
  532. else {
  533. uint64 dst_min = is_sign ? INT64_MIN : 0;
  534. uint64 dst_max = is_sign ? INT64_MAX : UINT64_MAX;
  535. dst_value_i64 = trunc_f32_to_i64(src_value, src_min, src_max,
  536. dst_min, dst_max, is_sign);
  537. SET_OPERAND(uint64, 2, dst_value_i64);
  538. }
  539. return false;
  540. }
  541. static bool
  542. trunc_f64_to_int(WASMModuleInstance *module,
  543. uint8 *frame_ip, uint32 *frame_lp,
  544. float64 src_min, float64 src_max,
  545. bool saturating, bool is_i32, bool is_sign)
  546. {
  547. float64 src_value = GET_OPERAND(float64, 0);
  548. uint64 dst_value_i64;
  549. uint32 dst_value_i32;
  550. if (!saturating) {
  551. if (isnan(src_value)) {
  552. wasm_set_exception(module, "invalid conversion to integer");
  553. return true;
  554. }
  555. else if (src_value <= src_min || src_value >= src_max) {
  556. wasm_set_exception(module, "integer overflow");
  557. return true;
  558. }
  559. }
  560. if (is_i32) {
  561. uint32 dst_min = is_sign ? INT32_MIN : 0;
  562. uint32 dst_max = is_sign ? INT32_MAX : UINT32_MAX;
  563. dst_value_i32 = trunc_f64_to_i32(src_value, src_min, src_max,
  564. dst_min, dst_max, is_sign);
  565. SET_OPERAND(uint32, 2, dst_value_i32);
  566. }
  567. else {
  568. uint64 dst_min = is_sign ? INT64_MIN : 0;
  569. uint64 dst_max = is_sign ? INT64_MAX : UINT64_MAX;
  570. dst_value_i64 = trunc_f64_to_i64(src_value, src_min, src_max,
  571. dst_min, dst_max, is_sign);
  572. SET_OPERAND(uint64, 2, dst_value_i64);
  573. }
  574. return false;
  575. }
  576. #define DEF_OP_TRUNC_F32(min, max, is_i32, is_sign) do { \
  577. if (trunc_f32_to_int(module, frame_ip, frame_lp, min, max, \
  578. false, is_i32, is_sign)) \
  579. goto got_exception; \
  580. frame_ip += 4; \
  581. } while (0)
  582. #define DEF_OP_TRUNC_F64(min, max, is_i32, is_sign) do { \
  583. if (trunc_f64_to_int(module, frame_ip, frame_lp, min, max, \
  584. false, is_i32, is_sign)) \
  585. goto got_exception; \
  586. frame_ip += 4; \
  587. } while (0)
  588. #define DEF_OP_TRUNC_SAT_F32(min, max, is_i32, is_sign) do { \
  589. (void)trunc_f32_to_int(module, frame_ip, frame_lp, min, max, \
  590. true, is_i32, is_sign); \
  591. frame_ip += 4; \
  592. } while (0)
  593. #define DEF_OP_TRUNC_SAT_F64(min, max, is_i32, is_sign) do { \
  594. (void)trunc_f64_to_int(module, frame_ip, frame_lp, min, max, \
  595. true, is_i32, is_sign); \
  596. frame_ip += 4; \
  597. } while (0)
  598. #define DEF_OP_CONVERT(dst_type, dst_op_type, \
  599. src_type, src_op_type) do { \
  600. dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
  601. PUSH_##dst_op_type(value); \
  602. } while (0)
  603. static bool
  604. copy_stack_values(WASMModuleInstance *module,
  605. uint32 *frame_lp,
  606. uint32 arity,
  607. uint32 total_cell_num,
  608. const uint8 *cells,
  609. const int16 *src_offsets,
  610. const uint16 *dst_offsets)
  611. {
  612. /* To avoid the overlap issue between src offsets and dst offset,
  613. * we use 2 steps to do the copy. First step, copy the src values
  614. * to a tmp buf. Second step, copy the values from tmp buf to dst.
  615. */
  616. uint32 buf[16] = {0}, i;
  617. uint32 *tmp_buf = buf;
  618. uint8 cell;
  619. int16 src, buf_index = 0;
  620. uint16 dst;
  621. /* Allocate memory if the buf is not large enough */
  622. if (total_cell_num > sizeof(buf)/sizeof(uint32)) {
  623. uint64 total_size = sizeof(uint32) * (uint64)total_cell_num;
  624. if (total_size >= UINT32_MAX
  625. || !(tmp_buf = wasm_runtime_malloc((uint32)total_size))) {
  626. wasm_set_exception(module,
  627. "WASM interp failed: allocate memory failed.");
  628. return false;
  629. }
  630. }
  631. /* 1) Copy values from src to tmp buf */
  632. for (i = 0; i < arity; i++) {
  633. cell = cells[i];
  634. src = src_offsets[i];
  635. if (cell == 1)
  636. tmp_buf[buf_index] = frame_lp[src];
  637. else
  638. *(uint64*)(tmp_buf + buf_index) = *(uint64*)(frame_lp + src);
  639. buf_index += cell;
  640. }
  641. /* 2) Copy values from tmp buf to dest */
  642. buf_index = 0;
  643. for (i = 0; i < arity; i++) {
  644. cell = cells[i];
  645. dst = dst_offsets[i];
  646. if (cell == 1)
  647. frame_lp[dst] = tmp_buf[buf_index];
  648. else
  649. *(uint64*)(frame_lp + dst) = *(uint64*)(tmp_buf + buf_index);
  650. buf_index += cell;
  651. }
  652. if (tmp_buf != buf) {
  653. wasm_runtime_free(tmp_buf);
  654. }
  655. return true;
  656. }
  657. #define RECOVER_BR_INFO() do { \
  658. uint32 arity; \
  659. /* read arity */ \
  660. arity = *(uint32*)frame_ip; \
  661. frame_ip += sizeof(arity); \
  662. if (arity) { \
  663. uint32 total_cell; \
  664. uint16 *dst_offsets = NULL; \
  665. uint8 *cells; \
  666. int16 *src_offsets = NULL; \
  667. /* read total cell num */ \
  668. total_cell = *(uint32*)frame_ip; \
  669. frame_ip += sizeof(total_cell); \
  670. /* cells */ \
  671. cells = (uint8 *)frame_ip; \
  672. frame_ip += arity * sizeof(uint8); \
  673. /* src offsets */ \
  674. src_offsets = (int16 *)frame_ip; \
  675. frame_ip += arity * sizeof(int16); \
  676. /* dst offsets */ \
  677. dst_offsets = (uint16*)frame_ip; \
  678. frame_ip += arity * sizeof(uint16); \
  679. if (arity == 1) { \
  680. if (cells[0] == 1) \
  681. frame_lp[dst_offsets[0]] = \
  682. frame_lp[src_offsets[0]]; \
  683. else if (cells[0] == 2) { \
  684. *(int64*)(frame_lp + dst_offsets[0]) = \
  685. *(int64*)(frame_lp + src_offsets[0]); \
  686. } \
  687. } \
  688. else { \
  689. if (!copy_stack_values(module, frame_lp, \
  690. arity, total_cell, \
  691. cells, src_offsets, \
  692. dst_offsets)) \
  693. goto got_exception; \
  694. } \
  695. } \
  696. frame_ip = *(uint8**)frame_ip; \
  697. } while (0)
  698. #define SKIP_BR_INFO() do { \
  699. uint32 arity; \
  700. /* read and skip arity */ \
  701. arity = *(uint32*)frame_ip; \
  702. frame_ip += sizeof(arity); \
  703. if (arity) { \
  704. /* skip total cell num */ \
  705. frame_ip += sizeof(uint32); \
  706. /* skip cells, src offsets and dst offsets */ \
  707. frame_ip += (sizeof(uint8) + sizeof(int16) + sizeof(uint16)) * arity; \
  708. } \
  709. /* skip target address */ \
  710. frame_ip += sizeof(uint8*); \
  711. } while (0)
  712. static inline int32
  713. sign_ext_8_32(int8 val)
  714. {
  715. if (val & 0x80)
  716. return (int32)val | (int32)0xffffff00;
  717. return val;
  718. }
  719. static inline int32
  720. sign_ext_16_32(int16 val)
  721. {
  722. if (val & 0x8000)
  723. return (int32)val | (int32)0xffff0000;
  724. return val;
  725. }
  726. static inline int64
  727. sign_ext_8_64(int8 val)
  728. {
  729. if (val & 0x80)
  730. return (int64)val | (int64)0xffffffffffffff00;
  731. return val;
  732. }
  733. static inline int64
  734. sign_ext_16_64(int16 val)
  735. {
  736. if (val & 0x8000)
  737. return (int64)val | (int64)0xffffffffffff0000;
  738. return val;
  739. }
  740. static inline int64
  741. sign_ext_32_64(int32 val)
  742. {
  743. if (val & (int32)0x80000000)
  744. return (int64)val | (int64)0xffffffff00000000;
  745. return val;
  746. }
  747. static inline void
  748. word_copy(uint32 *dest, uint32 *src, unsigned num)
  749. {
  750. for (; num > 0; num--)
  751. *dest++ = *src++;
  752. }
  753. static inline WASMInterpFrame*
  754. ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
  755. {
  756. WASMInterpFrame *frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
  757. if (frame)
  758. frame->prev_frame = prev_frame;
  759. else {
  760. wasm_set_exception((WASMModuleInstance*)exec_env->module_inst,
  761. "WASM interp failed: stack overflow.");
  762. }
  763. return frame;
  764. }
  765. static inline void
  766. FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *frame)
  767. {
  768. wasm_exec_env_free_wasm_frame(exec_env, frame);
  769. }
  770. static void
  771. wasm_interp_call_func_native(WASMModuleInstance *module_inst,
  772. WASMExecEnv *exec_env,
  773. WASMFunctionInstance *cur_func,
  774. WASMInterpFrame *prev_frame)
  775. {
  776. WASMFunctionImport *func_import = cur_func->u.func_import;
  777. unsigned local_cell_num = 2;
  778. WASMInterpFrame *frame;
  779. uint32 argv_ret[2];
  780. bool ret;
  781. if (!(frame = ALLOC_FRAME(exec_env,
  782. wasm_interp_interp_frame_size(local_cell_num),
  783. prev_frame)))
  784. return;
  785. frame->function = cur_func;
  786. frame->ip = NULL;
  787. frame->lp = frame->operand;
  788. wasm_exec_env_set_cur_frame(exec_env, frame);
  789. if (!func_import->func_ptr_linked) {
  790. char buf[128];
  791. snprintf(buf,
  792. sizeof(buf), "fail to call unlinked import function (%s, %s)",
  793. func_import->module_name, func_import->field_name);
  794. wasm_set_exception((WASMModuleInstance*)module_inst, buf);
  795. return;
  796. }
  797. if (!func_import->call_conv_raw) {
  798. ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
  799. func_import->func_type, func_import->signature,
  800. func_import->attachment,
  801. frame->lp, cur_func->param_cell_num, argv_ret);
  802. }
  803. else {
  804. ret = wasm_runtime_invoke_native_raw(exec_env, func_import->func_ptr_linked,
  805. func_import->func_type, func_import->signature,
  806. func_import->attachment,
  807. frame->lp, cur_func->param_cell_num, argv_ret);
  808. }
  809. if (!ret)
  810. return;
  811. if (cur_func->ret_cell_num == 1) {
  812. prev_frame->lp[prev_frame->ret_offset] = argv_ret[0];
  813. }
  814. else if (cur_func->ret_cell_num == 2) {
  815. prev_frame->lp[prev_frame->ret_offset] = argv_ret[0];
  816. prev_frame->lp[prev_frame->ret_offset + 1] = argv_ret[1];
  817. }
  818. FREE_FRAME(exec_env, frame);
  819. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  820. }
  821. #if WASM_ENABLE_MULTI_MODULE != 0
  822. static void
  823. wasm_interp_call_func_bytecode(WASMModuleInstance *module,
  824. WASMExecEnv *exec_env,
  825. WASMFunctionInstance *cur_func,
  826. WASMInterpFrame *prev_frame);
  827. static void
  828. wasm_interp_call_func_import(WASMModuleInstance *module_inst,
  829. WASMExecEnv *exec_env,
  830. WASMFunctionInstance *cur_func,
  831. WASMInterpFrame *prev_frame)
  832. {
  833. WASMModuleInstance *sub_module_inst = cur_func->import_module_inst;
  834. WASMFunctionInstance *sub_func_inst = cur_func->import_func_inst;
  835. WASMFunctionImport *func_import = cur_func->u.func_import;
  836. uint8 *ip = prev_frame->ip;
  837. char buf[128];
  838. if (!sub_func_inst) {
  839. snprintf(buf, sizeof(buf),
  840. "fail to call unlinked import function (%s, %s)",
  841. func_import->module_name, func_import->field_name);
  842. wasm_set_exception(module_inst, buf);
  843. return;
  844. }
  845. /* set ip NULL to make call_func_bytecode return after executing
  846. this function */
  847. prev_frame->ip = NULL;
  848. /* replace exec_env's module_inst with sub_module_inst so we can
  849. call it */
  850. exec_env->module_inst = (WASMModuleInstanceCommon *)sub_module_inst;
  851. /* call function of sub-module*/
  852. wasm_interp_call_func_bytecode(sub_module_inst, exec_env,
  853. sub_func_inst, prev_frame);
  854. /* restore ip and module_inst */
  855. prev_frame->ip = ip;
  856. exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
  857. /* transfer exception if it is thrown */
  858. if (wasm_get_exception(sub_module_inst)) {
  859. bh_memcpy_s(module_inst->cur_exception,
  860. sizeof(module_inst->cur_exception),
  861. sub_module_inst->cur_exception,
  862. sizeof(sub_module_inst->cur_exception));
  863. }
  864. }
  865. #endif
  866. #if WASM_ENABLE_THREAD_MGR != 0
  867. #define CHECK_SUSPEND_FLAGS() do { \
  868. if (exec_env->suspend_flags.flags != 0) { \
  869. if (exec_env->suspend_flags.flags & 0x01) { \
  870. /* terminate current thread */ \
  871. return; \
  872. } \
  873. /* TODO: support suspend and breakpoint */ \
  874. } \
  875. } while (0)
  876. #endif
  877. #if WASM_ENABLE_OPCODE_COUNTER != 0
  878. typedef struct OpcodeInfo {
  879. char *name;
  880. uint64 count;
  881. } OpcodeInfo;
  882. #define HANDLE_OPCODE(op) { #op, 0 }
  883. DEFINE_GOTO_TABLE (OpcodeInfo, opcode_table);
  884. #undef HANDLE_OPCODE
  885. static void
  886. wasm_interp_dump_op_count()
  887. {
  888. uint32 i;
  889. uint64 total_count = 0;
  890. for (i = 0; i < WASM_OP_IMPDEP; i++)
  891. total_count += opcode_table[i].count;
  892. printf("total opcode count: %ld\n", total_count);
  893. for (i = 0; i < WASM_OP_IMPDEP; i++)
  894. if (opcode_table[i].count > 0)
  895. printf("\t\t%s count:\t\t%ld,\t\t%.2f%%\n",
  896. opcode_table[i].name, opcode_table[i].count,
  897. opcode_table[i].count * 100.0f / total_count);
  898. }
  899. #endif
  900. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  901. //#define HANDLE_OP(opcode) HANDLE_##opcode:printf(#opcode"\n");h_##opcode
  902. #if WASM_ENABLE_OPCODE_COUNTER != 0
  903. #define HANDLE_OP(opcode) HANDLE_##opcode:opcode_table[opcode].count++;h_##opcode
  904. #else
  905. #define HANDLE_OP(opcode) HANDLE_##opcode
  906. #endif
  907. #if WASM_ENABLE_FAST_INTERP == 0
  908. #define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]
  909. #else
  910. #if WASM_ENABLE_ABS_LABEL_ADDR != 0
  911. #define FETCH_OPCODE_AND_DISPATCH() do { \
  912. const void *p_label_addr = *(void**)frame_ip; \
  913. frame_ip += sizeof(void*); \
  914. goto *p_label_addr; \
  915. } while (0)
  916. #else
  917. #define FETCH_OPCODE_AND_DISPATCH() do { \
  918. const void *p_label_addr = label_base \
  919. + *(int16*)frame_ip; \
  920. frame_ip += sizeof(int16); \
  921. goto *p_label_addr; \
  922. } while (0)
  923. #endif
  924. #endif
  925. #define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
  926. #else /* else of WASM_ENABLE_LABELS_AS_VALUES */
  927. #define HANDLE_OP(opcode) case opcode
  928. #define HANDLE_OP_END() continue
  929. #endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
  930. #if WASM_ENABLE_FAST_INTERP != 0
  931. static void **global_handle_table;
  932. #endif
  933. static void
  934. wasm_interp_call_func_bytecode(WASMModuleInstance *module,
  935. WASMExecEnv *exec_env,
  936. WASMFunctionInstance *cur_func,
  937. WASMInterpFrame *prev_frame)
  938. {
  939. WASMMemoryInstance *memory = module->default_memory;
  940. int32 heap_base_offset = memory ? memory->heap_base_offset : 0;
  941. uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
  942. uint8 *global_data = module->global_data;
  943. uint32 linear_mem_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
  944. WASMTableInstance *table = module->default_table;
  945. WASMGlobalInstance *globals = module->globals, *global;
  946. uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
  947. WASMInterpFrame *frame = NULL;
  948. /* Points to this special opcode so as to jump to the call_method_from_entry. */
  949. register uint8 *frame_ip = &opcode_IMPDEP; /* cache of frame->ip */
  950. register uint32 *frame_lp = NULL; /* cache of frame->lp */
  951. #if WASM_ENABLE_ABS_LABEL_ADDR == 0
  952. register uint8 *label_base = &&HANDLE_WASM_OP_UNREACHABLE; /* cache of label base addr */
  953. #endif
  954. uint8 *frame_ip_end;
  955. uint32 cond, count, fidx, tidx, frame_size = 0;
  956. uint64 all_cell_num = 0;
  957. int16 addr1, addr2, addr_ret = 0;
  958. int32 didx, val;
  959. uint8 *maddr = NULL;
  960. uint32 local_idx, local_offset, global_idx;
  961. uint8 opcode, local_type, *global_addr;
  962. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  963. #define HANDLE_OPCODE(op) &&HANDLE_##op
  964. DEFINE_GOTO_TABLE (const void*, handle_table);
  965. #undef HANDLE_OPCODE
  966. #if WASM_ENABLE_FAST_INTERP != 0
  967. if (exec_env == NULL) {
  968. global_handle_table = (void **)handle_table;
  969. return;
  970. }
  971. #endif
  972. #endif
  973. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  974. while (frame_ip < frame_ip_end) {
  975. opcode = *frame_ip++;
  976. switch (opcode) {
  977. #else
  978. goto *handle_table[WASM_OP_IMPDEP];
  979. #endif
  980. /* control instructions */
  981. HANDLE_OP (WASM_OP_UNREACHABLE):
  982. wasm_set_exception(module, "unreachable");
  983. goto got_exception;
  984. HANDLE_OP (WASM_OP_IF):
  985. cond = (uint32)POP_I32();
  986. if (cond == 0) {
  987. if (*(uint8**)frame_ip == NULL) {
  988. frame_ip = *(uint8**)(frame_ip + sizeof(uint8*));
  989. }
  990. else {
  991. frame_ip = *(uint8**)(frame_ip);
  992. }
  993. }
  994. else {
  995. frame_ip += sizeof(uint8*) * 2;
  996. }
  997. HANDLE_OP_END ();
  998. HANDLE_OP (WASM_OP_ELSE):
  999. frame_ip = *(uint8**)(frame_ip);
  1000. HANDLE_OP_END ();
  1001. HANDLE_OP (WASM_OP_BR):
  1002. #if WASM_ENABLE_THREAD_MGR != 0
  1003. CHECK_SUSPEND_FLAGS();
  1004. #endif
  1005. recover_br_info:
  1006. RECOVER_BR_INFO();
  1007. HANDLE_OP_END ();
  1008. HANDLE_OP (WASM_OP_BR_IF):
  1009. #if WASM_ENABLE_THREAD_MGR != 0
  1010. CHECK_SUSPEND_FLAGS();
  1011. #endif
  1012. cond = frame_lp[GET_OFFSET()];
  1013. if (cond)
  1014. goto recover_br_info;
  1015. else
  1016. SKIP_BR_INFO();
  1017. HANDLE_OP_END ();
  1018. HANDLE_OP (WASM_OP_BR_TABLE):
  1019. #if WASM_ENABLE_THREAD_MGR != 0
  1020. CHECK_SUSPEND_FLAGS();
  1021. #endif
  1022. count = read_uint32(frame_ip);
  1023. didx = GET_OPERAND(uint32, 0);
  1024. frame_ip += 2;
  1025. if (!(didx >= 0 && (uint32)didx < count))
  1026. didx = count;
  1027. while (didx--)
  1028. SKIP_BR_INFO();
  1029. goto recover_br_info;
  1030. HANDLE_OP (WASM_OP_RETURN):
  1031. {
  1032. uint32 ret_idx;
  1033. WASMType *func_type;
  1034. uint32 off, ret_offset;
  1035. uint8 *ret_types;
  1036. if (cur_func->is_import_func
  1037. #if WASM_ENABLE_MULTI_MODULE != 0
  1038. && !cur_func->import_func_inst
  1039. #endif
  1040. )
  1041. func_type = cur_func->u.func_import->func_type;
  1042. else
  1043. func_type = cur_func->u.func->func_type;
  1044. /* types of each return value */
  1045. ret_types = func_type->types + func_type->param_count;
  1046. ret_offset = prev_frame->ret_offset;
  1047. for (ret_idx = 0, off = sizeof(int16) * (func_type->result_count - 1);
  1048. ret_idx < func_type->result_count;
  1049. ret_idx++, off -= sizeof(int16)) {
  1050. if (ret_types[ret_idx] == VALUE_TYPE_I64
  1051. || ret_types[ret_idx] == VALUE_TYPE_F64) {
  1052. *((uint64 *)(prev_frame->lp + ret_offset)) =
  1053. GET_OPERAND(uint64, off);
  1054. ret_offset += 2;
  1055. }
  1056. else {
  1057. prev_frame->lp[ret_offset] = GET_OPERAND(int32, off);
  1058. ret_offset++;
  1059. }
  1060. }
  1061. }
  1062. goto return_func;
  1063. HANDLE_OP (WASM_OP_CALL_INDIRECT):
  1064. {
  1065. WASMType *cur_type, *cur_func_type;
  1066. WASMTableInstance *cur_table_inst;
  1067. #if WASM_ENABLE_THREAD_MGR != 0
  1068. CHECK_SUSPEND_FLAGS();
  1069. #endif
  1070. tidx = read_uint32(frame_ip);
  1071. val = GET_OPERAND(int32, 0);
  1072. frame_ip += 2;
  1073. if (tidx >= module->module->type_count) {
  1074. wasm_set_exception(module, "type index is overflow");
  1075. goto got_exception;
  1076. }
  1077. cur_type = module->module->types[tidx];
  1078. /* careful, it might be a table in another module */
  1079. cur_table_inst = table;
  1080. #if WASM_ENABLE_MULTI_MODULE != 0
  1081. if (table->table_inst_linked) {
  1082. cur_table_inst = table->table_inst_linked;
  1083. }
  1084. #endif
  1085. if (val < 0 || val >= (int32)cur_table_inst->cur_size) {
  1086. wasm_set_exception(module, "undefined element");
  1087. goto got_exception;
  1088. }
  1089. fidx = ((uint32*)cur_table_inst->base_addr)[val];
  1090. if (fidx == (uint32)-1) {
  1091. wasm_set_exception(module, "uninitialized element");
  1092. goto got_exception;
  1093. }
  1094. #if WASM_ENABLE_MULTI_MODULE != 0
  1095. if (fidx >= module->function_count) {
  1096. wasm_set_exception(module, "unknown function");
  1097. goto got_exception;
  1098. }
  1099. #endif
  1100. /* always call module own functions */
  1101. cur_func = module->functions + fidx;
  1102. if (cur_func->is_import_func
  1103. #if WASM_ENABLE_MULTI_MODULE != 0
  1104. && !cur_func->import_func_inst
  1105. #endif
  1106. )
  1107. cur_func_type = cur_func->u.func_import->func_type;
  1108. else
  1109. cur_func_type = cur_func->u.func->func_type;
  1110. if (!wasm_type_equal(cur_type, cur_func_type)) {
  1111. wasm_set_exception(module, "indirect call type mismatch");
  1112. goto got_exception;
  1113. }
  1114. goto call_func_from_interp;
  1115. }
  1116. /* parametric instructions */
  1117. HANDLE_OP (WASM_OP_SELECT):
  1118. {
  1119. cond = frame_lp[GET_OFFSET()];
  1120. addr1 = GET_OFFSET();
  1121. addr2 = GET_OFFSET();
  1122. addr_ret = GET_OFFSET();
  1123. if (!cond) {
  1124. #if defined(BUILD_TARGET_X86_32)
  1125. if (addr_ret != addr1)
  1126. bh_memcpy_s(frame_lp + addr_ret, sizeof(int32),
  1127. frame_lp + addr1, sizeof(int32));
  1128. #else
  1129. frame_lp[addr_ret] = frame_lp[addr1];
  1130. #endif
  1131. }
  1132. else {
  1133. #if defined(BUILD_TARGET_X86_32)
  1134. if (addr_ret != addr2)
  1135. bh_memcpy_s(frame_lp + addr_ret, sizeof(int32),
  1136. frame_lp + addr2, sizeof(int32));
  1137. #else
  1138. frame_lp[addr_ret] = frame_lp[addr2];
  1139. #endif
  1140. }
  1141. HANDLE_OP_END ();
  1142. }
  1143. HANDLE_OP (WASM_OP_SELECT_64):
  1144. {
  1145. cond = frame_lp[GET_OFFSET()];
  1146. addr1 = GET_OFFSET();
  1147. addr2 = GET_OFFSET();
  1148. addr_ret = GET_OFFSET();
  1149. if (!cond) {
  1150. #if defined(BUILD_TARGET_X86_32)
  1151. if (addr_ret != addr1)
  1152. bh_memcpy_s(frame_lp + addr_ret, sizeof(int64),
  1153. frame_lp + addr1, sizeof(int64));
  1154. #else
  1155. *(int64*)(frame_lp + addr_ret) = *(int64*)(frame_lp + addr1);
  1156. #endif
  1157. }
  1158. else {
  1159. #if defined(BUILD_TARGET_X86_32)
  1160. if (addr_ret != addr2)
  1161. bh_memcpy_s(frame_lp + addr_ret, sizeof(int64),
  1162. frame_lp + addr2, sizeof(int64));
  1163. #else
  1164. *(int64*)(frame_lp + addr_ret) = *(int64*)(frame_lp + addr2);
  1165. #endif
  1166. }
  1167. HANDLE_OP_END ();
  1168. }
  1169. /* variable instructions */
  1170. HANDLE_OP (EXT_OP_SET_LOCAL_FAST):
  1171. HANDLE_OP (EXT_OP_TEE_LOCAL_FAST):
  1172. {
  1173. local_offset = *frame_ip++;
  1174. *(int32*)(frame_lp + local_offset) = GET_OPERAND(uint32, 0);
  1175. frame_ip += 2;
  1176. HANDLE_OP_END ();
  1177. }
  1178. HANDLE_OP (EXT_OP_SET_LOCAL_FAST_I64):
  1179. HANDLE_OP (EXT_OP_TEE_LOCAL_FAST_I64):
  1180. {
  1181. local_offset = *frame_ip++;
  1182. PUT_I64_TO_ADDR((uint32*)(frame_lp + local_offset), GET_OPERAND(uint64, 0));
  1183. frame_ip += 2;
  1184. HANDLE_OP_END ();
  1185. }
  1186. HANDLE_OP (WASM_OP_GET_GLOBAL):
  1187. {
  1188. global_idx = read_uint32(frame_ip);
  1189. bh_assert(global_idx < module->global_count);
  1190. global = globals + global_idx;
  1191. #if WASM_ENABLE_MULTI_MODULE == 0
  1192. global_addr = global_data + global->data_offset;
  1193. #else
  1194. global_addr = global->import_global_inst
  1195. ? global->import_module_inst->global_data
  1196. + global->import_global_inst->data_offset
  1197. : global_data + global->data_offset;
  1198. #endif
  1199. addr_ret = GET_OFFSET();
  1200. frame_lp[addr_ret] = *(uint32*)global_addr;
  1201. HANDLE_OP_END ();
  1202. }
  1203. HANDLE_OP (WASM_OP_GET_GLOBAL_64):
  1204. {
  1205. global_idx = read_uint32(frame_ip);
  1206. bh_assert(global_idx < module->global_count);
  1207. global = globals + global_idx;
  1208. #if WASM_ENABLE_MULTI_MODULE == 0
  1209. global_addr = global_data + global->data_offset;
  1210. #else
  1211. global_addr = global->import_global_inst
  1212. ? global->import_module_inst->global_data
  1213. + global->import_global_inst->data_offset
  1214. : global_data + global->data_offset;
  1215. #endif
  1216. addr_ret = GET_OFFSET();
  1217. *(uint64 *)(frame_lp + addr_ret) = GET_I64_FROM_ADDR((uint32*)global_addr);
  1218. HANDLE_OP_END ();
  1219. }
  1220. HANDLE_OP (WASM_OP_SET_GLOBAL):
  1221. {
  1222. global_idx = read_uint32(frame_ip);
  1223. bh_assert(global_idx < module->global_count);
  1224. global = globals + global_idx;
  1225. #if WASM_ENABLE_MULTI_MODULE == 0
  1226. global_addr = global_data + global->data_offset;
  1227. #else
  1228. global_addr = global->import_global_inst
  1229. ? global->import_module_inst->global_data
  1230. + global->import_global_inst->data_offset
  1231. : global_data + global->data_offset;
  1232. #endif
  1233. addr1 = GET_OFFSET();
  1234. *(int32*)global_addr = frame_lp[addr1];
  1235. HANDLE_OP_END ();
  1236. }
  1237. HANDLE_OP (WASM_OP_SET_GLOBAL_AUX_STACK):
  1238. {
  1239. global_idx = read_uint32(frame_ip);
  1240. bh_assert(global_idx < module->global_count);
  1241. global = globals + global_idx;
  1242. #if WASM_ENABLE_MULTI_MODULE == 0
  1243. global_addr = global_data + global->data_offset;
  1244. #else
  1245. global_addr = global->import_global_inst
  1246. ? global->import_module_inst->global_data
  1247. + global->import_global_inst->data_offset
  1248. : global_data + global->data_offset;
  1249. #endif
  1250. addr1 = GET_OFFSET();
  1251. if (frame_lp[addr1] < exec_env->aux_stack_boundary)
  1252. goto out_of_bounds;
  1253. *(int32*)global_addr = frame_lp[addr1];
  1254. HANDLE_OP_END ();
  1255. }
  1256. HANDLE_OP (WASM_OP_SET_GLOBAL_64):
  1257. {
  1258. global_idx = read_uint32(frame_ip);
  1259. bh_assert(global_idx < module->global_count);
  1260. global = globals + global_idx;
  1261. #if WASM_ENABLE_MULTI_MODULE == 0
  1262. global_addr = global_data + global->data_offset;
  1263. #else
  1264. global_addr = global->import_global_inst
  1265. ? global->import_module_inst->global_data
  1266. + global->import_global_inst->data_offset
  1267. : global_data + global->data_offset;
  1268. #endif
  1269. addr1 = GET_OFFSET();
  1270. PUT_I64_TO_ADDR((uint32*)global_addr, *(int64 *)(frame_lp + addr1));
  1271. HANDLE_OP_END ();
  1272. }
  1273. /* memory load instructions */
  1274. HANDLE_OP (WASM_OP_I32_LOAD):
  1275. {
  1276. uint32 offset, addr;
  1277. offset = read_uint32(frame_ip);
  1278. addr = GET_OPERAND(uint32, 0);
  1279. frame_ip += 2;
  1280. addr_ret = GET_OFFSET();
  1281. CHECK_MEMORY_OVERFLOW(4);
  1282. frame_lp[addr_ret] = LOAD_I32(maddr);
  1283. HANDLE_OP_END ();
  1284. }
  1285. HANDLE_OP (WASM_OP_I64_LOAD):
  1286. {
  1287. uint32 offset, addr;
  1288. offset = read_uint32(frame_ip);
  1289. addr = GET_OPERAND(uint32, 0);
  1290. frame_ip += 2;
  1291. addr_ret = GET_OFFSET();
  1292. CHECK_MEMORY_OVERFLOW(8);
  1293. PUT_I64_TO_ADDR(frame_lp + addr_ret, LOAD_I64(maddr));
  1294. HANDLE_OP_END ();
  1295. }
  1296. HANDLE_OP (WASM_OP_I32_LOAD8_S):
  1297. {
  1298. uint32 offset, addr;
  1299. offset = read_uint32(frame_ip);
  1300. addr = GET_OPERAND(uint32, 0);
  1301. frame_ip += 2;
  1302. addr_ret = GET_OFFSET();
  1303. CHECK_MEMORY_OVERFLOW(1);
  1304. frame_lp[addr_ret] = sign_ext_8_32(*(int8*)maddr);
  1305. HANDLE_OP_END ();
  1306. }
  1307. HANDLE_OP (WASM_OP_I32_LOAD8_U):
  1308. {
  1309. uint32 offset, addr;
  1310. offset = read_uint32(frame_ip);
  1311. addr = GET_OPERAND(uint32, 0);
  1312. frame_ip += 2;
  1313. addr_ret = GET_OFFSET();
  1314. CHECK_MEMORY_OVERFLOW(1);
  1315. frame_lp[addr_ret] = (uint32)(*(uint8*)maddr);
  1316. HANDLE_OP_END ();
  1317. }
  1318. HANDLE_OP (WASM_OP_I32_LOAD16_S):
  1319. {
  1320. uint32 offset, addr;
  1321. offset = read_uint32(frame_ip);
  1322. addr = GET_OPERAND(uint32, 0);
  1323. frame_ip += 2;
  1324. addr_ret = GET_OFFSET();
  1325. CHECK_MEMORY_OVERFLOW(2);
  1326. frame_lp[addr_ret] = sign_ext_16_32(LOAD_I16(maddr));
  1327. HANDLE_OP_END ();
  1328. }
  1329. HANDLE_OP (WASM_OP_I32_LOAD16_U):
  1330. {
  1331. uint32 offset, addr;
  1332. offset = read_uint32(frame_ip);
  1333. addr = GET_OPERAND(uint32, 0);
  1334. frame_ip += 2;
  1335. addr_ret = GET_OFFSET();
  1336. CHECK_MEMORY_OVERFLOW(2);
  1337. frame_lp[addr_ret] = (uint32)(LOAD_U16(maddr));
  1338. HANDLE_OP_END ();
  1339. }
  1340. HANDLE_OP (WASM_OP_I64_LOAD8_S):
  1341. {
  1342. uint32 offset, addr;
  1343. offset = read_uint32(frame_ip);
  1344. addr = GET_OPERAND(uint32, 0);
  1345. frame_ip += 2;
  1346. addr_ret = GET_OFFSET();
  1347. CHECK_MEMORY_OVERFLOW(1);
  1348. *(int64 *)(frame_lp + addr_ret) = sign_ext_8_64(*(int8*)maddr);
  1349. HANDLE_OP_END ();
  1350. }
  1351. HANDLE_OP (WASM_OP_I64_LOAD8_U):
  1352. {
  1353. uint32 offset, addr;
  1354. offset = read_uint32(frame_ip);
  1355. addr = GET_OPERAND(uint32, 0);
  1356. frame_ip += 2;
  1357. addr_ret = GET_OFFSET();
  1358. CHECK_MEMORY_OVERFLOW(1);
  1359. *(int64 *)(frame_lp + addr_ret) = (uint64)(*(uint8*)maddr);
  1360. HANDLE_OP_END ();
  1361. }
  1362. HANDLE_OP (WASM_OP_I64_LOAD16_S):
  1363. {
  1364. uint32 offset, addr;
  1365. offset = read_uint32(frame_ip);
  1366. addr = GET_OPERAND(uint32, 0);
  1367. frame_ip += 2;
  1368. addr_ret = GET_OFFSET();
  1369. CHECK_MEMORY_OVERFLOW(2);
  1370. *(int64 *)(frame_lp + addr_ret) = sign_ext_16_64(LOAD_I16(maddr));
  1371. HANDLE_OP_END ();
  1372. }
  1373. HANDLE_OP (WASM_OP_I64_LOAD16_U):
  1374. {
  1375. uint32 offset, addr;
  1376. offset = read_uint32(frame_ip);
  1377. addr = GET_OPERAND(uint32, 0);
  1378. frame_ip += 2;
  1379. addr_ret = GET_OFFSET();
  1380. CHECK_MEMORY_OVERFLOW(2);
  1381. *(int64 *)(frame_lp + addr_ret) = (uint64)(LOAD_U16(maddr));
  1382. HANDLE_OP_END ();
  1383. }
  1384. HANDLE_OP (WASM_OP_I64_LOAD32_S):
  1385. {
  1386. uint32 offset, addr;
  1387. offset = read_uint32(frame_ip);
  1388. addr = GET_OPERAND(uint32, 0);
  1389. frame_ip += 2;
  1390. addr_ret = GET_OFFSET();
  1391. CHECK_MEMORY_OVERFLOW(4);
  1392. *(int64 *)(frame_lp + addr_ret) = sign_ext_32_64(LOAD_I32(maddr));
  1393. HANDLE_OP_END ();
  1394. }
  1395. HANDLE_OP (WASM_OP_I64_LOAD32_U):
  1396. {
  1397. uint32 offset, addr;
  1398. offset = read_uint32(frame_ip);
  1399. addr = GET_OPERAND(uint32, 0);
  1400. frame_ip += 2;
  1401. addr_ret = GET_OFFSET();
  1402. CHECK_MEMORY_OVERFLOW(4);
  1403. *(int64 *)(frame_lp + addr_ret) = (uint64)(LOAD_U32(maddr));
  1404. HANDLE_OP_END ();
  1405. }
  1406. HANDLE_OP (WASM_OP_I32_STORE):
  1407. {
  1408. uint32 offset, addr;
  1409. uint32 sval;
  1410. offset = read_uint32(frame_ip);
  1411. sval = GET_OPERAND(uint32, 0);
  1412. addr = GET_OPERAND(uint32, 2);
  1413. frame_ip += 4;
  1414. CHECK_MEMORY_OVERFLOW(4);
  1415. STORE_U32(maddr, sval);
  1416. HANDLE_OP_END ();
  1417. }
  1418. HANDLE_OP (WASM_OP_I32_STORE8):
  1419. {
  1420. uint32 offset, addr;
  1421. uint32 sval;
  1422. offset = read_uint32(frame_ip);
  1423. sval = GET_OPERAND(uint32, 0);
  1424. addr = GET_OPERAND(uint32, 2);
  1425. frame_ip += 4;
  1426. CHECK_MEMORY_OVERFLOW(1);
  1427. *(uint8*)maddr = (uint8)sval;
  1428. HANDLE_OP_END ();
  1429. }
  1430. HANDLE_OP (WASM_OP_I32_STORE16):
  1431. {
  1432. uint32 offset, addr;
  1433. uint32 sval;
  1434. offset = read_uint32(frame_ip);
  1435. sval = GET_OPERAND(uint32, 0);
  1436. addr = GET_OPERAND(uint32, 2);
  1437. frame_ip += 4;
  1438. CHECK_MEMORY_OVERFLOW(2);
  1439. STORE_U16(maddr, (uint16)sval);
  1440. HANDLE_OP_END ();
  1441. }
  1442. HANDLE_OP (WASM_OP_I64_STORE):
  1443. {
  1444. uint32 offset, addr;
  1445. uint64 sval;
  1446. offset = read_uint32(frame_ip);
  1447. sval = GET_OPERAND(uint64, 0);
  1448. addr = GET_OPERAND(uint32, 2);
  1449. frame_ip += 4;
  1450. CHECK_MEMORY_OVERFLOW(8);
  1451. STORE_I64(maddr, sval);
  1452. HANDLE_OP_END ();
  1453. }
  1454. HANDLE_OP (WASM_OP_I64_STORE8):
  1455. {
  1456. uint32 offset, addr;
  1457. uint64 sval;
  1458. offset = read_uint32(frame_ip);
  1459. sval = GET_OPERAND(uint64, 0);
  1460. addr = GET_OPERAND(uint32, 2);
  1461. frame_ip += 4;
  1462. CHECK_MEMORY_OVERFLOW(1);
  1463. *(uint8*)maddr = (uint8)sval;
  1464. HANDLE_OP_END ();
  1465. }
  1466. HANDLE_OP (WASM_OP_I64_STORE16):
  1467. {
  1468. uint32 offset, addr;
  1469. uint64 sval;
  1470. offset = read_uint32(frame_ip);
  1471. sval = GET_OPERAND(uint64, 0);
  1472. addr = GET_OPERAND(uint32, 2);
  1473. frame_ip += 4;
  1474. CHECK_MEMORY_OVERFLOW(2);
  1475. STORE_U16(maddr, (uint16)sval);
  1476. HANDLE_OP_END ();
  1477. }
  1478. HANDLE_OP (WASM_OP_I64_STORE32):
  1479. {
  1480. uint32 offset, addr;
  1481. uint64 sval;
  1482. offset = read_uint32(frame_ip);
  1483. sval = GET_OPERAND(uint64, 0);
  1484. addr = GET_OPERAND(uint32, 2);
  1485. frame_ip += 4;
  1486. CHECK_MEMORY_OVERFLOW(4);
  1487. STORE_U32(maddr, (uint32)sval);
  1488. HANDLE_OP_END ();
  1489. }
  1490. /* memory size and memory grow instructions */
  1491. HANDLE_OP (WASM_OP_MEMORY_SIZE):
  1492. {
  1493. uint32 reserved;
  1494. addr_ret = GET_OFFSET();
  1495. frame_lp[addr_ret] = memory->cur_page_count;
  1496. (void)reserved;
  1497. HANDLE_OP_END ();
  1498. }
  1499. HANDLE_OP (WASM_OP_MEMORY_GROW):
  1500. {
  1501. uint32 reserved, delta, prev_page_count = memory->cur_page_count;
  1502. addr1 = GET_OFFSET();
  1503. addr_ret = GET_OFFSET();
  1504. delta = (uint32)frame_lp[addr1];
  1505. if (!wasm_enlarge_memory(module, delta)) {
  1506. /* fail to memory.grow, return -1 */
  1507. frame_lp[addr_ret] = -1;
  1508. if (wasm_get_exception(module)) {
  1509. os_printf("%s\n", wasm_get_exception(module));
  1510. wasm_set_exception(module, NULL);
  1511. }
  1512. }
  1513. else {
  1514. /* success, return previous page count */
  1515. frame_lp[addr_ret] = prev_page_count;
  1516. /* update the memory instance ptr */
  1517. memory = module->default_memory;
  1518. linear_mem_size = num_bytes_per_page * memory->cur_page_count;
  1519. }
  1520. (void)reserved;
  1521. HANDLE_OP_END ();
  1522. }
  1523. /* comparison instructions of i32 */
  1524. HANDLE_OP (WASM_OP_I32_EQZ):
  1525. DEF_OP_EQZ(int32, I32);
  1526. HANDLE_OP_END ();
  1527. HANDLE_OP (WASM_OP_I32_EQ):
  1528. DEF_OP_CMP(uint32, I32, ==);
  1529. HANDLE_OP_END ();
  1530. HANDLE_OP (WASM_OP_I32_NE):
  1531. DEF_OP_CMP(uint32, I32, !=);
  1532. HANDLE_OP_END ();
  1533. HANDLE_OP (WASM_OP_I32_LT_S):
  1534. DEF_OP_CMP(int32, I32, <);
  1535. HANDLE_OP_END ();
  1536. HANDLE_OP (WASM_OP_I32_LT_U):
  1537. DEF_OP_CMP(uint32, I32, <);
  1538. HANDLE_OP_END ();
  1539. HANDLE_OP (WASM_OP_I32_GT_S):
  1540. DEF_OP_CMP(int32, I32, >);
  1541. HANDLE_OP_END ();
  1542. HANDLE_OP (WASM_OP_I32_GT_U):
  1543. DEF_OP_CMP(uint32, I32, >);
  1544. HANDLE_OP_END ();
  1545. HANDLE_OP (WASM_OP_I32_LE_S):
  1546. DEF_OP_CMP(int32, I32, <=);
  1547. HANDLE_OP_END ();
  1548. HANDLE_OP (WASM_OP_I32_LE_U):
  1549. DEF_OP_CMP(uint32, I32, <=);
  1550. HANDLE_OP_END ();
  1551. HANDLE_OP (WASM_OP_I32_GE_S):
  1552. DEF_OP_CMP(int32, I32, >=);
  1553. HANDLE_OP_END ();
  1554. HANDLE_OP (WASM_OP_I32_GE_U):
  1555. DEF_OP_CMP(uint32, I32, >=);
  1556. HANDLE_OP_END ();
  1557. /* comparison instructions of i64 */
  1558. HANDLE_OP (WASM_OP_I64_EQZ):
  1559. DEF_OP_EQZ(int64, I64);
  1560. HANDLE_OP_END ();
  1561. HANDLE_OP (WASM_OP_I64_EQ):
  1562. DEF_OP_CMP(uint64, I64, ==);
  1563. HANDLE_OP_END ();
  1564. HANDLE_OP (WASM_OP_I64_NE):
  1565. DEF_OP_CMP(uint64, I64, !=);
  1566. HANDLE_OP_END ();
  1567. HANDLE_OP (WASM_OP_I64_LT_S):
  1568. DEF_OP_CMP(int64, I64, <);
  1569. HANDLE_OP_END ();
  1570. HANDLE_OP (WASM_OP_I64_LT_U):
  1571. DEF_OP_CMP(uint64, I64, <);
  1572. HANDLE_OP_END ();
  1573. HANDLE_OP (WASM_OP_I64_GT_S):
  1574. DEF_OP_CMP(int64, I64, >);
  1575. HANDLE_OP_END ();
  1576. HANDLE_OP (WASM_OP_I64_GT_U):
  1577. DEF_OP_CMP(uint64, I64, >);
  1578. HANDLE_OP_END ();
  1579. HANDLE_OP (WASM_OP_I64_LE_S):
  1580. DEF_OP_CMP(int64, I64, <=);
  1581. HANDLE_OP_END ();
  1582. HANDLE_OP (WASM_OP_I64_LE_U):
  1583. DEF_OP_CMP(uint64, I64, <=);
  1584. HANDLE_OP_END ();
  1585. HANDLE_OP (WASM_OP_I64_GE_S):
  1586. DEF_OP_CMP(int64, I64, >=);
  1587. HANDLE_OP_END ();
  1588. HANDLE_OP (WASM_OP_I64_GE_U):
  1589. DEF_OP_CMP(uint64, I64, >=);
  1590. HANDLE_OP_END ();
  1591. /* comparison instructions of f32 */
  1592. HANDLE_OP (WASM_OP_F32_EQ):
  1593. DEF_OP_CMP(float32, F32, ==);
  1594. HANDLE_OP_END ();
  1595. HANDLE_OP (WASM_OP_F32_NE):
  1596. DEF_OP_CMP(float32, F32, !=);
  1597. HANDLE_OP_END ();
  1598. HANDLE_OP (WASM_OP_F32_LT):
  1599. DEF_OP_CMP(float32, F32, <);
  1600. HANDLE_OP_END ();
  1601. HANDLE_OP (WASM_OP_F32_GT):
  1602. DEF_OP_CMP(float32, F32, >);
  1603. HANDLE_OP_END ();
  1604. HANDLE_OP (WASM_OP_F32_LE):
  1605. DEF_OP_CMP(float32, F32, <=);
  1606. HANDLE_OP_END ();
  1607. HANDLE_OP (WASM_OP_F32_GE):
  1608. DEF_OP_CMP(float32, F32, >=);
  1609. HANDLE_OP_END ();
  1610. /* comparison instructions of f64 */
  1611. HANDLE_OP (WASM_OP_F64_EQ):
  1612. DEF_OP_CMP(float64, F64, ==);
  1613. HANDLE_OP_END ();
  1614. HANDLE_OP (WASM_OP_F64_NE):
  1615. DEF_OP_CMP(float64, F64, !=);
  1616. HANDLE_OP_END ();
  1617. HANDLE_OP (WASM_OP_F64_LT):
  1618. DEF_OP_CMP(float64, F64, <);
  1619. HANDLE_OP_END ();
  1620. HANDLE_OP (WASM_OP_F64_GT):
  1621. DEF_OP_CMP(float64, F64, >);
  1622. HANDLE_OP_END ();
  1623. HANDLE_OP (WASM_OP_F64_LE):
  1624. DEF_OP_CMP(float64, F64, <=);
  1625. HANDLE_OP_END ();
  1626. HANDLE_OP (WASM_OP_F64_GE):
  1627. DEF_OP_CMP(float64, F64, >=);
  1628. HANDLE_OP_END ();
  1629. /* numberic instructions of i32 */
  1630. HANDLE_OP (WASM_OP_I32_CLZ):
  1631. DEF_OP_BIT_COUNT(uint32, I32, clz32);
  1632. HANDLE_OP_END ();
  1633. HANDLE_OP (WASM_OP_I32_CTZ):
  1634. DEF_OP_BIT_COUNT(uint32, I32, ctz32);
  1635. HANDLE_OP_END ();
  1636. HANDLE_OP (WASM_OP_I32_POPCNT):
  1637. DEF_OP_BIT_COUNT(uint32, I32, popcount32);
  1638. HANDLE_OP_END ();
  1639. HANDLE_OP (WASM_OP_I32_ADD):
  1640. DEF_OP_NUMERIC(uint32, uint32, I32, +);
  1641. HANDLE_OP_END ();
  1642. HANDLE_OP (WASM_OP_I32_SUB):
  1643. DEF_OP_NUMERIC(uint32, uint32, I32, -);
  1644. HANDLE_OP_END ();
  1645. HANDLE_OP (WASM_OP_I32_MUL):
  1646. DEF_OP_NUMERIC(uint32, uint32, I32, *);
  1647. HANDLE_OP_END ();
  1648. HANDLE_OP (WASM_OP_I32_DIV_S):
  1649. {
  1650. int32 a, b;
  1651. b = frame_lp[GET_OFFSET()];
  1652. a = frame_lp[GET_OFFSET()];
  1653. addr_ret = GET_OFFSET();
  1654. if (a == (int32)0x80000000 && b == -1) {
  1655. wasm_set_exception(module, "integer overflow");
  1656. goto got_exception;
  1657. }
  1658. if (b == 0) {
  1659. wasm_set_exception(module, "integer divide by zero");
  1660. goto got_exception;
  1661. }
  1662. frame_lp[addr_ret] = (a / b);
  1663. HANDLE_OP_END ();
  1664. }
  1665. HANDLE_OP (WASM_OP_I32_DIV_U):
  1666. {
  1667. uint32 a, b;
  1668. addr1 = GET_OFFSET();
  1669. addr2 = GET_OFFSET();
  1670. addr_ret = GET_OFFSET();
  1671. b = (uint32)frame_lp[addr1];
  1672. a = (uint32)frame_lp[addr2];
  1673. if (b == 0) {
  1674. wasm_set_exception(module, "integer divide by zero");
  1675. goto got_exception;
  1676. }
  1677. frame_lp[addr_ret] = (a / b);
  1678. HANDLE_OP_END ();
  1679. }
  1680. HANDLE_OP (WASM_OP_I32_REM_S):
  1681. {
  1682. int32 a, b;
  1683. addr1 = GET_OFFSET();
  1684. addr2 = GET_OFFSET();
  1685. addr_ret = GET_OFFSET();
  1686. b = frame_lp[addr1];
  1687. a = frame_lp[addr2];
  1688. if (a == (int32)0x80000000 && b == -1) {
  1689. frame_lp[addr_ret] = 0;
  1690. HANDLE_OP_END ();
  1691. }
  1692. if (b == 0) {
  1693. wasm_set_exception(module, "integer divide by zero");
  1694. goto got_exception;
  1695. }
  1696. frame_lp[addr_ret] = (a % b);
  1697. HANDLE_OP_END ();
  1698. }
  1699. HANDLE_OP (WASM_OP_I32_REM_U):
  1700. {
  1701. uint32 a, b;
  1702. addr1 = GET_OFFSET();
  1703. addr2 = GET_OFFSET();
  1704. addr_ret = GET_OFFSET();
  1705. b = (uint32)frame_lp[addr1];
  1706. a = (uint32)frame_lp[addr2];
  1707. if (b == 0) {
  1708. wasm_set_exception(module, "integer divide by zero");
  1709. goto got_exception;
  1710. }
  1711. frame_lp[addr_ret] = (a % b);
  1712. HANDLE_OP_END ();
  1713. }
  1714. HANDLE_OP (WASM_OP_I32_AND):
  1715. DEF_OP_NUMERIC(uint32, uint32, I32, &);
  1716. HANDLE_OP_END ();
  1717. HANDLE_OP (WASM_OP_I32_OR):
  1718. DEF_OP_NUMERIC(uint32, uint32, I32, |);
  1719. HANDLE_OP_END ();
  1720. HANDLE_OP (WASM_OP_I32_XOR):
  1721. DEF_OP_NUMERIC(uint32, uint32, I32, ^);
  1722. HANDLE_OP_END ();
  1723. HANDLE_OP (WASM_OP_I32_SHL):
  1724. {
  1725. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1726. DEF_OP_NUMERIC(uint32, uint32, I32, <<);
  1727. #else
  1728. DEF_OP_NUMERIC2(uint32, uint32, I32, <<);
  1729. #endif
  1730. HANDLE_OP_END ();
  1731. }
  1732. HANDLE_OP (WASM_OP_I32_SHR_S):
  1733. {
  1734. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1735. DEF_OP_NUMERIC(int32, uint32, I32, >>);
  1736. #else
  1737. DEF_OP_NUMERIC2(int32, uint32, I32, >>);
  1738. #endif
  1739. HANDLE_OP_END ();
  1740. }
  1741. HANDLE_OP (WASM_OP_I32_SHR_U):
  1742. {
  1743. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1744. DEF_OP_NUMERIC(uint32, uint32, I32, >>);
  1745. #else
  1746. DEF_OP_NUMERIC2(uint32, uint32, I32, >>);
  1747. #endif
  1748. HANDLE_OP_END ();
  1749. }
  1750. HANDLE_OP (WASM_OP_I32_ROTL):
  1751. {
  1752. uint32 a, b;
  1753. b = (uint32)frame_lp[GET_OFFSET()];
  1754. a = (uint32)frame_lp[GET_OFFSET()];
  1755. frame_lp[GET_OFFSET()] = rotl32(a, b);
  1756. HANDLE_OP_END ();
  1757. }
  1758. HANDLE_OP (WASM_OP_I32_ROTR):
  1759. {
  1760. uint32 a, b;
  1761. b = (uint32)frame_lp[GET_OFFSET()];
  1762. a = (uint32)frame_lp[GET_OFFSET()];
  1763. frame_lp[GET_OFFSET()] = rotr32(a, b);
  1764. HANDLE_OP_END ();
  1765. }
  1766. /* numberic instructions of i64 */
  1767. HANDLE_OP (WASM_OP_I64_CLZ):
  1768. DEF_OP_BIT_COUNT(uint64, I64, clz64);
  1769. HANDLE_OP_END ();
  1770. HANDLE_OP (WASM_OP_I64_CTZ):
  1771. DEF_OP_BIT_COUNT(uint64, I64, ctz64);
  1772. HANDLE_OP_END ();
  1773. HANDLE_OP (WASM_OP_I64_POPCNT):
  1774. DEF_OP_BIT_COUNT(uint64, I64, popcount64);
  1775. HANDLE_OP_END ();
  1776. HANDLE_OP (WASM_OP_I64_ADD):
  1777. DEF_OP_NUMERIC_64(uint64, uint64, I64, +);
  1778. HANDLE_OP_END ();
  1779. HANDLE_OP (WASM_OP_I64_SUB):
  1780. DEF_OP_NUMERIC_64(uint64, uint64, I64, -);
  1781. HANDLE_OP_END ();
  1782. HANDLE_OP (WASM_OP_I64_MUL):
  1783. DEF_OP_NUMERIC_64(uint64, uint64, I64, *);
  1784. HANDLE_OP_END ();
  1785. HANDLE_OP (WASM_OP_I64_DIV_S):
  1786. {
  1787. int64 a, b;
  1788. b = *(int64*)(frame_lp + GET_OFFSET());
  1789. a = *(int64*)(frame_lp + GET_OFFSET());
  1790. if (a == (int64)0x8000000000000000LL && b == -1) {
  1791. wasm_set_exception(module, "integer overflow");
  1792. goto got_exception;
  1793. }
  1794. if (b == 0) {
  1795. wasm_set_exception(module, "integer divide by zero");
  1796. goto got_exception;
  1797. }
  1798. *(int64*)(frame_lp + GET_OFFSET()) = (a / b);
  1799. HANDLE_OP_END ();
  1800. }
  1801. HANDLE_OP (WASM_OP_I64_DIV_U):
  1802. {
  1803. uint64 a, b;
  1804. b = *(uint64*)(frame_lp + GET_OFFSET());
  1805. a = *(uint64*)(frame_lp + GET_OFFSET());
  1806. if (b == 0) {
  1807. wasm_set_exception(module, "integer divide by zero");
  1808. goto got_exception;
  1809. }
  1810. *(uint64*)(frame_lp + GET_OFFSET()) = (a / b);
  1811. HANDLE_OP_END ();
  1812. }
  1813. HANDLE_OP (WASM_OP_I64_REM_S):
  1814. {
  1815. int64 a, b;
  1816. b = *(int64*)(frame_lp + GET_OFFSET());
  1817. a = *(int64*)(frame_lp + GET_OFFSET());
  1818. if (a == (int64)0x8000000000000000LL && b == -1) {
  1819. *(int64*)(frame_lp + GET_OFFSET()) = 0;
  1820. HANDLE_OP_END ();
  1821. }
  1822. if (b == 0) {
  1823. wasm_set_exception(module, "integer divide by zero");
  1824. goto got_exception;
  1825. }
  1826. *(int64*)(frame_lp + GET_OFFSET()) = (a % b);
  1827. HANDLE_OP_END ();
  1828. }
  1829. HANDLE_OP (WASM_OP_I64_REM_U):
  1830. {
  1831. uint64 a, b;
  1832. b = *(uint64*)(frame_lp + GET_OFFSET());
  1833. a = *(uint64*)(frame_lp + GET_OFFSET());
  1834. if (b == 0) {
  1835. wasm_set_exception(module, "integer divide by zero");
  1836. goto got_exception;
  1837. }
  1838. *(uint64*)(frame_lp + GET_OFFSET()) = (a % b);
  1839. HANDLE_OP_END ();
  1840. }
  1841. HANDLE_OP (WASM_OP_I64_AND):
  1842. DEF_OP_NUMERIC_64(uint64, uint64, I64, &);
  1843. HANDLE_OP_END ();
  1844. HANDLE_OP (WASM_OP_I64_OR):
  1845. DEF_OP_NUMERIC_64(uint64, uint64, I64, |);
  1846. HANDLE_OP_END ();
  1847. HANDLE_OP (WASM_OP_I64_XOR):
  1848. DEF_OP_NUMERIC_64(uint64, uint64, I64, ^);
  1849. HANDLE_OP_END ();
  1850. HANDLE_OP (WASM_OP_I64_SHL):
  1851. {
  1852. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1853. DEF_OP_NUMERIC_64(uint64, uint64, I64, <<);
  1854. #else
  1855. DEF_OP_NUMERIC2_64(uint64, uint64, I64, <<);
  1856. #endif
  1857. HANDLE_OP_END ();
  1858. }
  1859. HANDLE_OP (WASM_OP_I64_SHR_S):
  1860. {
  1861. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1862. DEF_OP_NUMERIC_64(int64, uint64, I64, >>);
  1863. #else
  1864. DEF_OP_NUMERIC2_64(int64, uint64, I64, >>);
  1865. #endif
  1866. HANDLE_OP_END ();
  1867. }
  1868. HANDLE_OP (WASM_OP_I64_SHR_U):
  1869. {
  1870. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1871. DEF_OP_NUMERIC_64(uint64, uint64, I64, >>);
  1872. #else
  1873. DEF_OP_NUMERIC2_64(uint64, uint64, I64, >>);
  1874. #endif
  1875. HANDLE_OP_END ();
  1876. }
  1877. HANDLE_OP (WASM_OP_I64_ROTL):
  1878. {
  1879. uint64 a, b;
  1880. b = *(int64*)(frame_lp + GET_OFFSET());
  1881. a = *(int64*)(frame_lp + GET_OFFSET());
  1882. *(int64*)(frame_lp + GET_OFFSET()) = rotl64(a, b);
  1883. HANDLE_OP_END ();
  1884. }
  1885. HANDLE_OP (WASM_OP_I64_ROTR):
  1886. {
  1887. uint64 a, b;
  1888. b = *(uint64*)(frame_lp + GET_OFFSET());
  1889. a = *(uint64*)(frame_lp + GET_OFFSET());
  1890. *(uint64*)(frame_lp + GET_OFFSET()) = rotr64(a, b);
  1891. HANDLE_OP_END ();
  1892. }
  1893. /* numberic instructions of f32 */
  1894. HANDLE_OP (WASM_OP_F32_ABS):
  1895. DEF_OP_MATH(float32, F32, fabs);
  1896. HANDLE_OP_END ();
  1897. HANDLE_OP (WASM_OP_F32_NEG):
  1898. {
  1899. int32 i32 = (int32)frame_lp[GET_OFFSET()];
  1900. addr_ret = GET_OFFSET();
  1901. int32 sign_bit = i32 & (1 << 31);
  1902. if (sign_bit)
  1903. frame_lp[addr_ret] = i32 & ~(1 << 31);
  1904. else
  1905. frame_lp[addr_ret] = (uint32)(i32 | (1 << 31));
  1906. HANDLE_OP_END ();
  1907. }
  1908. HANDLE_OP (WASM_OP_F32_CEIL):
  1909. DEF_OP_MATH(float32, F32, ceil);
  1910. HANDLE_OP_END ();
  1911. HANDLE_OP (WASM_OP_F32_FLOOR):
  1912. DEF_OP_MATH(float32, F32, floor);
  1913. HANDLE_OP_END ();
  1914. HANDLE_OP (WASM_OP_F32_TRUNC):
  1915. DEF_OP_MATH(float32, F32, trunc);
  1916. HANDLE_OP_END ();
  1917. HANDLE_OP (WASM_OP_F32_NEAREST):
  1918. DEF_OP_MATH(float32, F32, rint);
  1919. HANDLE_OP_END ();
  1920. HANDLE_OP (WASM_OP_F32_SQRT):
  1921. DEF_OP_MATH(float32, F32, sqrt);
  1922. HANDLE_OP_END ();
  1923. HANDLE_OP (WASM_OP_F32_ADD):
  1924. DEF_OP_NUMERIC(float32, float32, F32, +);
  1925. HANDLE_OP_END ();
  1926. HANDLE_OP (WASM_OP_F32_SUB):
  1927. DEF_OP_NUMERIC(float32, float32, F32, -);
  1928. HANDLE_OP_END ();
  1929. HANDLE_OP (WASM_OP_F32_MUL):
  1930. DEF_OP_NUMERIC(float32, float32, F32, *);
  1931. HANDLE_OP_END ();
  1932. HANDLE_OP (WASM_OP_F32_DIV):
  1933. DEF_OP_NUMERIC(float32, float32, F32, /);
  1934. HANDLE_OP_END ();
  1935. HANDLE_OP (WASM_OP_F32_MIN):
  1936. {
  1937. float32 a, b;
  1938. b = *(float32*)(frame_lp + GET_OFFSET());
  1939. a = *(float32*)(frame_lp + GET_OFFSET());
  1940. if (isnan(a))
  1941. *(float32*)(frame_lp + GET_OFFSET()) = a;
  1942. else if (isnan(b))
  1943. *(float32*)(frame_lp + GET_OFFSET()) = b;
  1944. else
  1945. *(float32*)(frame_lp + GET_OFFSET()) = wa_fmin(a, b);
  1946. HANDLE_OP_END ();
  1947. }
  1948. HANDLE_OP (WASM_OP_F32_MAX):
  1949. {
  1950. float32 a, b;
  1951. b = *(float32*)(frame_lp + GET_OFFSET());
  1952. a = *(float32*)(frame_lp + GET_OFFSET());
  1953. if (isnan(a))
  1954. *(float32*)(frame_lp + GET_OFFSET()) = a;
  1955. else if (isnan(b))
  1956. *(float32*)(frame_lp + GET_OFFSET()) = b;
  1957. else
  1958. *(float32*)(frame_lp + GET_OFFSET()) = wa_fmax(a, b);
  1959. HANDLE_OP_END ();
  1960. }
  1961. HANDLE_OP (WASM_OP_F32_COPYSIGN):
  1962. {
  1963. float32 a, b;
  1964. b = *(float32*)(frame_lp + GET_OFFSET());
  1965. a = *(float32*)(frame_lp + GET_OFFSET());
  1966. *(float32*)(frame_lp + GET_OFFSET()) = (signbit(b) ? -fabs(a) : fabs(a));
  1967. HANDLE_OP_END ();
  1968. }
  1969. /* numberic instructions of f64 */
  1970. HANDLE_OP (WASM_OP_F64_ABS):
  1971. DEF_OP_MATH(float64, F64, fabs);
  1972. HANDLE_OP_END ();
  1973. HANDLE_OP (WASM_OP_F64_NEG):
  1974. {
  1975. int64 i64 = *(int64*)(frame_lp + GET_OFFSET());
  1976. int64 sign_bit = i64 & (((int64)1) << 63);
  1977. if (sign_bit)
  1978. *(int64*)(frame_lp + GET_OFFSET()) = (uint64)i64 & ~(((uint64)1) << 63);
  1979. else
  1980. *(int64*)(frame_lp + GET_OFFSET()) = (uint64)i64 | (((uint64)1) << 63);
  1981. HANDLE_OP_END ();
  1982. }
  1983. HANDLE_OP (WASM_OP_F64_CEIL):
  1984. DEF_OP_MATH(float64, F64, ceil);
  1985. HANDLE_OP_END ();
  1986. HANDLE_OP (WASM_OP_F64_FLOOR):
  1987. DEF_OP_MATH(float64, F64, floor);
  1988. HANDLE_OP_END ();
  1989. HANDLE_OP (WASM_OP_F64_TRUNC):
  1990. DEF_OP_MATH(float64, F64, trunc);
  1991. HANDLE_OP_END ();
  1992. HANDLE_OP (WASM_OP_F64_NEAREST):
  1993. DEF_OP_MATH(float64, F64, rint);
  1994. HANDLE_OP_END ();
  1995. HANDLE_OP (WASM_OP_F64_SQRT):
  1996. DEF_OP_MATH(float64, F64, sqrt);
  1997. HANDLE_OP_END ();
  1998. HANDLE_OP (WASM_OP_F64_ADD):
  1999. DEF_OP_NUMERIC_64(float64, float64, F64, +);
  2000. HANDLE_OP_END ();
  2001. HANDLE_OP (WASM_OP_F64_SUB):
  2002. DEF_OP_NUMERIC_64(float64, float64, F64, -);
  2003. HANDLE_OP_END ();
  2004. HANDLE_OP (WASM_OP_F64_MUL):
  2005. DEF_OP_NUMERIC_64(float64, float64, F64, *);
  2006. HANDLE_OP_END ();
  2007. HANDLE_OP (WASM_OP_F64_DIV):
  2008. DEF_OP_NUMERIC_64(float64, float64, F64, /);
  2009. HANDLE_OP_END ();
  2010. HANDLE_OP (WASM_OP_F64_MIN):
  2011. {
  2012. float64 a, b;
  2013. b = POP_F64();
  2014. a = POP_F64();
  2015. if (isnan(a))
  2016. PUSH_F64(a);
  2017. else if (isnan(b))
  2018. PUSH_F64(b);
  2019. else
  2020. PUSH_F64(wa_fmin(a, b));
  2021. HANDLE_OP_END ();
  2022. }
  2023. HANDLE_OP (WASM_OP_F64_MAX):
  2024. {
  2025. float64 a, b;
  2026. b = POP_F64();
  2027. a = POP_F64();
  2028. if (isnan(a))
  2029. PUSH_F64(a);
  2030. else if (isnan(b))
  2031. PUSH_F64(b);
  2032. else
  2033. PUSH_F64(wa_fmax(a, b));
  2034. HANDLE_OP_END ();
  2035. }
  2036. HANDLE_OP (WASM_OP_F64_COPYSIGN):
  2037. {
  2038. float64 a, b;
  2039. b = POP_F64();
  2040. a = POP_F64();
  2041. PUSH_F64(signbit(b) ? -fabs(a) : fabs(a));
  2042. HANDLE_OP_END ();
  2043. }
  2044. /* conversions of i32 */
  2045. HANDLE_OP (WASM_OP_I32_WRAP_I64):
  2046. {
  2047. int32 value = (int32)(POP_I64() & 0xFFFFFFFFLL);
  2048. PUSH_I32(value);
  2049. HANDLE_OP_END ();
  2050. }
  2051. HANDLE_OP (WASM_OP_I32_TRUNC_S_F32):
  2052. /* We don't use INT32_MIN/INT32_MAX/UINT32_MIN/UINT32_MAX,
  2053. since float/double values of ieee754 cannot precisely represent
  2054. all int32/uint32/int64/uint64 values, e.g.:
  2055. UINT32_MAX is 4294967295, but (float32)4294967295 is 4294967296.0f,
  2056. but not 4294967295.0f. */
  2057. DEF_OP_TRUNC_F32(-2147483904.0f, 2147483648.0f, true, true);
  2058. HANDLE_OP_END ();
  2059. HANDLE_OP (WASM_OP_I32_TRUNC_U_F32):
  2060. DEF_OP_TRUNC_F32(-1.0f, 4294967296.0f, true, false);
  2061. HANDLE_OP_END ();
  2062. HANDLE_OP (WASM_OP_I32_TRUNC_S_F64):
  2063. DEF_OP_TRUNC_F64(-2147483649.0, 2147483648.0, true, true);
  2064. HANDLE_OP_END ();
  2065. HANDLE_OP (WASM_OP_I32_TRUNC_U_F64):
  2066. DEF_OP_TRUNC_F64(-1.0, 4294967296.0, true, false);
  2067. HANDLE_OP_END ();
  2068. /* conversions of i64 */
  2069. HANDLE_OP (WASM_OP_I64_EXTEND_S_I32):
  2070. DEF_OP_CONVERT(int64, I64, int32, I32);
  2071. HANDLE_OP_END ();
  2072. HANDLE_OP (WASM_OP_I64_EXTEND_U_I32):
  2073. DEF_OP_CONVERT(int64, I64, uint32, I32);
  2074. HANDLE_OP_END ();
  2075. HANDLE_OP (WASM_OP_I64_TRUNC_S_F32):
  2076. DEF_OP_TRUNC_F32(-9223373136366403584.0f,
  2077. 9223372036854775808.0f, false, true);
  2078. HANDLE_OP_END ();
  2079. HANDLE_OP (WASM_OP_I64_TRUNC_U_F32):
  2080. DEF_OP_TRUNC_F32(-1.0f, 18446744073709551616.0f,
  2081. false, false);
  2082. HANDLE_OP_END ();
  2083. HANDLE_OP (WASM_OP_I64_TRUNC_S_F64):
  2084. DEF_OP_TRUNC_F64(-9223372036854777856.0,
  2085. 9223372036854775808.0, false, true);
  2086. HANDLE_OP_END ();
  2087. HANDLE_OP (WASM_OP_I64_TRUNC_U_F64):
  2088. DEF_OP_TRUNC_F64(-1.0, 18446744073709551616.0,
  2089. false, false);
  2090. HANDLE_OP_END ();
  2091. /* conversions of f32 */
  2092. HANDLE_OP (WASM_OP_F32_CONVERT_S_I32):
  2093. DEF_OP_CONVERT(float32, F32, int32, I32);
  2094. HANDLE_OP_END ();
  2095. HANDLE_OP (WASM_OP_F32_CONVERT_U_I32):
  2096. DEF_OP_CONVERT(float32, F32, uint32, I32);
  2097. HANDLE_OP_END ();
  2098. HANDLE_OP (WASM_OP_F32_CONVERT_S_I64):
  2099. DEF_OP_CONVERT(float32, F32, int64, I64);
  2100. HANDLE_OP_END ();
  2101. HANDLE_OP (WASM_OP_F32_CONVERT_U_I64):
  2102. DEF_OP_CONVERT(float32, F32, uint64, I64);
  2103. HANDLE_OP_END ();
  2104. HANDLE_OP (WASM_OP_F32_DEMOTE_F64):
  2105. DEF_OP_CONVERT(float32, F32, float64, F64);
  2106. HANDLE_OP_END ();
  2107. /* conversions of f64 */
  2108. HANDLE_OP (WASM_OP_F64_CONVERT_S_I32):
  2109. DEF_OP_CONVERT(float64, F64, int32, I32);
  2110. HANDLE_OP_END ();
  2111. HANDLE_OP (WASM_OP_F64_CONVERT_U_I32):
  2112. DEF_OP_CONVERT(float64, F64, uint32, I32);
  2113. HANDLE_OP_END ();
  2114. HANDLE_OP (WASM_OP_F64_CONVERT_S_I64):
  2115. DEF_OP_CONVERT(float64, F64, int64, I64);
  2116. HANDLE_OP_END ();
  2117. HANDLE_OP (WASM_OP_F64_CONVERT_U_I64):
  2118. DEF_OP_CONVERT(float64, F64, uint64, I64);
  2119. HANDLE_OP_END ();
  2120. HANDLE_OP (WASM_OP_F64_PROMOTE_F32):
  2121. DEF_OP_CONVERT(float64, F64, float32, F32);
  2122. HANDLE_OP_END ();
  2123. /* reinterpretations */
  2124. HANDLE_OP (WASM_OP_I32_REINTERPRET_F32):
  2125. DEF_OP_REINTERPRET(float32);
  2126. HANDLE_OP_END ();
  2127. HANDLE_OP (WASM_OP_I64_REINTERPRET_F64):
  2128. DEF_OP_REINTERPRET(float64);
  2129. HANDLE_OP_END ();
  2130. HANDLE_OP (WASM_OP_F32_REINTERPRET_I32):
  2131. DEF_OP_REINTERPRET(int32);
  2132. HANDLE_OP_END ();
  2133. HANDLE_OP (WASM_OP_F64_REINTERPRET_I64):
  2134. DEF_OP_REINTERPRET(int64);
  2135. HANDLE_OP_END ();
  2136. HANDLE_OP (EXT_OP_COPY_STACK_TOP):
  2137. addr1 = GET_OFFSET();
  2138. addr2 = GET_OFFSET();
  2139. frame_lp[addr2] = frame_lp[addr1];
  2140. HANDLE_OP_END ();
  2141. HANDLE_OP (EXT_OP_COPY_STACK_TOP_I64):
  2142. addr1 = GET_OFFSET();
  2143. addr2 = GET_OFFSET();
  2144. *(uint64*)(frame_lp + addr2) = *(uint64*)(frame_lp + addr1);
  2145. HANDLE_OP_END ();
  2146. HANDLE_OP (EXT_OP_COPY_STACK_VALUES):
  2147. {
  2148. uint32 values_count, total_cell;
  2149. uint8 *cells;
  2150. int16 *src_offsets = NULL;
  2151. uint16 *dst_offsets = NULL;
  2152. /* read values_count */
  2153. values_count = *(uint32*)frame_ip;
  2154. frame_ip += sizeof(values_count);
  2155. /* read total cell num */
  2156. total_cell = *(uint32*)frame_ip;
  2157. frame_ip += sizeof(total_cell);
  2158. /* cells */
  2159. cells = (uint8 *)frame_ip;
  2160. frame_ip += values_count * sizeof(uint8);
  2161. /* src offsets */
  2162. src_offsets = (int16 *)frame_ip;
  2163. frame_ip += values_count * sizeof(int16);
  2164. /* dst offsets */
  2165. dst_offsets = (uint16*)frame_ip;
  2166. frame_ip += values_count * sizeof(uint16);
  2167. if (!copy_stack_values(module, frame_lp,
  2168. values_count, total_cell,
  2169. cells, src_offsets,
  2170. dst_offsets))
  2171. goto got_exception;
  2172. HANDLE_OP_END ();
  2173. }
  2174. HANDLE_OP (WASM_OP_SET_LOCAL):
  2175. HANDLE_OP (WASM_OP_TEE_LOCAL):
  2176. {
  2177. GET_LOCAL_INDEX_TYPE_AND_OFFSET();
  2178. addr1 = GET_OFFSET();
  2179. if (local_type == VALUE_TYPE_I32
  2180. || local_type == VALUE_TYPE_F32) {
  2181. *(int32*)(frame_lp + local_offset) = frame_lp[addr1];
  2182. }
  2183. else if (local_type == VALUE_TYPE_I64
  2184. || local_type == VALUE_TYPE_F64) {
  2185. PUT_I64_TO_ADDR((uint32*)(frame_lp + local_offset),
  2186. GET_I64_FROM_ADDR(frame_lp + addr1));
  2187. }
  2188. else {
  2189. wasm_set_exception(module, "invalid local type");
  2190. goto got_exception;
  2191. }
  2192. HANDLE_OP_END ();
  2193. }
  2194. HANDLE_OP (WASM_OP_I32_EXTEND8_S):
  2195. DEF_OP_CONVERT(int32, I32, int8, I32);
  2196. HANDLE_OP_END ();
  2197. HANDLE_OP (WASM_OP_I32_EXTEND16_S):
  2198. DEF_OP_CONVERT(int32, I32, int16, I32);
  2199. HANDLE_OP_END ();
  2200. HANDLE_OP (WASM_OP_I64_EXTEND8_S):
  2201. DEF_OP_CONVERT(int64, I64, int8, I64);
  2202. HANDLE_OP_END ();
  2203. HANDLE_OP (WASM_OP_I64_EXTEND16_S):
  2204. DEF_OP_CONVERT(int64, I64, int16, I64);
  2205. HANDLE_OP_END ();
  2206. HANDLE_OP (WASM_OP_I64_EXTEND32_S):
  2207. DEF_OP_CONVERT(int64, I64, int32, I64);
  2208. HANDLE_OP_END ();
  2209. HANDLE_OP (WASM_OP_MISC_PREFIX):
  2210. {
  2211. GET_OPCODE();
  2212. switch (opcode)
  2213. {
  2214. case WASM_OP_I32_TRUNC_SAT_S_F32:
  2215. DEF_OP_TRUNC_SAT_F32(-2147483904.0f, 2147483648.0f,
  2216. true, true);
  2217. break;
  2218. case WASM_OP_I32_TRUNC_SAT_U_F32:
  2219. DEF_OP_TRUNC_SAT_F32(-1.0f, 4294967296.0f,
  2220. true, false);
  2221. break;
  2222. case WASM_OP_I32_TRUNC_SAT_S_F64:
  2223. DEF_OP_TRUNC_SAT_F64(-2147483649.0, 2147483648.0,
  2224. true, true);
  2225. break;
  2226. case WASM_OP_I32_TRUNC_SAT_U_F64:
  2227. DEF_OP_TRUNC_SAT_F64(-1.0, 4294967296.0,
  2228. true, false);
  2229. break;
  2230. case WASM_OP_I64_TRUNC_SAT_S_F32:
  2231. DEF_OP_TRUNC_SAT_F32(-9223373136366403584.0f, 9223372036854775808.0f,
  2232. false, true);
  2233. break;
  2234. case WASM_OP_I64_TRUNC_SAT_U_F32:
  2235. DEF_OP_TRUNC_SAT_F32(-1.0f, 18446744073709551616.0f,
  2236. false, false);
  2237. break;
  2238. case WASM_OP_I64_TRUNC_SAT_S_F64:
  2239. DEF_OP_TRUNC_SAT_F64(-9223372036854777856.0, 9223372036854775808.0,
  2240. false, true);
  2241. break;
  2242. case WASM_OP_I64_TRUNC_SAT_U_F64:
  2243. DEF_OP_TRUNC_SAT_F64(-1.0, 18446744073709551616.0,
  2244. false, false);
  2245. break;
  2246. #if WASM_ENABLE_BULK_MEMORY != 0
  2247. case WASM_OP_MEMORY_INIT:
  2248. {
  2249. uint32 addr, segment;
  2250. uint64 bytes, offset, seg_len;
  2251. uint8* data;
  2252. segment = read_uint32(frame_ip);
  2253. bytes = (uint64)POP_I32();
  2254. offset = (uint64)POP_I32();
  2255. addr = POP_I32();
  2256. CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
  2257. seg_len = (uint64)module->module->data_segments[segment]->data_length;
  2258. data = module->module->data_segments[segment]->data;
  2259. if (offset + bytes > seg_len)
  2260. goto out_of_bounds;
  2261. bh_memcpy_s(maddr, linear_mem_size - addr,
  2262. data + offset, bytes);
  2263. break;
  2264. }
  2265. case WASM_OP_DATA_DROP:
  2266. {
  2267. uint32 segment;
  2268. segment = read_uint32(frame_ip);
  2269. module->module->data_segments[segment]->data_length = 0;
  2270. break;
  2271. }
  2272. case WASM_OP_MEMORY_COPY:
  2273. {
  2274. uint32 dst, src, len;
  2275. uint8 *mdst, *msrc;
  2276. len = POP_I32();
  2277. src = POP_I32();
  2278. dst = POP_I32();
  2279. CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
  2280. CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
  2281. /* allowing the destination and source to overlap */
  2282. bh_memmove_s(mdst, linear_mem_size - dst,
  2283. msrc, len);
  2284. break;
  2285. }
  2286. case WASM_OP_MEMORY_FILL:
  2287. {
  2288. uint32 dst, len;
  2289. uint8 val, *mdst;
  2290. len = POP_I32();
  2291. val = POP_I32();
  2292. dst = POP_I32();
  2293. CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
  2294. memset(mdst, val, len);
  2295. break;
  2296. }
  2297. #endif /* WASM_ENABLE_BULK_MEMORY */
  2298. default:
  2299. wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
  2300. goto got_exception;
  2301. break;
  2302. }
  2303. HANDLE_OP_END ();
  2304. }
  2305. HANDLE_OP (WASM_OP_IMPDEP):
  2306. frame = prev_frame;
  2307. frame_ip = frame->ip;
  2308. goto call_func_from_entry;
  2309. HANDLE_OP (WASM_OP_CALL):
  2310. #if WASM_ENABLE_THREAD_MGR != 0
  2311. CHECK_SUSPEND_FLAGS();
  2312. #endif
  2313. fidx = read_uint32(frame_ip);
  2314. #if WASM_ENABLE_MULTI_MODULE != 0
  2315. if (fidx >= module->function_count) {
  2316. wasm_set_exception(module, "unknown function");
  2317. goto got_exception;
  2318. }
  2319. #endif
  2320. cur_func = module->functions + fidx;
  2321. goto call_func_from_interp;
  2322. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  2323. default:
  2324. wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
  2325. goto got_exception;
  2326. }
  2327. #endif
  2328. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  2329. HANDLE_OP (WASM_OP_UNUSED_0x06):
  2330. HANDLE_OP (WASM_OP_UNUSED_0x07):
  2331. HANDLE_OP (WASM_OP_UNUSED_0x08):
  2332. HANDLE_OP (WASM_OP_UNUSED_0x09):
  2333. HANDLE_OP (WASM_OP_UNUSED_0x0a):
  2334. HANDLE_OP (WASM_OP_UNUSED_0x12):
  2335. HANDLE_OP (WASM_OP_UNUSED_0x13):
  2336. HANDLE_OP (WASM_OP_UNUSED_0x14):
  2337. HANDLE_OP (WASM_OP_UNUSED_0x15):
  2338. HANDLE_OP (WASM_OP_UNUSED_0x16):
  2339. HANDLE_OP (WASM_OP_UNUSED_0x17):
  2340. HANDLE_OP (WASM_OP_UNUSED_0x18):
  2341. HANDLE_OP (WASM_OP_UNUSED_0x19):
  2342. HANDLE_OP (WASM_OP_UNUSED_0x1c):
  2343. HANDLE_OP (WASM_OP_UNUSED_0x1d):
  2344. HANDLE_OP (WASM_OP_UNUSED_0x1e):
  2345. HANDLE_OP (WASM_OP_UNUSED_0x1f):
  2346. /* optimized op code */
  2347. HANDLE_OP (WASM_OP_F32_STORE):
  2348. HANDLE_OP (WASM_OP_F64_STORE):
  2349. HANDLE_OP (WASM_OP_F32_LOAD):
  2350. HANDLE_OP (WASM_OP_F64_LOAD):
  2351. HANDLE_OP (EXT_OP_GET_LOCAL_FAST):
  2352. HANDLE_OP (WASM_OP_GET_LOCAL):
  2353. HANDLE_OP (WASM_OP_F64_CONST):
  2354. HANDLE_OP (WASM_OP_I64_CONST):
  2355. HANDLE_OP (WASM_OP_F32_CONST):
  2356. HANDLE_OP (WASM_OP_I32_CONST):
  2357. HANDLE_OP (WASM_OP_DROP):
  2358. HANDLE_OP (WASM_OP_DROP_64):
  2359. HANDLE_OP (WASM_OP_BLOCK):
  2360. HANDLE_OP (WASM_OP_LOOP):
  2361. HANDLE_OP (WASM_OP_END):
  2362. HANDLE_OP (WASM_OP_NOP):
  2363. HANDLE_OP (EXT_OP_BLOCK):
  2364. HANDLE_OP (EXT_OP_LOOP):
  2365. HANDLE_OP (EXT_OP_IF):
  2366. {
  2367. wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
  2368. goto got_exception;
  2369. }
  2370. #endif
  2371. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  2372. continue;
  2373. #else
  2374. FETCH_OPCODE_AND_DISPATCH ();
  2375. #endif
  2376. call_func_from_interp:
  2377. /* Only do the copy when it's called from interpreter. */
  2378. {
  2379. WASMInterpFrame *outs_area = wasm_exec_env_wasm_stack_top(exec_env);
  2380. outs_area->lp = outs_area->operand + cur_func->const_cell_num;
  2381. for (int i = 0; i < cur_func->param_count; i++) {
  2382. if (cur_func->param_types[i] == VALUE_TYPE_I64
  2383. || cur_func->param_types[i] == VALUE_TYPE_F64) {
  2384. *(int64*)(outs_area->lp) =
  2385. GET_OPERAND(int64, (2 * (cur_func->param_count - i - 1)));
  2386. outs_area->lp += 2;
  2387. } else {
  2388. *(outs_area->lp) = GET_OPERAND(int32, (2 * (cur_func->param_count - i - 1)));
  2389. outs_area->lp ++;
  2390. }
  2391. }
  2392. frame_ip += cur_func->param_count * sizeof(int16);
  2393. if (cur_func->ret_cell_num != 0) {
  2394. /* Get the first return value's offset. Since loader emit all return
  2395. * values' offset so we must skip remain return values' offsets.
  2396. */
  2397. WASMType *func_type;
  2398. if (cur_func->is_import_func
  2399. #if WASM_ENABLE_MULTI_MODULE != 0
  2400. && !cur_func->import_func_inst
  2401. #endif
  2402. )
  2403. func_type = cur_func->u.func_import->func_type;
  2404. else
  2405. func_type = cur_func->u.func->func_type;
  2406. frame->ret_offset = GET_OFFSET();
  2407. frame_ip += 2 * (func_type->result_count - 1);
  2408. }
  2409. SYNC_ALL_TO_FRAME();
  2410. prev_frame = frame;
  2411. }
  2412. call_func_from_entry:
  2413. {
  2414. if (cur_func->is_import_func) {
  2415. #if WASM_ENABLE_MULTI_MODULE != 0
  2416. if (cur_func->import_func_inst) {
  2417. wasm_interp_call_func_import(module, exec_env, cur_func,
  2418. prev_frame);
  2419. }
  2420. else
  2421. #endif
  2422. {
  2423. wasm_interp_call_func_native(module, exec_env, cur_func,
  2424. prev_frame);
  2425. }
  2426. prev_frame = frame->prev_frame;
  2427. cur_func = frame->function;
  2428. UPDATE_ALL_FROM_FRAME();
  2429. memory = module->default_memory;
  2430. if (wasm_get_exception(module))
  2431. goto got_exception;
  2432. }
  2433. else {
  2434. WASMFunction *cur_wasm_func = cur_func->u.func;
  2435. all_cell_num = (uint64)cur_func->param_cell_num
  2436. + (uint64)cur_func->local_cell_num
  2437. + (uint64)cur_func->const_cell_num
  2438. + (uint64)cur_wasm_func->max_stack_cell_num;
  2439. if (all_cell_num >= UINT32_MAX) {
  2440. wasm_set_exception(module, "WASM interp failed: stack overflow.");
  2441. goto got_exception;
  2442. }
  2443. frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num);
  2444. if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) {
  2445. frame = prev_frame;
  2446. goto got_exception;
  2447. }
  2448. /* Initialize the interpreter context. */
  2449. frame->function = cur_func;
  2450. frame_ip = wasm_get_func_code(cur_func);
  2451. frame_ip_end = wasm_get_func_code_end(cur_func);
  2452. frame_lp = frame->lp = frame->operand + cur_wasm_func->const_cell_num;
  2453. /* Initialize the consts */
  2454. bh_memcpy_s(frame->operand, all_cell_num * 4,
  2455. cur_wasm_func->consts, cur_wasm_func->const_cell_num * 4);
  2456. /* Initialize the local varialbes */
  2457. memset(frame_lp + cur_func->param_cell_num, 0,
  2458. (uint32)(cur_func->local_cell_num * 4));
  2459. wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame*)frame);
  2460. }
  2461. HANDLE_OP_END ();
  2462. }
  2463. return_func:
  2464. {
  2465. FREE_FRAME(exec_env, frame);
  2466. wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame*)prev_frame);
  2467. if (!prev_frame->ip)
  2468. /* Called from native. */
  2469. return;
  2470. RECOVER_CONTEXT(prev_frame);
  2471. HANDLE_OP_END ();
  2472. }
  2473. (void)frame_ip_end;
  2474. out_of_bounds:
  2475. wasm_set_exception(module, "out of bounds memory access");
  2476. got_exception:
  2477. return;
  2478. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  2479. }
  2480. #else
  2481. FETCH_OPCODE_AND_DISPATCH ();
  2482. #endif
  2483. }
  2484. #if WASM_ENABLE_FAST_INTERP != 0
  2485. void **
  2486. wasm_interp_get_handle_table()
  2487. {
  2488. WASMModuleInstance module;
  2489. memset(&module, 0, sizeof(WASMModuleInstance));
  2490. wasm_interp_call_func_bytecode(&module, NULL, NULL, NULL);
  2491. return global_handle_table;
  2492. }
  2493. #endif
  2494. void
  2495. wasm_interp_call_wasm(WASMModuleInstance *module_inst,
  2496. WASMExecEnv *exec_env,
  2497. WASMFunctionInstance *function,
  2498. uint32 argc, uint32 argv[])
  2499. {
  2500. WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
  2501. WASMInterpFrame *frame, *outs_area;
  2502. /* Allocate sufficient cells for all kinds of return values. */
  2503. unsigned all_cell_num = function->ret_cell_num > 2 ?
  2504. function->ret_cell_num : 2, i;
  2505. /* This frame won't be used by JITed code, so only allocate interp
  2506. frame here. */
  2507. unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
  2508. if (argc != function->param_cell_num) {
  2509. char buf[128];
  2510. snprintf(buf, sizeof(buf),
  2511. "invalid argument count %d, expected %d",
  2512. argc, function->param_cell_num);
  2513. wasm_set_exception(module_inst, buf);
  2514. return;
  2515. }
  2516. if ((uint8*)&prev_frame < exec_env->native_stack_boundary) {
  2517. wasm_set_exception((WASMModuleInstance*)exec_env->module_inst,
  2518. "WASM interp failed: native stack overflow.");
  2519. return;
  2520. }
  2521. if (!(frame = ALLOC_FRAME(exec_env, frame_size, (WASMInterpFrame*)prev_frame)))
  2522. return;
  2523. outs_area = wasm_exec_env_wasm_stack_top(exec_env);
  2524. frame->function = NULL;
  2525. frame->ip = NULL;
  2526. /* There is no local variable. */
  2527. frame->lp = frame->operand + 0;
  2528. frame->ret_offset = 0;
  2529. if (argc > 0)
  2530. word_copy(outs_area->operand + function->const_cell_num, argv, argc);
  2531. wasm_exec_env_set_cur_frame(exec_env, frame);
  2532. if (function->is_import_func) {
  2533. #if WASM_ENABLE_MULTI_MODULE != 0
  2534. if (function->import_module_inst) {
  2535. LOG_DEBUG("it is a function of a sub module");
  2536. wasm_interp_call_func_import(module_inst,
  2537. exec_env,
  2538. function,
  2539. frame);
  2540. }
  2541. else
  2542. #endif
  2543. {
  2544. LOG_DEBUG("it is an native function");
  2545. wasm_interp_call_func_native(module_inst,
  2546. exec_env,
  2547. function,
  2548. frame);
  2549. }
  2550. }
  2551. else {
  2552. wasm_interp_call_func_bytecode(module_inst, exec_env, function, frame);
  2553. }
  2554. /* Output the return value to the caller */
  2555. if (!wasm_get_exception(module_inst)) {
  2556. for (i = 0; i < function->ret_cell_num; i++)
  2557. argv[i] = *(frame->lp + i);
  2558. }
  2559. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  2560. FREE_FRAME(exec_env, frame);
  2561. #if WASM_ENABLE_OPCODE_COUNTER != 0
  2562. wasm_interp_dump_op_count();
  2563. #endif
  2564. }