test-vm.scm 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024
  1. ;;; WebAssembly virtual machine
  2. ;;; Copyright (C) 2023 David Thompson <dave@spritely.institute>
  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. ;;; Commentary:
  16. ;;;
  17. ;;; Virtual machine tests.
  18. ;;;
  19. ;;; Code:
  20. (use-modules (ice-9 binary-ports)
  21. (ice-9 exceptions)
  22. (ice-9 popen)
  23. (ice-9 textual-ports)
  24. (srfi srfi-64)
  25. (test utils)
  26. (wasm wat)
  27. (wasm lower)
  28. (wasm assemble)
  29. (wasm vm))
  30. (define s32-overflow (@@ (wasm vm) s32-overflow))
  31. (define s64-overflow (@@ (wasm vm) s64-overflow))
  32. (define (run-d8 read args)
  33. (let* ((args (cons* "--experimental-wasm-stringref" args))
  34. (port (apply open-pipe* OPEN_READ d8 args))
  35. (result (string-trim-both (get-string-all port))))
  36. (if (zero? (close-pipe port))
  37. (call-with-input-string result read)
  38. (throw 'd8-error result))))
  39. (define (run-wasm-in-d8 wasm func read args)
  40. (call-with-compiled-wasm-file
  41. wasm
  42. (lambda (wasm-file-name)
  43. (run-d8 read
  44. (cons* (scope-file "test/load-wasm-and-print-primitive.js")
  45. "--" wasm-file-name func
  46. (map (lambda (arg) (format #f "~a" arg)) args))))))
  47. (define (run-wasm-in-vm wasm func args imports)
  48. (let ((instance (instantiate-wasm (validate-wasm wasm) #:imports imports)))
  49. (apply (wasm-instance-export-ref instance func) args)))
  50. (define (wat->wasm* wat)
  51. (lower-wasm (wat->wasm wat) #:stringref-lowering 'stringref))
  52. (define (eval-wat wat func args imports d8? d8-read)
  53. (let* ((wasm (wat->wasm* wat))
  54. (our-result (run-wasm-in-vm wasm func args imports)))
  55. (when d8?
  56. (let ((d8-result (run-wasm-in-d8 wasm func d8-read args)))
  57. (unless (if (and (number? our-result) (number? d8-result))
  58. (= our-result d8-result)
  59. (equal? our-result d8-result))
  60. (error "our result differs from d8" our-result d8-result))))
  61. our-result))
  62. (define* (test-vm name expected wat #:key
  63. (func "main") (args '()) (imports '())
  64. (d8? use-d8?) (d8-read read))
  65. (test-equal name
  66. expected
  67. (eval-wat wat func args imports d8? d8-read)))
  68. (define (eval-wat/error wat func args imports d8? d8-read)
  69. (let ((wasm (wat->wasm* wat)))
  70. (define (handle-error e)
  71. (if d8?
  72. (with-exception-handler (lambda (e) #t)
  73. (lambda ()
  74. (let ((result (run-wasm-in-d8 wasm func d8-read args)))
  75. (error "d8 did not throw an error" result))
  76. #f)
  77. #:unwind? #t
  78. #:unwind-for-type 'd8-error)
  79. #t))
  80. (with-exception-handler handle-error
  81. (lambda ()
  82. (run-wasm-in-vm wasm func args imports)
  83. #f)
  84. #:unwind? #t
  85. #:unwind-for-type &wasm-error)))
  86. (define* (test-vm/error name wat #:key
  87. (func "main") (args '()) (imports '())
  88. (d8? #t) (d8-read read))
  89. (test-assert name
  90. (eval-wat/error wat func args imports d8? d8-read)))
  91. ;; For temporarily testing something that doesn't work in our VM yet.
  92. (define (eval-d8 wat func read args)
  93. (run-wasm-in-d8 (wat->wasm* wat) func read args))
  94. (define* (test-d8 name expected wat #:key (func "main") (args '()) (read read))
  95. (test-equal name
  96. expected
  97. (eval-d8 wat func read args)))
  98. (test-begin "test-vm")
  99. (test-vm "i32.eqz true"
  100. 1
  101. '(module
  102. (func (export "main") (result i32)
  103. (i32.eqz (i32.const 0)))))
  104. (test-vm "i32.eqz false"
  105. 0
  106. '(module
  107. (func (export "main") (result i32)
  108. (i32.eqz (i32.const 42)))))
  109. (test-vm "i32.eq true"
  110. 1
  111. '(module
  112. (func (export "main") (result i32)
  113. (i32.eq (i32.const 42) (i32.const 42)))))
  114. (test-vm "i32.eq false"
  115. 0
  116. '(module
  117. (func (export "main") (result i32)
  118. (i32.eq (i32.const 42) (i32.const 7)))))
  119. (test-vm "i32.ne true"
  120. 1
  121. '(module
  122. (func (export "main") (result i32)
  123. (i32.ne (i32.const 42) (i32.const 7)))))
  124. (test-vm "i32.ne false"
  125. 0
  126. '(module
  127. (func (export "main") (result i32)
  128. (i32.ne (i32.const 42) (i32.const 42)))))
  129. (test-vm "i32.lt_s true"
  130. 1
  131. '(module
  132. (func (export "main") (result i32)
  133. (i32.lt_s (i32.const -42) (i32.const 42)))))
  134. (test-vm "i32.lt_s false"
  135. 0
  136. '(module
  137. (func (export "main") (result i32)
  138. (i32.lt_s (i32.const 42) (i32.const -42)))))
  139. (test-vm "i32.lt_u true"
  140. 1
  141. '(module
  142. (func (export "main") (result i32)
  143. (i32.lt_s (i32.const 7) (i32.const 42)))))
  144. (test-vm "i32.lt_u false"
  145. 0
  146. '(module
  147. (func (export "main") (result i32)
  148. (i32.lt_s (i32.const 42) (i32.const 7)))))
  149. (test-vm "i32.le_s true"
  150. 1
  151. '(module
  152. (func (export "main") (result i32)
  153. (i32.le_s (i32.const 42) (i32.const 42)))))
  154. (test-vm "i32.le_s false"
  155. 0
  156. '(module
  157. (func (export "main") (result i32)
  158. (i32.le_s (i32.const 42) (i32.const -42)))))
  159. (test-vm "i32.le_u true"
  160. 1
  161. '(module
  162. (func (export "main") (result i32)
  163. (i32.le_s (i32.const 42) (i32.const 42)))))
  164. (test-vm "i32.le_u false"
  165. 0
  166. '(module
  167. (func (export "main") (result i32)
  168. (i32.le_s (i32.const 42) (i32.const 7)))))
  169. (test-vm "i32.gt_s true"
  170. 1
  171. '(module
  172. (func (export "main") (result i32)
  173. (i32.gt_s (i32.const 42) (i32.const -42)))))
  174. (test-vm "i32.gt_s false"
  175. 0
  176. '(module
  177. (func (export "main") (result i32)
  178. (i32.gt_s (i32.const -42) (i32.const 42)))))
  179. (test-vm "i32.gt_u true"
  180. 1
  181. '(module
  182. (func (export "main") (result i32)
  183. (i32.gt_s (i32.const 42) (i32.const 7)))))
  184. (test-vm "i32.gt_u false"
  185. 0
  186. '(module
  187. (func (export "main") (result i32)
  188. (i32.gt_s (i32.const 7) (i32.const 42)))))
  189. (test-vm "i32.ge_s true"
  190. 1
  191. '(module
  192. (func (export "main") (result i32)
  193. (i32.ge_s (i32.const 42) (i32.const 42)))))
  194. (test-vm "i32.ge_s false"
  195. 0
  196. '(module
  197. (func (export "main") (result i32)
  198. (i32.ge_s (i32.const -42) (i32.const 42)))))
  199. (test-vm "i32.ge_u true"
  200. 1
  201. '(module
  202. (func (export "main") (result i32)
  203. (i32.ge_s (i32.const 42) (i32.const 42)))))
  204. (test-vm "i32.ge_u false"
  205. 0
  206. '(module
  207. (func (export "main") (result i32)
  208. (i32.ge_s (i32.const 7) (i32.const 42)))))
  209. (test-vm "i32.add"
  210. 80
  211. '(module
  212. (func (export "main") (result i32)
  213. (i32.add (i32.const 42) (i32.const 38)))))
  214. (test-vm "i32.sub"
  215. 4
  216. '(module
  217. (func (export "main") (result i32)
  218. (i32.sub (i32.const 42) (i32.const 38)))))
  219. (test-vm "i32.mul"
  220. 42
  221. '(module
  222. (func (export "main") (result i32)
  223. (i32.mul (i32.const 7) (i32.const 6)))))
  224. (test-vm "i32.div_s"
  225. -6
  226. '(module
  227. (func (export "main") (result i32)
  228. (i32.div_s (i32.const -42) (i32.const 7)))))
  229. (test-vm "i32.div_u"
  230. 6
  231. '(module
  232. (func (export "main") (result i32)
  233. (i32.div_u (i32.const 42) (i32.const 7)))))
  234. (test-vm "i32.rem_s"
  235. -2
  236. '(module
  237. (func (export "main") (result i32)
  238. (i32.rem_s (i32.const -42) (i32.const 5)))))
  239. (test-vm "i32.rem_u"
  240. 2
  241. '(module
  242. (func (export "main") (result i32)
  243. (i32.rem_u (i32.const 42) (i32.const 5)))))
  244. (test-vm "i32.and"
  245. #b1010
  246. '(module
  247. (func (export "main") (result i32)
  248. (i32.and (i32.const #b1111) (i32.const #b1010)))))
  249. (test-vm "i32.or"
  250. #b1111
  251. '(module
  252. (func (export "main") (result i32)
  253. (i32.or (i32.const #b0101) (i32.const #b1010)))))
  254. (test-vm "i32.xor"
  255. #b1110
  256. '(module
  257. (func (export "main") (result i32)
  258. (i32.or (i32.const #b1010) (i32.const #b0100)))))
  259. (test-vm "i32.shl"
  260. #b1000
  261. '(module
  262. (func (export "main") (result i32)
  263. (i32.shl (i32.const #b0001) (i32.const 3)))))
  264. (test-vm "i32.shl - out of 32 bit range"
  265. 0
  266. `(module
  267. (func (export "main") (result i32)
  268. (i32.shl (i32.const ,(ash -1 31))
  269. (i32.const 2)))))
  270. (test-vm "i32.shl - more than 32 bits"
  271. #b1000
  272. '(module
  273. (func (export "main") (result i32)
  274. (i32.shl (i32.const #b0001) (i32.const 35)))))
  275. (test-vm "i32.shr_s"
  276. -2
  277. '(module
  278. (func (export "main") (result i32)
  279. (i32.shr_s (i32.const -16) (i32.const 3)))))
  280. (test-vm "i32.shr_u"
  281. #b0001
  282. '(module
  283. (func (export "main") (result i32)
  284. (i32.shr_u (i32.const #b1000) (i32.const 3)))))
  285. (test-vm "i32.shr_u - more than 32 bits"
  286. #b0001
  287. '(module
  288. (func (export "main") (result i32)
  289. (i32.shr_u (i32.const #b1000) (i32.const 35)))))
  290. (test-vm "i32.rotl"
  291. (s32-overflow #b11000011110000111100001111000011)
  292. `(module
  293. (func (export "main") (result i32)
  294. (i32.rotl (i32.const
  295. ,(s32-overflow #b11110000111100001111000011110000))
  296. (i32.const 2)))))
  297. (test-vm "i32.rotr"
  298. (s32-overflow #b00111100001111000011110000111100)
  299. `(module
  300. (func (export "main") (result i32)
  301. (i32.rotr (i32.const
  302. ,(s32-overflow #b11110000111100001111000011110000))
  303. (i32.const 2)))))
  304. (test-vm "i32.clz"
  305. 7
  306. `(module
  307. (func (export "main") (result i32)
  308. (i32.clz (i32.const ,(ash 1 24))))))
  309. (test-vm "i32.ctz"
  310. 24
  311. `(module
  312. (func (export "main") (result i32)
  313. (i32.ctz (i32.const ,(ash 1 24))))))
  314. (test-vm "i32.popcnt"
  315. 16
  316. `(module
  317. (func (export "main") (result i32)
  318. (i32.popcnt (i32.const ,(s32-overflow #xaaaaAAAA))))))
  319. (test-vm "i32.wrap_i64 positive"
  320. 3
  321. `(module
  322. (func (export "main") (result i32)
  323. (i32.wrap_i64 (i64.const ,(+ (ash 1 32) 3))))))
  324. (test-vm "i32.wrap_i64 negative"
  325. -3
  326. `(module
  327. (func (export "main") (result i32)
  328. (i32.wrap_i64 (i64.const ,(- (ash -1 32) 3))))))
  329. (test-vm "i32.trunc_f32_s"
  330. -1
  331. `(module
  332. (func (export "main") (result i32)
  333. (i32.trunc_f32_s (f32.const -1.2)))))
  334. (test-vm "i32.trunc_f32_u"
  335. 1
  336. `(module
  337. (func (export "main") (result i32)
  338. (i32.trunc_f32_u (f32.const 1.2)))))
  339. (test-vm "i32.trunc_f64_s"
  340. -1
  341. `(module
  342. (func (export "main") (result i32)
  343. (i32.trunc_f64_s (f64.const -1.2)))))
  344. (test-vm "i32.trunc_f64_u"
  345. 1
  346. `(module
  347. (func (export "main") (result i32)
  348. (i32.trunc_f64_u (f64.const 1.2)))))
  349. (test-vm "i32.reinterpret_f32"
  350. 1067030938
  351. `(module
  352. (func (export "main") (result i32)
  353. (i32.reinterpret_f32 (f32.const 1.2)))))
  354. (test-vm "i64.eqz true"
  355. 1
  356. '(module
  357. (func (export "main") (result i32)
  358. (i64.eqz (i64.const 0)))))
  359. (test-vm "i64.eqz false"
  360. 0
  361. '(module
  362. (func (export "main") (result i32)
  363. (i64.eqz (i64.const 42)))))
  364. (test-vm "i64.eq true"
  365. 1
  366. '(module
  367. (func (export "main") (result i32)
  368. (i64.eq (i64.const 42) (i64.const 42)))))
  369. (test-vm "i64.eq false"
  370. 0
  371. '(module
  372. (func (export "main") (result i32)
  373. (i64.eq (i64.const 42) (i64.const 7)))))
  374. (test-vm "i64.ne true"
  375. 1
  376. '(module
  377. (func (export "main") (result i32)
  378. (i64.ne (i64.const 42) (i64.const 7)))))
  379. (test-vm "i64.ne false"
  380. 0
  381. '(module
  382. (func (export "main") (result i32)
  383. (i64.ne (i64.const 42) (i64.const 42)))))
  384. (test-vm "i64.lt_s true"
  385. 1
  386. '(module
  387. (func (export "main") (result i32)
  388. (i64.lt_s (i64.const -42) (i64.const 42)))))
  389. (test-vm "i64.lt_s false"
  390. 0
  391. '(module
  392. (func (export "main") (result i32)
  393. (i64.lt_s (i64.const 42) (i64.const -42)))))
  394. (test-vm "i64.lt_u true"
  395. 1
  396. '(module
  397. (func (export "main") (result i32)
  398. (i64.lt_s (i64.const 7) (i64.const 42)))))
  399. (test-vm "i64.lt_u false"
  400. 0
  401. '(module
  402. (func (export "main") (result i32)
  403. (i64.lt_s (i64.const 42) (i64.const 7)))))
  404. (test-vm "i64.le_s true"
  405. 1
  406. '(module
  407. (func (export "main") (result i32)
  408. (i64.le_s (i64.const 42) (i64.const 42)))))
  409. (test-vm "i64.le_s false"
  410. 0
  411. '(module
  412. (func (export "main") (result i32)
  413. (i64.le_s (i64.const 42) (i64.const -42)))))
  414. (test-vm "i64.le_u true"
  415. 1
  416. '(module
  417. (func (export "main") (result i32)
  418. (i64.le_s (i64.const 42) (i64.const 42)))))
  419. (test-vm "i64.le_u false"
  420. 0
  421. '(module
  422. (func (export "main") (result i32)
  423. (i64.le_s (i64.const 42) (i64.const 7)))))
  424. (test-vm "i64.gt_s true"
  425. 1
  426. '(module
  427. (func (export "main") (result i32)
  428. (i64.gt_s (i64.const 42) (i64.const -42)))))
  429. (test-vm "i64.gt_s false"
  430. 0
  431. '(module
  432. (func (export "main") (result i32)
  433. (i64.gt_s (i64.const -42) (i64.const 42)))))
  434. (test-vm "i64.gt_u true"
  435. 1
  436. '(module
  437. (func (export "main") (result i32)
  438. (i64.gt_s (i64.const 42) (i64.const 7)))))
  439. (test-vm "i64.gt_u false"
  440. 0
  441. '(module
  442. (func (export "main") (result i32)
  443. (i64.gt_s (i64.const 7) (i64.const 42)))))
  444. (test-vm "i64.ge_s true"
  445. 1
  446. '(module
  447. (func (export "main") (result i32)
  448. (i64.ge_s (i64.const 42) (i64.const 42)))))
  449. (test-vm "i64.ge_s false"
  450. 0
  451. '(module
  452. (func (export "main") (result i32)
  453. (i64.ge_s (i64.const -42) (i64.const 42)))))
  454. (test-vm "i64.ge_u true"
  455. 1
  456. '(module
  457. (func (export "main") (result i32)
  458. (i64.ge_s (i64.const 42) (i64.const 42)))))
  459. (test-vm "i64.ge_u false"
  460. 0
  461. '(module
  462. (func (export "main") (result i32)
  463. (i64.ge_s (i64.const 7) (i64.const 42)))))
  464. (test-vm "i64.add"
  465. 80
  466. '(module
  467. (func (export "main") (result i64)
  468. (i64.add (i64.const 42) (i64.const 38)))))
  469. (test-vm "i64.sub"
  470. 4
  471. '(module
  472. (func (export "main") (result i64)
  473. (i64.sub (i64.const 42) (i64.const 38)))))
  474. (test-vm "i64.mul"
  475. 42
  476. '(module
  477. (func (export "main") (result i64)
  478. (i64.mul (i64.const 7) (i64.const 6)))))
  479. (test-vm "i64.div_s"
  480. -6
  481. '(module
  482. (func (export "main") (result i64)
  483. (i64.div_s (i64.const -42) (i64.const 7)))))
  484. (test-vm "i64.div_u"
  485. 6
  486. '(module
  487. (func (export "main") (result i64)
  488. (i64.div_u (i64.const 42) (i64.const 7)))))
  489. (test-vm "i64.rem_s"
  490. -2
  491. '(module
  492. (func (export "main") (result i64)
  493. (i64.rem_s (i64.const -42) (i64.const 5)))))
  494. (test-vm "i64.rem_u"
  495. 2
  496. '(module
  497. (func (export "main") (result i64)
  498. (i64.rem_u (i64.const 42) (i64.const 5)))))
  499. (test-vm "i64.and"
  500. #b1010
  501. '(module
  502. (func (export "main") (result i64)
  503. (i64.and (i64.const #b1111) (i64.const #b1010)))))
  504. (test-vm "i64.or"
  505. #b1111
  506. '(module
  507. (func (export "main") (result i64)
  508. (i64.or (i64.const #b0101) (i64.const #b1010)))))
  509. (test-vm "i64.xor"
  510. #b1110
  511. '(module
  512. (func (export "main") (result i64)
  513. (i64.or (i64.const #b1010) (i64.const #b0100)))))
  514. (test-vm "i64.shl"
  515. #b1000
  516. '(module
  517. (func (export "main") (result i64)
  518. (i64.shl (i64.const #b0001) (i64.const 3)))))
  519. (test-vm "i64.shr_s"
  520. -2
  521. '(module
  522. (func (export "main") (result i64)
  523. (i64.shr_s (i64.const -16) (i64.const 3)))))
  524. (test-vm "i64.shr_u"
  525. #b0001
  526. '(module
  527. (func (export "main") (result i64)
  528. (i64.shr_u (i64.const #b1000) (i64.const 3)))))
  529. (test-vm "i64.rotl"
  530. (s64-overflow #xfff0000ffff0000f)
  531. `(module
  532. (func (export "main") (result i64)
  533. (i64.rotl (i64.const
  534. ,(s64-overflow #xffff0000ffff0000))
  535. (i64.const 4)))))
  536. (test-vm "i64.rotr"
  537. (s64-overflow #xffff0000ffff0000)
  538. `(module
  539. (func (export "main") (result i64)
  540. (i64.rotr (i64.const
  541. ,(s64-overflow #xfff0000ffff0000f))
  542. (i64.const 4)))))
  543. (test-vm "i64.clz"
  544. 15
  545. `(module
  546. (func (export "main") (result i64)
  547. (i64.clz (i64.const ,(ash 1 48))))))
  548. (test-vm "i64.ctz"
  549. 48
  550. `(module
  551. (func (export "main") (result i64)
  552. (i64.ctz (i64.const ,(ash 1 48))))))
  553. (test-vm "i64.popcnt"
  554. 32
  555. `(module
  556. (func (export "main") (result i64)
  557. (i64.popcnt (i64.const ,(s64-overflow #xaaaaAAAAaaaaAAAA))))))
  558. (test-vm "i64.extend_i32_s"
  559. -42
  560. `(module
  561. (func (export "main") (result i64)
  562. (i64.extend_i32_s (i32.const -42)))))
  563. (test-vm "i64.extend_i32_u"
  564. 42
  565. `(module
  566. (func (export "main") (result i64)
  567. (i64.extend_i32_u (i32.const 42)))))
  568. (test-vm "i64.trunc_f32_s"
  569. -1
  570. `(module
  571. (func (export "main") (result i64)
  572. (i64.trunc_f32_s (f32.const -1.2)))))
  573. (test-vm "i64.trunc_f32_u"
  574. 1
  575. `(module
  576. (func (export "main") (result i64)
  577. (i64.trunc_f32_u (f32.const 1.2)))))
  578. (test-vm "i64.trunc_f64_s"
  579. -1
  580. `(module
  581. (func (export "main") (result i64)
  582. (i64.trunc_f64_s (f64.const -1.2)))))
  583. (test-vm "i64.trunc_f64_u"
  584. 1
  585. `(module
  586. (func (export "main") (result i64)
  587. (i64.trunc_f64_u (f64.const 1.2)))))
  588. (test-vm "i64.reinterpret_f64"
  589. 4608083138725491507
  590. `(module
  591. (func (export "main") (result i64)
  592. (i64.reinterpret_f64 (f64.const 1.2)))))
  593. (test-vm "f32.eq true"
  594. 1
  595. '(module
  596. (func (export "main") (result i32)
  597. (f32.eq (f32.const 42.0) (f32.const 42.0)))))
  598. (test-vm "f32.eq false"
  599. 0
  600. '(module
  601. (func (export "main") (result i32)
  602. (f32.eq (f32.const 42.0) (f32.const 7.0)))))
  603. (test-vm "f32.ne true"
  604. 1
  605. '(module
  606. (func (export "main") (result i32)
  607. (f32.ne (f32.const 42.0) (f32.const 7.0)))))
  608. (test-vm "f32.ne false"
  609. 0
  610. '(module
  611. (func (export "main") (result i32)
  612. (f32.ne (f32.const 42.0) (f32.const 42.0)))))
  613. (test-vm "f32.lt true"
  614. 1
  615. '(module
  616. (func (export "main") (result i32)
  617. (f32.lt (f32.const -42.0) (f32.const 42.0)))))
  618. (test-vm "f32.lt false"
  619. 0
  620. '(module
  621. (func (export "main") (result i32)
  622. (f32.lt (f32.const 42.0) (f32.const -42.0)))))
  623. (test-vm "f32.le true"
  624. 1
  625. '(module
  626. (func (export "main") (result i32)
  627. (f32.le (f32.const 42.0) (f32.const 42.0)))))
  628. (test-vm "f32.le false"
  629. 0
  630. '(module
  631. (func (export "main") (result i32)
  632. (f32.le (f32.const 42.0) (f32.const -42.0)))))
  633. (test-vm "f32.gt true"
  634. 1
  635. '(module
  636. (func (export "main") (result i32)
  637. (f32.gt (f32.const 42.0) (f32.const -42.0)))))
  638. (test-vm "f32.gt false"
  639. 0
  640. '(module
  641. (func (export "main") (result i32)
  642. (f32.gt (f32.const -42.0) (f32.const 42.0)))))
  643. (test-vm "f32.ge true"
  644. 1
  645. '(module
  646. (func (export "main") (result i32)
  647. (f32.ge (f32.const 42.0) (f32.const 42.0)))))
  648. (test-vm "f32.ge false"
  649. 0
  650. '(module
  651. (func (export "main") (result i32)
  652. (f32.ge (f32.const -42.0) (f32.const 42.0)))))
  653. (test-vm "f32.add"
  654. 3.5
  655. '(module
  656. (func (export "main") (result f32)
  657. (f32.add (f32.const 1.5) (f32.const 2.0)))))
  658. (test-vm "f32.sub"
  659. 2.5
  660. '(module
  661. (func (export "main") (result f32)
  662. (f32.sub (f32.const 3.0) (f32.const 0.5)))))
  663. (test-vm "f32.mul"
  664. 4.5
  665. '(module
  666. (func (export "main") (result f32)
  667. (f32.mul (f32.const 1.5) (f32.const 3.0)))))
  668. (test-vm "f32.div"
  669. 0.5
  670. '(module
  671. (func (export "main") (result f32)
  672. (f32.div (f32.const 1.0) (f32.const 2.0)))))
  673. (test-vm "f32.abs"
  674. 1.5
  675. '(module
  676. (func (export "main") (result f32)
  677. (f32.abs (f32.const -1.5)))))
  678. (test-vm "f32.neg"
  679. -1.5
  680. '(module
  681. (func (export "main") (result f32)
  682. (f32.neg (f32.const 1.5)))))
  683. (test-vm "f32.ceil"
  684. 2.0
  685. '(module
  686. (func (export "main") (result f32)
  687. (f32.ceil (f32.const 1.5)))))
  688. (test-vm "f32.floor"
  689. 1.0
  690. '(module
  691. (func (export "main") (result f32)
  692. (f32.floor (f32.const 1.5)))))
  693. (test-vm "f32.trunc"
  694. 1.0
  695. '(module
  696. (func (export "main") (result f32)
  697. (f32.trunc (f32.const 1.5)))))
  698. (test-vm "f32.nearest"
  699. 1.0
  700. '(module
  701. (func (export "main") (result f32)
  702. (f32.nearest (f32.const 1.4)))))
  703. (test-vm "f32.sqrt"
  704. 2.0
  705. '(module
  706. (func (export "main") (result f32)
  707. (f32.sqrt (f32.const 4.0)))))
  708. (test-vm "f32.min"
  709. 0.5
  710. '(module
  711. (func (export "main") (result f32)
  712. (f32.min (f32.const 0.5) (f32.const 1.5)))))
  713. (test-vm "f32.max"
  714. 1.5
  715. '(module
  716. (func (export "main") (result f32)
  717. (f32.max (f32.const 0.5) (f32.const 1.5)))))
  718. (test-vm "f32.copysign"
  719. -1.5
  720. '(module
  721. (func (export "main") (result f32)
  722. (f32.copysign (f32.const 1.5) (f32.const -2.0)))))
  723. (test-vm "f32.convert_i32_s"
  724. -42.0
  725. '(module
  726. (func (export "main") (result f32)
  727. (f32.convert_i32_s (i32.const -42)))))
  728. (test-vm "f32.convert_i32_u"
  729. 42.0
  730. '(module
  731. (func (export "main") (result f32)
  732. (f32.convert_i32_u (i32.const 42)))))
  733. (test-vm "f32.convert_i64_s"
  734. -42.0
  735. '(module
  736. (func (export "main") (result f32)
  737. (f32.convert_i64_s (i64.const -42)))))
  738. (test-vm "f32.convert_i64_u"
  739. 42.0
  740. '(module
  741. (func (export "main") (result f32)
  742. (f32.convert_i64_u (i64.const 42)))))
  743. (test-vm "f32.demote_f64"
  744. 42.0
  745. '(module
  746. (func (export "main") (result f32)
  747. (f32.demote_f64 (f64.const 42.0)))))
  748. (test-vm "f32.reinterpret_i32"
  749. 1.5
  750. '(module
  751. (func (export "main") (result f32)
  752. (f32.reinterpret_i32 (i32.const 1069547520)))))
  753. (test-vm "f64.eq true"
  754. 1
  755. '(module
  756. (func (export "main") (result i32)
  757. (f64.eq (f64.const 42.0) (f64.const 42.0)))))
  758. (test-vm "f64.eq false"
  759. 0
  760. '(module
  761. (func (export "main") (result i32)
  762. (f64.eq (f64.const 42.0) (f64.const 7.0)))))
  763. (test-vm "f64.ne true"
  764. 1
  765. '(module
  766. (func (export "main") (result i32)
  767. (f64.ne (f64.const 42.0) (f64.const 7.0)))))
  768. (test-vm "f64.ne false"
  769. 0
  770. '(module
  771. (func (export "main") (result i32)
  772. (f64.ne (f64.const 42.0) (f64.const 42.0)))))
  773. (test-vm "f64.lt true"
  774. 1
  775. '(module
  776. (func (export "main") (result i32)
  777. (f64.lt (f64.const -42.0) (f64.const 42.0)))))
  778. (test-vm "f64.lt false"
  779. 0
  780. '(module
  781. (func (export "main") (result i32)
  782. (f64.lt (f64.const 42.0) (f64.const -42.0)))))
  783. (test-vm "f64.le true"
  784. 1
  785. '(module
  786. (func (export "main") (result i32)
  787. (f64.le (f64.const 42.0) (f64.const 42.0)))))
  788. (test-vm "f64.le false"
  789. 0
  790. '(module
  791. (func (export "main") (result i32)
  792. (f64.le (f64.const 42.0) (f64.const -42.0)))))
  793. (test-vm "f64.gt true"
  794. 1
  795. '(module
  796. (func (export "main") (result i32)
  797. (f64.gt (f64.const 42.0) (f64.const -42.0)))))
  798. (test-vm "f64.gt false"
  799. 0
  800. '(module
  801. (func (export "main") (result i32)
  802. (f64.gt (f64.const -42.0) (f64.const 42.0)))))
  803. (test-vm "f64.ge true"
  804. 1
  805. '(module
  806. (func (export "main") (result i32)
  807. (f64.ge (f64.const 42.0) (f64.const 42.0)))))
  808. (test-vm "f64.ge false"
  809. 0
  810. '(module
  811. (func (export "main") (result i32)
  812. (f64.ge (f64.const -42.0) (f64.const 42.0)))))
  813. (test-vm "f64.add"
  814. 3.5
  815. '(module
  816. (func (export "main") (result f64)
  817. (f64.add (f64.const 1.5) (f64.const 2.0)))))
  818. (test-vm "f64.sub"
  819. 2.5
  820. '(module
  821. (func (export "main") (result f64)
  822. (f64.sub (f64.const 3.0) (f64.const 0.5)))))
  823. (test-vm "f64.mul"
  824. 4.5
  825. '(module
  826. (func (export "main") (result f64)
  827. (f64.mul (f64.const 1.5) (f64.const 3.0)))))
  828. (test-vm "f64.div"
  829. 0.5
  830. '(module
  831. (func (export "main") (result f64)
  832. (f64.div (f64.const 1.0) (f64.const 2.0)))))
  833. (test-vm "f64.abs"
  834. 1.5
  835. '(module
  836. (func (export "main") (result f64)
  837. (f64.abs (f64.const -1.5)))))
  838. (test-vm "f64.neg"
  839. -1.5
  840. '(module
  841. (func (export "main") (result f64)
  842. (f64.neg (f64.const 1.5)))))
  843. (test-vm "f64.ceil"
  844. 2.0
  845. '(module
  846. (func (export "main") (result f64)
  847. (f64.ceil (f64.const 1.5)))))
  848. (test-vm "f64.floor"
  849. 1.0
  850. '(module
  851. (func (export "main") (result f64)
  852. (f64.floor (f64.const 1.5)))))
  853. (test-vm "f64.trunc"
  854. 1.0
  855. '(module
  856. (func (export "main") (result f64)
  857. (f64.trunc (f64.const 1.5)))))
  858. (test-vm "f64.nearest"
  859. 1.0
  860. '(module
  861. (func (export "main") (result f64)
  862. (f64.nearest (f64.const 1.4)))))
  863. (test-vm "f64.sqrt"
  864. 2.0
  865. '(module
  866. (func (export "main") (result f64)
  867. (f64.sqrt (f64.const 4.0)))))
  868. (test-vm "f64.min"
  869. 0.5
  870. '(module
  871. (func (export "main") (result f64)
  872. (f64.min (f64.const 0.5) (f64.const 1.5)))))
  873. (test-vm "f64.max"
  874. 1.5
  875. '(module
  876. (func (export "main") (result f64)
  877. (f64.max (f64.const 0.5) (f64.const 1.5)))))
  878. (test-vm "f64.copysign"
  879. -1.5
  880. '(module
  881. (func (export "main") (result f64)
  882. (f64.copysign (f64.const 1.5) (f64.const -2.0)))))
  883. (test-vm "f64.convert_i32_s"
  884. -42.0
  885. '(module
  886. (func (export "main") (result f64)
  887. (f64.convert_i32_s (i32.const -42)))))
  888. (test-vm "f64.convert_i32_u"
  889. 42.0
  890. '(module
  891. (func (export "main") (result f64)
  892. (f64.convert_i32_u (i32.const 42)))))
  893. (test-vm "f64.convert_i64_s"
  894. -42.0
  895. '(module
  896. (func (export "main") (result f64)
  897. (f64.convert_i64_s (i64.const -42)))))
  898. (test-vm "f64.convert_i64_u"
  899. 42.0
  900. '(module
  901. (func (export "main") (result f64)
  902. (f64.convert_i64_u (i64.const 42)))))
  903. (test-vm "f64.promote_f32"
  904. 42.0
  905. '(module
  906. (func (export "main") (result f64)
  907. (f64.promote_f32 (f32.const 42.0)))))
  908. (test-vm "f64.reinterpret_i64"
  909. 1.5
  910. '(module
  911. (func (export "main") (result f64)
  912. (f64.reinterpret_i64 (i64.const 4609434218613702656)))))
  913. (test-vm "i32.store + i32.load"
  914. 42
  915. '(module
  916. (memory 1)
  917. (func (export "main") (result i32)
  918. (i32.store (i32.const 0) (i32.const 42))
  919. (i32.load (i32.const 0)))))
  920. (test-vm "i32.store16 + i32.load16_s"
  921. -42
  922. '(module
  923. (memory $memory 1)
  924. (func (export "main") (result i32)
  925. (i32.store16 (i32.const 0) (i32.const -42))
  926. (i32.load16_s (i32.const 0)))))
  927. (test-vm "i32.store16 + i32.load16_s wrap"
  928. -1
  929. '(module
  930. (memory $memory 1)
  931. (func (export "main") (result i32)
  932. (i32.store16 (i32.const 0) (i32.const -65537))
  933. (i32.load16_s (i32.const 0)))))
  934. (test-vm "i32.store16 + i32.load16_u"
  935. 65535
  936. '(module
  937. (memory $memory 1)
  938. (func (export "main") (result i32)
  939. (i32.store16 (i32.const 0) (i32.const 65535))
  940. (i32.load16_u (i32.const 0)))))
  941. (test-vm "i32.store16 + i32.load16_u wrap"
  942. 65535
  943. '(module
  944. (memory $memory 1)
  945. (func (export "main") (result i32)
  946. (i32.store16 (i32.const 0) (i32.const -65537))
  947. (i32.load16_u (i32.const 0)))))
  948. (test-vm "i32.store8 + i32.load8_s"
  949. -42
  950. '(module
  951. (memory $memory 1)
  952. (func (export "main") (result i32)
  953. (i32.store8 (i32.const 0) (i32.const -42))
  954. (i32.load8_s (i32.const 0)))))
  955. (test-vm "i32.store8 + i32.load8_s wrap"
  956. -1
  957. '(module
  958. (memory $memory 1)
  959. (func (export "main") (result i32)
  960. (i32.store8 (i32.const 0) (i32.const -257))
  961. (i32.load8_s (i32.const 0)))))
  962. (test-vm "i32.store8 + i32.load8_u"
  963. 255
  964. '(module
  965. (memory $memory 1)
  966. (func (export "main") (result i32)
  967. (i32.store8 (i32.const 0) (i32.const 255))
  968. (i32.load8_u (i32.const 0)))))
  969. (test-vm "i32.store8 + i32.load8_u wrap"
  970. 255
  971. '(module
  972. (memory $memory 1)
  973. (func (export "main") (result i32)
  974. (i32.store8 (i32.const 0) (i32.const -257))
  975. (i32.load8_u (i32.const 0)))))
  976. (test-vm "i64.store + i64.load"
  977. 42
  978. '(module
  979. (memory 1)
  980. (func (export "main") (result i64)
  981. (i64.store (i32.const 0) (i64.const 42))
  982. (i64.load (i32.const 0)))))
  983. (test-vm "i64.store32 + i64.load32_s"
  984. -42
  985. '(module
  986. (memory $memory 1)
  987. (func (export "main") (result i64)
  988. (i64.store32 (i32.const 0) (i64.const -42))
  989. (i64.load32_s (i32.const 0)))))
  990. (test-vm "i64.store32 + i64.load32_s wrap"
  991. -1
  992. `(module
  993. (memory $memory 1)
  994. (func (export "main") (result i64)
  995. (i64.store32 (i32.const 0) (i64.const ,(- (ash 1 32) 1)))
  996. (i64.load32_s (i32.const 0)))))
  997. (test-vm "i64.store32 + i64.load32_u"
  998. (- (ash 1 32) 1)
  999. `(module
  1000. (memory $memory 1)
  1001. (func (export "main") (result i64)
  1002. (i64.store32 (i32.const 0) (i64.const ,(- (ash 1 32) 1)))
  1003. (i64.load32_u (i32.const 0)))))
  1004. (test-vm "i64.store32 + i64.load32_u wrap"
  1005. (- (ash 1 32) 1)
  1006. `(module
  1007. (memory $memory 1)
  1008. (func (export "main") (result i64)
  1009. (i64.store32 (i32.const 0) (i64.const ,(- (ash -1 32) 1)))
  1010. (i64.load32_u (i32.const 0)))))
  1011. (test-vm "i64.store16 + i64.load16_s"
  1012. -42
  1013. '(module
  1014. (memory $memory 1)
  1015. (func (export "main") (result i64)
  1016. (i64.store16 (i32.const 0) (i64.const -42))
  1017. (i64.load16_s (i32.const 0)))))
  1018. (test-vm "i64.store16 + i64.load16_s wrap"
  1019. -1
  1020. '(module
  1021. (memory $memory 1)
  1022. (func (export "main") (result i64)
  1023. (i64.store16 (i32.const 0) (i64.const -65537))
  1024. (i64.load16_s (i32.const 0)))))
  1025. (test-vm "i64.store16 + i64.load16_u"
  1026. 65535
  1027. '(module
  1028. (memory $memory 1)
  1029. (func (export "main") (result i64)
  1030. (i64.store16 (i32.const 0) (i64.const 65535))
  1031. (i64.load16_u (i32.const 0)))))
  1032. (test-vm "i64.store16 + i64.load16_u wrap"
  1033. 65535
  1034. '(module
  1035. (memory $memory 1)
  1036. (func (export "main") (result i64)
  1037. (i64.store16 (i32.const 0) (i64.const -65537))
  1038. (i64.load16_u (i32.const 0)))))
  1039. (test-vm "i64.store8 + i64.load8_s"
  1040. -42
  1041. '(module
  1042. (memory $memory 1)
  1043. (func (export "main") (result i64)
  1044. (i64.store8 (i32.const 0) (i64.const -42))
  1045. (i64.load8_s (i32.const 0)))))
  1046. (test-vm "i64.store8 + i64.load8_s wrap"
  1047. -1
  1048. '(module
  1049. (memory $memory 1)
  1050. (func (export "main") (result i64)
  1051. (i64.store8 (i32.const 0) (i64.const -257))
  1052. (i64.load8_s (i32.const 0)))))
  1053. (test-vm "i64.store8 + i64.load8_u"
  1054. 255
  1055. '(module
  1056. (memory $memory 1)
  1057. (func (export "main") (result i64)
  1058. (i64.store8 (i32.const 0) (i64.const 255))
  1059. (i64.load8_u (i32.const 0)))))
  1060. (test-vm "i64.store8 + i64.load8_u wrap"
  1061. 255
  1062. '(module
  1063. (memory $memory 1)
  1064. (func (export "main") (result i64)
  1065. (i64.store8 (i32.const 0) (i64.const -257))
  1066. (i64.load8_u (i32.const 0)))))
  1067. (test-vm "f32.store + f32.load"
  1068. 1.5
  1069. '(module
  1070. (memory 1)
  1071. (func (export "main") (result f32)
  1072. (f32.store (i32.const 0) (f32.const 1.5))
  1073. (f32.load (i32.const 0)))))
  1074. (test-vm "f64.store + f64.load"
  1075. 1.5
  1076. '(module
  1077. (memory 1)
  1078. (func (export "main") (result f64)
  1079. (f64.store (i32.const 0) (f64.const 1.5))
  1080. (f64.load (i32.const 0)))))
  1081. (test-vm "memory.size"
  1082. 1
  1083. '(module
  1084. (memory 1)
  1085. (func (export "main") (result i32)
  1086. (memory.size))))
  1087. (test-vm "memory.grow within limits"
  1088. 2
  1089. '(module
  1090. (memory 2 3)
  1091. (func (export "main") (result i32)
  1092. (i32.const 1)
  1093. (memory.grow))))
  1094. (test-vm "memory.grow outside limits"
  1095. -1
  1096. '(module
  1097. (memory 1 1)
  1098. (func (export "main") (result i32)
  1099. (i32.const 1)
  1100. (memory.grow))))
  1101. (test-vm "memory.grow no-op"
  1102. 1
  1103. '(module
  1104. (memory 1 1)
  1105. (func (export "main") (result i32)
  1106. (i32.const 0)
  1107. (memory.grow))))
  1108. (test-vm "if"
  1109. 37
  1110. '(module
  1111. (func (export "main") (result i32)
  1112. (if (result i32)
  1113. (i32.eq (i32.const 42) (i32.const 47))
  1114. (then (i32.const 13))
  1115. (else (i32.const 37))))))
  1116. (test-vm "branching in a block"
  1117. 42
  1118. '(module
  1119. (func (export "main") (result i32)
  1120. (block $foo
  1121. (br $foo)
  1122. (unreachable))
  1123. (i32.const 42))))
  1124. (test-vm "return"
  1125. 42
  1126. '(module
  1127. (func (export "main") (result i32)
  1128. (block $foo (result i32)
  1129. (i32.const 42)
  1130. (return)
  1131. (unreachable)))))
  1132. (test-vm "return via br"
  1133. 42
  1134. '(module
  1135. (func (export "main") (result i32)
  1136. (i32.const 42)
  1137. (br 0)
  1138. (unreachable))))
  1139. (test-vm "return_call"
  1140. 42
  1141. '(module
  1142. (func $count (param $i i32) (param $k i32) (result i32)
  1143. (if (result i32)
  1144. (i32.eq (local.get $i) (local.get $k))
  1145. (then (local.get $k))
  1146. (else (return_call $count
  1147. (i32.add (local.get $i) (i32.const 1))
  1148. (local.get $k)))))
  1149. (func $main (export "main") (param $k i32) (result i32)
  1150. (call $count (i32.const 0) (local.get $k))))
  1151. #:args '(42))
  1152. (test-vm "return with extra values on stack"
  1153. 42
  1154. '(module
  1155. (func (export "main") (result i32)
  1156. (block $foo (result i32)
  1157. (i32.const 13)
  1158. (i32.const 42)
  1159. (return)))))
  1160. (test-vm/error "fallthrough with too many values on stack"
  1161. '(module
  1162. (func (export "main") (result i32)
  1163. (i32.const 1)
  1164. (i32.const 2))))
  1165. (test-vm/error "fallthrough with too many values on invalid stack"
  1166. '(module
  1167. (func (export "main") (result i32)
  1168. (i32.const 1)
  1169. (return) ; stack is invalid after this
  1170. (i32.const 2)
  1171. (i32.const 3))))
  1172. (test-vm "branching in a loop"
  1173. 24
  1174. '(module
  1175. ;; Iterative factorial.
  1176. (func (export "main") (param $n i32) (result i32)
  1177. (local $result i32)
  1178. (local.set $result (i32.const 1))
  1179. (loop $loop (result i32)
  1180. (if (result i32)
  1181. (i32.eq (local.get $n) (i32.const 1))
  1182. (then (local.get $result))
  1183. (else (local.set $result (i32.mul (local.get $n)
  1184. (local.get $result)))
  1185. (local.set $n (i32.sub (local.get $n) (i32.const 1)))
  1186. (br $loop))))))
  1187. #:args '(4))
  1188. (test-vm "blocks with params and results"
  1189. 24
  1190. '(module
  1191. (func (export "main") (param $n i32) (result i32)
  1192. (local.get $n)
  1193. (block $block (param i32) (result i32)
  1194. (loop $loop (param i32) (result i32)
  1195. (i32.eq (local.get $n) (i32.const 1))
  1196. (br_if $block)
  1197. (local.tee $n (i32.sub (local.get $n) (i32.const 1)))
  1198. (i32.mul)
  1199. (br $loop)))))
  1200. #:args '(4))
  1201. (test-vm "br_table"
  1202. 42
  1203. '(module
  1204. (func (export "main") (result i32)
  1205. (block $foo (result i32)
  1206. (block $bar (result i32)
  1207. (i32.const 21)
  1208. (i32.const 0)
  1209. (br_table $foo $bar))
  1210. (unreachable))
  1211. (i32.const 21)
  1212. (i32.add))))
  1213. (test-vm "br_table with negative i"
  1214. 42
  1215. '(module
  1216. (func (export "main") (result i32)
  1217. (block $foo (result i32)
  1218. (block $bar (result i32)
  1219. (i32.const 21)
  1220. (i32.const -1)
  1221. (br_table $bar $foo))
  1222. (unreachable))
  1223. (i32.const 21)
  1224. (i32.add))))
  1225. (test-vm "inner function call"
  1226. 11
  1227. '(module
  1228. (func $y (param $m i32) (param $x i32) (param $b i32) (result i32)
  1229. (i32.add (i32.mul (local.get $m) (local.get $x)) (local.get $b)))
  1230. (func (export "main") (param $x i32) (result i32)
  1231. (call $y (i32.const 2) (local.get $x) (i32.const 3))))
  1232. #:args '(4))
  1233. (test-vm "imported function call"
  1234. 80
  1235. '(module
  1236. (func $add42 (import "lib" "add42")
  1237. (param i32) (result i32))
  1238. (func (export "main") (param $x i32) (result i32)
  1239. (call $add42 (local.get $x))))
  1240. #:imports `(("lib" . (("add42" . ,(lambda (x) (+ x 42))))))
  1241. #:args '(38)
  1242. #:d8? #f)
  1243. (test-vm "mutable globals"
  1244. 42
  1245. '(module
  1246. (global $foo (mut i32) (i32.const 30))
  1247. (func (export "main") (param $n i32) (result i32)
  1248. (global.set $foo (i32.add (local.get $n) (global.get $foo)))
  1249. (global.get $foo)))
  1250. #:args '(12))
  1251. (test-vm "imported globals"
  1252. 80
  1253. '(module
  1254. (global $foo i32 (i32.const 42))
  1255. (global $bar (import "globals" "bar") i32)
  1256. (func (export "main") (result i32)
  1257. (i32.add (global.get $foo) (global.get $bar))))
  1258. #:imports `(("globals" . (("bar" . ,(make-wasm-global 38 #f)))))
  1259. #:d8? #f)
  1260. (test-vm "immutable global reference in constant expression"
  1261. 42
  1262. '(module
  1263. (global $foo i32 (i32.const 42))
  1264. (global $bar i32 (global.get $foo))
  1265. (func (export "main") (result i32)
  1266. (global.get $bar))))
  1267. (test-vm/error "reference to mutable global in constant expression"
  1268. '(module
  1269. (global $foo (mut i32) (i32.const 42))
  1270. (global $bar i32 (global.get $foo))
  1271. (func (export "main") (result i32)
  1272. (global.get $bar))))
  1273. (test-vm/error "reference to subsequent global in constant expression"
  1274. '(module
  1275. (global $bar i32 (global.get $foo))
  1276. (global $foo i32 (i32.const 42))
  1277. (func (export "main") (result i32)
  1278. (global.get $bar))))
  1279. (test-vm "drop"
  1280. 42
  1281. '(module
  1282. (func (export "main") (result i32)
  1283. (i32.const 42)
  1284. (i32.const 13)
  1285. (drop))))
  1286. (test-vm "drop in unreachable code"
  1287. 42
  1288. '(module
  1289. (func (export "main") (result i32)
  1290. (i32.const 42)
  1291. (return)
  1292. (drop))))
  1293. (test-vm "select first"
  1294. 42
  1295. '(module
  1296. (func (export "main") (result i32)
  1297. (i32.const 42)
  1298. (i32.const 13)
  1299. (i32.const 1)
  1300. (select))))
  1301. (test-vm "select second"
  1302. 13
  1303. '(module
  1304. (func (export "main") (result i32)
  1305. (i32.const 42)
  1306. (i32.const 13)
  1307. (i32.const 0)
  1308. (select))))
  1309. (test-vm "select in unreachable code"
  1310. 42
  1311. '(module
  1312. (func (export "main") (result i32)
  1313. (i32.const 42)
  1314. (return)
  1315. (select))))
  1316. (test-vm "select in unreachable code with i32 on top"
  1317. 42
  1318. '(module
  1319. (func (export "main") (result i32)
  1320. (i32.const 42)
  1321. (return)
  1322. (i32.const 0)
  1323. (select))))
  1324. (test-vm "start function"
  1325. 42
  1326. '(module
  1327. (global $foo (mut i32) (i32.const 13))
  1328. (func $init
  1329. (global.set $foo (i32.const 42)))
  1330. (start $init)
  1331. (func (export "main") (result i32)
  1332. (global.get $foo))))
  1333. (test-vm "table.size"
  1334. 2
  1335. '(module
  1336. (table $funcs 2 funcref)
  1337. (func (export "main") (result i32)
  1338. (table.size $funcs))))
  1339. (test-vm "table.grow within limits"
  1340. 2
  1341. '(module
  1342. (table $funcs 2 3 funcref)
  1343. (func $main (export "main") (result i32)
  1344. (ref.func $main)
  1345. (i32.const 1)
  1346. (table.grow $funcs))))
  1347. (test-vm "table.grow outside limits"
  1348. -1
  1349. '(module
  1350. (table $funcs 1 1 funcref)
  1351. (func $main (export "main") (result i32)
  1352. (ref.func $main)
  1353. (i32.const 1)
  1354. (table.grow $funcs))))
  1355. (test-vm "table.grow no-op"
  1356. 1
  1357. '(module
  1358. (table $funcs 1 1 funcref)
  1359. (func $main (export "main") (result i32)
  1360. (ref.func $main)
  1361. (i32.const 0)
  1362. (table.grow $funcs))))
  1363. (test-vm "table.init with passive element segment"
  1364. 1
  1365. '(module
  1366. (table $a 1 funcref)
  1367. (elem $funcs funcref (ref.null func))
  1368. (func $main (export "main") (result i32)
  1369. (table.init $a $funcs
  1370. (i32.const 0)
  1371. (i32.const 0)
  1372. (i32.const 1))
  1373. (ref.is_null (table.get $a (i32.const 0))))))
  1374. (test-vm "table.fill"
  1375. 1
  1376. '(module
  1377. (table $funcs 3 funcref)
  1378. (elem $funcs (i32.const 0) $main)
  1379. (func $main (export "main") (result i32)
  1380. (i32.const 1)
  1381. (ref.func $main)
  1382. (i32.const 2)
  1383. (table.fill $funcs)
  1384. (i32.const 1))))
  1385. (test-vm "table.copy"
  1386. 1
  1387. '(module
  1388. (table $a 3 funcref)
  1389. (table $b 3 funcref)
  1390. (elem $funcs (i32.const 0) $main $main $main)
  1391. (func $main (export "main") (result i32)
  1392. (i32.const 3)
  1393. (i32.const 0)
  1394. (i32.const 0)
  1395. (table.copy $b $a)
  1396. (i32.const 1))))
  1397. (test-vm "elem.drop"
  1398. 1
  1399. '(module
  1400. (table $funcs 1 funcref)
  1401. (elem $foo (i32.const 0) $main)
  1402. (func $main (export "main") (result i32)
  1403. (elem.drop $foo)
  1404. (i32.const 1))))
  1405. (test-vm "call_indirect"
  1406. 42
  1407. '(module
  1408. (table $funcs 1 funcref)
  1409. (type $i32->i32 (func (param i32) (result i32)))
  1410. (func $inc (param $a i32) (result i32)
  1411. (i32.add (local.get $a) (i32.const 1)))
  1412. (elem $funcs (i32.const 0) $inc)
  1413. (func (export "main") (result i32)
  1414. (call_indirect $funcs (type $i32->i32)
  1415. (i32.const 41) (i32.const 0)))))
  1416. (test-vm "call_ref"
  1417. 42
  1418. '(module
  1419. (type $i32->i32 (func (param i32) (result i32)))
  1420. (func $sum-41 (param $x i32) (result i32)
  1421. (i32.add (local.get $x) (i32.const 41)))
  1422. (func (export "main") (result i32)
  1423. (call_ref $i32->i32 (i32.const 1) (ref.func $sum-41)))))
  1424. (test-vm "ref.null + ref.is_null"
  1425. 1
  1426. '(module
  1427. (func (export "main") (result i32)
  1428. (ref.null func)
  1429. (ref.is_null))))
  1430. (test-vm "ref.test true"
  1431. 1
  1432. '(module
  1433. (type $foo (struct (field $bar (ref eq))))
  1434. (func (export "main") (result i32)
  1435. (ref.test $foo (struct.new $foo (ref.i31 (i32.const 42)))))))
  1436. (test-vm "ref.test false"
  1437. 0
  1438. '(module
  1439. (type $foo (struct (field $bar (ref eq))))
  1440. (func (export "main") (result i32)
  1441. (ref.test $foo (ref.null $foo)))))
  1442. (test-vm "ref.as_non_null"
  1443. 42
  1444. '(module
  1445. (type $foo (struct (field $bar i32)))
  1446. (func (export "main") (result i32)
  1447. (struct.get $foo $bar
  1448. (ref.as_non_null
  1449. (struct.new $foo (i32.const 42)))))))
  1450. (test-vm "ref.cast identity non-null"
  1451. 42
  1452. '(module
  1453. (func (export "main") (result i32)
  1454. (ref.i31 (i32.const 42))
  1455. (ref.cast i31)
  1456. (i31.get_s))))
  1457. (test-vm "ref.cast identity null"
  1458. 42
  1459. '(module
  1460. (func (export "main") (result i32)
  1461. (ref.null i31)
  1462. (ref.cast null i31)
  1463. (drop)
  1464. (i32.const 42))))
  1465. (test-vm/error "ref.cast null"
  1466. '(module
  1467. (func (export "main") (result i32)
  1468. (ref.null i31)
  1469. (ref.cast i31)
  1470. (i31.get_s))))
  1471. (test-vm "external reference passthrough"
  1472. '(opaque to wasm)
  1473. '(module
  1474. (func (export "main") (param $foo externref) (result externref)
  1475. (local.get $foo)))
  1476. #:args '((opaque to wasm))
  1477. #:d8? #f)
  1478. (test-vm "i31.get_s"
  1479. -42
  1480. '(module
  1481. (func (export "main") (result i32)
  1482. (i31.get_s (ref.i31 (i32.const -42))))))
  1483. (test-vm "i31.get_u"
  1484. 2147483606
  1485. '(module
  1486. (func (export "main") (result i32)
  1487. (i31.get_u (ref.i31 (i32.const -42))))))
  1488. (test-vm "struct.get"
  1489. 5.0
  1490. '(module
  1491. (type $vec2 (struct (field $x f32) (field $y f32)))
  1492. (func (export "main") (result f32) (local $v (ref $vec2))
  1493. (local.set $v (struct.new $vec2 (f32.const 3.0) (f32.const 4.0)))
  1494. ;; Calculate vector magnitude, for fun.
  1495. (f32.sqrt
  1496. (f32.add (f32.mul (struct.get $vec2 $x (local.get $v))
  1497. (struct.get $vec2 $x (local.get $v)))
  1498. (f32.mul (struct.get $vec2 $y (local.get $v))
  1499. (struct.get $vec2 $y (local.get $v))))))))
  1500. (test-vm "struct.get_s"
  1501. -42
  1502. '(module
  1503. (type $foo (struct (field $bar i8)))
  1504. (func (export "main") (result i32)
  1505. (struct.get_s $foo $bar (struct.new $foo (i32.const -42))))))
  1506. (test-vm "struct.get_u"
  1507. 214
  1508. '(module
  1509. (type $foo (struct (field $bar i8)))
  1510. (func (export "main") (result i32)
  1511. (struct.get_u $foo $bar (struct.new $foo (i32.const -42))))))
  1512. (test-vm "struct.set"
  1513. 42
  1514. '(module
  1515. (type $foo (struct (field $bar (mut i32))))
  1516. (func (export "main") (result i32) (local $a (ref $foo))
  1517. (local.set $a (struct.new $foo (i32.const 0)))
  1518. (struct.set $foo $bar (local.get $a) (i32.const 42))
  1519. (struct.get $foo $bar (local.get $a)))))
  1520. (test-vm "struct subtyping"
  1521. 42
  1522. '(module
  1523. (type $heap-object
  1524. (sub
  1525. (struct
  1526. (field $hash (mut i32)))))
  1527. (type $pair
  1528. (sub $heap-object
  1529. (struct
  1530. (field $hash (mut i32))
  1531. (field $car (mut (ref eq)))
  1532. (field $cdr (mut (ref eq))))))
  1533. (func (export "main") (result i32) (local $a (ref $pair))
  1534. (local.set $a (struct.new $pair (i32.const 1)
  1535. (ref.i31 (i32.const 21))
  1536. (ref.i31 (i32.const 21))))
  1537. (i32.add (i31.get_s (ref.cast i31 (struct.get $pair $car (local.get $a))))
  1538. (i31.get_s (ref.cast i31 (struct.get $pair $cdr (local.get $a))))))))
  1539. (test-vm "struct.new_default"
  1540. 0
  1541. '(module
  1542. (type $foo (struct (field $bar i32)))
  1543. (func (export "main") (result i32)
  1544. (struct.get $foo $bar (struct.new_default $foo)))))
  1545. (test-vm "array.len"
  1546. 3
  1547. '(module
  1548. (type $foo (array i32))
  1549. (func (export "main") (result i32)
  1550. (array.len (array.new $foo (i32.const 0) (i32.const 3))))))
  1551. (test-vm "array.get"
  1552. 42
  1553. '(module
  1554. (type $foo (array i32))
  1555. (func (export "main") (result i32)
  1556. (array.get $foo (array.new $foo (i32.const 42) (i32.const 1)) (i32.const 0)))))
  1557. (test-vm "array.get_s"
  1558. -42
  1559. '(module
  1560. (type $foo (array i8))
  1561. (func (export "main") (result i32)
  1562. (array.get_s $foo (array.new_fixed $foo 1 (i32.const -42)) (i32.const 0)))))
  1563. (test-vm "array.get_u"
  1564. 214
  1565. '(module
  1566. (type $foo (array i8))
  1567. (func (export "main") (result i32)
  1568. (array.get_u $foo (array.new_fixed $foo 1 (i32.const -42)) (i32.const 0)))))
  1569. (test-vm "array.set"
  1570. 42
  1571. '(module
  1572. (type $foo (array (mut i32)))
  1573. (func (export "main") (result i32) (local $a (ref $foo))
  1574. (local.set $a (array.new $foo (i32.const 0) (i32.const 1)))
  1575. (array.set $foo (local.get $a) (i32.const 0) (i32.const 42))
  1576. (array.get $foo (local.get $a) (i32.const 0)))))
  1577. (test-vm "array.new_fixed"
  1578. 42
  1579. '(module
  1580. (type $foo (array i32))
  1581. (func (export "main") (result i32)
  1582. (array.get $foo (array.new_fixed $foo 1 (i32.const 42)) (i32.const 0)))))
  1583. (test-vm "array.new_default"
  1584. 0
  1585. '(module
  1586. (type $foo (array i32))
  1587. (func (export "main") (result i32)
  1588. (array.get $foo (array.new_default $foo (i32.const 1)) (i32.const 0)))))
  1589. (test-vm "array.new_data"
  1590. 4
  1591. '(module
  1592. (type $foo (array i32))
  1593. (data $init #s32(1 2 3 4))
  1594. (func (export "main") (result i32)
  1595. (array.get $foo (array.new_data $foo $init
  1596. (i32.const 0)
  1597. (i32.const 4))
  1598. (i32.const 3)))))
  1599. (test-vm "array.new_elem"
  1600. 4
  1601. '(module
  1602. (type $foo (array (ref i31)))
  1603. (elem $init (ref i31)
  1604. (item (ref.i31 (i32.const 1)))
  1605. (item (ref.i31 (i32.const 2)))
  1606. (item (ref.i31 (i32.const 3)))
  1607. (item (ref.i31 (i32.const 4))))
  1608. (func (export "main") (result i32)
  1609. (i31.get_s
  1610. (array.get $foo (array.new_elem $foo $init
  1611. (i32.const 0)
  1612. (i32.const 4))
  1613. (i32.const 3))))))
  1614. (test-vm "array.init_data"
  1615. 4
  1616. '(module
  1617. (type $foo (array (mut i32)))
  1618. (data $init #s32(1 2 3 4))
  1619. (func (export "main") (result i32)
  1620. (local $a (ref $foo))
  1621. (local.set $a (array.new $foo
  1622. (i32.const 0)
  1623. (i32.const 4)))
  1624. (array.init_data $foo $init
  1625. (local.get $a)
  1626. (i32.const 0)
  1627. (i32.const 0)
  1628. (i32.const 4))
  1629. (array.get $foo (local.get $a) (i32.const 3)))))
  1630. (test-vm "array.init_elem"
  1631. 4
  1632. '(module
  1633. (type $foo (array (mut (ref i31))))
  1634. (elem $init (ref i31)
  1635. (item (ref.i31 (i32.const 1)))
  1636. (item (ref.i31 (i32.const 2)))
  1637. (item (ref.i31 (i32.const 3)))
  1638. (item (ref.i31 (i32.const 4))))
  1639. (func (export "main") (result i32)
  1640. (local $a (ref $foo))
  1641. (local.set $a (array.new $foo
  1642. (ref.i31 (i32.const 0))
  1643. (i32.const 4)))
  1644. (array.init_elem $foo $init
  1645. (local.get $a)
  1646. (i32.const 0)
  1647. (i32.const 0)
  1648. (i32.const 4))
  1649. (i31.get_s
  1650. (array.get $foo (local.get $a) (i32.const 3))))))
  1651. (test-vm "array.fill"
  1652. 42
  1653. '(module
  1654. (type $foo (array (mut i32)))
  1655. (func (export "main") (result i32) (local $a (ref $foo))
  1656. (local.set $a (array.new_default $foo (i32.const 1)))
  1657. (array.fill $foo
  1658. (local.get $a)
  1659. (i32.const 0)
  1660. (i32.const 42)
  1661. (i32.const 1))
  1662. (array.get $foo (local.get $a) (i32.const 0)))))
  1663. (test-vm "array.copy"
  1664. 42
  1665. '(module
  1666. (type $foo (array (mut i32)))
  1667. (func (export "main") (result i32) (local $a (ref $foo))
  1668. (local.set $a (array.new_default $foo (i32.const 1)))
  1669. (array.copy $foo $foo
  1670. (local.get $a)
  1671. (i32.const 0)
  1672. (array.new_fixed $foo 1 (i32.const 42))
  1673. (i32.const 0)
  1674. (i32.const 1))
  1675. (array.get $foo (local.get $a) (i32.const 0)))))
  1676. (test-vm "reference type constants"
  1677. 42
  1678. '(module
  1679. (type $foo (array (ref i31)))
  1680. (global $bar (ref $foo)
  1681. (array.new $foo
  1682. (ref.i31 (i32.const 42))
  1683. (i32.const 1)))
  1684. (func (export "main") (result i32)
  1685. (i31.get_s
  1686. (array.get $foo
  1687. (global.get $bar)
  1688. (i32.const 0))))))
  1689. (test-vm "string.const"
  1690. "Hello, world!"
  1691. '(module
  1692. (func (export "main") (result (ref string))
  1693. (string.const "Hello, world!")))
  1694. #:d8-read get-line)
  1695. (test-vm "string.new_lossy_utf8_array"
  1696. "HELLO"
  1697. '(module
  1698. (type $utf8 (array (mut i8)))
  1699. (func (export "main") (result (ref string))
  1700. (string.new_lossy_utf8_array (array.new_fixed $utf8 5
  1701. (i32.const 72)
  1702. (i32.const 69)
  1703. (i32.const 76)
  1704. (i32.const 76)
  1705. (i32.const 79))
  1706. (i32.const 0)
  1707. (i32.const 5))))
  1708. #:d8-read get-line)
  1709. (test-vm "string.encode_wtf8_array"
  1710. 5
  1711. '(module
  1712. (type $utf8 (array (mut i8)))
  1713. (func (export "main") (result i32)
  1714. (string.encode_wtf8_array (string.const "HELLO")
  1715. (array.new $utf8
  1716. (i32.const 0)
  1717. (i32.const 5))
  1718. (i32.const 0)))))
  1719. (test-vm "string.measure_utf8"
  1720. 5
  1721. '(module
  1722. (func (export "main") (result i32)
  1723. (string.measure_utf8 (string.const "HELLO")))))
  1724. (test-vm "string.measure_wtf8"
  1725. 5
  1726. '(module
  1727. (func (export "main") (result i32)
  1728. (string.measure_wtf8 (string.const "HELLO")))))
  1729. (test-equal "inter-instance function calls"
  1730. 17
  1731. (let* ((wat-a '(module
  1732. (func (export "square") (param $x i32) (result i32)
  1733. (i32.mul (local.get $x) (local.get $x)))))
  1734. (wat-b '(module
  1735. (func $square (import "wasm" "square") (param i32) (result i32))
  1736. (func (export "main") (param $x i32) (result i32)
  1737. (i32.add (call $square (local.get $x)) (i32.const 1)))))
  1738. (wasm-a (wat->wasm* wat-a))
  1739. (wasm-b (wat->wasm* wat-b))
  1740. (inst-a (instantiate-wasm (validate-wasm wasm-a)))
  1741. (square (wasm-instance-export-ref inst-a "square"))
  1742. (inst-b (instantiate-wasm (validate-wasm wasm-b)
  1743. #:imports `(("wasm" .
  1744. (("square" . ,square)))))))
  1745. ((wasm-instance-export-ref inst-b "main") 4)))
  1746. (test-end* "test-vm")