wasm-interp.c 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "wasm-interp.h"
  17. #include "wasm-runtime.h"
  18. #include "wasm-thread.h"
  19. #include "wasm-opcode.h"
  20. #include "wasm-loader.h"
  21. #include "wasm_log.h"
  22. #include "wasm_memory.h"
  23. typedef int32 CellType_I32;
  24. typedef int64 CellType_I64;
  25. typedef float32 CellType_F32;
  26. typedef float64 CellType_F64;
  27. #define BR_TABLE_TMP_BUF_LEN 32
  28. /* 64-bit Memory accessors. */
  29. #if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
  30. #define PUT_I64_TO_ADDR(addr, value) do { \
  31. *(int64*)(addr) = (int64)(value); \
  32. } while (0)
  33. #define PUT_F64_TO_ADDR(addr, value) do { \
  34. *(float64*)(addr) = (float64)(value); \
  35. } while (0)
  36. #define GET_I64_FROM_ADDR(addr) (*(int64*)(addr))
  37. #define GET_F64_FROM_ADDR(addr) (*(float64*)(addr))
  38. #else /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
  39. #define PUT_I64_TO_ADDR(addr, value) do { \
  40. union { int64 val; uint32 parts[2]; } u; \
  41. u.val = (value); \
  42. (addr)[0] = u.parts[0]; \
  43. (addr)[1] = u.parts[1]; \
  44. } while (0)
  45. #define PUT_F64_TO_ADDR(addr, value) do { \
  46. union { float64 val; uint32 parts[2]; } u; \
  47. u.val = (value); \
  48. (addr)[0] = u.parts[0]; \
  49. (addr)[1] = u.parts[1]; \
  50. } while (0)
  51. static inline int64
  52. GET_I64_FROM_ADDR(uint32 *addr)
  53. {
  54. union { int64 val; uint32 parts[2]; } u;
  55. u.parts[0] = addr[0];
  56. u.parts[1] = addr[1];
  57. return u.val;
  58. }
  59. static inline float64
  60. GET_F64_FROM_ADDR (uint32 *addr)
  61. {
  62. union { float64 val; uint32 parts[2]; } u;
  63. u.parts[0] = addr[0];
  64. u.parts[1] = addr[1];
  65. return u.val;
  66. }
  67. #endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
  68. #define is_valid_addr(memory, heap, addr) \
  69. (memory->base_addr <= addr && addr <= memory->end_addr) \
  70. #define CHECK_MEMORY_OVERFLOW() do { \
  71. uint8 *maddr1; \
  72. if (flags != 2) \
  73. LOG_VERBOSE("unaligned load/store in wasm interp, flag is: %d.\n", flags);\
  74. if (offset + addr < addr) { \
  75. wasm_runtime_set_exception(module, "out of bounds memory access"); \
  76. goto got_exception; \
  77. } \
  78. maddr = memory->memory_data + (offset + addr); \
  79. if (!is_valid_addr(memory, NULL, maddr)) { \
  80. wasm_runtime_set_exception(module, "out of bounds memory access"); \
  81. goto got_exception; \
  82. } \
  83. maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \
  84. if (!is_valid_addr(memory, NULL, maddr1)) { \
  85. wasm_runtime_set_exception(module, "out of bounds memory access"); \
  86. goto got_exception; \
  87. } \
  88. } while (0)
  89. static inline uint32
  90. rotl32(uint32 n, unsigned int c)
  91. {
  92. const unsigned int mask = (31);
  93. c = c % 32;
  94. c &= mask;
  95. return (n<<c) | (n>>( (-c)&mask ));
  96. }
  97. static inline uint32
  98. rotr32(uint32 n, unsigned int c)
  99. {
  100. const unsigned int mask = (31);
  101. c = c % 32;
  102. c &= mask;
  103. return (n>>c) | (n<<( (-c)&mask ));
  104. }
  105. static inline uint64
  106. rotl64(uint64 n, unsigned int c)
  107. {
  108. const unsigned int mask = (63);
  109. c = c % 64;
  110. c &= mask;
  111. return (n<<c) | (n>>( (-c)&mask ));
  112. }
  113. static inline uint64
  114. rotr64(uint64 n, unsigned int c)
  115. {
  116. const unsigned int mask = (63);
  117. c = c % 64;
  118. c &= mask;
  119. return (n>>c) | (n<<( (-c)&mask ));
  120. }
  121. static inline double
  122. wa_fmax(double a, double b)
  123. {
  124. double c = fmax(a, b);
  125. if (c==0 && a==b)
  126. return signbit(a) ? b : a;
  127. return c;
  128. }
  129. static inline double
  130. wa_fmin(double a, double b)
  131. {
  132. double c = fmin(a, b);
  133. if (c==0 && a==b)
  134. return signbit(a) ? a : b;
  135. return c;
  136. }
  137. static inline uint32
  138. clz32(uint32 type)
  139. {
  140. uint32 num = 0;
  141. if (type == 0)
  142. return 32;
  143. while (!(type & 0x80000000)) {
  144. num++;
  145. type <<= 1;
  146. }
  147. return num;
  148. }
  149. static inline uint32
  150. clz64(uint64 type)
  151. {
  152. uint32 num = 0;
  153. if (type == 0)
  154. return 64;
  155. while (!(type & 0x8000000000000000LL)) {
  156. num++;
  157. type <<= 1;
  158. }
  159. return num;
  160. }
  161. static inline uint32
  162. ctz32(uint32 type)
  163. {
  164. uint32 num = 0;
  165. if (type == 0)
  166. return 32;
  167. while (!(type & 1)) {
  168. num++;
  169. type >>= 1;
  170. }
  171. return num;
  172. }
  173. static inline uint32
  174. ctz64(uint64 type)
  175. {
  176. uint32 num = 0;
  177. if (type == 0)
  178. return 64;
  179. while (!(type & 1)) {
  180. num++;
  181. type >>= 1;
  182. }
  183. return num;
  184. }
  185. static inline uint32
  186. popcount32(uint32 u)
  187. {
  188. uint32 ret = 0;
  189. while (u) {
  190. u = (u & (u - 1));
  191. ret++;
  192. }
  193. return ret;
  194. }
  195. static inline uint32
  196. popcount64(uint64 u)
  197. {
  198. uint32 ret = 0;
  199. while (u) {
  200. u = (u & (u - 1));
  201. ret++;
  202. }
  203. return ret;
  204. }
  205. static inline WASMGlobalInstance*
  206. get_global(const WASMModuleInstance *module, uint32 global_idx)
  207. {
  208. if (global_idx >= module->global_count)
  209. return NULL;
  210. return module->globals + global_idx;
  211. }
  212. static inline uint8*
  213. get_global_addr(WASMMemoryInstance *memory, WASMGlobalInstance *global)
  214. {
  215. return memory->global_data + global->data_offset;
  216. }
  217. static uint64
  218. read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
  219. {
  220. uint64 result = 0;
  221. uint32 shift = 0;
  222. uint32 bcnt = 0;
  223. uint64 byte;
  224. while (true) {
  225. byte = buf[*p_offset];
  226. *p_offset += 1;
  227. result |= ((byte & 0x7f) << shift);
  228. shift += 7;
  229. if ((byte & 0x80) == 0) {
  230. break;
  231. }
  232. bcnt += 1;
  233. }
  234. if (sign && (shift < maxbits) && (byte & 0x40)) {
  235. /* Sign extend */
  236. result |= - (1 << shift);
  237. }
  238. return result;
  239. }
  240. #define PUSH_I32(value) do { \
  241. *(int32*)frame_sp++ = (int32)(value); \
  242. } while (0)
  243. #define PUSH_F32(value) do { \
  244. *(float32*)frame_sp++ = (float32)(value); \
  245. } while (0)
  246. #define PUSH_I64(value) do { \
  247. PUT_I64_TO_ADDR(frame_sp, value); \
  248. frame_sp += 2; \
  249. } while (0)
  250. #define PUSH_F64(value) do { \
  251. PUT_F64_TO_ADDR(frame_sp, value); \
  252. frame_sp += 2; \
  253. } while (0)
  254. #define PUSH_CSP(type, ret_type, start, else_, end) do {\
  255. wasm_assert(frame_csp < frame->csp_boundary); \
  256. frame_csp->block_type = type; \
  257. frame_csp->return_type = ret_type; \
  258. frame_csp->start_addr = start; \
  259. frame_csp->else_addr = else_; \
  260. frame_csp->end_addr = end; \
  261. frame_csp->frame_sp = frame_sp; \
  262. frame_csp++; \
  263. } while (0)
  264. #define POP_I32() (--frame_sp, *(int32*)frame_sp)
  265. #define POP_F32() (--frame_sp, *(float32*)frame_sp)
  266. #define POP_I64() (frame_sp -= 2, GET_I64_FROM_ADDR(frame_sp))
  267. #define POP_F64() (frame_sp -= 2, GET_F64_FROM_ADDR(frame_sp))
  268. #define POP_CSP_CHECK_OVERFLOW(n) do { \
  269. wasm_assert(frame_csp - n >= frame->csp_bottom); \
  270. } while (0)
  271. #define POP_CSP() do { \
  272. POP_CSP_CHECK_OVERFLOW(1); \
  273. --frame_csp; \
  274. } while (0)
  275. #define POP_CSP_N(n) do { \
  276. uint32 *frame_sp_old = frame_sp; \
  277. POP_CSP_CHECK_OVERFLOW(n + 1); \
  278. frame_csp -= n; \
  279. if ((frame_csp - 1)->block_type != BLOCK_TYPE_LOOP) \
  280. /* block block/if/function, jump to end of block */ \
  281. frame_ip = (frame_csp - 1)->end_addr; \
  282. else /* loop block, jump to start of block */ \
  283. frame_ip = (frame_csp - 1)->start_addr; \
  284. /* copy return value of block */ \
  285. frame_sp = (frame_csp - 1)->frame_sp; \
  286. switch ((frame_csp - 1)->return_type) { \
  287. case VALUE_TYPE_I32: \
  288. PUSH_I32(*(frame_sp_old - 1)); \
  289. break; \
  290. case VALUE_TYPE_I64: \
  291. PUSH_I64(GET_I64_FROM_ADDR(frame_sp_old - 2)); \
  292. break; \
  293. case VALUE_TYPE_F32: \
  294. PUSH_F32(*(float32*)(frame_sp_old - 1)); \
  295. break; \
  296. case VALUE_TYPE_F64: \
  297. PUSH_F64(GET_F64_FROM_ADDR(frame_sp_old - 2)); \
  298. break; \
  299. } \
  300. } while (0)
  301. #define local_off(n) (frame_lp + cur_func->local_offsets[n])
  302. #define LOCAL_I32(n) (*(int32*)(local_off(n)))
  303. #define SET_LOCAL_I32(N, val) do { \
  304. int n = (N); \
  305. *(int32*)(local_off(n)) = (int32)(val); \
  306. } while (0)
  307. #define LOCAL_F32(n) (*(float32*)(local_off(n)))
  308. #define SET_LOCAL_F32(N, val) do { \
  309. int n = (N); \
  310. *(float32*)(local_off(n)) = (float32)(val); \
  311. } while (0)
  312. #define LOCAL_I64(n) (GET_I64_FROM_ADDR(local_off(n)))
  313. #define SET_LOCAL_I64(N, val) do { \
  314. int n = (N); \
  315. PUT_I64_TO_ADDR(local_off(n), val); \
  316. } while (0)
  317. #define LOCAL_F64(n) (GET_F64_FROM_ADDR(local_off(n)))
  318. #define SET_LOCAL_F64(N, val) do { \
  319. int n = (N); \
  320. PUT_F64_TO_ADDR(local_off(n), val); \
  321. } while (0)
  322. /* Pop the given number of elements from the given frame's stack. */
  323. #define POP(N) do { \
  324. int n = (N); \
  325. frame_sp -= n; \
  326. } while (0)
  327. #define SYNC_ALL_TO_FRAME() do { \
  328. frame->sp = frame_sp; \
  329. frame->ip = frame_ip; \
  330. frame->csp = frame_csp; \
  331. } while (0)
  332. #define UPDATE_ALL_FROM_FRAME() do { \
  333. frame_sp = frame->sp; \
  334. frame_ip = frame->ip; \
  335. frame_csp = frame->csp; \
  336. } while (0)
  337. #define read_leb_uint64(p, p_end, res) do { \
  338. uint32 _off = 0; \
  339. res = read_leb(p, &_off, 64, false); \
  340. p += _off; \
  341. } while (0)
  342. #define read_leb_int64(p, p_end, res) do { \
  343. uint32 _off = 0; \
  344. res = (int64)read_leb(p, &_off, 64, true); \
  345. p += _off; \
  346. } while (0)
  347. #define read_leb_uint32(p, p_end, res) do { \
  348. uint32 _off = 0; \
  349. res = (uint32)read_leb(p, &_off, 32, false); \
  350. p += _off; \
  351. } while (0)
  352. #define read_leb_int32(p, p_end, res) do { \
  353. uint32 _off = 0; \
  354. res = (int32)read_leb(p, &_off, 32, true); \
  355. p += _off; \
  356. } while (0)
  357. #define read_leb_uint8(p, p_end, res) do { \
  358. uint32 _off = 0; \
  359. res = (uint8)read_leb(p, &_off, 7, false); \
  360. p += _off; \
  361. } while (0)
  362. #define RECOVER_CONTEXT(new_frame) do { \
  363. frame = (new_frame); \
  364. cur_func = frame->function; \
  365. prev_frame = frame->prev_frame; \
  366. frame_ip = frame->ip; \
  367. frame_ip_end = wasm_runtime_get_func_code_end(cur_func); \
  368. frame_lp = frame->lp; \
  369. frame_sp = frame->sp; \
  370. frame_csp = frame->csp; \
  371. } while (0)
  372. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  373. #define GET_OPCODE() opcode = *(frame_ip - 1);
  374. #else
  375. #define GET_OPCODE() (void)0
  376. #endif
  377. #define DEF_OP_LOAD(operation) do { \
  378. uint32 offset, flags, addr; \
  379. GET_OPCODE(); \
  380. read_leb_uint32(frame_ip, frame_ip_end, flags); \
  381. read_leb_uint32(frame_ip, frame_ip_end, offset); \
  382. addr = POP_I32(); \
  383. CHECK_MEMORY_OVERFLOW(); \
  384. operation; \
  385. (void)flags; \
  386. } while (0)
  387. #define DEF_OP_STORE(sval_type, sval_op_type, operation) do { \
  388. uint32 offset, flags, addr; \
  389. sval_type sval; \
  390. GET_OPCODE(); \
  391. read_leb_uint32(frame_ip, frame_ip_end, flags); \
  392. read_leb_uint32(frame_ip, frame_ip_end, offset); \
  393. sval = POP_##sval_op_type(); \
  394. addr = POP_I32(); \
  395. CHECK_MEMORY_OVERFLOW(); \
  396. operation; \
  397. (void)flags; \
  398. } while (0)
  399. #define DEF_OP_I_CONST(ctype, src_op_type) do { \
  400. ctype cval; \
  401. read_leb_##ctype(frame_ip, frame_ip_end, cval); \
  402. PUSH_##src_op_type(cval); \
  403. } while (0)
  404. #define DEF_OP_EQZ(src_op_type) do { \
  405. uint32 val; \
  406. val = POP_##src_op_type() == 0; \
  407. PUSH_I32(val); \
  408. } while (0)
  409. #define DEF_OP_CMP(src_type, src_op_type, cond) do { \
  410. uint32 res; \
  411. src_type val1, val2; \
  412. val2 = POP_##src_op_type(); \
  413. val1 = POP_##src_op_type(); \
  414. res = val1 cond val2; \
  415. PUSH_I32(res); \
  416. } while (0)
  417. #define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
  418. src_type val1, val2; \
  419. val1 = POP_##src_op_type(); \
  420. val2 = operation(val1); \
  421. PUSH_##src_op_type(val2); \
  422. } while (0)
  423. #define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) do { \
  424. frame_sp -= sizeof(src_type2)/sizeof(uint32); \
  425. *(src_type1*)(frame_sp - sizeof(src_type1)/sizeof(uint32)) operation##= \
  426. *(src_type2*)(frame_sp); \
  427. } while (0)
  428. #define DEF_OP_MATH(src_type, src_op_type, method) do { \
  429. src_type val; \
  430. val = POP_##src_op_type(); \
  431. PUSH_##src_op_type(method(val)); \
  432. } while (0)
  433. #define DEF_OP_TRUNC(dst_type, dst_op_type, src_type, src_op_type, \
  434. min_cond, max_cond) do { \
  435. src_type value = POP_##src_op_type(); \
  436. if (isnan(value)) { \
  437. wasm_runtime_set_exception(module, \
  438. "invalid conversion to integer"); \
  439. goto got_exception; \
  440. } \
  441. else if (value min_cond || value max_cond) { \
  442. wasm_runtime_set_exception(module, "integer overflow"); \
  443. goto got_exception; \
  444. } \
  445. PUSH_##dst_op_type(((dst_type)value)); \
  446. } while (0)
  447. #define DEF_OP_CONVERT(dst_type, dst_op_type, \
  448. src_type, src_op_type) do { \
  449. dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
  450. PUSH_##dst_op_type(value); \
  451. } while (0)
  452. #define GET_LOCAL_INDEX_AND_TYPE() do { \
  453. param_count = cur_func->u.func->func_type->param_count; \
  454. local_count = cur_func->u.func->local_count; \
  455. read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
  456. wasm_assert(local_idx < param_count + local_count); \
  457. if (local_idx < param_count) \
  458. local_type = cur_func->u.func->func_type->types[local_idx]; \
  459. else \
  460. local_type = \
  461. cur_func->u.func->local_types[local_idx - param_count]; \
  462. } while (0)
  463. static inline int32
  464. sign_ext_8_32(int8 val)
  465. {
  466. if (val & 0x80)
  467. return val | 0xffffff00;
  468. return val;
  469. }
  470. static inline int32
  471. sign_ext_16_32(int16 val)
  472. {
  473. if (val & 0x8000)
  474. return val | 0xffff0000;
  475. return val;
  476. }
  477. static inline int64
  478. sign_ext_8_64(int8 val)
  479. {
  480. if (val & 0x80)
  481. return val | 0xffffffffffffff00;
  482. return val;
  483. }
  484. static inline int64
  485. sign_ext_16_64(int16 val)
  486. {
  487. if (val & 0x8000)
  488. return val | 0xffffffffffff0000;
  489. return val;
  490. }
  491. static inline int64
  492. sign_ext_32_64(int32 val)
  493. {
  494. if (val & 0x80000000)
  495. return val | 0xffffffff00000000;
  496. return val;
  497. }
  498. static inline void
  499. word_copy(uint32 *dest, uint32 *src, unsigned num)
  500. {
  501. for (; num > 0; num--)
  502. *dest++ = *src++;
  503. }
  504. static inline WASMInterpFrame*
  505. ALLOC_FRAME(WASMThread *self, uint32 size, WASMInterpFrame *prev_frame)
  506. {
  507. WASMInterpFrame *frame = wasm_thread_alloc_wasm_frame(self, size);
  508. if (frame)
  509. frame->prev_frame = prev_frame;
  510. else {
  511. wasm_runtime_set_exception(self->module_inst,
  512. "WASM interp failed, alloc frame failed.");
  513. }
  514. return frame;
  515. }
  516. static inline void
  517. FREE_FRAME(WASMThread *self, WASMInterpFrame *frame)
  518. {
  519. wasm_thread_free_wasm_frame(self, frame);
  520. }
  521. typedef void (*GenericFunctionPointer)();
  522. int64 invokeNative(uint32 *args, uint32 sz, GenericFunctionPointer f);
  523. typedef float64 (*Float64FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  524. typedef float32 (*Float32FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  525. typedef int64 (*Int64FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  526. typedef int32 (*Int32FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  527. typedef void (*VoidFuncPtr)(uint32*, uint32, GenericFunctionPointer);
  528. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
  529. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
  530. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
  531. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
  532. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
  533. static void
  534. wasm_interp_call_func_native(WASMThread *self,
  535. WASMFunctionInstance *cur_func,
  536. WASMInterpFrame *prev_frame)
  537. {
  538. unsigned local_cell_num = 2;
  539. WASMInterpFrame *frame;
  540. typedef void (*F)(WASMThread*, uint32 *argv);
  541. union { F f; void *v; } u;
  542. uint32 argv_buf[32], *argv, argc = cur_func->param_cell_num;
  543. if (!(frame = ALLOC_FRAME
  544. (self, wasm_interp_interp_frame_size(local_cell_num), prev_frame)))
  545. return;
  546. frame->function = cur_func;
  547. frame->ip = NULL;
  548. frame->sp = frame->lp + local_cell_num;
  549. wasm_thread_set_cur_frame (self, frame);
  550. if (argc <= 32)
  551. argv = argv_buf;
  552. else {
  553. if (!(argv = wasm_malloc(sizeof(uint32) * argc))) {
  554. wasm_runtime_set_exception(self->module_inst,
  555. "WASM call native failed: alloc memory for argv failed.");
  556. return;
  557. }
  558. }
  559. word_copy(argv, frame->lp, argc);
  560. u.v = cur_func->u.func_import->func_ptr_linked;
  561. {
  562. WASMType *func_type = cur_func->u.func_import->func_type;
  563. uint8 ret_type = func_type->result_count
  564. ? func_type->types[func_type->param_count]
  565. : VALUE_TYPE_VOID;
  566. GenericFunctionPointer f = (GenericFunctionPointer)(uintptr_t)u.v;
  567. if (func_type->result_count == 0) {
  568. invokeNative_Void(argv, argc, f);
  569. }
  570. else {
  571. switch (ret_type) {
  572. case VALUE_TYPE_I32:
  573. argv[0] = invokeNative_Int32(argv, argc, f);
  574. break;
  575. case VALUE_TYPE_I64:
  576. PUT_I64_TO_ADDR(argv, invokeNative_Int64(argv, argc, f));
  577. break;
  578. case VALUE_TYPE_F32:
  579. *(float32*)argv = invokeNative_Float32(argv, argc, f);
  580. break;
  581. case VALUE_TYPE_F64:
  582. PUT_F64_TO_ADDR(argv, invokeNative_Float64(argv, argc, f));
  583. break;
  584. }
  585. }
  586. }
  587. if (cur_func->ret_cell_num == 1) {
  588. prev_frame->sp[0] = argv[0];
  589. prev_frame->sp++;
  590. }
  591. else if (cur_func->ret_cell_num == 2) {
  592. prev_frame->sp[0] = argv[0];
  593. prev_frame->sp[1] = argv[1];
  594. prev_frame->sp += 2;
  595. }
  596. if (argc > 32)
  597. wasm_free(argv);
  598. FREE_FRAME(self, frame);
  599. wasm_thread_set_cur_frame(self, prev_frame);
  600. }
  601. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  602. #define HANDLE_OP(opcode) HANDLE_##opcode
  603. #define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]
  604. #define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
  605. #else /* else of WASM_ENABLE_LABELS_AS_VALUES */
  606. #define HANDLE_OP(opcode) case opcode
  607. #define HANDLE_OP_END() continue
  608. #endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
  609. static void
  610. wasm_interp_call_func_bytecode(WASMThread *self,
  611. WASMFunctionInstance *cur_func,
  612. WASMInterpFrame *prev_frame)
  613. {
  614. WASMModuleInstance *module = self->module_inst;
  615. WASMMemoryInstance *memory = module->default_memory;
  616. WASMTableInstance *table = module->default_table;
  617. uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2;
  618. WASMInterpFrame *frame = NULL;
  619. /* Points to this special opcode so as to jump to the
  620. call_method_from_entry. */
  621. register uint8 *frame_ip = &opcode_IMPDEP2; /* cache of frame->ip */
  622. register uint32 *frame_lp = NULL; /* cache of frame->lp */
  623. register uint32 *frame_sp = NULL; /* cache of frame->sp */
  624. WASMBranchBlock *frame_csp = NULL;
  625. uint8 *frame_ip_end = frame_ip + 1;
  626. uint8 opcode, block_ret_type;
  627. uint32 *depths = NULL;
  628. uint32 depth_buf[BR_TABLE_TMP_BUF_LEN];
  629. uint32 i, depth, cond, count, fidx, tidx, frame_size = 0, all_cell_num = 0;
  630. int32 didx, val;
  631. uint8 *else_addr, *end_addr;
  632. uint8 *maddr;
  633. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  634. #define HANDLE_OPCODE(op) &&HANDLE_##op
  635. DEFINE_GOTO_TABLE (handle_table);
  636. #undef HANDLE_OPCODE
  637. #endif
  638. /* Size of memory load.
  639. This starts with the first memory load operator at opcode 0x28 */
  640. uint32 LOAD_SIZE[] = {
  641. 4, 8, 4, 8, 1, 1, 2, 2, 1, 1, 2, 2, 4, 4, /* loads */
  642. 4, 8, 4, 8, 1, 2, 1, 2, 4 }; /* stores */
  643. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  644. while (frame_ip < frame_ip_end) {
  645. opcode = *frame_ip++;
  646. switch (opcode) {
  647. #else
  648. FETCH_OPCODE_AND_DISPATCH ();
  649. #endif
  650. /* control instructions */
  651. HANDLE_OP (WASM_OP_UNREACHABLE):
  652. wasm_runtime_set_exception(module, "unreachable");
  653. goto got_exception;
  654. HANDLE_OP (WASM_OP_NOP):
  655. HANDLE_OP_END ();
  656. HANDLE_OP (WASM_OP_BLOCK):
  657. read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
  658. if (!wasm_loader_find_block_addr(module->branch_set, frame_ip,
  659. frame_ip_end, BLOCK_TYPE_BLOCK,
  660. &else_addr, &end_addr,
  661. NULL, 0)) {
  662. wasm_runtime_set_exception(module, "wasm loader find block addr failed");
  663. goto got_exception;
  664. }
  665. PUSH_CSP(BLOCK_TYPE_BLOCK, block_ret_type, frame_ip, NULL, end_addr);
  666. HANDLE_OP_END ();
  667. HANDLE_OP (WASM_OP_LOOP):
  668. read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
  669. if (!wasm_loader_find_block_addr(module->branch_set, frame_ip,
  670. frame_ip_end, BLOCK_TYPE_LOOP,
  671. &else_addr, &end_addr,
  672. NULL, 0)) {
  673. wasm_runtime_set_exception(module, "wasm loader find block addr failed");
  674. goto got_exception;
  675. }
  676. PUSH_CSP(BLOCK_TYPE_LOOP, block_ret_type, frame_ip, NULL, end_addr);
  677. HANDLE_OP_END ();
  678. HANDLE_OP (WASM_OP_IF):
  679. read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
  680. if (!wasm_loader_find_block_addr(module->branch_set, frame_ip,
  681. frame_ip_end, BLOCK_TYPE_IF,
  682. &else_addr, &end_addr,
  683. NULL, 0)) {
  684. wasm_runtime_set_exception(module, "wasm loader find block addr failed");
  685. goto got_exception;
  686. }
  687. cond = POP_I32();
  688. PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, frame_ip, else_addr, end_addr);
  689. /* condition of the if branch is false, else condition is met */
  690. if (cond == 0) {
  691. /* if there is no else branch, go to the end addr */
  692. if (else_addr == NULL) {
  693. POP_CSP();
  694. frame_ip = end_addr + 1;
  695. }
  696. /* if there is an else branch, go to the else addr */
  697. else
  698. frame_ip = else_addr + 1;
  699. }
  700. HANDLE_OP_END ();
  701. HANDLE_OP (WASM_OP_ELSE):
  702. /* comes from the if branch in WASM_OP_IF */
  703. frame_ip = (frame_csp - 1)->end_addr;
  704. HANDLE_OP_END ();
  705. HANDLE_OP (WASM_OP_END):
  706. if (frame_csp > frame->csp_bottom + 1) {
  707. POP_CSP();
  708. }
  709. else { /* end of function, treat as WASM_OP_RETURN */
  710. frame_sp -= cur_func->ret_cell_num;
  711. for (i = 0; i < cur_func->ret_cell_num; i++) {
  712. *prev_frame->sp++ = frame_sp[i];
  713. }
  714. goto return_func;
  715. }
  716. HANDLE_OP_END ();
  717. HANDLE_OP (WASM_OP_BR):
  718. read_leb_uint32(frame_ip, frame_ip_end, depth);
  719. POP_CSP_N(depth);
  720. HANDLE_OP_END ();
  721. HANDLE_OP (WASM_OP_BR_IF):
  722. read_leb_uint32(frame_ip, frame_ip_end, depth);
  723. cond = POP_I32();
  724. if (cond)
  725. POP_CSP_N(depth);
  726. HANDLE_OP_END ();
  727. HANDLE_OP (WASM_OP_BR_TABLE):
  728. read_leb_uint32(frame_ip, frame_ip_end, count);
  729. if (count <= BR_TABLE_TMP_BUF_LEN)
  730. depths = depth_buf;
  731. else {
  732. if (!(depths = wasm_malloc(sizeof(uint32) * count))) {
  733. wasm_runtime_set_exception(module, "WASM interp failed, "
  734. "alloc block memory for br_table failed.");
  735. goto got_exception;
  736. }
  737. }
  738. for (i = 0; i < count; i++) {
  739. read_leb_uint32(frame_ip, frame_ip_end, depths[i]);
  740. }
  741. read_leb_uint32(frame_ip, frame_ip_end, depth);
  742. didx = POP_I32();
  743. if (didx >= 0 && (uint32)didx < count) {
  744. depth = depths[didx];
  745. }
  746. if (depths != depth_buf) {
  747. wasm_free(depths);
  748. depths = NULL;
  749. }
  750. POP_CSP_N(depth);
  751. HANDLE_OP_END ();
  752. HANDLE_OP (WASM_OP_RETURN):
  753. frame_sp -= cur_func->ret_cell_num;
  754. for (i = 0; i < cur_func->ret_cell_num; i++) {
  755. *prev_frame->sp++ = frame_sp[i];
  756. }
  757. goto return_func;
  758. HANDLE_OP (WASM_OP_CALL):
  759. read_leb_uint32(frame_ip, frame_ip_end, fidx);
  760. wasm_assert(fidx < module->function_count);
  761. cur_func = module->functions + fidx;
  762. goto call_func_from_interp;
  763. HANDLE_OP (WASM_OP_CALL_INDIRECT):
  764. {
  765. WASMType *cur_type, *cur_func_type;
  766. /* TODO: test */
  767. read_leb_uint32(frame_ip, frame_ip_end, tidx);
  768. if (tidx >= module->module->type_count) {
  769. wasm_runtime_set_exception(module, "type index is overflow");
  770. goto got_exception;
  771. }
  772. cur_type = module->module->types[tidx];
  773. /* to skip 0x00 here */
  774. frame_ip++;
  775. val = POP_I32();
  776. if (val < 0 || val >= (int32)table->cur_size) {
  777. wasm_runtime_set_exception(module, "undefined element");
  778. goto got_exception;
  779. }
  780. fidx = ((uint32*)table->base_addr)[val];
  781. if (fidx >= module->function_count) {
  782. wasm_runtime_set_exception(module, "function index is overflow");
  783. goto got_exception;
  784. }
  785. cur_func = module->functions + fidx;
  786. if (cur_func->is_import_func)
  787. cur_func_type = cur_func->u.func_import->func_type;
  788. else
  789. cur_func_type = cur_func->u.func->func_type;
  790. if (!wasm_type_equal(cur_type, cur_func_type)) {
  791. wasm_runtime_set_exception(module, "indirect call type mismatch");
  792. goto got_exception;
  793. }
  794. goto call_func_from_interp;
  795. }
  796. /* parametric instructions */
  797. HANDLE_OP (WASM_OP_DROP):
  798. {
  799. wasm_runtime_set_exception(module,
  800. "wasm interp failed: unsupported opcode");
  801. goto got_exception;
  802. }
  803. HANDLE_OP (WASM_OP_DROP_32):
  804. {
  805. frame_sp--;
  806. HANDLE_OP_END ();
  807. }
  808. HANDLE_OP (WASM_OP_DROP_64):
  809. {
  810. frame_sp -= 2;
  811. HANDLE_OP_END ();
  812. }
  813. HANDLE_OP (WASM_OP_SELECT):
  814. {
  815. wasm_runtime_set_exception(module,
  816. "wasm interp failed: unsupported opcode");
  817. goto got_exception;
  818. }
  819. HANDLE_OP (WASM_OP_SELECT_32):
  820. {
  821. cond = POP_I32();
  822. frame_sp--;
  823. if (!cond)
  824. *(frame_sp - 1) = *frame_sp;
  825. HANDLE_OP_END ();
  826. }
  827. HANDLE_OP (WASM_OP_SELECT_64):
  828. {
  829. cond = POP_I32();
  830. frame_sp -= 2;
  831. if (!cond) {
  832. *(frame_sp - 2) = *frame_sp;
  833. *(frame_sp - 1) = *(frame_sp + 1);
  834. }
  835. HANDLE_OP_END ();
  836. }
  837. /* variable instructions */
  838. HANDLE_OP (WASM_OP_GET_LOCAL):
  839. {
  840. uint32 local_idx, param_count, local_count;
  841. uint8 local_type;
  842. GET_LOCAL_INDEX_AND_TYPE();
  843. switch (local_type) {
  844. case VALUE_TYPE_I32:
  845. PUSH_I32(LOCAL_I32(local_idx));
  846. break;
  847. case VALUE_TYPE_F32:
  848. PUSH_F32(LOCAL_F32(local_idx));
  849. break;
  850. case VALUE_TYPE_I64:
  851. PUSH_I64(LOCAL_I64(local_idx));
  852. break;
  853. case VALUE_TYPE_F64:
  854. PUSH_F64(LOCAL_F64(local_idx));
  855. break;
  856. default:
  857. wasm_runtime_set_exception(module,
  858. "get local type is invalid");
  859. goto got_exception;
  860. }
  861. (void)local_count;
  862. HANDLE_OP_END ();
  863. }
  864. HANDLE_OP (WASM_OP_SET_LOCAL):
  865. {
  866. uint32 local_idx, param_count, local_count;
  867. uint8 local_type;
  868. GET_LOCAL_INDEX_AND_TYPE();
  869. switch (local_type) {
  870. case VALUE_TYPE_I32:
  871. SET_LOCAL_I32(local_idx, POP_I32());
  872. break;
  873. case VALUE_TYPE_F32:
  874. SET_LOCAL_F32(local_idx, POP_F32());
  875. break;
  876. case VALUE_TYPE_I64:
  877. SET_LOCAL_I64(local_idx, POP_I64());
  878. break;
  879. case VALUE_TYPE_F64:
  880. SET_LOCAL_F64(local_idx, POP_F64());
  881. break;
  882. default:
  883. wasm_runtime_set_exception(module,
  884. "set local type is invalid");
  885. goto got_exception;
  886. }
  887. (void)local_count;
  888. HANDLE_OP_END ();
  889. }
  890. HANDLE_OP (WASM_OP_TEE_LOCAL):
  891. {
  892. uint32 local_idx, param_count, local_count;
  893. uint8 local_type;
  894. GET_LOCAL_INDEX_AND_TYPE();
  895. switch (local_type) {
  896. case VALUE_TYPE_I32:
  897. SET_LOCAL_I32(local_idx, *(frame_sp - 1));
  898. break;
  899. case VALUE_TYPE_F32:
  900. SET_LOCAL_F32(local_idx, *(float32*)(frame_sp - 1));
  901. break;
  902. case VALUE_TYPE_I64:
  903. SET_LOCAL_I64(local_idx, GET_I64_FROM_ADDR(frame_sp - 2));
  904. break;
  905. case VALUE_TYPE_F64:
  906. SET_LOCAL_F64(local_idx, GET_F64_FROM_ADDR(frame_sp - 2));
  907. break;
  908. default:
  909. wasm_runtime_set_exception(module, "tee local type is invalid");
  910. goto got_exception;
  911. }
  912. (void)local_count;
  913. HANDLE_OP_END ();
  914. }
  915. HANDLE_OP (WASM_OP_GET_GLOBAL):
  916. {
  917. WASMGlobalInstance *global;
  918. uint32 global_idx;
  919. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  920. global = get_global(module, global_idx);
  921. wasm_assert(global && global_idx < module->global_count);
  922. switch (global->type) {
  923. case VALUE_TYPE_I32:
  924. PUSH_I32(*(uint32*)get_global_addr(memory, global));
  925. break;
  926. case VALUE_TYPE_F32:
  927. PUSH_F32(*(float32*)get_global_addr(memory, global));
  928. break;
  929. case VALUE_TYPE_I64:
  930. PUSH_I64(*(uint64*)get_global_addr(memory, global));
  931. break;
  932. case VALUE_TYPE_F64:
  933. PUSH_F64(*(float64*)get_global_addr(memory, global));
  934. break;
  935. default:
  936. wasm_runtime_set_exception(module, "get global type is invalid");
  937. goto got_exception;
  938. }
  939. HANDLE_OP_END ();
  940. }
  941. HANDLE_OP (WASM_OP_SET_GLOBAL):
  942. {
  943. WASMGlobalInstance *global;
  944. uint32 global_idx;
  945. uint8 *global_addr;
  946. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  947. global = get_global(module, global_idx);
  948. wasm_assert(global && global_idx < module->global_count);
  949. global_addr = get_global_addr(memory, global);
  950. switch (global->type) {
  951. case VALUE_TYPE_I32:
  952. *(uint32*)global_addr = POP_I32();
  953. break;
  954. case VALUE_TYPE_F32:
  955. *(float32*)global_addr = POP_F32();
  956. break;
  957. case VALUE_TYPE_I64:
  958. PUT_I64_TO_ADDR((uint32*)global_addr, POP_I64());
  959. break;
  960. case VALUE_TYPE_F64:
  961. PUT_F64_TO_ADDR((uint32*)global_addr, POP_F64());
  962. break;
  963. default:
  964. wasm_runtime_set_exception(module, "set global index is overflow");
  965. goto got_exception;
  966. }
  967. HANDLE_OP_END ();
  968. }
  969. /* memory load instructions */
  970. HANDLE_OP (WASM_OP_I32_LOAD):
  971. DEF_OP_LOAD(PUSH_I32(*(int32*)maddr));
  972. HANDLE_OP_END ();
  973. HANDLE_OP (WASM_OP_I64_LOAD):
  974. DEF_OP_LOAD(PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr)));
  975. HANDLE_OP_END ();
  976. HANDLE_OP (WASM_OP_F32_LOAD):
  977. DEF_OP_LOAD(PUSH_F32(*(float32*)maddr));
  978. HANDLE_OP_END ();
  979. HANDLE_OP (WASM_OP_F64_LOAD):
  980. DEF_OP_LOAD(PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr)));
  981. HANDLE_OP_END ();
  982. HANDLE_OP (WASM_OP_I32_LOAD8_S):
  983. DEF_OP_LOAD(PUSH_I32(sign_ext_8_32(*(int8*)maddr)));
  984. HANDLE_OP_END ();
  985. HANDLE_OP (WASM_OP_I32_LOAD8_U):
  986. DEF_OP_LOAD(PUSH_I32((uint32)(*(uint8*)maddr)));
  987. HANDLE_OP_END ();
  988. HANDLE_OP (WASM_OP_I32_LOAD16_S):
  989. DEF_OP_LOAD(PUSH_I32(sign_ext_16_32(*(int16*)maddr)));
  990. HANDLE_OP_END ();
  991. HANDLE_OP (WASM_OP_I32_LOAD16_U):
  992. DEF_OP_LOAD(PUSH_I32((uint32)(*(uint16*)maddr)));
  993. HANDLE_OP_END ();
  994. HANDLE_OP (WASM_OP_I64_LOAD8_S):
  995. DEF_OP_LOAD(PUSH_I64(sign_ext_8_64(*(int8*)maddr)));
  996. HANDLE_OP_END ();
  997. HANDLE_OP (WASM_OP_I64_LOAD8_U):
  998. DEF_OP_LOAD(PUSH_I64((uint64)(*(uint8*)maddr)));
  999. HANDLE_OP_END ();
  1000. HANDLE_OP (WASM_OP_I64_LOAD16_S):
  1001. DEF_OP_LOAD(PUSH_I64(sign_ext_16_64(*(int16*)maddr)));
  1002. HANDLE_OP_END ();
  1003. HANDLE_OP (WASM_OP_I64_LOAD16_U):
  1004. DEF_OP_LOAD(PUSH_I64((uint64)(*(uint16*)maddr)));
  1005. HANDLE_OP_END ();
  1006. HANDLE_OP (WASM_OP_I64_LOAD32_S):
  1007. DEF_OP_LOAD(PUSH_I64(sign_ext_32_64(*(int32*)maddr)));
  1008. HANDLE_OP_END ();
  1009. HANDLE_OP (WASM_OP_I64_LOAD32_U):
  1010. DEF_OP_LOAD(PUSH_I64((uint64)(*(uint32*)maddr)));
  1011. HANDLE_OP_END ();
  1012. /* memory store instructions */
  1013. HANDLE_OP (WASM_OP_I32_STORE):
  1014. DEF_OP_STORE(uint32, I32, *(int32*)maddr = sval);
  1015. HANDLE_OP_END ();
  1016. HANDLE_OP (WASM_OP_I64_STORE):
  1017. DEF_OP_STORE(uint64, I64, PUT_I64_TO_ADDR((uint32*)maddr, sval));
  1018. HANDLE_OP_END ();
  1019. HANDLE_OP (WASM_OP_F32_STORE):
  1020. {
  1021. uint32 offset, flags, addr;
  1022. GET_OPCODE();
  1023. read_leb_uint32(frame_ip, frame_ip_end, flags);
  1024. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1025. frame_sp--;
  1026. addr = POP_I32();
  1027. CHECK_MEMORY_OVERFLOW();
  1028. *(uint32*)maddr = frame_sp[1];
  1029. (void)flags;
  1030. HANDLE_OP_END ();
  1031. }
  1032. HANDLE_OP (WASM_OP_F64_STORE):
  1033. {
  1034. uint32 offset, flags, addr;
  1035. GET_OPCODE();
  1036. read_leb_uint32(frame_ip, frame_ip_end, flags);
  1037. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1038. frame_sp -= 2;
  1039. addr = POP_I32();
  1040. CHECK_MEMORY_OVERFLOW();
  1041. *(uint32*)maddr = frame_sp[1];
  1042. *((uint32*)maddr + 1) = frame_sp[2];
  1043. (void)flags;
  1044. HANDLE_OP_END ();
  1045. }
  1046. HANDLE_OP (WASM_OP_I32_STORE8):
  1047. DEF_OP_STORE(uint32, I32, *(uint8*)maddr = (uint8)sval);
  1048. HANDLE_OP_END ();
  1049. HANDLE_OP (WASM_OP_I32_STORE16):
  1050. DEF_OP_STORE(uint32, I32, *(uint16*)maddr = (uint16)sval);
  1051. HANDLE_OP_END ();
  1052. HANDLE_OP (WASM_OP_I64_STORE8):
  1053. DEF_OP_STORE(uint64, I64, *(uint8*)maddr = (uint8)sval);
  1054. HANDLE_OP_END ();
  1055. HANDLE_OP (WASM_OP_I64_STORE16):
  1056. DEF_OP_STORE(uint64, I64, *(uint16*)maddr = (uint16)sval);
  1057. HANDLE_OP_END ();
  1058. HANDLE_OP (WASM_OP_I64_STORE32):
  1059. DEF_OP_STORE(uint64, I64, *(uint32*)maddr = (uint32)sval);
  1060. HANDLE_OP_END ();
  1061. /* memory size and memory grow instructions */
  1062. HANDLE_OP (WASM_OP_MEMORY_SIZE):
  1063. {
  1064. uint32 reserved;
  1065. read_leb_uint32(frame_ip, frame_ip_end, reserved);
  1066. PUSH_I32(memory->cur_page_count);
  1067. (void)reserved;
  1068. HANDLE_OP_END ();
  1069. }
  1070. HANDLE_OP (WASM_OP_MEMORY_GROW):
  1071. {
  1072. uint32 reserved, prev_page_count, delta, tmp;
  1073. read_leb_uint32(frame_ip, frame_ip_end, reserved);
  1074. prev_page_count = memory->cur_page_count;
  1075. delta = POP_I32();
  1076. PUSH_I32(prev_page_count);
  1077. if (delta == 0)
  1078. HANDLE_OP_END ();
  1079. else if (delta + prev_page_count > memory->max_page_count ||
  1080. delta + prev_page_count < prev_page_count) {
  1081. tmp = POP_I32();
  1082. PUSH_I32(-1);
  1083. (void)tmp;
  1084. HANDLE_OP_END ();
  1085. }
  1086. if (!wasm_runtime_enlarge_memory(module, delta))
  1087. goto got_exception;
  1088. memory = module->default_memory;
  1089. (void)reserved;
  1090. HANDLE_OP_END ();
  1091. }
  1092. /* constant instructions */
  1093. HANDLE_OP (WASM_OP_I32_CONST):
  1094. DEF_OP_I_CONST(int32, I32);
  1095. HANDLE_OP_END ();
  1096. HANDLE_OP (WASM_OP_I64_CONST):
  1097. DEF_OP_I_CONST(int64, I64);
  1098. HANDLE_OP_END ();
  1099. HANDLE_OP (WASM_OP_F32_CONST):
  1100. {
  1101. uint8 *p_float = (uint8*)frame_sp++;
  1102. for (i = 0; i < sizeof(float32); i++)
  1103. *p_float++ = *frame_ip++;
  1104. HANDLE_OP_END ();
  1105. }
  1106. HANDLE_OP (WASM_OP_F64_CONST):
  1107. {
  1108. uint8 *p_float = (uint8*)frame_sp++;
  1109. frame_sp++;
  1110. for (i = 0; i < sizeof(float64); i++)
  1111. *p_float++ = *frame_ip++;
  1112. HANDLE_OP_END ();
  1113. }
  1114. /* comparison instructions of i32 */
  1115. HANDLE_OP (WASM_OP_I32_EQZ):
  1116. DEF_OP_EQZ(I32);
  1117. HANDLE_OP_END ();
  1118. HANDLE_OP (WASM_OP_I32_EQ):
  1119. DEF_OP_CMP(uint32, I32, ==);
  1120. HANDLE_OP_END ();
  1121. HANDLE_OP (WASM_OP_I32_NE):
  1122. DEF_OP_CMP(uint32, I32, !=);
  1123. HANDLE_OP_END ();
  1124. HANDLE_OP (WASM_OP_I32_LT_S):
  1125. DEF_OP_CMP(int32, I32, <);
  1126. HANDLE_OP_END ();
  1127. HANDLE_OP (WASM_OP_I32_LT_U):
  1128. DEF_OP_CMP(uint32, I32, <);
  1129. HANDLE_OP_END ();
  1130. HANDLE_OP (WASM_OP_I32_GT_S):
  1131. DEF_OP_CMP(int32, I32, >);
  1132. HANDLE_OP_END ();
  1133. HANDLE_OP (WASM_OP_I32_GT_U):
  1134. DEF_OP_CMP(uint32, I32, >);
  1135. HANDLE_OP_END ();
  1136. HANDLE_OP (WASM_OP_I32_LE_S):
  1137. DEF_OP_CMP(int32, I32, <=);
  1138. HANDLE_OP_END ();
  1139. HANDLE_OP (WASM_OP_I32_LE_U):
  1140. DEF_OP_CMP(uint32, I32, <=);
  1141. HANDLE_OP_END ();
  1142. HANDLE_OP (WASM_OP_I32_GE_S):
  1143. DEF_OP_CMP(int32, I32, >=);
  1144. HANDLE_OP_END ();
  1145. HANDLE_OP (WASM_OP_I32_GE_U):
  1146. DEF_OP_CMP(uint32, I32, >=);
  1147. HANDLE_OP_END ();
  1148. /* comparison instructions of i64 */
  1149. HANDLE_OP (WASM_OP_I64_EQZ):
  1150. DEF_OP_EQZ(I64);
  1151. HANDLE_OP_END ();
  1152. HANDLE_OP (WASM_OP_I64_EQ):
  1153. DEF_OP_CMP(uint64, I64, ==);
  1154. HANDLE_OP_END ();
  1155. HANDLE_OP (WASM_OP_I64_NE):
  1156. DEF_OP_CMP(uint64, I64, !=);
  1157. HANDLE_OP_END ();
  1158. HANDLE_OP (WASM_OP_I64_LT_S):
  1159. DEF_OP_CMP(int64, I64, <);
  1160. HANDLE_OP_END ();
  1161. HANDLE_OP (WASM_OP_I64_LT_U):
  1162. DEF_OP_CMP(uint64, I64, <);
  1163. HANDLE_OP_END ();
  1164. HANDLE_OP (WASM_OP_I64_GT_S):
  1165. DEF_OP_CMP(int64, I64, >);
  1166. HANDLE_OP_END ();
  1167. HANDLE_OP (WASM_OP_I64_GT_U):
  1168. DEF_OP_CMP(uint64, I64, >);
  1169. HANDLE_OP_END ();
  1170. HANDLE_OP (WASM_OP_I64_LE_S):
  1171. DEF_OP_CMP(int64, I64, <=);
  1172. HANDLE_OP_END ();
  1173. HANDLE_OP (WASM_OP_I64_LE_U):
  1174. DEF_OP_CMP(uint64, I64, <=);
  1175. HANDLE_OP_END ();
  1176. HANDLE_OP (WASM_OP_I64_GE_S):
  1177. DEF_OP_CMP(int64, I64, >=);
  1178. HANDLE_OP_END ();
  1179. HANDLE_OP (WASM_OP_I64_GE_U):
  1180. DEF_OP_CMP(uint64, I64, >=);
  1181. HANDLE_OP_END ();
  1182. /* comparison instructions of f32 */
  1183. HANDLE_OP (WASM_OP_F32_EQ):
  1184. DEF_OP_CMP(float32, F32, ==);
  1185. HANDLE_OP_END ();
  1186. HANDLE_OP (WASM_OP_F32_NE):
  1187. DEF_OP_CMP(float32, F32, !=);
  1188. HANDLE_OP_END ();
  1189. HANDLE_OP (WASM_OP_F32_LT):
  1190. DEF_OP_CMP(float32, F32, <);
  1191. HANDLE_OP_END ();
  1192. HANDLE_OP (WASM_OP_F32_GT):
  1193. DEF_OP_CMP(float32, F32, >);
  1194. HANDLE_OP_END ();
  1195. HANDLE_OP (WASM_OP_F32_LE):
  1196. DEF_OP_CMP(float32, F32, <=);
  1197. HANDLE_OP_END ();
  1198. HANDLE_OP (WASM_OP_F32_GE):
  1199. DEF_OP_CMP(float32, F32, >=);
  1200. HANDLE_OP_END ();
  1201. /* comparison instructions of f64 */
  1202. HANDLE_OP (WASM_OP_F64_EQ):
  1203. DEF_OP_CMP(float64, F64, ==);
  1204. HANDLE_OP_END ();
  1205. HANDLE_OP (WASM_OP_F64_NE):
  1206. DEF_OP_CMP(float64, F64, !=);
  1207. HANDLE_OP_END ();
  1208. HANDLE_OP (WASM_OP_F64_LT):
  1209. DEF_OP_CMP(float64, F64, <);
  1210. HANDLE_OP_END ();
  1211. HANDLE_OP (WASM_OP_F64_GT):
  1212. DEF_OP_CMP(float64, F64, >);
  1213. HANDLE_OP_END ();
  1214. HANDLE_OP (WASM_OP_F64_LE):
  1215. DEF_OP_CMP(float64, F64, <=);
  1216. HANDLE_OP_END ();
  1217. HANDLE_OP (WASM_OP_F64_GE):
  1218. DEF_OP_CMP(float64, F64, >=);
  1219. HANDLE_OP_END ();
  1220. /* numberic instructions of i32 */
  1221. HANDLE_OP (WASM_OP_I32_CLZ):
  1222. DEF_OP_BIT_COUNT(uint32, I32, clz32);
  1223. HANDLE_OP_END ();
  1224. HANDLE_OP (WASM_OP_I32_CTZ):
  1225. DEF_OP_BIT_COUNT(uint32, I32, ctz32);
  1226. HANDLE_OP_END ();
  1227. HANDLE_OP (WASM_OP_I32_POPCNT):
  1228. DEF_OP_BIT_COUNT(uint32, I32, popcount32);
  1229. HANDLE_OP_END ();
  1230. HANDLE_OP (WASM_OP_I32_ADD):
  1231. DEF_OP_NUMERIC(uint32, uint32, I32, +);
  1232. HANDLE_OP_END ();
  1233. HANDLE_OP (WASM_OP_I32_SUB):
  1234. DEF_OP_NUMERIC(uint32, uint32, I32, -);
  1235. HANDLE_OP_END ();
  1236. HANDLE_OP (WASM_OP_I32_MUL):
  1237. DEF_OP_NUMERIC(uint32, uint32, I32, *);
  1238. HANDLE_OP_END ();
  1239. HANDLE_OP (WASM_OP_I32_DIV_S):
  1240. {
  1241. int32 a, b;
  1242. b = POP_I32();
  1243. a = POP_I32();
  1244. if (a == (int32)0x80000000 && b == -1) {
  1245. wasm_runtime_set_exception(module, "integer overflow");
  1246. goto got_exception;
  1247. }
  1248. if (b == 0) {
  1249. wasm_runtime_set_exception(module, "integer divide by zero");
  1250. goto got_exception;
  1251. }
  1252. PUSH_I32(a / b);
  1253. HANDLE_OP_END ();
  1254. }
  1255. HANDLE_OP (WASM_OP_I32_DIV_U):
  1256. {
  1257. uint32 a, b;
  1258. b = POP_I32();
  1259. a = POP_I32();
  1260. if (b == 0) {
  1261. wasm_runtime_set_exception(module, "integer divide by zero");
  1262. goto got_exception;
  1263. }
  1264. PUSH_I32(a / b);
  1265. HANDLE_OP_END ();
  1266. }
  1267. HANDLE_OP (WASM_OP_I32_REM_S):
  1268. {
  1269. int32 a, b;
  1270. b = POP_I32();
  1271. a = POP_I32();
  1272. if (a == (int32)0x80000000 && b == -1) {
  1273. PUSH_I32(0);
  1274. HANDLE_OP_END ();
  1275. }
  1276. if (b == 0) {
  1277. wasm_runtime_set_exception(module, "integer divide by zero");
  1278. goto got_exception;
  1279. }
  1280. PUSH_I32(a % b);
  1281. HANDLE_OP_END ();
  1282. }
  1283. HANDLE_OP (WASM_OP_I32_REM_U):
  1284. {
  1285. uint32 a, b;
  1286. b = POP_I32();
  1287. a = POP_I32();
  1288. if (b == 0) {
  1289. wasm_runtime_set_exception(module, "integer divide by zero");
  1290. goto got_exception;
  1291. }
  1292. PUSH_I32(a % b);
  1293. HANDLE_OP_END ();
  1294. }
  1295. HANDLE_OP (WASM_OP_I32_AND):
  1296. DEF_OP_NUMERIC(uint32, uint32, I32, &);
  1297. HANDLE_OP_END ();
  1298. HANDLE_OP (WASM_OP_I32_OR):
  1299. DEF_OP_NUMERIC(uint32, uint32, I32, |);
  1300. HANDLE_OP_END ();
  1301. HANDLE_OP (WASM_OP_I32_XOR):
  1302. DEF_OP_NUMERIC(uint32, uint32, I32, ^);
  1303. HANDLE_OP_END ();
  1304. HANDLE_OP (WASM_OP_I32_SHL):
  1305. DEF_OP_NUMERIC(uint32, uint32, I32, <<);
  1306. HANDLE_OP_END ();
  1307. HANDLE_OP (WASM_OP_I32_SHR_S):
  1308. DEF_OP_NUMERIC(int32, uint32, I32, >>);
  1309. HANDLE_OP_END ();
  1310. HANDLE_OP (WASM_OP_I32_SHR_U):
  1311. DEF_OP_NUMERIC(uint32, uint32, I32, >>);
  1312. HANDLE_OP_END ();
  1313. HANDLE_OP (WASM_OP_I32_ROTL):
  1314. {
  1315. uint32 a, b;
  1316. b = POP_I32();
  1317. a = POP_I32();
  1318. PUSH_I32(rotl32(a, b));
  1319. HANDLE_OP_END ();
  1320. }
  1321. HANDLE_OP (WASM_OP_I32_ROTR):
  1322. {
  1323. uint32 a, b;
  1324. b = POP_I32();
  1325. a = POP_I32();
  1326. PUSH_I32(rotr32(a, b));
  1327. HANDLE_OP_END ();
  1328. }
  1329. /* numberic instructions of i64 */
  1330. HANDLE_OP (WASM_OP_I64_CLZ):
  1331. DEF_OP_BIT_COUNT(uint64, I64, clz64);
  1332. HANDLE_OP_END ();
  1333. HANDLE_OP (WASM_OP_I64_CTZ):
  1334. DEF_OP_BIT_COUNT(uint64, I64, ctz64);
  1335. HANDLE_OP_END ();
  1336. HANDLE_OP (WASM_OP_I64_POPCNT):
  1337. DEF_OP_BIT_COUNT(uint64, I64, popcount64);
  1338. HANDLE_OP_END ();
  1339. HANDLE_OP (WASM_OP_I64_ADD):
  1340. DEF_OP_NUMERIC(uint64, uint64, I64, +);
  1341. HANDLE_OP_END ();
  1342. HANDLE_OP (WASM_OP_I64_SUB):
  1343. DEF_OP_NUMERIC(uint64, uint64, I64, -);
  1344. HANDLE_OP_END ();
  1345. HANDLE_OP (WASM_OP_I64_MUL):
  1346. DEF_OP_NUMERIC(uint64, uint64, I64, *);
  1347. HANDLE_OP_END ();
  1348. HANDLE_OP (WASM_OP_I64_DIV_S):
  1349. {
  1350. int64 a, b;
  1351. b = POP_I64();
  1352. a = POP_I64();
  1353. if (a == (int64)0x8000000000000000LL && b == -1) {
  1354. wasm_runtime_set_exception(module, "integer overflow");
  1355. goto got_exception;
  1356. }
  1357. if (b == 0) {
  1358. wasm_runtime_set_exception(module, "integer divide by zero");
  1359. goto got_exception;
  1360. }
  1361. PUSH_I64(a / b);
  1362. HANDLE_OP_END ();
  1363. }
  1364. HANDLE_OP (WASM_OP_I64_DIV_U):
  1365. {
  1366. uint64 a, b;
  1367. b = POP_I64();
  1368. a = POP_I64();
  1369. if (b == 0) {
  1370. wasm_runtime_set_exception(module, "integer divide by zero");
  1371. goto got_exception;
  1372. }
  1373. PUSH_I64(a / b);
  1374. HANDLE_OP_END ();
  1375. }
  1376. HANDLE_OP (WASM_OP_I64_REM_S):
  1377. {
  1378. int64 a, b;
  1379. b = POP_I64();
  1380. a = POP_I64();
  1381. if (a == (int64)0x8000000000000000LL && b == -1) {
  1382. PUSH_I64(0);
  1383. HANDLE_OP_END ();
  1384. }
  1385. if (b == 0) {
  1386. wasm_runtime_set_exception(module, "integer divide by zero");
  1387. goto got_exception;
  1388. }
  1389. PUSH_I64(a % b);
  1390. HANDLE_OP_END ();
  1391. }
  1392. HANDLE_OP (WASM_OP_I64_REM_U):
  1393. {
  1394. uint64 a, b;
  1395. b = POP_I64();
  1396. a = POP_I64();
  1397. if (b == 0) {
  1398. wasm_runtime_set_exception(module, "integer divide by zero");
  1399. goto got_exception;
  1400. }
  1401. PUSH_I64(a % b);
  1402. HANDLE_OP_END ();
  1403. }
  1404. HANDLE_OP (WASM_OP_I64_AND):
  1405. DEF_OP_NUMERIC(uint64, uint64, I64, &);
  1406. HANDLE_OP_END ();
  1407. HANDLE_OP (WASM_OP_I64_OR):
  1408. DEF_OP_NUMERIC(uint64, uint64, I64, |);
  1409. HANDLE_OP_END ();
  1410. HANDLE_OP (WASM_OP_I64_XOR):
  1411. DEF_OP_NUMERIC(uint64, uint64, I64, ^);
  1412. HANDLE_OP_END ();
  1413. HANDLE_OP (WASM_OP_I64_SHL):
  1414. DEF_OP_NUMERIC(uint64, uint64, I64, <<);
  1415. HANDLE_OP_END ();
  1416. HANDLE_OP (WASM_OP_I64_SHR_S):
  1417. DEF_OP_NUMERIC(int64, uint64, I64, >>);
  1418. HANDLE_OP_END ();
  1419. HANDLE_OP (WASM_OP_I64_SHR_U):
  1420. DEF_OP_NUMERIC(uint64, uint64, I64, >>);
  1421. HANDLE_OP_END ();
  1422. HANDLE_OP (WASM_OP_I64_ROTL):
  1423. {
  1424. uint64 a, b;
  1425. b = POP_I64();
  1426. a = POP_I64();
  1427. PUSH_I64(rotl64(a, b));
  1428. HANDLE_OP_END ();
  1429. }
  1430. HANDLE_OP (WASM_OP_I64_ROTR):
  1431. {
  1432. uint64 a, b;
  1433. b = POP_I64();
  1434. a = POP_I64();
  1435. PUSH_I64(rotr64(a, b));
  1436. HANDLE_OP_END ();
  1437. }
  1438. /* numberic instructions of f32 */
  1439. HANDLE_OP (WASM_OP_F32_ABS):
  1440. DEF_OP_MATH(float32, F32, fabs);
  1441. HANDLE_OP_END ();
  1442. HANDLE_OP (WASM_OP_F32_NEG):
  1443. DEF_OP_MATH(float32, F32, -);
  1444. HANDLE_OP_END ();
  1445. HANDLE_OP (WASM_OP_F32_CEIL):
  1446. DEF_OP_MATH(float32, F32, ceil);
  1447. HANDLE_OP_END ();
  1448. HANDLE_OP (WASM_OP_F32_FLOOR):
  1449. DEF_OP_MATH(float32, F32, floor);
  1450. HANDLE_OP_END ();
  1451. HANDLE_OP (WASM_OP_F32_TRUNC):
  1452. DEF_OP_MATH(float32, F32, trunc);
  1453. HANDLE_OP_END ();
  1454. HANDLE_OP (WASM_OP_F32_NEAREST):
  1455. DEF_OP_MATH(float32, F32, rint);
  1456. HANDLE_OP_END ();
  1457. HANDLE_OP (WASM_OP_F32_SQRT):
  1458. DEF_OP_MATH(float32, F32, sqrt);
  1459. HANDLE_OP_END ();
  1460. HANDLE_OP (WASM_OP_F32_ADD):
  1461. DEF_OP_NUMERIC(float32, float32, F32, +);
  1462. HANDLE_OP_END ();
  1463. HANDLE_OP (WASM_OP_F32_SUB):
  1464. DEF_OP_NUMERIC(float32, float32, F32, -);
  1465. HANDLE_OP_END ();
  1466. HANDLE_OP (WASM_OP_F32_MUL):
  1467. DEF_OP_NUMERIC(float32, float32, F32, *);
  1468. HANDLE_OP_END ();
  1469. HANDLE_OP (WASM_OP_F32_DIV):
  1470. DEF_OP_NUMERIC(float32, float32, F32, /);
  1471. HANDLE_OP_END ();
  1472. HANDLE_OP (WASM_OP_F32_MIN):
  1473. {
  1474. float32 a, b;
  1475. b = POP_F32();
  1476. a = POP_F32();
  1477. PUSH_F32(wa_fmin(a, b));
  1478. HANDLE_OP_END ();
  1479. }
  1480. HANDLE_OP (WASM_OP_F32_MAX):
  1481. {
  1482. float32 a, b;
  1483. b = POP_F32();
  1484. a = POP_F32();
  1485. PUSH_F32(wa_fmax(a, b));
  1486. HANDLE_OP_END ();
  1487. }
  1488. HANDLE_OP (WASM_OP_F32_COPYSIGN):
  1489. {
  1490. float32 a, b;
  1491. b = POP_F32();
  1492. a = POP_F32();
  1493. PUSH_F32(signbit(b) ? -fabs(a) : fabs(a));
  1494. HANDLE_OP_END ();
  1495. }
  1496. /* numberic instructions of f64 */
  1497. HANDLE_OP (WASM_OP_F64_ABS):
  1498. DEF_OP_MATH(float64, F64, fabs);
  1499. HANDLE_OP_END ();
  1500. HANDLE_OP (WASM_OP_F64_NEG):
  1501. DEF_OP_MATH(float64, F64, -);
  1502. HANDLE_OP_END ();
  1503. HANDLE_OP (WASM_OP_F64_CEIL):
  1504. DEF_OP_MATH(float64, F64, ceil);
  1505. HANDLE_OP_END ();
  1506. HANDLE_OP (WASM_OP_F64_FLOOR):
  1507. DEF_OP_MATH(float64, F64, floor);
  1508. HANDLE_OP_END ();
  1509. HANDLE_OP (WASM_OP_F64_TRUNC):
  1510. DEF_OP_MATH(float64, F64, trunc);
  1511. HANDLE_OP_END ();
  1512. HANDLE_OP (WASM_OP_F64_NEAREST):
  1513. DEF_OP_MATH(float64, F64, rint);
  1514. HANDLE_OP_END ();
  1515. HANDLE_OP (WASM_OP_F64_SQRT):
  1516. DEF_OP_MATH(float64, F64, sqrt);
  1517. HANDLE_OP_END ();
  1518. HANDLE_OP (WASM_OP_F64_ADD):
  1519. DEF_OP_NUMERIC(float64, float64, F64, +);
  1520. HANDLE_OP_END ();
  1521. HANDLE_OP (WASM_OP_F64_SUB):
  1522. DEF_OP_NUMERIC(float64, float64, F64, -);
  1523. HANDLE_OP_END ();
  1524. HANDLE_OP (WASM_OP_F64_MUL):
  1525. DEF_OP_NUMERIC(float64, float64, F64, *);
  1526. HANDLE_OP_END ();
  1527. HANDLE_OP (WASM_OP_F64_DIV):
  1528. DEF_OP_NUMERIC(float64, float64, F64, /);
  1529. HANDLE_OP_END ();
  1530. HANDLE_OP (WASM_OP_F64_MIN):
  1531. {
  1532. float64 a, b;
  1533. b = POP_F64();
  1534. a = POP_F64();
  1535. PUSH_F64(wa_fmin(a, b));
  1536. HANDLE_OP_END ();
  1537. }
  1538. HANDLE_OP (WASM_OP_F64_MAX):
  1539. {
  1540. float64 a, b;
  1541. b = POP_F64();
  1542. a = POP_F64();
  1543. PUSH_F64(wa_fmax(a, b));
  1544. HANDLE_OP_END ();
  1545. }
  1546. HANDLE_OP (WASM_OP_F64_COPYSIGN):
  1547. {
  1548. float64 a, b;
  1549. b = POP_F64();
  1550. a = POP_F64();
  1551. PUSH_F64(signbit(b) ? -fabs(a) : fabs(a));
  1552. HANDLE_OP_END ();
  1553. }
  1554. /* conversions of i32 */
  1555. HANDLE_OP (WASM_OP_I32_WRAP_I64):
  1556. {
  1557. int32 value = (int32)(POP_I64() & 0xFFFFFFFFLL);
  1558. PUSH_I32(value);
  1559. HANDLE_OP_END ();
  1560. }
  1561. HANDLE_OP (WASM_OP_I32_TRUNC_S_F32):
  1562. /* Copy the float32/float64 values from WAVM, need to test more.
  1563. We don't use INT32_MIN/INT32_MAX/UINT32_MIN/UINT32_MAX,
  1564. since float/double values of ieee754 cannot precisely represent
  1565. all int32/uint32/int64/uint64 values, e.g.:
  1566. UINT32_MAX is 4294967295, but (float32)4294967295 is 4294967296.0f,
  1567. but not 4294967295.0f. */
  1568. DEF_OP_TRUNC(int32, I32, float32, F32, <= -2147483904.0f,
  1569. >= 2147483648.0f);
  1570. HANDLE_OP_END ();
  1571. HANDLE_OP (WASM_OP_I32_TRUNC_U_F32):
  1572. DEF_OP_TRUNC(uint32, I32, float32, F32, <= -1.0f,
  1573. >= 4294967296.0f);
  1574. HANDLE_OP_END ();
  1575. HANDLE_OP (WASM_OP_I32_TRUNC_S_F64):
  1576. DEF_OP_TRUNC(int32, I32, float64, F64, <= -2147483649.0,
  1577. >= 2147483648.0);
  1578. HANDLE_OP_END ();
  1579. HANDLE_OP (WASM_OP_I32_TRUNC_U_F64):
  1580. DEF_OP_TRUNC(uint32, I32, float64, F64, <= -1.0 ,
  1581. >= 4294967296.0);
  1582. HANDLE_OP_END ();
  1583. /* conversions of i64 */
  1584. HANDLE_OP (WASM_OP_I64_EXTEND_S_I32):
  1585. DEF_OP_CONVERT(int64, I64, int32, I32);
  1586. HANDLE_OP_END ();
  1587. HANDLE_OP (WASM_OP_I64_EXTEND_U_I32):
  1588. DEF_OP_CONVERT(int64, I64, uint32, I32);
  1589. HANDLE_OP_END ();
  1590. HANDLE_OP (WASM_OP_I64_TRUNC_S_F32):
  1591. DEF_OP_TRUNC(int64, I64, float32, F32, <= -9223373136366403584.0f,
  1592. >= 9223372036854775808.0f);
  1593. HANDLE_OP_END ();
  1594. HANDLE_OP (WASM_OP_I64_TRUNC_U_F32):
  1595. DEF_OP_TRUNC(uint64, I64, float32, F32, <= -1.0f,
  1596. >= 18446744073709551616.0f);
  1597. HANDLE_OP_END ();
  1598. HANDLE_OP (WASM_OP_I64_TRUNC_S_F64):
  1599. DEF_OP_TRUNC(int64, I64, float64, F64, <= -9223372036854777856.0,
  1600. >= 9223372036854775808.0);
  1601. HANDLE_OP_END ();
  1602. HANDLE_OP (WASM_OP_I64_TRUNC_U_F64):
  1603. DEF_OP_TRUNC(uint64, I64, float64, F64, <= -1.0,
  1604. >= 18446744073709551616.0);
  1605. HANDLE_OP_END ();
  1606. /* conversions of f32 */
  1607. HANDLE_OP (WASM_OP_F32_CONVERT_S_I32):
  1608. DEF_OP_CONVERT(float32, F32, int32, I32);
  1609. HANDLE_OP_END ();
  1610. HANDLE_OP (WASM_OP_F32_CONVERT_U_I32):
  1611. DEF_OP_CONVERT(float32, F32, uint32, I32);
  1612. HANDLE_OP_END ();
  1613. HANDLE_OP (WASM_OP_F32_CONVERT_S_I64):
  1614. DEF_OP_CONVERT(float32, F32, int64, I64);
  1615. HANDLE_OP_END ();
  1616. HANDLE_OP (WASM_OP_F32_CONVERT_U_I64):
  1617. DEF_OP_CONVERT(float32, F32, uint64, I64);
  1618. HANDLE_OP_END ();
  1619. HANDLE_OP (WASM_OP_F32_DEMOTE_F64):
  1620. DEF_OP_CONVERT(float32, F32, float64, F64);
  1621. HANDLE_OP_END ();
  1622. /* conversions of f64 */
  1623. HANDLE_OP (WASM_OP_F64_CONVERT_S_I32):
  1624. DEF_OP_CONVERT(float64, F64, int32, I32);
  1625. HANDLE_OP_END ();
  1626. HANDLE_OP (WASM_OP_F64_CONVERT_U_I32):
  1627. DEF_OP_CONVERT(float64, F64, uint32, I32);
  1628. HANDLE_OP_END ();
  1629. HANDLE_OP (WASM_OP_F64_CONVERT_S_I64):
  1630. DEF_OP_CONVERT(float64, F64, int64, I64);
  1631. HANDLE_OP_END ();
  1632. HANDLE_OP (WASM_OP_F64_CONVERT_U_I64):
  1633. DEF_OP_CONVERT(float64, F64, uint64, I64);
  1634. HANDLE_OP_END ();
  1635. HANDLE_OP (WASM_OP_F64_PROMOTE_F32):
  1636. DEF_OP_CONVERT(float64, F64, float32, F32);
  1637. HANDLE_OP_END ();
  1638. /* reinterpretations */
  1639. HANDLE_OP (WASM_OP_I32_REINTERPRET_F32):
  1640. HANDLE_OP (WASM_OP_I64_REINTERPRET_F64):
  1641. HANDLE_OP (WASM_OP_F32_REINTERPRET_I32):
  1642. HANDLE_OP (WASM_OP_F64_REINTERPRET_I64):
  1643. HANDLE_OP_END ();
  1644. HANDLE_OP (WASM_OP_IMPDEP2):
  1645. frame = prev_frame;
  1646. frame_ip = frame->ip;
  1647. frame_sp = frame->sp;
  1648. frame_csp = frame->csp;
  1649. goto call_func_from_entry;
  1650. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  1651. default:
  1652. wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode");
  1653. goto got_exception;
  1654. }
  1655. #endif
  1656. #if WASM_ENABLE_LABELS_AS_VALUES != 0
  1657. HANDLE_OP (WASM_OP_IMPDEP1):
  1658. HANDLE_OP (WASM_OP_UNUSED_0x06):
  1659. HANDLE_OP (WASM_OP_UNUSED_0x07):
  1660. HANDLE_OP (WASM_OP_UNUSED_0x08):
  1661. HANDLE_OP (WASM_OP_UNUSED_0x09):
  1662. HANDLE_OP (WASM_OP_UNUSED_0x0a):
  1663. HANDLE_OP (WASM_OP_UNUSED_0x12):
  1664. HANDLE_OP (WASM_OP_UNUSED_0x13):
  1665. HANDLE_OP (WASM_OP_UNUSED_0x14):
  1666. HANDLE_OP (WASM_OP_UNUSED_0x15):
  1667. HANDLE_OP (WASM_OP_UNUSED_0x16):
  1668. HANDLE_OP (WASM_OP_UNUSED_0x17):
  1669. HANDLE_OP (WASM_OP_UNUSED_0x18):
  1670. HANDLE_OP (WASM_OP_UNUSED_0x19):
  1671. HANDLE_OP (WASM_OP_UNUSED_0x1c):
  1672. HANDLE_OP (WASM_OP_UNUSED_0x1d):
  1673. HANDLE_OP (WASM_OP_UNUSED_0x1e):
  1674. HANDLE_OP (WASM_OP_UNUSED_0x1f):
  1675. HANDLE_OP (WASM_OP_UNUSED_0x25):
  1676. HANDLE_OP (WASM_OP_UNUSED_0x26):
  1677. HANDLE_OP (WASM_OP_UNUSED_0x27):
  1678. {
  1679. wasm_runtime_set_exception(module, "wasm interp failed: unsupported opcode");
  1680. goto got_exception;
  1681. }
  1682. #endif
  1683. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  1684. continue;
  1685. #else
  1686. FETCH_OPCODE_AND_DISPATCH ();
  1687. #endif
  1688. call_func_from_interp:
  1689. /* Only do the copy when it's called from interpreter. */
  1690. {
  1691. WASMInterpFrame *outs_area = wasm_thread_wasm_stack_top(self);
  1692. POP(cur_func->param_cell_num);
  1693. SYNC_ALL_TO_FRAME();
  1694. word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num);
  1695. prev_frame = frame;
  1696. }
  1697. call_func_from_entry:
  1698. {
  1699. if (cur_func->is_import_func) {
  1700. wasm_interp_call_func_native(self, cur_func, prev_frame);
  1701. prev_frame = frame->prev_frame;
  1702. cur_func = frame->function;
  1703. UPDATE_ALL_FROM_FRAME();
  1704. memory = module->default_memory;
  1705. if (wasm_runtime_get_exception(module))
  1706. goto got_exception;
  1707. }
  1708. else {
  1709. WASMType *func_type;
  1710. uint8 ret_type;
  1711. all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num
  1712. + cur_func->u.func->max_stack_cell_num
  1713. + cur_func->u.func->max_block_num * sizeof(WASMBranchBlock) / 4;
  1714. frame_size = wasm_interp_interp_frame_size(all_cell_num);
  1715. if (!(frame = ALLOC_FRAME(self, frame_size, prev_frame))) {
  1716. frame = prev_frame;
  1717. goto got_exception;
  1718. }
  1719. /* Initialize the interpreter context. */
  1720. frame->function = cur_func;
  1721. frame_ip = wasm_runtime_get_func_code(cur_func);
  1722. frame_ip_end = wasm_runtime_get_func_code_end(cur_func);
  1723. frame_lp = frame->lp;
  1724. frame_sp = frame->sp_bottom = frame_lp + cur_func->param_cell_num
  1725. + cur_func->local_cell_num;
  1726. frame->sp_boundary = frame->sp_bottom + cur_func->u.func->max_stack_cell_num;
  1727. frame_csp = frame->csp_bottom = (WASMBranchBlock*)frame->sp_boundary;
  1728. frame->csp_boundary = frame->csp_bottom + cur_func->u.func->max_block_num;
  1729. /* Initialize the local varialbes */
  1730. memset(frame_lp + cur_func->param_cell_num, 0,
  1731. cur_func->local_cell_num * 4);
  1732. /* Push function block as first block */
  1733. func_type = cur_func->u.func->func_type;
  1734. ret_type = func_type->result_count
  1735. ? func_type->types[func_type->param_count]
  1736. : VALUE_TYPE_VOID;
  1737. PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type,
  1738. frame_ip, NULL, frame_ip_end - 1);
  1739. wasm_thread_set_cur_frame(self, (WASMRuntimeFrame*)frame);
  1740. }
  1741. HANDLE_OP_END ();
  1742. }
  1743. return_func:
  1744. {
  1745. FREE_FRAME(self, frame);
  1746. wasm_thread_set_cur_frame(self, (WASMRuntimeFrame*)prev_frame);
  1747. if (!prev_frame->ip)
  1748. /* Called from native. */
  1749. return;
  1750. RECOVER_CONTEXT(prev_frame);
  1751. HANDLE_OP_END ();
  1752. }
  1753. got_exception:
  1754. if (depths && depths != depth_buf) {
  1755. wasm_free(depths);
  1756. depths = NULL;
  1757. }
  1758. return;
  1759. #if WASM_ENABLE_LABELS_AS_VALUES == 0
  1760. }
  1761. #else
  1762. FETCH_OPCODE_AND_DISPATCH ();
  1763. #endif
  1764. }
  1765. void
  1766. wasm_interp_call_wasm(WASMFunctionInstance *function,
  1767. uint32 argc, uint32 argv[])
  1768. {
  1769. WASMThread *self = wasm_runtime_get_self();
  1770. WASMRuntimeFrame *prev_frame = wasm_thread_get_cur_frame(self);
  1771. WASMInterpFrame *frame, *outs_area;
  1772. /* Allocate sufficient cells for all kinds of return values. */
  1773. unsigned all_cell_num = 2, i;
  1774. /* This frame won't be used by JITed code, so only allocate interp
  1775. frame here. */
  1776. unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
  1777. if (argc != function->param_cell_num) {
  1778. char buf[128];
  1779. snprintf(buf, sizeof(buf),
  1780. "invalid argument count %d, expected %d",
  1781. argc, function->param_cell_num);
  1782. wasm_runtime_set_exception(self->module_inst, buf);
  1783. return;
  1784. }
  1785. /* TODO: check stack overflow. */
  1786. if (!(frame = ALLOC_FRAME(self, frame_size, (WASMInterpFrame*)prev_frame)))
  1787. return;
  1788. outs_area = wasm_thread_wasm_stack_top(self);
  1789. frame->function = NULL;
  1790. frame->ip = NULL;
  1791. /* There is no local variable. */
  1792. frame->sp = frame->lp + 0;
  1793. if (argc > 0)
  1794. word_copy(outs_area->lp, argv, argc);
  1795. wasm_thread_set_cur_frame(self, frame);
  1796. if (function->is_import_func)
  1797. wasm_interp_call_func_native(self, function, frame);
  1798. else
  1799. wasm_interp_call_func_bytecode(self, function, frame);
  1800. /* Output the return value to the caller */
  1801. if (!wasm_runtime_get_exception(self->module_inst)) {
  1802. for (i = 0; i < function->ret_cell_num; i++)
  1803. argv[i] = *(frame->sp + i - function->ret_cell_num);
  1804. }
  1805. wasm_thread_set_cur_frame(self, prev_frame);
  1806. FREE_FRAME(self, frame);
  1807. }