wasm_interp.c 68 KB

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