wasm_interp.c 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526
  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_memory.h"
  7. #include "bh_log.h"
  8. #include "wasm_runtime.h"
  9. #include "wasm_opcode.h"
  10. #include "wasm_loader.h"
  11. #include "../common/wasm_exec_env.h"
  12. typedef int32 CellType_I32;
  13. typedef int64 CellType_I64;
  14. typedef float32 CellType_F32;
  15. typedef float64 CellType_F64;
  16. #define BR_TABLE_TMP_BUF_LEN 32
  17. /* 64-bit Memory accessors. */
  18. #if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
  19. #define PUT_I64_TO_ADDR(addr, value) do { \
  20. *(int64*)(addr) = (int64)(value); \
  21. } while (0)
  22. #define PUT_F64_TO_ADDR(addr, value) do { \
  23. *(float64*)(addr) = (float64)(value); \
  24. } while (0)
  25. #define GET_I64_FROM_ADDR(addr) (*(int64*)(addr))
  26. #define GET_F64_FROM_ADDR(addr) (*(float64*)(addr))
  27. /* For STORE opcodes */
  28. #define STORE_I64 PUT_I64_TO_ADDR
  29. #define STORE_U32(addr, value) do { \
  30. *(uint32*)(addr) = (uint32)(value); \
  31. } while (0)
  32. #define STORE_U16(addr, value) do { \
  33. *(uint16*)(addr) = (uint16)(value); \
  34. } while (0)
  35. /* For LOAD opcodes */
  36. #define LOAD_I64(addr) (*(int64*)(addr))
  37. #define LOAD_F64(addr) (*(float64*)(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. #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
  204. #define CHECK_MEMORY_OVERFLOW() do { \
  205. uint32 offset1 = offset + addr; \
  206. /* if (flags != 2) \
  207. LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\
  208. /* The WASM spec doesn't require that the dynamic address operand must be \
  209. unsigned, so we don't check whether integer overflow or not here. */ \
  210. /* if (offset1 < offset) \
  211. goto out_of_bounds; */ \
  212. if (offset1 < memory_data_size) { \
  213. /* If offset1 is in valid range, maddr must also be in valid range, \
  214. no need to check it again. */ \
  215. maddr = memory->memory_data + offset1; \
  216. if (maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] > memory->end_addr) \
  217. goto out_of_bounds; \
  218. } \
  219. else if (offset1 > heap_base_offset \
  220. && offset1 < heap_base_offset + heap_data_size) { \
  221. /* If offset1 is in valid range, maddr must also be in valid range, \
  222. no need to check it again. */ \
  223. maddr = memory->heap_data + offset1 - memory->heap_base_offset; \
  224. if (maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] > memory->heap_data_end) \
  225. goto out_of_bounds; \
  226. } \
  227. else \
  228. goto out_of_bounds; \
  229. } while (0)
  230. static inline uint32
  231. rotl32(uint32 n, uint32 c)
  232. {
  233. const uint32 mask = (31);
  234. c = c % 32;
  235. c &= mask;
  236. return (n<<c) | (n>>( (-c)&mask ));
  237. }
  238. static inline uint32
  239. rotr32(uint32 n, uint32 c)
  240. {
  241. const uint32 mask = (31);
  242. c = c % 32;
  243. c &= mask;
  244. return (n>>c) | (n<<( (-c)&mask ));
  245. }
  246. static inline uint64
  247. rotl64(uint64 n, uint64 c)
  248. {
  249. const uint64 mask = (63);
  250. c = c % 64;
  251. c &= mask;
  252. return (n<<c) | (n>>( (-c)&mask ));
  253. }
  254. static inline uint64
  255. rotr64(uint64 n, uint64 c)
  256. {
  257. const uint64 mask = (63);
  258. c = c % 64;
  259. c &= mask;
  260. return (n>>c) | (n<<( (-c)&mask ));
  261. }
  262. static inline double
  263. wa_fmax(double a, double b)
  264. {
  265. double c = fmax(a, b);
  266. if (c==0 && a==b)
  267. return signbit(a) ? b : a;
  268. return c;
  269. }
  270. static inline double
  271. wa_fmin(double a, double b)
  272. {
  273. double c = fmin(a, b);
  274. if (c==0 && a==b)
  275. return signbit(a) ? a : b;
  276. return c;
  277. }
  278. static inline uint32
  279. clz32(uint32 type)
  280. {
  281. uint32 num = 0;
  282. if (type == 0)
  283. return 32;
  284. while (!(type & 0x80000000)) {
  285. num++;
  286. type <<= 1;
  287. }
  288. return num;
  289. }
  290. static inline uint32
  291. clz64(uint64 type)
  292. {
  293. uint32 num = 0;
  294. if (type == 0)
  295. return 64;
  296. while (!(type & 0x8000000000000000LL)) {
  297. num++;
  298. type <<= 1;
  299. }
  300. return num;
  301. }
  302. static inline uint32
  303. ctz32(uint32 type)
  304. {
  305. uint32 num = 0;
  306. if (type == 0)
  307. return 32;
  308. while (!(type & 1)) {
  309. num++;
  310. type >>= 1;
  311. }
  312. return num;
  313. }
  314. static inline uint32
  315. ctz64(uint64 type)
  316. {
  317. uint32 num = 0;
  318. if (type == 0)
  319. return 64;
  320. while (!(type & 1)) {
  321. num++;
  322. type >>= 1;
  323. }
  324. return num;
  325. }
  326. static inline uint32
  327. popcount32(uint32 u)
  328. {
  329. uint32 ret = 0;
  330. while (u) {
  331. u = (u & (u - 1));
  332. ret++;
  333. }
  334. return ret;
  335. }
  336. static inline uint32
  337. popcount64(uint64 u)
  338. {
  339. uint32 ret = 0;
  340. while (u) {
  341. u = (u & (u - 1));
  342. ret++;
  343. }
  344. return ret;
  345. }
  346. static uint64
  347. read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
  348. {
  349. uint64 result = 0;
  350. uint32 shift = 0;
  351. uint32 bcnt = 0;
  352. uint64 byte;
  353. while (true) {
  354. byte = buf[*p_offset];
  355. *p_offset += 1;
  356. result |= ((byte & 0x7f) << shift);
  357. shift += 7;
  358. if ((byte & 0x80) == 0) {
  359. break;
  360. }
  361. bcnt += 1;
  362. }
  363. if (sign && (shift < maxbits) && (byte & 0x40)) {
  364. /* Sign extend */
  365. result |= - ((uint64)1 << shift);
  366. }
  367. return result;
  368. }
  369. #define PUSH_I32(value) do { \
  370. *(int32*)frame_sp++ = (int32)(value); \
  371. } while (0)
  372. #define PUSH_F32(value) do { \
  373. *(float32*)frame_sp++ = (float32)(value); \
  374. } while (0)
  375. #define PUSH_I64(value) do { \
  376. PUT_I64_TO_ADDR(frame_sp, value); \
  377. frame_sp += 2; \
  378. } while (0)
  379. #define PUSH_F64(value) do { \
  380. PUT_F64_TO_ADDR(frame_sp, value); \
  381. frame_sp += 2; \
  382. } while (0)
  383. #define PUSH_CSP(type, ret_type, start, else_, end) do {\
  384. bh_assert(frame_csp < frame->csp_boundary); \
  385. frame_csp->block_type = type; \
  386. frame_csp->return_type = ret_type; \
  387. frame_csp->start_addr = start; \
  388. frame_csp->end_addr = end; \
  389. frame_csp->frame_sp = frame_sp; \
  390. frame_csp++; \
  391. } while (0)
  392. #define POP_I32() (--frame_sp, *(int32*)frame_sp)
  393. #define POP_F32() (--frame_sp, *(float32*)frame_sp)
  394. #define POP_I64() (frame_sp -= 2, GET_I64_FROM_ADDR(frame_sp))
  395. #define POP_F64() (frame_sp -= 2, GET_F64_FROM_ADDR(frame_sp))
  396. #define POP_CSP_CHECK_OVERFLOW(n) do { \
  397. bh_assert(frame_csp - n >= frame->csp_bottom); \
  398. } while (0)
  399. #define POP_CSP() do { \
  400. POP_CSP_CHECK_OVERFLOW(1); \
  401. --frame_csp; \
  402. } while (0)
  403. #define POP_CSP_N(n) do { \
  404. uint32 *frame_sp_old = frame_sp; \
  405. POP_CSP_CHECK_OVERFLOW(n + 1); \
  406. frame_csp -= n; \
  407. if ((frame_csp - 1)->block_type != BLOCK_TYPE_LOOP) \
  408. /* block block/if/function, jump to end of block */ \
  409. frame_ip = (frame_csp - 1)->end_addr; \
  410. else /* loop block, jump to start of block */ \
  411. frame_ip = (frame_csp - 1)->start_addr; \
  412. /* copy return value of block */ \
  413. frame_sp = (frame_csp - 1)->frame_sp; \
  414. switch ((frame_csp - 1)->return_type) { \
  415. case VALUE_TYPE_I32: \
  416. PUSH_I32(*(frame_sp_old - 1)); \
  417. break; \
  418. case VALUE_TYPE_I64: \
  419. PUSH_I64(GET_I64_FROM_ADDR(frame_sp_old - 2)); \
  420. break; \
  421. case VALUE_TYPE_F32: \
  422. PUSH_F32(*(float32*)(frame_sp_old - 1)); \
  423. break; \
  424. case VALUE_TYPE_F64: \
  425. PUSH_F64(GET_F64_FROM_ADDR(frame_sp_old - 2)); \
  426. break; \
  427. } \
  428. } while (0)
  429. /* Pop the given number of elements from the given frame's stack. */
  430. #define POP(N) do { \
  431. int n = (N); \
  432. frame_sp -= n; \
  433. } while (0)
  434. #define SYNC_ALL_TO_FRAME() do { \
  435. frame->sp = frame_sp; \
  436. frame->ip = frame_ip; \
  437. frame->csp = frame_csp; \
  438. } while (0)
  439. #define UPDATE_ALL_FROM_FRAME() do { \
  440. frame_sp = frame->sp; \
  441. frame_ip = frame->ip; \
  442. frame_csp = frame->csp; \
  443. } while (0)
  444. #define read_leb_int64(p, p_end, res) do { \
  445. uint8 _val = *p; \
  446. if (!(_val & 0x80)) { \
  447. res = (int64)_val; \
  448. if (_val & 0x40) \
  449. /* sign extend */ \
  450. res |= 0xFFFFFFFFFFFFFF80LL; \
  451. p++; \
  452. break; \
  453. } \
  454. uint32 _off = 0; \
  455. res = (int64)read_leb(p, &_off, 64, true); \
  456. p += _off; \
  457. } while (0)
  458. #define read_leb_uint32(p, p_end, res) do { \
  459. uint8 _val = *p; \
  460. if (!(_val & 0x80)) { \
  461. res = _val; \
  462. p++; \
  463. break; \
  464. } \
  465. uint32 _off = 0; \
  466. res = (uint32)read_leb(p, &_off, 32, false); \
  467. p += _off; \
  468. } while (0)
  469. #define read_leb_int32(p, p_end, res) do { \
  470. uint8 _val = *p; \
  471. if (!(_val & 0x80)) { \
  472. res = (int32)_val; \
  473. if (_val & 0x40) \
  474. /* sign extend */ \
  475. res |= 0xFFFFFF80; \
  476. p++; \
  477. break; \
  478. } \
  479. uint32 _off = 0; \
  480. res = (int32)read_leb(p, &_off, 32, true); \
  481. p += _off; \
  482. } while (0)
  483. #define RECOVER_CONTEXT(new_frame) do { \
  484. frame = (new_frame); \
  485. cur_func = frame->function; \
  486. prev_frame = frame->prev_frame; \
  487. frame_ip = frame->ip; \
  488. frame_ip_end = wasm_get_func_code_end(cur_func); \
  489. frame_lp = frame->lp; \
  490. frame_sp = frame->sp; \
  491. frame_csp = frame->csp; \
  492. } while (0)
  493. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  494. #define GET_OPCODE() opcode = *(frame_ip - 1);
  495. #else
  496. #define GET_OPCODE() (void)0
  497. #endif
  498. #define DEF_OP_I_CONST(ctype, src_op_type) do { \
  499. ctype cval; \
  500. read_leb_##ctype(frame_ip, frame_ip_end, cval); \
  501. PUSH_##src_op_type(cval); \
  502. } while (0)
  503. #define DEF_OP_EQZ(src_op_type) do { \
  504. int32 val; \
  505. val = POP_##src_op_type() == 0; \
  506. PUSH_I32(val); \
  507. } while (0)
  508. #define DEF_OP_CMP(src_type, src_op_type, cond) do { \
  509. uint32 res; \
  510. src_type val1, val2; \
  511. val2 = (src_type)POP_##src_op_type(); \
  512. val1 = (src_type)POP_##src_op_type(); \
  513. res = val1 cond val2; \
  514. PUSH_I32(res); \
  515. } while (0)
  516. #define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
  517. src_type val1, val2; \
  518. val1 = (src_type)POP_##src_op_type(); \
  519. val2 = (src_type)operation(val1); \
  520. PUSH_##src_op_type(val2); \
  521. } while (0)
  522. #define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) do { \
  523. frame_sp -= sizeof(src_type2)/sizeof(uint32); \
  524. *(src_type1*)(frame_sp - sizeof(src_type1)/sizeof(uint32)) operation##= \
  525. *(src_type2*)(frame_sp); \
  526. } while (0)
  527. #if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
  528. #define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC
  529. #else
  530. #define DEF_OP_NUMERIC_64(src_type1, src_type2, src_op_type, operation) do {\
  531. src_type1 val1; \
  532. src_type2 val2; \
  533. frame_sp -= 2; \
  534. val1 = (src_type1)GET_##src_op_type##_FROM_ADDR(frame_sp - 2); \
  535. val2 = (src_type2)GET_##src_op_type##_FROM_ADDR(frame_sp); \
  536. val1 operation##= val2; \
  537. PUT_##src_op_type##_TO_ADDR(frame_sp - 2, val1); \
  538. } while (0)
  539. #endif
  540. #define DEF_OP_NUMERIC2(src_type1, src_type2, src_op_type, operation) do { \
  541. frame_sp -= sizeof(src_type2)/sizeof(uint32); \
  542. *(src_type1*)(frame_sp - sizeof(src_type1)/sizeof(uint32)) operation##= \
  543. (*(src_type2*)(frame_sp) % 32); \
  544. } while (0)
  545. #define DEF_OP_NUMERIC2_64(src_type1, src_type2, src_op_type, operation) do { \
  546. src_type1 val1; \
  547. src_type2 val2; \
  548. frame_sp -= 2; \
  549. val1 = (src_type1)GET_##src_op_type##_FROM_ADDR(frame_sp - 2); \
  550. val2 = (src_type2)GET_##src_op_type##_FROM_ADDR(frame_sp); \
  551. val1 operation##= (val2 % 64); \
  552. PUT_##src_op_type##_TO_ADDR(frame_sp - 2, val1); \
  553. } while (0)
  554. #define DEF_OP_MATH(src_type, src_op_type, method) do { \
  555. src_type val; \
  556. val = POP_##src_op_type(); \
  557. PUSH_##src_op_type(method(val)); \
  558. } while (0)
  559. #define DEF_OP_TRUNC(dst_type, dst_op_type, src_type, src_op_type, \
  560. min_cond, max_cond) do { \
  561. src_type value = POP_##src_op_type(); \
  562. if (isnan(value)) { \
  563. wasm_set_exception(module, "invalid conversion to integer"); \
  564. goto got_exception; \
  565. } \
  566. else if (value min_cond || value max_cond) { \
  567. wasm_set_exception(module, "integer overflow"); \
  568. goto got_exception; \
  569. } \
  570. PUSH_##dst_op_type(((dst_type)value)); \
  571. } while (0)
  572. #define DEF_OP_CONVERT(dst_type, dst_op_type, \
  573. src_type, src_op_type) do { \
  574. dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
  575. PUSH_##dst_op_type(value); \
  576. } while (0)
  577. #define GET_LOCAL_INDEX_TYPE_AND_OFFSET() do { \
  578. uint32 param_count = cur_func->param_count; \
  579. read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
  580. bh_assert(local_idx < param_count + cur_func->local_count); \
  581. local_offset = cur_func->local_offsets[local_idx]; \
  582. if (local_idx < param_count) \
  583. local_type = cur_func->param_types[local_idx]; \
  584. else \
  585. local_type = cur_func->local_types[local_idx - param_count]; \
  586. } while (0)
  587. static inline int32
  588. sign_ext_8_32(int8 val)
  589. {
  590. if (val & 0x80)
  591. return (int32)val | (int32)0xffffff00;
  592. return val;
  593. }
  594. static inline int32
  595. sign_ext_16_32(int16 val)
  596. {
  597. if (val & 0x8000)
  598. return (int32)val | (int32)0xffff0000;
  599. return val;
  600. }
  601. static inline int64
  602. sign_ext_8_64(int8 val)
  603. {
  604. if (val & 0x80)
  605. return (int64)val | (int64)0xffffffffffffff00;
  606. return val;
  607. }
  608. static inline int64
  609. sign_ext_16_64(int16 val)
  610. {
  611. if (val & 0x8000)
  612. return (int64)val | (int64)0xffffffffffff0000;
  613. return val;
  614. }
  615. static inline int64
  616. sign_ext_32_64(int32 val)
  617. {
  618. if (val & (int32)0x80000000)
  619. return (int64)val | (int64)0xffffffff00000000;
  620. return val;
  621. }
  622. static inline void
  623. word_copy(uint32 *dest, uint32 *src, unsigned num)
  624. {
  625. for (; num > 0; num--)
  626. *dest++ = *src++;
  627. }
  628. static inline WASMInterpFrame*
  629. ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
  630. {
  631. WASMInterpFrame *frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
  632. if (frame)
  633. frame->prev_frame = prev_frame;
  634. else {
  635. wasm_set_exception((WASMModuleInstance*)exec_env->module_inst,
  636. "WASM interp failed: stack overflow.");
  637. }
  638. return frame;
  639. }
  640. static inline void
  641. FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *frame)
  642. {
  643. wasm_exec_env_free_wasm_frame(exec_env, frame);
  644. }
  645. static void
  646. wasm_interp_call_func_native(WASMModuleInstance *module_inst,
  647. WASMExecEnv *exec_env,
  648. WASMFunctionInstance *cur_func,
  649. WASMInterpFrame *prev_frame)
  650. {
  651. unsigned local_cell_num = 2;
  652. WASMInterpFrame *frame;
  653. uint32 argv_ret[2];
  654. bool ret;
  655. if (!(frame = ALLOC_FRAME(exec_env,
  656. wasm_interp_interp_frame_size(local_cell_num),
  657. prev_frame)))
  658. return;
  659. frame->function = cur_func;
  660. frame->ip = NULL;
  661. frame->sp = frame->lp + local_cell_num;
  662. wasm_exec_env_set_cur_frame(exec_env, frame);
  663. if (!cur_func->u.func_import->func_ptr_linked) {
  664. char buf[128];
  665. snprintf(buf,
  666. sizeof(buf), "fail to call unlinked import function (%s, %s)",
  667. cur_func->u.func_import->module_name,
  668. cur_func->u.func_import->field_name);
  669. wasm_set_exception((WASMModuleInstance*)module_inst, buf);
  670. return;
  671. }
  672. ret = wasm_runtime_invoke_native(cur_func->u.func_import->func_ptr_linked,
  673. cur_func->u.func_import->func_type,
  674. exec_env,
  675. frame->lp, cur_func->param_cell_num, argv_ret);
  676. if (!ret)
  677. return;
  678. if (cur_func->ret_cell_num == 1) {
  679. prev_frame->sp[0] = argv_ret[0];
  680. prev_frame->sp++;
  681. }
  682. else if (cur_func->ret_cell_num == 2) {
  683. prev_frame->sp[0] = argv_ret[0];
  684. prev_frame->sp[1] = argv_ret[1];
  685. prev_frame->sp += 2;
  686. }
  687. FREE_FRAME(exec_env, frame);
  688. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  689. }
  690. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  691. #define HANDLE_OP(opcode) HANDLE_##opcode
  692. #define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]
  693. #define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
  694. #else /* else of WASM_ENABLE_LABELS_AS_VALUES */
  695. #define HANDLE_OP(opcode) case opcode
  696. #define HANDLE_OP_END() continue
  697. #endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
  698. typedef struct BlockAddrCache {
  699. uint8 *frame_ip;
  700. uint8 *else_addr;
  701. uint8 *end_addr;
  702. } BlockAddrCache;
  703. static void
  704. wasm_interp_call_func_bytecode(WASMModuleInstance *module,
  705. WASMExecEnv *exec_env,
  706. WASMFunctionInstance *cur_func,
  707. WASMInterpFrame *prev_frame)
  708. {
  709. WASMMemoryInstance *memory = module->default_memory;
  710. uint32 memory_data_size = memory
  711. ? memory->num_bytes_per_page * memory->cur_page_count : 0;
  712. uint32 heap_base_offset = memory ? (uint32)memory->heap_base_offset : 0;
  713. uint32 heap_data_size = memory
  714. ? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
  715. WASMTableInstance *table = module->default_table;
  716. WASMGlobalInstance *globals = module->globals;
  717. uint8 *global_data = memory ? memory->global_data : NULL;
  718. uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2;
  719. WASMInterpFrame *frame = NULL;
  720. /* Points to this special opcode so as to jump to the
  721. call_method_from_entry. */
  722. register uint8 *frame_ip = &opcode_IMPDEP2; /* cache of frame->ip */
  723. register uint32 *frame_lp = NULL; /* cache of frame->lp */
  724. register uint32 *frame_sp = NULL; /* cache of frame->sp */
  725. WASMBranchBlock *frame_csp = NULL;
  726. WASMGlobalInstance *global;
  727. uint8 *frame_ip_end = frame_ip + 1, *frame_ip_org;
  728. uint8 opcode, block_ret_type;
  729. uint32 *depths = NULL;
  730. uint32 depth_buf[BR_TABLE_TMP_BUF_LEN];
  731. uint32 i, depth, cond, count, fidx, tidx, frame_size = 0;
  732. uint64 all_cell_num = 0;
  733. int32 didx, val;
  734. uint8 *else_addr, *end_addr, *maddr = NULL;
  735. uint32 local_idx, local_offset, global_idx, global_data_offset;
  736. uint8 local_type, *global_addr;
  737. BlockAddrCache block_addr_cache[32] = { 0 };
  738. uint32 cache_index, block_addr_cache_size = 32;
  739. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  740. #define HANDLE_OPCODE(op) &&HANDLE_##op
  741. DEFINE_GOTO_TABLE (handle_table);
  742. #undef HANDLE_OPCODE
  743. #endif
  744. /* Size of memory load.
  745. This starts with the first memory load operator at opcode 0x28 */
  746. uint32 LOAD_SIZE[] = {
  747. 4, 8, 4, 8, 1, 1, 2, 2, 1, 1, 2, 2, 4, 4, /* loads */
  748. 4, 8, 4, 8, 1, 2, 1, 2, 4 }; /* stores */
  749. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  750. while (frame_ip < frame_ip_end) {
  751. opcode = *frame_ip++;
  752. switch (opcode) {
  753. #else
  754. FETCH_OPCODE_AND_DISPATCH ();
  755. #endif
  756. /* control instructions */
  757. HANDLE_OP (WASM_OP_UNREACHABLE):
  758. wasm_set_exception(module, "unreachable");
  759. goto got_exception;
  760. HANDLE_OP (WASM_OP_NOP):
  761. HANDLE_OP_END ();
  762. HANDLE_OP (WASM_OP_BLOCK):
  763. block_ret_type = *frame_ip++;
  764. cache_index = ((uintptr_t)frame_ip) % block_addr_cache_size;
  765. if (block_addr_cache[cache_index].frame_ip == frame_ip) {
  766. end_addr = block_addr_cache[cache_index].end_addr;
  767. }
  768. else {
  769. if (!wasm_loader_find_block_addr(module->module,
  770. frame_ip, frame_ip_end,
  771. BLOCK_TYPE_BLOCK,
  772. &else_addr, &end_addr,
  773. NULL, 0)) {
  774. wasm_set_exception(module, "find block address failed");
  775. goto got_exception;
  776. }
  777. block_addr_cache[cache_index].frame_ip = frame_ip;
  778. block_addr_cache[cache_index].end_addr = end_addr;
  779. }
  780. PUSH_CSP(BLOCK_TYPE_BLOCK, block_ret_type, frame_ip, NULL, end_addr);
  781. HANDLE_OP_END ();
  782. HANDLE_OP (WASM_OP_LOOP):
  783. block_ret_type = *frame_ip++;
  784. cache_index = ((uintptr_t)frame_ip) % block_addr_cache_size;
  785. if (block_addr_cache[cache_index].frame_ip == frame_ip) {
  786. end_addr = block_addr_cache[cache_index].end_addr;
  787. }
  788. else {
  789. if (!wasm_loader_find_block_addr(module->module,
  790. frame_ip, frame_ip_end,
  791. BLOCK_TYPE_LOOP,
  792. &else_addr, &end_addr,
  793. NULL, 0)) {
  794. wasm_set_exception(module, "find block address failed");
  795. goto got_exception;
  796. }
  797. block_addr_cache[cache_index].frame_ip = frame_ip;
  798. block_addr_cache[cache_index].end_addr = end_addr;
  799. }
  800. PUSH_CSP(BLOCK_TYPE_LOOP, block_ret_type, frame_ip, NULL, end_addr);
  801. HANDLE_OP_END ();
  802. HANDLE_OP (WASM_OP_IF):
  803. block_ret_type = *frame_ip++;
  804. cache_index = ((uintptr_t)frame_ip) % block_addr_cache_size;
  805. if (block_addr_cache[cache_index].frame_ip == frame_ip) {
  806. else_addr = block_addr_cache[cache_index].else_addr;
  807. end_addr = block_addr_cache[cache_index].end_addr;
  808. }
  809. else {
  810. if (!wasm_loader_find_block_addr(module->module,
  811. frame_ip, frame_ip_end,
  812. BLOCK_TYPE_IF,
  813. &else_addr, &end_addr,
  814. NULL, 0)) {
  815. wasm_set_exception(module, "find block address failed");
  816. goto got_exception;
  817. }
  818. block_addr_cache[cache_index].frame_ip = frame_ip;
  819. block_addr_cache[cache_index].else_addr = else_addr;
  820. block_addr_cache[cache_index].end_addr = end_addr;
  821. }
  822. cond = (uint32)POP_I32();
  823. PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, frame_ip, else_addr, end_addr);
  824. /* condition of the if branch is false, else condition is met */
  825. if (cond == 0) {
  826. /* if there is no else branch, go to the end addr */
  827. if (else_addr == NULL) {
  828. POP_CSP();
  829. frame_ip = end_addr + 1;
  830. }
  831. /* if there is an else branch, go to the else addr */
  832. else
  833. frame_ip = else_addr + 1;
  834. }
  835. HANDLE_OP_END ();
  836. HANDLE_OP (WASM_OP_ELSE):
  837. /* comes from the if branch in WASM_OP_IF */
  838. frame_ip = (frame_csp - 1)->end_addr;
  839. HANDLE_OP_END ();
  840. HANDLE_OP (WASM_OP_END):
  841. if (frame_csp > frame->csp_bottom + 1) {
  842. POP_CSP();
  843. }
  844. else { /* end of function, treat as WASM_OP_RETURN */
  845. frame_sp -= cur_func->ret_cell_num;
  846. for (i = 0; i < cur_func->ret_cell_num; i++) {
  847. *prev_frame->sp++ = frame_sp[i];
  848. }
  849. goto return_func;
  850. }
  851. HANDLE_OP_END ();
  852. HANDLE_OP (WASM_OP_BR):
  853. read_leb_uint32(frame_ip, frame_ip_end, depth);
  854. POP_CSP_N(depth);
  855. HANDLE_OP_END ();
  856. HANDLE_OP (WASM_OP_BR_IF):
  857. read_leb_uint32(frame_ip, frame_ip_end, depth);
  858. cond = (uint32)POP_I32();
  859. if (cond)
  860. POP_CSP_N(depth);
  861. HANDLE_OP_END ();
  862. HANDLE_OP (WASM_OP_BR_TABLE):
  863. read_leb_uint32(frame_ip, frame_ip_end, count);
  864. if (count <= BR_TABLE_TMP_BUF_LEN)
  865. depths = depth_buf;
  866. else {
  867. uint64 total_size = sizeof(uint32) * (uint64)count;
  868. if (total_size >= UINT32_MAX
  869. || !(depths = wasm_malloc((uint32)total_size))) {
  870. wasm_set_exception(module,
  871. "WASM interp failed: allocate memory failed.");
  872. goto got_exception;
  873. }
  874. }
  875. for (i = 0; i < count; i++) {
  876. read_leb_uint32(frame_ip, frame_ip_end, depths[i]);
  877. }
  878. read_leb_uint32(frame_ip, frame_ip_end, depth);
  879. didx = POP_I32();
  880. if (didx >= 0 && (uint32)didx < count) {
  881. depth = depths[didx];
  882. }
  883. if (depths != depth_buf) {
  884. wasm_free(depths);
  885. depths = NULL;
  886. }
  887. POP_CSP_N(depth);
  888. HANDLE_OP_END ();
  889. HANDLE_OP (WASM_OP_RETURN):
  890. frame_sp -= cur_func->ret_cell_num;
  891. for (i = 0; i < cur_func->ret_cell_num; i++) {
  892. *prev_frame->sp++ = frame_sp[i];
  893. }
  894. goto return_func;
  895. HANDLE_OP (WASM_OP_CALL):
  896. read_leb_uint32(frame_ip, frame_ip_end, fidx);
  897. bh_assert(fidx < module->function_count);
  898. cur_func = module->functions + fidx;
  899. goto call_func_from_interp;
  900. HANDLE_OP (WASM_OP_CALL_INDIRECT):
  901. {
  902. WASMType *cur_type, *cur_func_type;
  903. read_leb_uint32(frame_ip, frame_ip_end, tidx);
  904. if (tidx >= module->module->type_count) {
  905. wasm_set_exception(module, "type index is overflow");
  906. goto got_exception;
  907. }
  908. cur_type = module->module->types[tidx];
  909. /* to skip 0x00 here */
  910. frame_ip++;
  911. val = POP_I32();
  912. if (val < 0 || val >= (int32)table->cur_size) {
  913. wasm_set_exception(module, "undefined element");
  914. goto got_exception;
  915. }
  916. fidx = ((uint32*)table->base_addr)[val];
  917. if (fidx == (uint32)-1) {
  918. wasm_set_exception(module, "uninitialized element");
  919. goto got_exception;
  920. }
  921. cur_func = module->functions + fidx;
  922. if (cur_func->is_import_func)
  923. cur_func_type = cur_func->u.func_import->func_type;
  924. else
  925. cur_func_type = cur_func->u.func->func_type;
  926. if (!wasm_type_equal(cur_type, cur_func_type)) {
  927. wasm_set_exception(module, "indirect call type mismatch");
  928. goto got_exception;
  929. }
  930. goto call_func_from_interp;
  931. }
  932. /* parametric instructions */
  933. HANDLE_OP (WASM_OP_DROP):
  934. {
  935. wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
  936. goto got_exception;
  937. }
  938. HANDLE_OP (WASM_OP_DROP_32):
  939. {
  940. frame_sp--;
  941. HANDLE_OP_END ();
  942. }
  943. HANDLE_OP (WASM_OP_DROP_64):
  944. {
  945. frame_sp -= 2;
  946. HANDLE_OP_END ();
  947. }
  948. HANDLE_OP (WASM_OP_SELECT):
  949. {
  950. wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
  951. goto got_exception;
  952. }
  953. HANDLE_OP (WASM_OP_SELECT_32):
  954. {
  955. cond = (uint32)POP_I32();
  956. frame_sp--;
  957. if (!cond)
  958. *(frame_sp - 1) = *frame_sp;
  959. HANDLE_OP_END ();
  960. }
  961. HANDLE_OP (WASM_OP_SELECT_64):
  962. {
  963. cond = (uint32)POP_I32();
  964. frame_sp -= 2;
  965. if (!cond) {
  966. *(frame_sp - 2) = *frame_sp;
  967. *(frame_sp - 1) = *(frame_sp + 1);
  968. }
  969. HANDLE_OP_END ();
  970. }
  971. /* variable instructions */
  972. HANDLE_OP (WASM_OP_GET_LOCAL):
  973. {
  974. frame_ip_org = frame_ip - 1;
  975. GET_LOCAL_INDEX_TYPE_AND_OFFSET();
  976. switch (local_type) {
  977. case VALUE_TYPE_I32:
  978. case VALUE_TYPE_F32:
  979. PUSH_I32(*(int32*)(frame_lp + local_offset));
  980. break;
  981. case VALUE_TYPE_I64:
  982. case VALUE_TYPE_F64:
  983. PUSH_I64(GET_I64_FROM_ADDR(frame_lp + local_offset));
  984. break;
  985. default:
  986. wasm_set_exception(module, "invalid local type");
  987. goto got_exception;
  988. }
  989. if (local_offset < 0x80) {
  990. *frame_ip_org++ = WASM_OP_GET_LOCAL_FAST;
  991. if (local_type == VALUE_TYPE_I32
  992. || local_type == VALUE_TYPE_F32)
  993. *frame_ip_org++ = (uint8)local_offset;
  994. else
  995. *frame_ip_org++ = (uint8)(local_offset | 0x80);
  996. while (frame_ip_org < frame_ip)
  997. *frame_ip_org++ = WASM_OP_NOP;
  998. }
  999. HANDLE_OP_END ();
  1000. }
  1001. HANDLE_OP (WASM_OP_GET_LOCAL_FAST):
  1002. {
  1003. local_offset = *frame_ip++;
  1004. if (local_offset & 0x80)
  1005. PUSH_I64(GET_I64_FROM_ADDR(frame_lp + (local_offset & 0x7F)));
  1006. else
  1007. PUSH_I32(*(int32*)(frame_lp + local_offset));
  1008. HANDLE_OP_END ();
  1009. }
  1010. HANDLE_OP (WASM_OP_SET_LOCAL):
  1011. {
  1012. frame_ip_org = frame_ip - 1;
  1013. GET_LOCAL_INDEX_TYPE_AND_OFFSET();
  1014. switch (local_type) {
  1015. case VALUE_TYPE_I32:
  1016. case VALUE_TYPE_F32:
  1017. *(int32*)(frame_lp + local_offset) = POP_I32();
  1018. break;
  1019. case VALUE_TYPE_I64:
  1020. case VALUE_TYPE_F64:
  1021. PUT_I64_TO_ADDR((uint32*)(frame_lp + local_offset), POP_I64());
  1022. break;
  1023. default:
  1024. wasm_set_exception(module, "invalid local type");
  1025. goto got_exception;
  1026. }
  1027. if (local_offset < 0x80) {
  1028. *frame_ip_org++ = WASM_OP_SET_LOCAL_FAST;
  1029. if (local_type == VALUE_TYPE_I32
  1030. || local_type == VALUE_TYPE_F32)
  1031. *frame_ip_org++ = (uint8)local_offset;
  1032. else
  1033. *frame_ip_org++ = (uint8)(local_offset | 0x80);
  1034. while (frame_ip_org < frame_ip)
  1035. *frame_ip_org++ = WASM_OP_NOP;
  1036. }
  1037. HANDLE_OP_END ();
  1038. }
  1039. HANDLE_OP (WASM_OP_SET_LOCAL_FAST):
  1040. {
  1041. local_offset = *frame_ip++;
  1042. if (local_offset & 0x80)
  1043. PUT_I64_TO_ADDR((uint32*)(frame_lp + (local_offset & 0x7F)), POP_I64());
  1044. else
  1045. *(int32*)(frame_lp + local_offset) = POP_I32();
  1046. HANDLE_OP_END ();
  1047. }
  1048. HANDLE_OP (WASM_OP_TEE_LOCAL):
  1049. {
  1050. frame_ip_org = frame_ip - 1;
  1051. GET_LOCAL_INDEX_TYPE_AND_OFFSET();
  1052. switch (local_type) {
  1053. case VALUE_TYPE_I32:
  1054. case VALUE_TYPE_F32:
  1055. *(int32*)(frame_lp + local_offset) = *(int32*)(frame_sp - 1);
  1056. break;
  1057. case VALUE_TYPE_I64:
  1058. case VALUE_TYPE_F64:
  1059. PUT_I64_TO_ADDR((uint32*)(frame_lp + local_offset),
  1060. GET_I64_FROM_ADDR(frame_sp - 2));
  1061. break;
  1062. default:
  1063. wasm_set_exception(module, "invalid local type");
  1064. goto got_exception;
  1065. }
  1066. if (local_offset < 0x80) {
  1067. *frame_ip_org++ = WASM_OP_TEE_LOCAL_FAST;
  1068. if (local_type == VALUE_TYPE_I32
  1069. || local_type == VALUE_TYPE_F32)
  1070. *frame_ip_org++ = (uint8)local_offset;
  1071. else
  1072. *frame_ip_org++ = (uint8)(local_offset | 0x80);
  1073. while (frame_ip_org < frame_ip)
  1074. *frame_ip_org++ = WASM_OP_NOP;
  1075. }
  1076. HANDLE_OP_END ();
  1077. }
  1078. HANDLE_OP (WASM_OP_TEE_LOCAL_FAST):
  1079. {
  1080. local_offset = *frame_ip++;
  1081. if (local_offset & 0x80)
  1082. PUT_I64_TO_ADDR((uint32*)(frame_lp + (local_offset & 0x7F)),
  1083. GET_I64_FROM_ADDR(frame_sp - 2));
  1084. else
  1085. *(int32*)(frame_lp + local_offset) = *(int32*)(frame_sp - 1);
  1086. HANDLE_OP_END ();
  1087. }
  1088. HANDLE_OP (WASM_OP_GET_GLOBAL):
  1089. {
  1090. frame_ip_org = frame_ip - 1;
  1091. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  1092. bh_assert(global_idx < module->global_count);
  1093. global = globals + global_idx;
  1094. global_addr = global_data + global->data_offset;
  1095. switch (global->type) {
  1096. case VALUE_TYPE_I32:
  1097. case VALUE_TYPE_F32:
  1098. PUSH_I32(*(uint32*)global_addr);
  1099. break;
  1100. case VALUE_TYPE_I64:
  1101. case VALUE_TYPE_F64:
  1102. PUSH_I64(GET_I64_FROM_ADDR((uint32*)global_addr));
  1103. break;
  1104. default:
  1105. wasm_set_exception(module, "invalid global type");
  1106. goto got_exception;
  1107. }
  1108. if (global->data_offset < 0x80) {
  1109. *frame_ip_org++ = WASM_OP_GET_GLOBAL_FAST;
  1110. if (global->type == VALUE_TYPE_I32
  1111. || global->type == VALUE_TYPE_F32)
  1112. *frame_ip_org++ = (uint8)global->data_offset;
  1113. else
  1114. *frame_ip_org++ = (uint8)(global->data_offset | 0x80);
  1115. while (frame_ip_org < frame_ip)
  1116. *frame_ip_org++ = WASM_OP_NOP;
  1117. }
  1118. HANDLE_OP_END ();
  1119. }
  1120. HANDLE_OP (WASM_OP_GET_GLOBAL_FAST):
  1121. {
  1122. global_data_offset = *frame_ip++;
  1123. if (global_data_offset & 0x80)
  1124. PUSH_I64(GET_I64_FROM_ADDR((uint32*)(global_data + (global_data_offset & 0x7F))));
  1125. else
  1126. PUSH_I32(*(uint32*)(global_data + global_data_offset));
  1127. HANDLE_OP_END ();
  1128. }
  1129. HANDLE_OP (WASM_OP_SET_GLOBAL):
  1130. {
  1131. frame_ip_org = frame_ip - 1;
  1132. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  1133. bh_assert(global_idx < module->global_count);
  1134. global = globals + global_idx;
  1135. global_addr = global_data + global->data_offset;
  1136. switch (global->type) {
  1137. case VALUE_TYPE_I32:
  1138. case VALUE_TYPE_F32:
  1139. *(int32*)global_addr = POP_I32();
  1140. break;
  1141. case VALUE_TYPE_I64:
  1142. case VALUE_TYPE_F64:
  1143. PUT_I64_TO_ADDR((uint32*)global_addr, POP_I64());
  1144. break;
  1145. default:
  1146. wasm_set_exception(module, "invalid global type");
  1147. goto got_exception;
  1148. }
  1149. if (global->data_offset < 0x80) {
  1150. *frame_ip_org++ = WASM_OP_SET_GLOBAL_FAST;
  1151. if (global->type == VALUE_TYPE_I32
  1152. || global->type == VALUE_TYPE_F32)
  1153. *frame_ip_org++ = (uint8)global->data_offset;
  1154. else
  1155. *frame_ip_org++ = (uint8)(global->data_offset | 0x80);
  1156. while (frame_ip_org < frame_ip)
  1157. *frame_ip_org++ = WASM_OP_NOP;
  1158. }
  1159. HANDLE_OP_END ();
  1160. }
  1161. HANDLE_OP (WASM_OP_SET_GLOBAL_FAST):
  1162. {
  1163. global_data_offset = *frame_ip++;
  1164. if (global_data_offset & 0x80)
  1165. PUT_I64_TO_ADDR((uint32*)(global_data + (global_data_offset & 0x7F)),
  1166. POP_I64());
  1167. else
  1168. *(uint32*)(global_data + global_data_offset) = POP_I32();
  1169. HANDLE_OP_END ();
  1170. }
  1171. /* memory load instructions */
  1172. HANDLE_OP (WASM_OP_I32_LOAD):
  1173. HANDLE_OP (WASM_OP_I64_LOAD):
  1174. HANDLE_OP (WASM_OP_F32_LOAD):
  1175. HANDLE_OP (WASM_OP_F64_LOAD):
  1176. HANDLE_OP (WASM_OP_I32_LOAD8_S):
  1177. HANDLE_OP (WASM_OP_I32_LOAD8_U):
  1178. HANDLE_OP (WASM_OP_I32_LOAD16_S):
  1179. HANDLE_OP (WASM_OP_I32_LOAD16_U):
  1180. HANDLE_OP (WASM_OP_I64_LOAD8_S):
  1181. HANDLE_OP (WASM_OP_I64_LOAD8_U):
  1182. HANDLE_OP (WASM_OP_I64_LOAD16_S):
  1183. HANDLE_OP (WASM_OP_I64_LOAD16_U):
  1184. HANDLE_OP (WASM_OP_I64_LOAD32_S):
  1185. HANDLE_OP (WASM_OP_I64_LOAD32_U):
  1186. {
  1187. uint32 offset, flags, addr;
  1188. GET_OPCODE();
  1189. read_leb_uint32(frame_ip, frame_ip_end, flags);
  1190. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1191. addr = (uint32)POP_I32();
  1192. CHECK_MEMORY_OVERFLOW();
  1193. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  1194. static const void *handle_load_table[] = {
  1195. &&HANDLE_LOAD_WASM_OP_I32_LOAD,
  1196. &&HANDLE_LOAD_WASM_OP_I64_LOAD,
  1197. &&HANDLE_LOAD_WASM_OP_F32_LOAD,
  1198. &&HANDLE_LOAD_WASM_OP_F64_LOAD,
  1199. &&HANDLE_LOAD_WASM_OP_I32_LOAD8_S,
  1200. &&HANDLE_LOAD_WASM_OP_I32_LOAD8_U,
  1201. &&HANDLE_LOAD_WASM_OP_I32_LOAD16_S,
  1202. &&HANDLE_LOAD_WASM_OP_I32_LOAD16_U,
  1203. &&HANDLE_LOAD_WASM_OP_I64_LOAD8_S,
  1204. &&HANDLE_LOAD_WASM_OP_I64_LOAD8_U,
  1205. &&HANDLE_LOAD_WASM_OP_I64_LOAD16_S,
  1206. &&HANDLE_LOAD_WASM_OP_I64_LOAD16_U,
  1207. &&HANDLE_LOAD_WASM_OP_I64_LOAD32_S,
  1208. &&HANDLE_LOAD_WASM_OP_I64_LOAD32_U
  1209. };
  1210. #define HANDLE_OP_LOAD(opcode) HANDLE_LOAD_##opcode
  1211. goto *handle_load_table[opcode - WASM_OP_I32_LOAD];
  1212. #else
  1213. #define HANDLE_OP_LOAD(opcode) case opcode
  1214. switch (opcode)
  1215. #endif
  1216. {
  1217. HANDLE_OP_LOAD(WASM_OP_I32_LOAD):
  1218. PUSH_I32(LOAD_I32(maddr));
  1219. HANDLE_OP_END();
  1220. HANDLE_OP_LOAD(WASM_OP_I64_LOAD):
  1221. PUSH_I64(LOAD_I64(maddr));
  1222. HANDLE_OP_END();
  1223. HANDLE_OP_LOAD(WASM_OP_F32_LOAD):
  1224. PUSH_I32(LOAD_I32(maddr));
  1225. HANDLE_OP_END();
  1226. HANDLE_OP_LOAD(WASM_OP_F64_LOAD):
  1227. PUSH_F64(LOAD_F64(maddr));
  1228. HANDLE_OP_END();
  1229. HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_S):
  1230. PUSH_I32(sign_ext_8_32(*(int8*)maddr));
  1231. HANDLE_OP_END();
  1232. HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_U):
  1233. PUSH_I32((uint32)(*(uint8*)maddr));
  1234. HANDLE_OP_END();
  1235. HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_S):
  1236. PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
  1237. HANDLE_OP_END();
  1238. HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_U):
  1239. PUSH_I32((uint32)(LOAD_U16(maddr)));
  1240. HANDLE_OP_END();
  1241. HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_S):
  1242. PUSH_I64(sign_ext_8_64(*(int8*)maddr));
  1243. HANDLE_OP_END();
  1244. HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_U):
  1245. PUSH_I64((uint64)(*(uint8*)maddr));
  1246. HANDLE_OP_END();
  1247. HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_S):
  1248. PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
  1249. HANDLE_OP_END();
  1250. HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_U):
  1251. PUSH_I64((uint64)(LOAD_U16(maddr)));
  1252. HANDLE_OP_END();
  1253. HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_S):
  1254. PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
  1255. HANDLE_OP_END();
  1256. HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_U):
  1257. PUSH_I64((uint64)(LOAD_U32(maddr)));
  1258. HANDLE_OP_END();
  1259. }
  1260. (void)flags;
  1261. HANDLE_OP_END ();
  1262. }
  1263. /* memory store instructions */
  1264. HANDLE_OP (WASM_OP_F32_STORE):
  1265. {
  1266. uint32 offset, flags, addr;
  1267. GET_OPCODE();
  1268. read_leb_uint32(frame_ip, frame_ip_end, flags);
  1269. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1270. frame_sp--;
  1271. addr = (uint32)POP_I32();
  1272. CHECK_MEMORY_OVERFLOW();
  1273. STORE_U32(maddr, frame_sp[1]);
  1274. (void)flags;
  1275. HANDLE_OP_END ();
  1276. }
  1277. HANDLE_OP (WASM_OP_F64_STORE):
  1278. {
  1279. uint32 offset, flags, addr;
  1280. GET_OPCODE();
  1281. read_leb_uint32(frame_ip, frame_ip_end, flags);
  1282. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1283. frame_sp -= 2;
  1284. addr = (uint32)POP_I32();
  1285. CHECK_MEMORY_OVERFLOW();
  1286. STORE_U32(maddr, frame_sp[1]);
  1287. STORE_U32(maddr + 4, frame_sp[2]);
  1288. (void)flags;
  1289. HANDLE_OP_END ();
  1290. }
  1291. HANDLE_OP (WASM_OP_I32_STORE):
  1292. HANDLE_OP (WASM_OP_I32_STORE8):
  1293. HANDLE_OP (WASM_OP_I32_STORE16):
  1294. {
  1295. uint32 offset, flags, addr;
  1296. uint32 sval;
  1297. GET_OPCODE();
  1298. read_leb_uint32(frame_ip, frame_ip_end, flags);
  1299. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1300. sval = (uint32)POP_I32();
  1301. addr = (uint32)POP_I32();
  1302. CHECK_MEMORY_OVERFLOW();
  1303. switch (opcode) {
  1304. case WASM_OP_I32_STORE:
  1305. STORE_U32(maddr, sval);
  1306. break;
  1307. case WASM_OP_I32_STORE8:
  1308. *(uint8*)maddr = (uint8)sval;
  1309. break;
  1310. case WASM_OP_I32_STORE16:
  1311. STORE_U16(maddr, (uint16)sval);
  1312. break;
  1313. }
  1314. (void)flags;
  1315. HANDLE_OP_END ();
  1316. }
  1317. HANDLE_OP (WASM_OP_I64_STORE):
  1318. HANDLE_OP (WASM_OP_I64_STORE8):
  1319. HANDLE_OP (WASM_OP_I64_STORE16):
  1320. HANDLE_OP (WASM_OP_I64_STORE32):
  1321. {
  1322. uint32 offset, flags, addr;
  1323. uint64 sval;
  1324. GET_OPCODE();
  1325. read_leb_uint32(frame_ip, frame_ip_end, flags);
  1326. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1327. sval = (uint64)POP_I64();
  1328. addr = (uint32)POP_I32();
  1329. CHECK_MEMORY_OVERFLOW();
  1330. switch (opcode) {
  1331. case WASM_OP_I64_STORE:
  1332. STORE_I64(maddr, sval);
  1333. break;
  1334. case WASM_OP_I64_STORE8:
  1335. *(uint8*)maddr = (uint8)sval;
  1336. break;
  1337. case WASM_OP_I64_STORE16:
  1338. STORE_U16(maddr, (uint16)sval);
  1339. break;
  1340. case WASM_OP_I64_STORE32:
  1341. STORE_U32(maddr, (uint32)sval);
  1342. break;
  1343. }
  1344. (void)flags;
  1345. HANDLE_OP_END ();
  1346. }
  1347. /* memory size and memory grow instructions */
  1348. HANDLE_OP (WASM_OP_MEMORY_SIZE):
  1349. {
  1350. uint32 reserved;
  1351. read_leb_uint32(frame_ip, frame_ip_end, reserved);
  1352. PUSH_I32(memory->cur_page_count);
  1353. (void)reserved;
  1354. HANDLE_OP_END ();
  1355. }
  1356. HANDLE_OP (WASM_OP_MEMORY_GROW):
  1357. {
  1358. uint32 reserved, delta, prev_page_count = memory->cur_page_count;
  1359. read_leb_uint32(frame_ip, frame_ip_end, reserved);
  1360. delta = (uint32)POP_I32();
  1361. if (!wasm_enlarge_memory(module, delta)) {
  1362. /* fail to memory.grow, return -1 */
  1363. PUSH_I32(-1);
  1364. if (wasm_get_exception(module)) {
  1365. bh_printf("%s\n", wasm_get_exception(module));
  1366. wasm_set_exception(module, NULL);
  1367. }
  1368. }
  1369. else {
  1370. /* success, return previous page count */
  1371. PUSH_I32(prev_page_count);
  1372. /* update the memory instance ptr */
  1373. memory = module->default_memory;
  1374. memory_data_size = memory->num_bytes_per_page * memory->cur_page_count;
  1375. global_data = memory->global_data;
  1376. }
  1377. (void)reserved;
  1378. HANDLE_OP_END ();
  1379. }
  1380. /* constant instructions */
  1381. HANDLE_OP (WASM_OP_I32_CONST):
  1382. DEF_OP_I_CONST(int32, I32);
  1383. HANDLE_OP_END ();
  1384. HANDLE_OP (WASM_OP_I64_CONST):
  1385. DEF_OP_I_CONST(int64, I64);
  1386. HANDLE_OP_END ();
  1387. HANDLE_OP (WASM_OP_F32_CONST):
  1388. {
  1389. uint8 *p_float = (uint8*)frame_sp++;
  1390. for (i = 0; i < sizeof(float32); i++)
  1391. *p_float++ = *frame_ip++;
  1392. HANDLE_OP_END ();
  1393. }
  1394. HANDLE_OP (WASM_OP_F64_CONST):
  1395. {
  1396. uint8 *p_float = (uint8*)frame_sp++;
  1397. frame_sp++;
  1398. for (i = 0; i < sizeof(float64); i++)
  1399. *p_float++ = *frame_ip++;
  1400. HANDLE_OP_END ();
  1401. }
  1402. /* comparison instructions of i32 */
  1403. HANDLE_OP (WASM_OP_I32_EQZ):
  1404. DEF_OP_EQZ(I32);
  1405. HANDLE_OP_END ();
  1406. HANDLE_OP (WASM_OP_I32_EQ):
  1407. DEF_OP_CMP(uint32, I32, ==);
  1408. HANDLE_OP_END ();
  1409. HANDLE_OP (WASM_OP_I32_NE):
  1410. DEF_OP_CMP(uint32, I32, !=);
  1411. HANDLE_OP_END ();
  1412. HANDLE_OP (WASM_OP_I32_LT_S):
  1413. DEF_OP_CMP(int32, I32, <);
  1414. HANDLE_OP_END ();
  1415. HANDLE_OP (WASM_OP_I32_LT_U):
  1416. DEF_OP_CMP(uint32, I32, <);
  1417. HANDLE_OP_END ();
  1418. HANDLE_OP (WASM_OP_I32_GT_S):
  1419. DEF_OP_CMP(int32, I32, >);
  1420. HANDLE_OP_END ();
  1421. HANDLE_OP (WASM_OP_I32_GT_U):
  1422. DEF_OP_CMP(uint32, I32, >);
  1423. HANDLE_OP_END ();
  1424. HANDLE_OP (WASM_OP_I32_LE_S):
  1425. DEF_OP_CMP(int32, I32, <=);
  1426. HANDLE_OP_END ();
  1427. HANDLE_OP (WASM_OP_I32_LE_U):
  1428. DEF_OP_CMP(uint32, I32, <=);
  1429. HANDLE_OP_END ();
  1430. HANDLE_OP (WASM_OP_I32_GE_S):
  1431. DEF_OP_CMP(int32, I32, >=);
  1432. HANDLE_OP_END ();
  1433. HANDLE_OP (WASM_OP_I32_GE_U):
  1434. DEF_OP_CMP(uint32, I32, >=);
  1435. HANDLE_OP_END ();
  1436. /* comparison instructions of i64 */
  1437. HANDLE_OP (WASM_OP_I64_EQZ):
  1438. DEF_OP_EQZ(I64);
  1439. HANDLE_OP_END ();
  1440. HANDLE_OP (WASM_OP_I64_EQ):
  1441. DEF_OP_CMP(uint64, I64, ==);
  1442. HANDLE_OP_END ();
  1443. HANDLE_OP (WASM_OP_I64_NE):
  1444. DEF_OP_CMP(uint64, I64, !=);
  1445. HANDLE_OP_END ();
  1446. HANDLE_OP (WASM_OP_I64_LT_S):
  1447. DEF_OP_CMP(int64, I64, <);
  1448. HANDLE_OP_END ();
  1449. HANDLE_OP (WASM_OP_I64_LT_U):
  1450. DEF_OP_CMP(uint64, I64, <);
  1451. HANDLE_OP_END ();
  1452. HANDLE_OP (WASM_OP_I64_GT_S):
  1453. DEF_OP_CMP(int64, I64, >);
  1454. HANDLE_OP_END ();
  1455. HANDLE_OP (WASM_OP_I64_GT_U):
  1456. DEF_OP_CMP(uint64, I64, >);
  1457. HANDLE_OP_END ();
  1458. HANDLE_OP (WASM_OP_I64_LE_S):
  1459. DEF_OP_CMP(int64, I64, <=);
  1460. HANDLE_OP_END ();
  1461. HANDLE_OP (WASM_OP_I64_LE_U):
  1462. DEF_OP_CMP(uint64, I64, <=);
  1463. HANDLE_OP_END ();
  1464. HANDLE_OP (WASM_OP_I64_GE_S):
  1465. DEF_OP_CMP(int64, I64, >=);
  1466. HANDLE_OP_END ();
  1467. HANDLE_OP (WASM_OP_I64_GE_U):
  1468. DEF_OP_CMP(uint64, I64, >=);
  1469. HANDLE_OP_END ();
  1470. /* comparison instructions of f32 */
  1471. HANDLE_OP (WASM_OP_F32_EQ):
  1472. DEF_OP_CMP(float32, F32, ==);
  1473. HANDLE_OP_END ();
  1474. HANDLE_OP (WASM_OP_F32_NE):
  1475. DEF_OP_CMP(float32, F32, !=);
  1476. HANDLE_OP_END ();
  1477. HANDLE_OP (WASM_OP_F32_LT):
  1478. DEF_OP_CMP(float32, F32, <);
  1479. HANDLE_OP_END ();
  1480. HANDLE_OP (WASM_OP_F32_GT):
  1481. DEF_OP_CMP(float32, F32, >);
  1482. HANDLE_OP_END ();
  1483. HANDLE_OP (WASM_OP_F32_LE):
  1484. DEF_OP_CMP(float32, F32, <=);
  1485. HANDLE_OP_END ();
  1486. HANDLE_OP (WASM_OP_F32_GE):
  1487. DEF_OP_CMP(float32, F32, >=);
  1488. HANDLE_OP_END ();
  1489. /* comparison instructions of f64 */
  1490. HANDLE_OP (WASM_OP_F64_EQ):
  1491. DEF_OP_CMP(float64, F64, ==);
  1492. HANDLE_OP_END ();
  1493. HANDLE_OP (WASM_OP_F64_NE):
  1494. DEF_OP_CMP(float64, F64, !=);
  1495. HANDLE_OP_END ();
  1496. HANDLE_OP (WASM_OP_F64_LT):
  1497. DEF_OP_CMP(float64, F64, <);
  1498. HANDLE_OP_END ();
  1499. HANDLE_OP (WASM_OP_F64_GT):
  1500. DEF_OP_CMP(float64, F64, >);
  1501. HANDLE_OP_END ();
  1502. HANDLE_OP (WASM_OP_F64_LE):
  1503. DEF_OP_CMP(float64, F64, <=);
  1504. HANDLE_OP_END ();
  1505. HANDLE_OP (WASM_OP_F64_GE):
  1506. DEF_OP_CMP(float64, F64, >=);
  1507. HANDLE_OP_END ();
  1508. /* numberic instructions of i32 */
  1509. HANDLE_OP (WASM_OP_I32_CLZ):
  1510. DEF_OP_BIT_COUNT(uint32, I32, clz32);
  1511. HANDLE_OP_END ();
  1512. HANDLE_OP (WASM_OP_I32_CTZ):
  1513. DEF_OP_BIT_COUNT(uint32, I32, ctz32);
  1514. HANDLE_OP_END ();
  1515. HANDLE_OP (WASM_OP_I32_POPCNT):
  1516. DEF_OP_BIT_COUNT(uint32, I32, popcount32);
  1517. HANDLE_OP_END ();
  1518. HANDLE_OP (WASM_OP_I32_ADD):
  1519. DEF_OP_NUMERIC(uint32, uint32, I32, +);
  1520. HANDLE_OP_END ();
  1521. HANDLE_OP (WASM_OP_I32_SUB):
  1522. DEF_OP_NUMERIC(uint32, uint32, I32, -);
  1523. HANDLE_OP_END ();
  1524. HANDLE_OP (WASM_OP_I32_MUL):
  1525. DEF_OP_NUMERIC(uint32, uint32, I32, *);
  1526. HANDLE_OP_END ();
  1527. HANDLE_OP (WASM_OP_I32_DIV_S):
  1528. {
  1529. int32 a, b;
  1530. b = POP_I32();
  1531. a = POP_I32();
  1532. if (a == (int32)0x80000000 && b == -1) {
  1533. wasm_set_exception(module, "integer overflow");
  1534. goto got_exception;
  1535. }
  1536. if (b == 0) {
  1537. wasm_set_exception(module, "integer divide by zero");
  1538. goto got_exception;
  1539. }
  1540. PUSH_I32(a / b);
  1541. HANDLE_OP_END ();
  1542. }
  1543. HANDLE_OP (WASM_OP_I32_DIV_U):
  1544. {
  1545. uint32 a, b;
  1546. b = (uint32)POP_I32();
  1547. a = (uint32)POP_I32();
  1548. if (b == 0) {
  1549. wasm_set_exception(module, "integer divide by zero");
  1550. goto got_exception;
  1551. }
  1552. PUSH_I32(a / b);
  1553. HANDLE_OP_END ();
  1554. }
  1555. HANDLE_OP (WASM_OP_I32_REM_S):
  1556. {
  1557. int32 a, b;
  1558. b = POP_I32();
  1559. a = POP_I32();
  1560. if (a == (int32)0x80000000 && b == -1) {
  1561. PUSH_I32(0);
  1562. HANDLE_OP_END ();
  1563. }
  1564. if (b == 0) {
  1565. wasm_set_exception(module, "integer divide by zero");
  1566. goto got_exception;
  1567. }
  1568. PUSH_I32(a % b);
  1569. HANDLE_OP_END ();
  1570. }
  1571. HANDLE_OP (WASM_OP_I32_REM_U):
  1572. {
  1573. uint32 a, b;
  1574. b = (uint32)POP_I32();
  1575. a = (uint32)POP_I32();
  1576. if (b == 0) {
  1577. wasm_set_exception(module, "integer divide by zero");
  1578. goto got_exception;
  1579. }
  1580. PUSH_I32(a % b);
  1581. HANDLE_OP_END ();
  1582. }
  1583. HANDLE_OP (WASM_OP_I32_AND):
  1584. DEF_OP_NUMERIC(uint32, uint32, I32, &);
  1585. HANDLE_OP_END ();
  1586. HANDLE_OP (WASM_OP_I32_OR):
  1587. DEF_OP_NUMERIC(uint32, uint32, I32, |);
  1588. HANDLE_OP_END ();
  1589. HANDLE_OP (WASM_OP_I32_XOR):
  1590. DEF_OP_NUMERIC(uint32, uint32, I32, ^);
  1591. HANDLE_OP_END ();
  1592. HANDLE_OP (WASM_OP_I32_SHL):
  1593. {
  1594. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1595. DEF_OP_NUMERIC(uint32, uint32, I32, <<);
  1596. #else
  1597. DEF_OP_NUMERIC2(uint32, uint32, I32, <<);
  1598. #endif
  1599. HANDLE_OP_END ();
  1600. }
  1601. HANDLE_OP (WASM_OP_I32_SHR_S):
  1602. {
  1603. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1604. DEF_OP_NUMERIC(int32, uint32, I32, >>);
  1605. #else
  1606. DEF_OP_NUMERIC2(int32, uint32, I32, >>);
  1607. #endif
  1608. HANDLE_OP_END ();
  1609. }
  1610. HANDLE_OP (WASM_OP_I32_SHR_U):
  1611. {
  1612. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1613. DEF_OP_NUMERIC(uint32, uint32, I32, >>);
  1614. #else
  1615. DEF_OP_NUMERIC2(uint32, uint32, I32, >>);
  1616. #endif
  1617. HANDLE_OP_END ();
  1618. }
  1619. HANDLE_OP (WASM_OP_I32_ROTL):
  1620. {
  1621. uint32 a, b;
  1622. b = (uint32)POP_I32();
  1623. a = (uint32)POP_I32();
  1624. PUSH_I32(rotl32(a, b));
  1625. HANDLE_OP_END ();
  1626. }
  1627. HANDLE_OP (WASM_OP_I32_ROTR):
  1628. {
  1629. uint32 a, b;
  1630. b = (uint32)POP_I32();
  1631. a = (uint32)POP_I32();
  1632. PUSH_I32(rotr32(a, b));
  1633. HANDLE_OP_END ();
  1634. }
  1635. /* numberic instructions of i64 */
  1636. HANDLE_OP (WASM_OP_I64_CLZ):
  1637. DEF_OP_BIT_COUNT(uint64, I64, clz64);
  1638. HANDLE_OP_END ();
  1639. HANDLE_OP (WASM_OP_I64_CTZ):
  1640. DEF_OP_BIT_COUNT(uint64, I64, ctz64);
  1641. HANDLE_OP_END ();
  1642. HANDLE_OP (WASM_OP_I64_POPCNT):
  1643. DEF_OP_BIT_COUNT(uint64, I64, popcount64);
  1644. HANDLE_OP_END ();
  1645. HANDLE_OP (WASM_OP_I64_ADD):
  1646. DEF_OP_NUMERIC_64(uint64, uint64, I64, +);
  1647. HANDLE_OP_END ();
  1648. HANDLE_OP (WASM_OP_I64_SUB):
  1649. DEF_OP_NUMERIC_64(uint64, uint64, I64, -);
  1650. HANDLE_OP_END ();
  1651. HANDLE_OP (WASM_OP_I64_MUL):
  1652. DEF_OP_NUMERIC_64(uint64, uint64, I64, *);
  1653. HANDLE_OP_END ();
  1654. HANDLE_OP (WASM_OP_I64_DIV_S):
  1655. {
  1656. int64 a, b;
  1657. b = POP_I64();
  1658. a = POP_I64();
  1659. if (a == (int64)0x8000000000000000LL && b == -1) {
  1660. wasm_set_exception(module, "integer overflow");
  1661. goto got_exception;
  1662. }
  1663. if (b == 0) {
  1664. wasm_set_exception(module, "integer divide by zero");
  1665. goto got_exception;
  1666. }
  1667. PUSH_I64(a / b);
  1668. HANDLE_OP_END ();
  1669. }
  1670. HANDLE_OP (WASM_OP_I64_DIV_U):
  1671. {
  1672. uint64 a, b;
  1673. b = (uint64)POP_I64();
  1674. a = (uint64)POP_I64();
  1675. if (b == 0) {
  1676. wasm_set_exception(module, "integer divide by zero");
  1677. goto got_exception;
  1678. }
  1679. PUSH_I64(a / b);
  1680. HANDLE_OP_END ();
  1681. }
  1682. HANDLE_OP (WASM_OP_I64_REM_S):
  1683. {
  1684. int64 a, b;
  1685. b = POP_I64();
  1686. a = POP_I64();
  1687. if (a == (int64)0x8000000000000000LL && b == -1) {
  1688. PUSH_I64(0);
  1689. HANDLE_OP_END ();
  1690. }
  1691. if (b == 0) {
  1692. wasm_set_exception(module, "integer divide by zero");
  1693. goto got_exception;
  1694. }
  1695. PUSH_I64(a % b);
  1696. HANDLE_OP_END ();
  1697. }
  1698. HANDLE_OP (WASM_OP_I64_REM_U):
  1699. {
  1700. uint64 a, b;
  1701. b = (uint64)POP_I64();
  1702. a = (uint64)POP_I64();
  1703. if (b == 0) {
  1704. wasm_set_exception(module, "integer divide by zero");
  1705. goto got_exception;
  1706. }
  1707. PUSH_I64(a % b);
  1708. HANDLE_OP_END ();
  1709. }
  1710. HANDLE_OP (WASM_OP_I64_AND):
  1711. DEF_OP_NUMERIC_64(uint64, uint64, I64, &);
  1712. HANDLE_OP_END ();
  1713. HANDLE_OP (WASM_OP_I64_OR):
  1714. DEF_OP_NUMERIC_64(uint64, uint64, I64, |);
  1715. HANDLE_OP_END ();
  1716. HANDLE_OP (WASM_OP_I64_XOR):
  1717. DEF_OP_NUMERIC_64(uint64, uint64, I64, ^);
  1718. HANDLE_OP_END ();
  1719. HANDLE_OP (WASM_OP_I64_SHL):
  1720. {
  1721. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1722. DEF_OP_NUMERIC_64(uint64, uint64, I64, <<);
  1723. #else
  1724. DEF_OP_NUMERIC2_64(uint64, uint64, I64, <<);
  1725. #endif
  1726. HANDLE_OP_END ();
  1727. }
  1728. HANDLE_OP (WASM_OP_I64_SHR_S):
  1729. {
  1730. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1731. DEF_OP_NUMERIC_64(int64, uint64, I64, >>);
  1732. #else
  1733. DEF_OP_NUMERIC2_64(int64, uint64, I64, >>);
  1734. #endif
  1735. HANDLE_OP_END ();
  1736. }
  1737. HANDLE_OP (WASM_OP_I64_SHR_U):
  1738. {
  1739. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_X86_32)
  1740. DEF_OP_NUMERIC_64(uint64, uint64, I64, >>);
  1741. #else
  1742. DEF_OP_NUMERIC2_64(uint64, uint64, I64, >>);
  1743. #endif
  1744. HANDLE_OP_END ();
  1745. }
  1746. HANDLE_OP (WASM_OP_I64_ROTL):
  1747. {
  1748. uint64 a, b;
  1749. b = (uint64)POP_I64();
  1750. a = (uint64)POP_I64();
  1751. PUSH_I64(rotl64(a, b));
  1752. HANDLE_OP_END ();
  1753. }
  1754. HANDLE_OP (WASM_OP_I64_ROTR):
  1755. {
  1756. uint64 a, b;
  1757. b = (uint64)POP_I64();
  1758. a = (uint64)POP_I64();
  1759. PUSH_I64(rotr64(a, b));
  1760. HANDLE_OP_END ();
  1761. }
  1762. /* numberic instructions of f32 */
  1763. HANDLE_OP (WASM_OP_F32_ABS):
  1764. DEF_OP_MATH(float32, F32, fabs);
  1765. HANDLE_OP_END ();
  1766. HANDLE_OP (WASM_OP_F32_NEG):
  1767. {
  1768. int32 i32 = (int32)frame_sp[-1];
  1769. int32 sign_bit = i32 & (1 << 31);
  1770. if (sign_bit)
  1771. frame_sp[-1] = i32 & ~(1 << 31);
  1772. else
  1773. frame_sp[-1] = (uint32)(i32 | (1 << 31));
  1774. HANDLE_OP_END ();
  1775. }
  1776. HANDLE_OP (WASM_OP_F32_CEIL):
  1777. DEF_OP_MATH(float32, F32, ceil);
  1778. HANDLE_OP_END ();
  1779. HANDLE_OP (WASM_OP_F32_FLOOR):
  1780. DEF_OP_MATH(float32, F32, floor);
  1781. HANDLE_OP_END ();
  1782. HANDLE_OP (WASM_OP_F32_TRUNC):
  1783. DEF_OP_MATH(float32, F32, trunc);
  1784. HANDLE_OP_END ();
  1785. HANDLE_OP (WASM_OP_F32_NEAREST):
  1786. DEF_OP_MATH(float32, F32, rint);
  1787. HANDLE_OP_END ();
  1788. HANDLE_OP (WASM_OP_F32_SQRT):
  1789. DEF_OP_MATH(float32, F32, sqrt);
  1790. HANDLE_OP_END ();
  1791. HANDLE_OP (WASM_OP_F32_ADD):
  1792. DEF_OP_NUMERIC(float32, float32, F32, +);
  1793. HANDLE_OP_END ();
  1794. HANDLE_OP (WASM_OP_F32_SUB):
  1795. DEF_OP_NUMERIC(float32, float32, F32, -);
  1796. HANDLE_OP_END ();
  1797. HANDLE_OP (WASM_OP_F32_MUL):
  1798. DEF_OP_NUMERIC(float32, float32, F32, *);
  1799. HANDLE_OP_END ();
  1800. HANDLE_OP (WASM_OP_F32_DIV):
  1801. DEF_OP_NUMERIC(float32, float32, F32, /);
  1802. HANDLE_OP_END ();
  1803. HANDLE_OP (WASM_OP_F32_MIN):
  1804. {
  1805. float32 a, b;
  1806. b = POP_F32();
  1807. a = POP_F32();
  1808. if (isnan(a))
  1809. PUSH_F32(a);
  1810. else if (isnan(b))
  1811. PUSH_F32(b);
  1812. else
  1813. PUSH_F32(wa_fmin(a, b));
  1814. HANDLE_OP_END ();
  1815. }
  1816. HANDLE_OP (WASM_OP_F32_MAX):
  1817. {
  1818. float32 a, b;
  1819. b = POP_F32();
  1820. a = POP_F32();
  1821. if (isnan(a))
  1822. PUSH_F32(a);
  1823. else if (isnan(b))
  1824. PUSH_F32(b);
  1825. else
  1826. PUSH_F32(wa_fmax(a, b));
  1827. HANDLE_OP_END ();
  1828. }
  1829. HANDLE_OP (WASM_OP_F32_COPYSIGN):
  1830. {
  1831. float32 a, b;
  1832. b = POP_F32();
  1833. a = POP_F32();
  1834. PUSH_F32(signbit(b) ? -fabs(a) : fabs(a));
  1835. HANDLE_OP_END ();
  1836. }
  1837. /* numberic instructions of f64 */
  1838. HANDLE_OP (WASM_OP_F64_ABS):
  1839. DEF_OP_MATH(float64, F64, fabs);
  1840. HANDLE_OP_END ();
  1841. HANDLE_OP (WASM_OP_F64_NEG):
  1842. {
  1843. int64 i64 = GET_I64_FROM_ADDR(frame_sp - 2);
  1844. int64 sign_bit = i64 & (((int64)1) << 63);
  1845. if (sign_bit)
  1846. PUT_I64_TO_ADDR(frame_sp - 2, ((uint64)i64 & ~(((uint64)1) << 63)));
  1847. else
  1848. PUT_I64_TO_ADDR(frame_sp - 2, ((uint64)i64 | (((uint64)1) << 63)));
  1849. HANDLE_OP_END ();
  1850. }
  1851. HANDLE_OP (WASM_OP_F64_CEIL):
  1852. DEF_OP_MATH(float64, F64, ceil);
  1853. HANDLE_OP_END ();
  1854. HANDLE_OP (WASM_OP_F64_FLOOR):
  1855. DEF_OP_MATH(float64, F64, floor);
  1856. HANDLE_OP_END ();
  1857. HANDLE_OP (WASM_OP_F64_TRUNC):
  1858. DEF_OP_MATH(float64, F64, trunc);
  1859. HANDLE_OP_END ();
  1860. HANDLE_OP (WASM_OP_F64_NEAREST):
  1861. DEF_OP_MATH(float64, F64, rint);
  1862. HANDLE_OP_END ();
  1863. HANDLE_OP (WASM_OP_F64_SQRT):
  1864. DEF_OP_MATH(float64, F64, sqrt);
  1865. HANDLE_OP_END ();
  1866. HANDLE_OP (WASM_OP_F64_ADD):
  1867. DEF_OP_NUMERIC_64(float64, float64, F64, +);
  1868. HANDLE_OP_END ();
  1869. HANDLE_OP (WASM_OP_F64_SUB):
  1870. DEF_OP_NUMERIC_64(float64, float64, F64, -);
  1871. HANDLE_OP_END ();
  1872. HANDLE_OP (WASM_OP_F64_MUL):
  1873. DEF_OP_NUMERIC_64(float64, float64, F64, *);
  1874. HANDLE_OP_END ();
  1875. HANDLE_OP (WASM_OP_F64_DIV):
  1876. DEF_OP_NUMERIC_64(float64, float64, F64, /);
  1877. HANDLE_OP_END ();
  1878. HANDLE_OP (WASM_OP_F64_MIN):
  1879. {
  1880. float64 a, b;
  1881. b = POP_F64();
  1882. a = POP_F64();
  1883. if (isnan(a))
  1884. PUSH_F64(a);
  1885. else if (isnan(b))
  1886. PUSH_F64(b);
  1887. else
  1888. PUSH_F64(wa_fmin(a, b));
  1889. HANDLE_OP_END ();
  1890. }
  1891. HANDLE_OP (WASM_OP_F64_MAX):
  1892. {
  1893. float64 a, b;
  1894. b = POP_F64();
  1895. a = POP_F64();
  1896. if (isnan(a))
  1897. PUSH_F64(a);
  1898. else if (isnan(b))
  1899. PUSH_F64(b);
  1900. else
  1901. PUSH_F64(wa_fmax(a, b));
  1902. HANDLE_OP_END ();
  1903. }
  1904. HANDLE_OP (WASM_OP_F64_COPYSIGN):
  1905. {
  1906. float64 a, b;
  1907. b = POP_F64();
  1908. a = POP_F64();
  1909. PUSH_F64(signbit(b) ? -fabs(a) : fabs(a));
  1910. HANDLE_OP_END ();
  1911. }
  1912. /* conversions of i32 */
  1913. HANDLE_OP (WASM_OP_I32_WRAP_I64):
  1914. {
  1915. int32 value = (int32)(POP_I64() & 0xFFFFFFFFLL);
  1916. PUSH_I32(value);
  1917. HANDLE_OP_END ();
  1918. }
  1919. HANDLE_OP (WASM_OP_I32_TRUNC_S_F32):
  1920. /* Copy the float32/float64 values from WAVM, need to test more.
  1921. We don't use INT32_MIN/INT32_MAX/UINT32_MIN/UINT32_MAX,
  1922. since float/double values of ieee754 cannot precisely represent
  1923. all int32/uint32/int64/uint64 values, e.g.:
  1924. UINT32_MAX is 4294967295, but (float32)4294967295 is 4294967296.0f,
  1925. but not 4294967295.0f. */
  1926. DEF_OP_TRUNC(int32, I32, float32, F32, <= -2147483904.0f,
  1927. >= 2147483648.0f);
  1928. HANDLE_OP_END ();
  1929. HANDLE_OP (WASM_OP_I32_TRUNC_U_F32):
  1930. DEF_OP_TRUNC(uint32, I32, float32, F32, <= -1.0f,
  1931. >= 4294967296.0f);
  1932. HANDLE_OP_END ();
  1933. HANDLE_OP (WASM_OP_I32_TRUNC_S_F64):
  1934. DEF_OP_TRUNC(int32, I32, float64, F64, <= -2147483649.0,
  1935. >= 2147483648.0);
  1936. HANDLE_OP_END ();
  1937. HANDLE_OP (WASM_OP_I32_TRUNC_U_F64):
  1938. DEF_OP_TRUNC(uint32, I32, float64, F64, <= -1.0 ,
  1939. >= 4294967296.0);
  1940. HANDLE_OP_END ();
  1941. /* conversions of i64 */
  1942. HANDLE_OP (WASM_OP_I64_EXTEND_S_I32):
  1943. DEF_OP_CONVERT(int64, I64, int32, I32);
  1944. HANDLE_OP_END ();
  1945. HANDLE_OP (WASM_OP_I64_EXTEND_U_I32):
  1946. DEF_OP_CONVERT(int64, I64, uint32, I32);
  1947. HANDLE_OP_END ();
  1948. HANDLE_OP (WASM_OP_I64_TRUNC_S_F32):
  1949. DEF_OP_TRUNC(int64, I64, float32, F32, <= -9223373136366403584.0f,
  1950. >= 9223372036854775808.0f);
  1951. HANDLE_OP_END ();
  1952. HANDLE_OP (WASM_OP_I64_TRUNC_U_F32):
  1953. DEF_OP_TRUNC(uint64, I64, float32, F32, <= -1.0f,
  1954. >= 18446744073709551616.0f);
  1955. HANDLE_OP_END ();
  1956. HANDLE_OP (WASM_OP_I64_TRUNC_S_F64):
  1957. DEF_OP_TRUNC(int64, I64, float64, F64, <= -9223372036854777856.0,
  1958. >= 9223372036854775808.0);
  1959. HANDLE_OP_END ();
  1960. HANDLE_OP (WASM_OP_I64_TRUNC_U_F64):
  1961. DEF_OP_TRUNC(uint64, I64, float64, F64, <= -1.0,
  1962. >= 18446744073709551616.0);
  1963. HANDLE_OP_END ();
  1964. /* conversions of f32 */
  1965. HANDLE_OP (WASM_OP_F32_CONVERT_S_I32):
  1966. DEF_OP_CONVERT(float32, F32, int32, I32);
  1967. HANDLE_OP_END ();
  1968. HANDLE_OP (WASM_OP_F32_CONVERT_U_I32):
  1969. DEF_OP_CONVERT(float32, F32, uint32, I32);
  1970. HANDLE_OP_END ();
  1971. HANDLE_OP (WASM_OP_F32_CONVERT_S_I64):
  1972. DEF_OP_CONVERT(float32, F32, int64, I64);
  1973. HANDLE_OP_END ();
  1974. HANDLE_OP (WASM_OP_F32_CONVERT_U_I64):
  1975. DEF_OP_CONVERT(float32, F32, uint64, I64);
  1976. HANDLE_OP_END ();
  1977. HANDLE_OP (WASM_OP_F32_DEMOTE_F64):
  1978. DEF_OP_CONVERT(float32, F32, float64, F64);
  1979. HANDLE_OP_END ();
  1980. /* conversions of f64 */
  1981. HANDLE_OP (WASM_OP_F64_CONVERT_S_I32):
  1982. DEF_OP_CONVERT(float64, F64, int32, I32);
  1983. HANDLE_OP_END ();
  1984. HANDLE_OP (WASM_OP_F64_CONVERT_U_I32):
  1985. DEF_OP_CONVERT(float64, F64, uint32, I32);
  1986. HANDLE_OP_END ();
  1987. HANDLE_OP (WASM_OP_F64_CONVERT_S_I64):
  1988. DEF_OP_CONVERT(float64, F64, int64, I64);
  1989. HANDLE_OP_END ();
  1990. HANDLE_OP (WASM_OP_F64_CONVERT_U_I64):
  1991. DEF_OP_CONVERT(float64, F64, uint64, I64);
  1992. HANDLE_OP_END ();
  1993. HANDLE_OP (WASM_OP_F64_PROMOTE_F32):
  1994. DEF_OP_CONVERT(float64, F64, float32, F32);
  1995. HANDLE_OP_END ();
  1996. /* reinterpretations */
  1997. HANDLE_OP (WASM_OP_I32_REINTERPRET_F32):
  1998. HANDLE_OP (WASM_OP_I64_REINTERPRET_F64):
  1999. HANDLE_OP (WASM_OP_F32_REINTERPRET_I32):
  2000. HANDLE_OP (WASM_OP_F64_REINTERPRET_I64):
  2001. HANDLE_OP_END ();
  2002. HANDLE_OP (WASM_OP_IMPDEP2):
  2003. frame = prev_frame;
  2004. frame_ip = frame->ip;
  2005. frame_sp = frame->sp;
  2006. frame_csp = frame->csp;
  2007. goto call_func_from_entry;
  2008. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  2009. default:
  2010. wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
  2011. goto got_exception;
  2012. }
  2013. #endif
  2014. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  2015. HANDLE_OP (WASM_OP_IMPDEP1):
  2016. HANDLE_OP (WASM_OP_UNUSED_0x06):
  2017. HANDLE_OP (WASM_OP_UNUSED_0x07):
  2018. HANDLE_OP (WASM_OP_UNUSED_0x08):
  2019. HANDLE_OP (WASM_OP_UNUSED_0x09):
  2020. HANDLE_OP (WASM_OP_UNUSED_0x0a):
  2021. HANDLE_OP (WASM_OP_UNUSED_0x12):
  2022. HANDLE_OP (WASM_OP_UNUSED_0x13):
  2023. HANDLE_OP (WASM_OP_UNUSED_0x14):
  2024. HANDLE_OP (WASM_OP_UNUSED_0x15):
  2025. HANDLE_OP (WASM_OP_UNUSED_0x16):
  2026. HANDLE_OP (WASM_OP_UNUSED_0x17):
  2027. HANDLE_OP (WASM_OP_UNUSED_0x18):
  2028. HANDLE_OP (WASM_OP_UNUSED_0x19):
  2029. HANDLE_OP (WASM_OP_UNUSED_0x1c):
  2030. HANDLE_OP (WASM_OP_UNUSED_0x1d):
  2031. HANDLE_OP (WASM_OP_UNUSED_0x1e):
  2032. HANDLE_OP (WASM_OP_UNUSED_0x1f):
  2033. HANDLE_OP (WASM_OP_UNUSED_0x25):
  2034. HANDLE_OP (WASM_OP_UNUSED_0x26):
  2035. HANDLE_OP (WASM_OP_UNUSED_0x27):
  2036. {
  2037. wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
  2038. goto got_exception;
  2039. }
  2040. #endif
  2041. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  2042. continue;
  2043. #else
  2044. FETCH_OPCODE_AND_DISPATCH ();
  2045. #endif
  2046. call_func_from_interp:
  2047. /* Only do the copy when it's called from interpreter. */
  2048. {
  2049. WASMInterpFrame *outs_area = wasm_exec_env_wasm_stack_top(exec_env);
  2050. POP(cur_func->param_cell_num);
  2051. SYNC_ALL_TO_FRAME();
  2052. word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num);
  2053. prev_frame = frame;
  2054. }
  2055. call_func_from_entry:
  2056. {
  2057. if (cur_func->is_import_func) {
  2058. wasm_interp_call_func_native(module, exec_env, cur_func, prev_frame);
  2059. prev_frame = frame->prev_frame;
  2060. cur_func = frame->function;
  2061. UPDATE_ALL_FROM_FRAME();
  2062. memory = module->default_memory;
  2063. if (wasm_get_exception(module))
  2064. goto got_exception;
  2065. }
  2066. else {
  2067. WASMFunction *cur_wasm_func = cur_func->u.func;
  2068. WASMType *func_type;
  2069. uint8 ret_type;
  2070. func_type = cur_wasm_func->func_type;
  2071. all_cell_num = (uint64)cur_func->param_cell_num
  2072. + (uint64)cur_func->local_cell_num
  2073. + (uint64)cur_wasm_func->max_stack_cell_num
  2074. + ((uint64)cur_wasm_func->max_block_num) * sizeof(WASMBranchBlock) / 4;
  2075. if (all_cell_num >= UINT32_MAX) {
  2076. wasm_set_exception(module, "WASM interp failed: stack overflow.");
  2077. goto got_exception;
  2078. }
  2079. frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num);
  2080. if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame))) {
  2081. frame = prev_frame;
  2082. goto got_exception;
  2083. }
  2084. /* Initialize the interpreter context. */
  2085. frame->function = cur_func;
  2086. frame_ip = wasm_get_func_code(cur_func);
  2087. frame_ip_end = wasm_get_func_code_end(cur_func);
  2088. frame_lp = frame->lp;
  2089. frame_sp = frame->sp_bottom = frame_lp + cur_func->param_cell_num
  2090. + cur_func->local_cell_num;
  2091. frame->sp_boundary = frame->sp_bottom + cur_wasm_func->max_stack_cell_num;
  2092. frame_csp = frame->csp_bottom = (WASMBranchBlock*)frame->sp_boundary;
  2093. frame->csp_boundary = frame->csp_bottom + cur_wasm_func->max_block_num;
  2094. /* Initialize the local varialbes */
  2095. memset(frame_lp + cur_func->param_cell_num, 0,
  2096. (uint32)(cur_func->local_cell_num * 4));
  2097. /* Push function block as first block */
  2098. ret_type = func_type->result_count
  2099. ? cur_func->param_types[func_type->param_count]
  2100. : VALUE_TYPE_VOID;
  2101. PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type,
  2102. frame_ip, NULL, frame_ip_end - 1);
  2103. wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame*)frame);
  2104. }
  2105. HANDLE_OP_END ();
  2106. }
  2107. return_func:
  2108. {
  2109. FREE_FRAME(exec_env, frame);
  2110. wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame*)prev_frame);
  2111. if (!prev_frame->ip)
  2112. /* Called from native. */
  2113. return;
  2114. RECOVER_CONTEXT(prev_frame);
  2115. HANDLE_OP_END ();
  2116. }
  2117. out_of_bounds:
  2118. wasm_set_exception(module, "out of bounds memory access");
  2119. got_exception:
  2120. if (depths && depths != depth_buf) {
  2121. wasm_free(depths);
  2122. depths = NULL;
  2123. }
  2124. return;
  2125. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  2126. }
  2127. #else
  2128. FETCH_OPCODE_AND_DISPATCH ();
  2129. #endif
  2130. }
  2131. void
  2132. wasm_interp_call_wasm(WASMModuleInstance *module_inst,
  2133. WASMExecEnv *exec_env,
  2134. WASMFunctionInstance *function,
  2135. uint32 argc, uint32 argv[])
  2136. {
  2137. WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
  2138. WASMInterpFrame *frame, *outs_area;
  2139. /* Allocate sufficient cells for all kinds of return values. */
  2140. unsigned all_cell_num = 2, i;
  2141. /* This frame won't be used by JITed code, so only allocate interp
  2142. frame here. */
  2143. unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
  2144. if (argc != function->param_cell_num) {
  2145. char buf[128];
  2146. snprintf(buf, sizeof(buf),
  2147. "invalid argument count %d, expected %d",
  2148. argc, function->param_cell_num);
  2149. wasm_set_exception(module_inst, buf);
  2150. return;
  2151. }
  2152. /* TODO: check stack overflow. */
  2153. if (!(frame = ALLOC_FRAME(exec_env, frame_size, (WASMInterpFrame*)prev_frame)))
  2154. return;
  2155. outs_area = wasm_exec_env_wasm_stack_top(exec_env);
  2156. frame->function = NULL;
  2157. frame->ip = NULL;
  2158. /* There is no local variable. */
  2159. frame->sp = frame->lp + 0;
  2160. if (argc > 0)
  2161. word_copy(outs_area->lp, argv, argc);
  2162. wasm_exec_env_set_cur_frame(exec_env, frame);
  2163. if (function->is_import_func)
  2164. wasm_interp_call_func_native(module_inst, exec_env, function, frame);
  2165. else
  2166. wasm_interp_call_func_bytecode(module_inst, exec_env, function, frame);
  2167. /* Output the return value to the caller */
  2168. if (!wasm_get_exception(module_inst)) {
  2169. for (i = 0; i < function->ret_cell_num; i++)
  2170. argv[i] = *(frame->sp + i - function->ret_cell_num);
  2171. }
  2172. wasm_exec_env_set_cur_frame(exec_env, prev_frame);
  2173. FREE_FRAME(exec_env, frame);
  2174. }