1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245 |
- ;;; WebAssembly virtual machine
- ;;; Copyright (C) 2023, 2024 David Thompson <dave@spritely.institute>
- ;;;
- ;;; Licensed under the Apache License, Version 2.0 (the "License");
- ;;; you may not use this file except in compliance with the License.
- ;;; You may obtain a copy of the License at
- ;;;
- ;;; http://www.apache.org/licenses/LICENSE-2.0
- ;;;
- ;;; Unless required by applicable law or agreed to in writing, software
- ;;; distributed under the License is distributed on an "AS IS" BASIS,
- ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ;;; See the License for the specific language governing permissions and
- ;;; limitations under the License.
- ;;; Commentary:
- ;;;
- ;;; Virtual machine tests.
- ;;;
- ;;; Code:
- (use-modules (ice-9 binary-ports)
- (ice-9 exceptions)
- (ice-9 popen)
- (ice-9 textual-ports)
- (srfi srfi-64)
- (test utils)
- (hoot config)
- (wasm wat)
- (wasm lower)
- (wasm assemble)
- (wasm vm))
- (define s32-overflow (@@ (wasm vm) s32-overflow))
- (define s64-overflow (@@ (wasm vm) s64-overflow))
- (define (run-v8 read args)
- (let* ((port (apply open-pipe* OPEN_READ
- (v8) "--experimental-wasm-stringref" args))
- (result (string-trim-both (get-string-all port))))
- (if (zero? (close-pipe port))
- (call-with-input-string result read)
- (throw 'v8-error result))))
- (define (run-wasm-in-v8 wasm func read args)
- (call-with-compiled-wasm-file
- wasm
- (lambda (wasm-file-name)
- (run-v8 read
- (cons* (in-vicinity %js-runner-dir "load-primitive.js")
- "--" wasm-file-name func
- (map (lambda (arg) (format #f "~a" arg)) args))))))
- (define (run-wasm-in-vm wasm func args imports)
- (let ((instance (instantiate-wasm (validate-wasm wasm) #:imports imports)))
- (apply (wasm-instance-export-ref instance func) args)))
- (define (wat->wasm* wat)
- (lower-wasm (wat->wasm wat) #:stringref-lowering 'stringref))
- (define (eval-wat wat func args imports v8? v8-read)
- (let* ((wasm (wat->wasm* wat))
- (our-result (run-wasm-in-vm wasm func args imports)))
- (when v8?
- (let ((v8-result (run-wasm-in-v8 wasm func v8-read args)))
- (unless (if (and (number? our-result) (number? v8-result))
- (= our-result v8-result)
- (equal? our-result v8-result))
- (error "our result differs from v8" our-result v8-result))))
- our-result))
- (define* (test-vm name expected wat #:key
- (func "main") (args '()) (imports '())
- (v8? (or (use-node?) (use-d8?))) (v8-read read))
- (test-equal name
- expected
- (eval-wat wat func args imports v8? v8-read)))
- (define (eval-wat/error wat func args imports v8? v8-read)
- (let ((wasm (wat->wasm* wat)))
- (define (handle-error e)
- (if v8?
- (with-exception-handler (lambda (e) #t)
- (lambda ()
- (let ((result (run-wasm-in-v8 wasm func v8-read args)))
- (error "v8 did not throw an error" result))
- #f)
- #:unwind? #t
- #:unwind-for-type 'v8-error)
- #t))
- (with-exception-handler handle-error
- (lambda ()
- (run-wasm-in-vm wasm func args imports)
- #f)
- #:unwind? #t
- #:unwind-for-type &wasm-error)))
- (define* (test-vm/error name wat #:key
- (func "main") (args '()) (imports '())
- (v8? (or (use-node?) (use-d8?))) (v8-read read))
- (test-assert name
- (eval-wat/error wat func args imports v8? v8-read)))
- (test-begin "test-vm")
- (test-vm "i32.eqz true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.eqz (i32.const 0)))))
- (test-vm "i32.eqz false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.eqz (i32.const 42)))))
- (test-vm "i32.eq true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.eq (i32.const 42) (i32.const 42)))))
- (test-vm "i32.eq false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.eq (i32.const 42) (i32.const 7)))))
- (test-vm "i32.ne true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.ne (i32.const 42) (i32.const 7)))))
- (test-vm "i32.ne false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.ne (i32.const 42) (i32.const 42)))))
- (test-vm "i32.lt_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.lt_s (i32.const -42) (i32.const 42)))))
- (test-vm "i32.lt_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.lt_s (i32.const 42) (i32.const -42)))))
- (test-vm "i32.lt_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.lt_s (i32.const 7) (i32.const 42)))))
- (test-vm "i32.lt_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.lt_s (i32.const 42) (i32.const 7)))))
- (test-vm "i32.le_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.le_s (i32.const 42) (i32.const 42)))))
- (test-vm "i32.le_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.le_s (i32.const 42) (i32.const -42)))))
- (test-vm "i32.le_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.le_s (i32.const 42) (i32.const 42)))))
- (test-vm "i32.le_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.le_s (i32.const 42) (i32.const 7)))))
- (test-vm "i32.gt_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.gt_s (i32.const 42) (i32.const -42)))))
- (test-vm "i32.gt_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.gt_s (i32.const -42) (i32.const 42)))))
- (test-vm "i32.gt_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.gt_s (i32.const 42) (i32.const 7)))))
- (test-vm "i32.gt_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.gt_s (i32.const 7) (i32.const 42)))))
- (test-vm "i32.ge_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.ge_s (i32.const 42) (i32.const 42)))))
- (test-vm "i32.ge_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.ge_s (i32.const -42) (i32.const 42)))))
- (test-vm "i32.ge_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i32.ge_s (i32.const 42) (i32.const 42)))))
- (test-vm "i32.ge_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i32.ge_s (i32.const 7) (i32.const 42)))))
- (test-vm "i32.add"
- 80
- '(module
- (func (export "main") (result i32)
- (i32.add (i32.const 42) (i32.const 38)))))
- (test-vm "i32.sub"
- 4
- '(module
- (func (export "main") (result i32)
- (i32.sub (i32.const 42) (i32.const 38)))))
- (test-vm "i32.mul"
- 42
- '(module
- (func (export "main") (result i32)
- (i32.mul (i32.const 7) (i32.const 6)))))
- (test-vm "i32.div_s"
- -6
- '(module
- (func (export "main") (result i32)
- (i32.div_s (i32.const -42) (i32.const 7)))))
- (test-vm "i32.div_u"
- 6
- '(module
- (func (export "main") (result i32)
- (i32.div_u (i32.const 42) (i32.const 7)))))
- (test-vm "i32.rem_s"
- -2
- '(module
- (func (export "main") (result i32)
- (i32.rem_s (i32.const -42) (i32.const 5)))))
- (test-vm "i32.rem_u"
- 2
- '(module
- (func (export "main") (result i32)
- (i32.rem_u (i32.const 42) (i32.const 5)))))
- (test-vm "i32.and"
- #b1010
- '(module
- (func (export "main") (result i32)
- (i32.and (i32.const #b1111) (i32.const #b1010)))))
- (test-vm "i32.or"
- #b1111
- '(module
- (func (export "main") (result i32)
- (i32.or (i32.const #b0101) (i32.const #b1010)))))
- (test-vm "i32.xor"
- #b1110
- '(module
- (func (export "main") (result i32)
- (i32.or (i32.const #b1010) (i32.const #b0100)))))
- (test-vm "i32.shl"
- #b1000
- '(module
- (func (export "main") (result i32)
- (i32.shl (i32.const #b0001) (i32.const 3)))))
- (test-vm "i32.shl - out of 32 bit range"
- 0
- `(module
- (func (export "main") (result i32)
- (i32.shl (i32.const ,(ash -1 31))
- (i32.const 2)))))
- (test-vm "i32.shl - more than 32 bits"
- #b1000
- '(module
- (func (export "main") (result i32)
- (i32.shl (i32.const #b0001) (i32.const 35)))))
- (test-vm "i32.shr_s"
- -2
- '(module
- (func (export "main") (result i32)
- (i32.shr_s (i32.const -16) (i32.const 3)))))
- (test-vm "i32.shr_u"
- #b0001
- '(module
- (func (export "main") (result i32)
- (i32.shr_u (i32.const #b1000) (i32.const 3)))))
- (test-vm "i32.shr_u - more than 32 bits"
- #b0001
- '(module
- (func (export "main") (result i32)
- (i32.shr_u (i32.const #b1000) (i32.const 35)))))
- (test-vm "i32.rotl"
- (s32-overflow #b11000011110000111100001111000011)
- `(module
- (func (export "main") (result i32)
- (i32.rotl (i32.const
- ,(s32-overflow #b11110000111100001111000011110000))
- (i32.const 2)))))
- (test-vm "i32.rotr"
- (s32-overflow #b00111100001111000011110000111100)
- `(module
- (func (export "main") (result i32)
- (i32.rotr (i32.const
- ,(s32-overflow #b11110000111100001111000011110000))
- (i32.const 2)))))
- (test-vm "i32.clz"
- 7
- `(module
- (func (export "main") (result i32)
- (i32.clz (i32.const ,(ash 1 24))))))
- (test-vm "i32.ctz"
- 24
- `(module
- (func (export "main") (result i32)
- (i32.ctz (i32.const ,(ash 1 24))))))
- (test-vm "i32.popcnt"
- 16
- `(module
- (func (export "main") (result i32)
- (i32.popcnt (i32.const ,(s32-overflow #xaaaaAAAA))))))
- (test-vm "i32.wrap_i64 positive"
- 3
- `(module
- (func (export "main") (result i32)
- (i32.wrap_i64 (i64.const ,(+ (ash 1 32) 3))))))
- (test-vm "i32.wrap_i64 negative"
- -3
- `(module
- (func (export "main") (result i32)
- (i32.wrap_i64 (i64.const ,(- (ash -1 32) 3))))))
- (test-vm "i32.trunc_f32_s"
- -1
- `(module
- (func (export "main") (result i32)
- (i32.trunc_f32_s (f32.const -1.2)))))
- (test-vm "i32.trunc_f32_u"
- 1
- `(module
- (func (export "main") (result i32)
- (i32.trunc_f32_u (f32.const 1.2)))))
- (test-vm "i32.trunc_f64_s"
- -1
- `(module
- (func (export "main") (result i32)
- (i32.trunc_f64_s (f64.const -1.2)))))
- (test-vm "i32.trunc_f64_u"
- 1
- `(module
- (func (export "main") (result i32)
- (i32.trunc_f64_u (f64.const 1.2)))))
- (test-vm "i32.reinterpret_f32"
- 1067030938
- `(module
- (func (export "main") (result i32)
- (i32.reinterpret_f32 (f32.const 1.2)))))
- (test-vm "i64.eqz true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.eqz (i64.const 0)))))
- (test-vm "i64.eqz false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.eqz (i64.const 42)))))
- (test-vm "i64.eq true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.eq (i64.const 42) (i64.const 42)))))
- (test-vm "i64.eq false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.eq (i64.const 42) (i64.const 7)))))
- (test-vm "i64.ne true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.ne (i64.const 42) (i64.const 7)))))
- (test-vm "i64.ne false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.ne (i64.const 42) (i64.const 42)))))
- (test-vm "i64.lt_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.lt_s (i64.const -42) (i64.const 42)))))
- (test-vm "i64.lt_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.lt_s (i64.const 42) (i64.const -42)))))
- (test-vm "i64.lt_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.lt_s (i64.const 7) (i64.const 42)))))
- (test-vm "i64.lt_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.lt_s (i64.const 42) (i64.const 7)))))
- (test-vm "i64.le_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.le_s (i64.const 42) (i64.const 42)))))
- (test-vm "i64.le_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.le_s (i64.const 42) (i64.const -42)))))
- (test-vm "i64.le_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.le_s (i64.const 42) (i64.const 42)))))
- (test-vm "i64.le_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.le_s (i64.const 42) (i64.const 7)))))
- (test-vm "i64.gt_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.gt_s (i64.const 42) (i64.const -42)))))
- (test-vm "i64.gt_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.gt_s (i64.const -42) (i64.const 42)))))
- (test-vm "i64.gt_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.gt_s (i64.const 42) (i64.const 7)))))
- (test-vm "i64.gt_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.gt_s (i64.const 7) (i64.const 42)))))
- (test-vm "i64.ge_s true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.ge_s (i64.const 42) (i64.const 42)))))
- (test-vm "i64.ge_s false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.ge_s (i64.const -42) (i64.const 42)))))
- (test-vm "i64.ge_u true"
- 1
- '(module
- (func (export "main") (result i32)
- (i64.ge_s (i64.const 42) (i64.const 42)))))
- (test-vm "i64.ge_u false"
- 0
- '(module
- (func (export "main") (result i32)
- (i64.ge_s (i64.const 7) (i64.const 42)))))
- (test-vm "i64.add"
- 80
- '(module
- (func (export "main") (result i64)
- (i64.add (i64.const 42) (i64.const 38)))))
- (test-vm "i64.sub"
- 4
- '(module
- (func (export "main") (result i64)
- (i64.sub (i64.const 42) (i64.const 38)))))
- (test-vm "i64.mul"
- 42
- '(module
- (func (export "main") (result i64)
- (i64.mul (i64.const 7) (i64.const 6)))))
- (test-vm "i64.div_s"
- -6
- '(module
- (func (export "main") (result i64)
- (i64.div_s (i64.const -42) (i64.const 7)))))
- (test-vm "i64.div_u"
- 6
- '(module
- (func (export "main") (result i64)
- (i64.div_u (i64.const 42) (i64.const 7)))))
- (test-vm "i64.rem_s"
- -2
- '(module
- (func (export "main") (result i64)
- (i64.rem_s (i64.const -42) (i64.const 5)))))
- (test-vm "i64.rem_u"
- 2
- '(module
- (func (export "main") (result i64)
- (i64.rem_u (i64.const 42) (i64.const 5)))))
- (test-vm "i64.and"
- #b1010
- '(module
- (func (export "main") (result i64)
- (i64.and (i64.const #b1111) (i64.const #b1010)))))
- (test-vm "i64.or"
- #b1111
- '(module
- (func (export "main") (result i64)
- (i64.or (i64.const #b0101) (i64.const #b1010)))))
- (test-vm "i64.xor"
- #b1110
- '(module
- (func (export "main") (result i64)
- (i64.or (i64.const #b1010) (i64.const #b0100)))))
- (test-vm "i64.shl"
- #b1000
- '(module
- (func (export "main") (result i64)
- (i64.shl (i64.const #b0001) (i64.const 3)))))
- (test-vm "i64.shr_s"
- -2
- '(module
- (func (export "main") (result i64)
- (i64.shr_s (i64.const -16) (i64.const 3)))))
- (test-vm "i64.shr_u"
- #b0001
- '(module
- (func (export "main") (result i64)
- (i64.shr_u (i64.const #b1000) (i64.const 3)))))
- (test-vm "i64.rotl"
- (s64-overflow #xfff0000ffff0000f)
- `(module
- (func (export "main") (result i64)
- (i64.rotl (i64.const
- ,(s64-overflow #xffff0000ffff0000))
- (i64.const 4)))))
- (test-vm "i64.rotr"
- (s64-overflow #xffff0000ffff0000)
- `(module
- (func (export "main") (result i64)
- (i64.rotr (i64.const
- ,(s64-overflow #xfff0000ffff0000f))
- (i64.const 4)))))
- (test-vm "i64.clz"
- 15
- `(module
- (func (export "main") (result i64)
- (i64.clz (i64.const ,(ash 1 48))))))
- (test-vm "i64.ctz"
- 48
- `(module
- (func (export "main") (result i64)
- (i64.ctz (i64.const ,(ash 1 48))))))
- (test-vm "i64.popcnt"
- 32
- `(module
- (func (export "main") (result i64)
- (i64.popcnt (i64.const ,(s64-overflow #xaaaaAAAAaaaaAAAA))))))
- (test-vm "i64.extend_i32_s"
- -42
- `(module
- (func (export "main") (result i64)
- (i64.extend_i32_s (i32.const -42)))))
- (test-vm "i64.extend_i32_u"
- 42
- `(module
- (func (export "main") (result i64)
- (i64.extend_i32_u (i32.const 42)))))
- (test-vm "i64.trunc_f32_s"
- -1
- `(module
- (func (export "main") (result i64)
- (i64.trunc_f32_s (f32.const -1.2)))))
- (test-vm "i64.trunc_f32_u"
- 1
- `(module
- (func (export "main") (result i64)
- (i64.trunc_f32_u (f32.const 1.2)))))
- (test-vm "i64.trunc_f64_s"
- -1
- `(module
- (func (export "main") (result i64)
- (i64.trunc_f64_s (f64.const -1.2)))))
- (test-vm "i64.trunc_f64_u"
- 1
- `(module
- (func (export "main") (result i64)
- (i64.trunc_f64_u (f64.const 1.2)))))
- (test-vm "i64.reinterpret_f64"
- 4608083138725491507
- `(module
- (func (export "main") (result i64)
- (i64.reinterpret_f64 (f64.const 1.2)))))
- (test-vm "f32.eq true"
- 1
- '(module
- (func (export "main") (result i32)
- (f32.eq (f32.const 42.0) (f32.const 42.0)))))
- (test-vm "f32.eq false"
- 0
- '(module
- (func (export "main") (result i32)
- (f32.eq (f32.const 42.0) (f32.const 7.0)))))
- (test-vm "f32.ne true"
- 1
- '(module
- (func (export "main") (result i32)
- (f32.ne (f32.const 42.0) (f32.const 7.0)))))
- (test-vm "f32.ne false"
- 0
- '(module
- (func (export "main") (result i32)
- (f32.ne (f32.const 42.0) (f32.const 42.0)))))
- (test-vm "f32.lt true"
- 1
- '(module
- (func (export "main") (result i32)
- (f32.lt (f32.const -42.0) (f32.const 42.0)))))
- (test-vm "f32.lt false"
- 0
- '(module
- (func (export "main") (result i32)
- (f32.lt (f32.const 42.0) (f32.const -42.0)))))
- (test-vm "f32.le true"
- 1
- '(module
- (func (export "main") (result i32)
- (f32.le (f32.const 42.0) (f32.const 42.0)))))
- (test-vm "f32.le false"
- 0
- '(module
- (func (export "main") (result i32)
- (f32.le (f32.const 42.0) (f32.const -42.0)))))
- (test-vm "f32.gt true"
- 1
- '(module
- (func (export "main") (result i32)
- (f32.gt (f32.const 42.0) (f32.const -42.0)))))
- (test-vm "f32.gt false"
- 0
- '(module
- (func (export "main") (result i32)
- (f32.gt (f32.const -42.0) (f32.const 42.0)))))
- (test-vm "f32.ge true"
- 1
- '(module
- (func (export "main") (result i32)
- (f32.ge (f32.const 42.0) (f32.const 42.0)))))
- (test-vm "f32.ge false"
- 0
- '(module
- (func (export "main") (result i32)
- (f32.ge (f32.const -42.0) (f32.const 42.0)))))
- (test-vm "f32.add"
- 3.5
- '(module
- (func (export "main") (result f32)
- (f32.add (f32.const 1.5) (f32.const 2.0)))))
- (test-vm "f32.sub"
- 2.5
- '(module
- (func (export "main") (result f32)
- (f32.sub (f32.const 3.0) (f32.const 0.5)))))
- (test-vm "f32.mul"
- 4.5
- '(module
- (func (export "main") (result f32)
- (f32.mul (f32.const 1.5) (f32.const 3.0)))))
- (test-vm "f32.div"
- 0.5
- '(module
- (func (export "main") (result f32)
- (f32.div (f32.const 1.0) (f32.const 2.0)))))
- (test-vm "f32.abs"
- 1.5
- '(module
- (func (export "main") (result f32)
- (f32.abs (f32.const -1.5)))))
- (test-vm "f32.neg"
- -1.5
- '(module
- (func (export "main") (result f32)
- (f32.neg (f32.const 1.5)))))
- (test-vm "f32.ceil"
- 2.0
- '(module
- (func (export "main") (result f32)
- (f32.ceil (f32.const 1.5)))))
- (test-vm "f32.floor"
- 1.0
- '(module
- (func (export "main") (result f32)
- (f32.floor (f32.const 1.5)))))
- (test-vm "f32.trunc"
- 1.0
- '(module
- (func (export "main") (result f32)
- (f32.trunc (f32.const 1.5)))))
- (test-vm "f32.nearest"
- 1.0
- '(module
- (func (export "main") (result f32)
- (f32.nearest (f32.const 1.4)))))
- (test-vm "f32.sqrt"
- 2.0
- '(module
- (func (export "main") (result f32)
- (f32.sqrt (f32.const 4.0)))))
- (test-vm "f32.min"
- 0.5
- '(module
- (func (export "main") (result f32)
- (f32.min (f32.const 0.5) (f32.const 1.5)))))
- (test-vm "f32.max"
- 1.5
- '(module
- (func (export "main") (result f32)
- (f32.max (f32.const 0.5) (f32.const 1.5)))))
- (test-vm "f32.copysign +42.0, +inf.0"
- +42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const +42.0) (f32.const +inf.0)))))
- (test-vm "f32.copysign -42.0, +inf.0"
- +42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const -42.0) (f32.const +inf.0)))))
- (test-vm "f32.copysign +42.0, -inf.0"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const +42.0) (f32.const -inf.0)))))
- (test-vm "f32.copysign -42.0, -inf.0"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const -42.0) (f32.const -inf.0)))))
- (test-vm "f32.copysign +42.0, +nan.0"
- +42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const +42.0) (f32.const +nan.0)))))
- (test-vm "f32.copysign -42.0, +nan.0"
- 42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const -42.0) (f32.const +nan.0)))))
- (test-vm "f32.copysign +42.0, +0.0"
- 42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const +42.0) (f32.const +0.0)))))
- (test-vm "f32.copysign -42.0, +0.0"
- +42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const -42.0) (f32.const +0.0)))))
- (test-vm "f32.copysign +42.0, -0.0"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const +42.0) (f32.const -0.0)))))
- (test-vm "f32.copysign -42.0, -0.0"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const -42.0) (f32.const -0.0)))))
- (test-vm "f32.copysign +42.0, +3.14"
- +42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const +42.0) (f32.const +3.14)))))
- (test-vm "f32.copysign -42.0, +3.14"
- +42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const -42.0) (f32.const +3.14)))))
- (test-vm "f32.copysign +42.0, -3.14"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const +42.0) (f32.const -3.14)))))
- (test-vm "f32.copysign -42.0, -3.14"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.copysign (f32.const -42.0) (f32.const -3.14)))))
- (test-vm "f32.convert_i32_s"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.convert_i32_s (i32.const -42)))))
- (test-vm "f32.convert_i32_u"
- 42.0
- '(module
- (func (export "main") (result f32)
- (f32.convert_i32_u (i32.const 42)))))
- (test-vm "f32.convert_i64_s"
- -42.0
- '(module
- (func (export "main") (result f32)
- (f32.convert_i64_s (i64.const -42)))))
- (test-vm "f32.convert_i64_u"
- 42.0
- '(module
- (func (export "main") (result f32)
- (f32.convert_i64_u (i64.const 42)))))
- (test-vm "f32.demote_f64"
- 42.0
- '(module
- (func (export "main") (result f32)
- (f32.demote_f64 (f64.const 42.0)))))
- (test-vm "f32.reinterpret_i32"
- 1.5
- '(module
- (func (export "main") (result f32)
- (f32.reinterpret_i32 (i32.const 1069547520)))))
- (test-vm "f64.eq true"
- 1
- '(module
- (func (export "main") (result i32)
- (f64.eq (f64.const 42.0) (f64.const 42.0)))))
- (test-vm "f64.eq false"
- 0
- '(module
- (func (export "main") (result i32)
- (f64.eq (f64.const 42.0) (f64.const 7.0)))))
- (test-vm "f64.ne true"
- 1
- '(module
- (func (export "main") (result i32)
- (f64.ne (f64.const 42.0) (f64.const 7.0)))))
- (test-vm "f64.ne false"
- 0
- '(module
- (func (export "main") (result i32)
- (f64.ne (f64.const 42.0) (f64.const 42.0)))))
- (test-vm "f64.lt true"
- 1
- '(module
- (func (export "main") (result i32)
- (f64.lt (f64.const -42.0) (f64.const 42.0)))))
- (test-vm "f64.lt false"
- 0
- '(module
- (func (export "main") (result i32)
- (f64.lt (f64.const 42.0) (f64.const -42.0)))))
- (test-vm "f64.le true"
- 1
- '(module
- (func (export "main") (result i32)
- (f64.le (f64.const 42.0) (f64.const 42.0)))))
- (test-vm "f64.le false"
- 0
- '(module
- (func (export "main") (result i32)
- (f64.le (f64.const 42.0) (f64.const -42.0)))))
- (test-vm "f64.gt true"
- 1
- '(module
- (func (export "main") (result i32)
- (f64.gt (f64.const 42.0) (f64.const -42.0)))))
- (test-vm "f64.gt false"
- 0
- '(module
- (func (export "main") (result i32)
- (f64.gt (f64.const -42.0) (f64.const 42.0)))))
- (test-vm "f64.ge true"
- 1
- '(module
- (func (export "main") (result i32)
- (f64.ge (f64.const 42.0) (f64.const 42.0)))))
- (test-vm "f64.ge false"
- 0
- '(module
- (func (export "main") (result i32)
- (f64.ge (f64.const -42.0) (f64.const 42.0)))))
- (test-vm "f64.add"
- 3.5
- '(module
- (func (export "main") (result f64)
- (f64.add (f64.const 1.5) (f64.const 2.0)))))
- (test-vm "f64.sub"
- 2.5
- '(module
- (func (export "main") (result f64)
- (f64.sub (f64.const 3.0) (f64.const 0.5)))))
- (test-vm "f64.mul"
- 4.5
- '(module
- (func (export "main") (result f64)
- (f64.mul (f64.const 1.5) (f64.const 3.0)))))
- (test-vm "f64.div"
- 0.5
- '(module
- (func (export "main") (result f64)
- (f64.div (f64.const 1.0) (f64.const 2.0)))))
- (test-vm "f64.abs"
- 1.5
- '(module
- (func (export "main") (result f64)
- (f64.abs (f64.const -1.5)))))
- (test-vm "f64.neg"
- -1.5
- '(module
- (func (export "main") (result f64)
- (f64.neg (f64.const 1.5)))))
- (test-vm "f64.ceil"
- 2.0
- '(module
- (func (export "main") (result f64)
- (f64.ceil (f64.const 1.5)))))
- (test-vm "f64.floor"
- 1.0
- '(module
- (func (export "main") (result f64)
- (f64.floor (f64.const 1.5)))))
- (test-vm "f64.trunc"
- 1.0
- '(module
- (func (export "main") (result f64)
- (f64.trunc (f64.const 1.5)))))
- (test-vm "f64.nearest"
- 1.0
- '(module
- (func (export "main") (result f64)
- (f64.nearest (f64.const 1.4)))))
- (test-vm "f64.sqrt"
- 2.0
- '(module
- (func (export "main") (result f64)
- (f64.sqrt (f64.const 4.0)))))
- (test-vm "f64.min"
- 0.5
- '(module
- (func (export "main") (result f64)
- (f64.min (f64.const 0.5) (f64.const 1.5)))))
- (test-vm "f64.max"
- 1.5
- '(module
- (func (export "main") (result f64)
- (f64.max (f64.const 0.5) (f64.const 1.5)))))
- (test-vm "f64.copysign +42.0, +inf.0"
- +42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const +42.0) (f64.const +inf.0)))))
- (test-vm "f64.copysign -42.0, +inf.0"
- +42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const -42.0) (f64.const +inf.0)))))
- (test-vm "f64.copysign +42.0, -inf.0"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const +42.0) (f64.const -inf.0)))))
- (test-vm "f64.copysign -42.0, -inf.0"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const -42.0) (f64.const -inf.0)))))
- (test-vm "f64.copysign +42.0, +nan.0"
- +42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const +42.0) (f64.const +nan.0)))))
- (test-vm "f64.copysign -42.0, +nan.0"
- 42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const -42.0) (f64.const +nan.0)))))
- (test-vm "f64.copysign +42.0, +0.0"
- 42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const +42.0) (f64.const +0.0)))))
- (test-vm "f64.copysign -42.0, +0.0"
- +42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const -42.0) (f64.const +0.0)))))
- (test-vm "f64.copysign +42.0, -0.0"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const +42.0) (f64.const -0.0)))))
- (test-vm "f64.copysign -42.0, -0.0"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const -42.0) (f64.const -0.0)))))
- (test-vm "f64.copysign +42.0, +3.14"
- +42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const +42.0) (f64.const +3.14)))))
- (test-vm "f64.copysign -42.0, +3.14"
- +42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const -42.0) (f64.const +3.14)))))
- (test-vm "f64.copysign +42.0, -3.14"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const +42.0) (f64.const -3.14)))))
- (test-vm "f64.copysign -42.0, -3.14"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.copysign (f64.const -42.0) (f64.const -3.14)))))
- (test-vm "f64.convert_i32_s"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.convert_i32_s (i32.const -42)))))
- (test-vm "f64.convert_i32_u"
- 42.0
- '(module
- (func (export "main") (result f64)
- (f64.convert_i32_u (i32.const 42)))))
- (test-vm "f64.convert_i64_s"
- -42.0
- '(module
- (func (export "main") (result f64)
- (f64.convert_i64_s (i64.const -42)))))
- (test-vm "f64.convert_i64_u"
- 42.0
- '(module
- (func (export "main") (result f64)
- (f64.convert_i64_u (i64.const 42)))))
- (test-vm "f64.promote_f32"
- 42.0
- '(module
- (func (export "main") (result f64)
- (f64.promote_f32 (f32.const 42.0)))))
- (test-vm "f64.reinterpret_i64"
- 1.5
- '(module
- (func (export "main") (result f64)
- (f64.reinterpret_i64 (i64.const 4609434218613702656)))))
- (test-vm "i32.store + i32.load"
- 42
- '(module
- (memory 1)
- (func (export "main") (result i32)
- (i32.store (i32.const 0) (i32.const 42))
- (i32.load (i32.const 0)))))
- (test-vm "i32.store16 + i32.load16_s"
- -42
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store16 (i32.const 0) (i32.const -42))
- (i32.load16_s (i32.const 0)))))
- (test-vm "i32.store16 + i32.load16_s wrap"
- -1
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store16 (i32.const 0) (i32.const -65537))
- (i32.load16_s (i32.const 0)))))
- (test-vm "i32.store16 + i32.load16_u"
- 65535
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store16 (i32.const 0) (i32.const 65535))
- (i32.load16_u (i32.const 0)))))
- (test-vm "i32.store16 + i32.load16_u wrap"
- 65535
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store16 (i32.const 0) (i32.const -65537))
- (i32.load16_u (i32.const 0)))))
- (test-vm "i32.store8 + i32.load8_s"
- -42
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store8 (i32.const 0) (i32.const -42))
- (i32.load8_s (i32.const 0)))))
- (test-vm "i32.store8 + i32.load8_s wrap"
- -1
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store8 (i32.const 0) (i32.const -257))
- (i32.load8_s (i32.const 0)))))
- (test-vm "i32.store8 + i32.load8_u"
- 255
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store8 (i32.const 0) (i32.const 255))
- (i32.load8_u (i32.const 0)))))
- (test-vm "i32.store8 + i32.load8_u wrap"
- 255
- '(module
- (memory $memory 1)
- (func (export "main") (result i32)
- (i32.store8 (i32.const 0) (i32.const -257))
- (i32.load8_u (i32.const 0)))))
- (test-vm "i64.store + i64.load"
- 42
- '(module
- (memory 1)
- (func (export "main") (result i64)
- (i64.store (i32.const 0) (i64.const 42))
- (i64.load (i32.const 0)))))
- (test-vm "i64.store32 + i64.load32_s"
- -42
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store32 (i32.const 0) (i64.const -42))
- (i64.load32_s (i32.const 0)))))
- (test-vm "i64.store32 + i64.load32_s wrap"
- -1
- `(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store32 (i32.const 0) (i64.const ,(- (ash 1 32) 1)))
- (i64.load32_s (i32.const 0)))))
- (test-vm "i64.store32 + i64.load32_u"
- (- (ash 1 32) 1)
- `(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store32 (i32.const 0) (i64.const ,(- (ash 1 32) 1)))
- (i64.load32_u (i32.const 0)))))
- (test-vm "i64.store32 + i64.load32_u wrap"
- (- (ash 1 32) 1)
- `(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store32 (i32.const 0) (i64.const ,(- (ash -1 32) 1)))
- (i64.load32_u (i32.const 0)))))
- (test-vm "i64.store16 + i64.load16_s"
- -42
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store16 (i32.const 0) (i64.const -42))
- (i64.load16_s (i32.const 0)))))
- (test-vm "i64.store16 + i64.load16_s wrap"
- -1
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store16 (i32.const 0) (i64.const -65537))
- (i64.load16_s (i32.const 0)))))
- (test-vm "i64.store16 + i64.load16_u"
- 65535
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store16 (i32.const 0) (i64.const 65535))
- (i64.load16_u (i32.const 0)))))
- (test-vm "i64.store16 + i64.load16_u wrap"
- 65535
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store16 (i32.const 0) (i64.const -65537))
- (i64.load16_u (i32.const 0)))))
- (test-vm "i64.store8 + i64.load8_s"
- -42
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store8 (i32.const 0) (i64.const -42))
- (i64.load8_s (i32.const 0)))))
- (test-vm "i64.store8 + i64.load8_s wrap"
- -1
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store8 (i32.const 0) (i64.const -257))
- (i64.load8_s (i32.const 0)))))
- (test-vm "i64.store8 + i64.load8_u"
- 255
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store8 (i32.const 0) (i64.const 255))
- (i64.load8_u (i32.const 0)))))
- (test-vm "i64.store8 + i64.load8_u wrap"
- 255
- '(module
- (memory $memory 1)
- (func (export "main") (result i64)
- (i64.store8 (i32.const 0) (i64.const -257))
- (i64.load8_u (i32.const 0)))))
- (test-vm "f32.store + f32.load"
- 1.5
- '(module
- (memory 1)
- (func (export "main") (result f32)
- (f32.store (i32.const 0) (f32.const 1.5))
- (f32.load (i32.const 0)))))
- (test-vm "f64.store + f64.load"
- 1.5
- '(module
- (memory 1)
- (func (export "main") (result f64)
- (f64.store (i32.const 0) (f64.const 1.5))
- (f64.load (i32.const 0)))))
- (test-vm "memory.size"
- 1
- '(module
- (memory 1)
- (func (export "main") (result i32)
- (memory.size))))
- (test-vm "memory.grow within limits"
- 2
- '(module
- (memory 2 3)
- (func (export "main") (result i32)
- (i32.const 1)
- (memory.grow))))
- (test-vm "memory.grow outside limits"
- -1
- '(module
- (memory 1 1)
- (func (export "main") (result i32)
- (i32.const 1)
- (memory.grow))))
- (test-vm "memory.grow no-op"
- 1
- '(module
- (memory 1 1)
- (func (export "main") (result i32)
- (i32.const 0)
- (memory.grow))))
- (test-vm "if"
- 37
- '(module
- (func (export "main") (result i32)
- (if (result i32)
- (i32.eq (i32.const 42) (i32.const 47))
- (then (i32.const 13))
- (else (i32.const 37))))))
- (test-vm "branching in a block"
- 42
- '(module
- (func (export "main") (result i32)
- (block $foo
- (br $foo)
- (unreachable))
- (i32.const 42))))
- (test-vm "return"
- 42
- '(module
- (func (export "main") (result i32)
- (block $foo (result i32)
- (i32.const 42)
- (return)
- (unreachable)))))
- (test-vm "return via br"
- 42
- '(module
- (func (export "main") (result i32)
- (i32.const 42)
- (br 0)
- (unreachable))))
- (test-vm "return_call"
- 42
- '(module
- (func $count (param $i i32) (param $k i32) (result i32)
- (if (result i32)
- (i32.eq (local.get $i) (local.get $k))
- (then (local.get $k))
- (else (return_call $count
- (i32.add (local.get $i) (i32.const 1))
- (local.get $k)))))
- (func $main (export "main") (param $k i32) (result i32)
- (call $count (i32.const 0) (local.get $k))))
- #:args '(42))
- (test-vm "return with extra values on stack"
- 42
- '(module
- (func (export "main") (result i32)
- (block $foo (result i32)
- (i32.const 13)
- (i32.const 42)
- (return)))))
- (test-vm/error "fallthrough with too many values on stack"
- '(module
- (func (export "main") (result i32)
- (i32.const 1)
- (i32.const 2))))
- (test-vm/error "fallthrough with too many values on invalid stack"
- '(module
- (func (export "main") (result i32)
- (i32.const 1)
- (return) ; stack is invalid after this
- (i32.const 2)
- (i32.const 3))))
- (test-vm "branching in a loop"
- 24
- '(module
- ;; Iterative factorial.
- (func (export "main") (param $n i32) (result i32)
- (local $result i32)
- (local.set $result (i32.const 1))
- (loop $loop (result i32)
- (if (result i32)
- (i32.eq (local.get $n) (i32.const 1))
- (then (local.get $result))
- (else (local.set $result (i32.mul (local.get $n)
- (local.get $result)))
- (local.set $n (i32.sub (local.get $n) (i32.const 1)))
- (br $loop))))))
- #:args '(4))
- (test-vm "blocks with params and results"
- 24
- '(module
- (func (export "main") (param $n i32) (result i32)
- (local.get $n)
- (block $block (param i32) (result i32)
- (loop $loop (param i32) (result i32)
- (i32.eq (local.get $n) (i32.const 1))
- (br_if $block)
- (local.tee $n (i32.sub (local.get $n) (i32.const 1)))
- (i32.mul)
- (br $loop)))))
- #:args '(4))
- (test-vm "br_table"
- 42
- '(module
- (func (export "main") (result i32)
- (block $foo (result i32)
- (block $bar (result i32)
- (i32.const 21)
- (i32.const 0)
- (br_table $foo $bar))
- (unreachable))
- (i32.const 21)
- (i32.add))))
- (test-vm "br_table with negative i"
- 42
- '(module
- (func (export "main") (result i32)
- (block $foo (result i32)
- (block $bar (result i32)
- (i32.const 21)
- (i32.const -1)
- (br_table $bar $foo))
- (unreachable))
- (i32.const 21)
- (i32.add))))
- (test-vm "inner function call"
- 11
- '(module
- (func $y (param $m i32) (param $x i32) (param $b i32) (result i32)
- (i32.add (i32.mul (local.get $m) (local.get $x)) (local.get $b)))
- (func (export "main") (param $x i32) (result i32)
- (call $y (i32.const 2) (local.get $x) (i32.const 3))))
- #:args '(4))
- (test-vm "imported function call"
- 80
- '(module
- (func $add42 (import "lib" "add42")
- (param i32) (result i32))
- (func (export "main") (param $x i32) (result i32)
- (call $add42 (local.get $x))))
- #:imports `(("lib" . (("add42" . ,(lambda (x) (+ x 42))))))
- #:args '(38)
- #:v8? #f)
- (test-vm "mutable globals"
- 42
- '(module
- (global $foo (mut i32) (i32.const 30))
- (func (export "main") (param $n i32) (result i32)
- (global.set $foo (i32.add (local.get $n) (global.get $foo)))
- (global.get $foo)))
- #:args '(12))
- (test-vm "imported globals"
- 80
- '(module
- (global $foo i32 (i32.const 42))
- (global $bar (import "globals" "bar") i32)
- (func (export "main") (result i32)
- (i32.add (global.get $foo) (global.get $bar))))
- #:imports `(("globals" . (("bar" . ,(make-wasm-global 38 #f)))))
- #:v8? #f)
- (test-vm "immutable global reference in constant expression"
- 42
- '(module
- (global $foo i32 (i32.const 42))
- (global $bar i32 (global.get $foo))
- (func (export "main") (result i32)
- (global.get $bar))))
- (test-vm/error "reference to mutable global in constant expression"
- '(module
- (global $foo (mut i32) (i32.const 42))
- (global $bar i32 (global.get $foo))
- (func (export "main") (result i32)
- (global.get $bar))))
- (test-vm/error "reference to subsequent global in constant expression"
- '(module
- (global $bar i32 (global.get $foo))
- (global $foo i32 (i32.const 42))
- (func (export "main") (result i32)
- (global.get $bar))))
- (test-vm "drop"
- 42
- '(module
- (func (export "main") (result i32)
- (i32.const 42)
- (i32.const 13)
- (drop))))
- (test-vm "drop in unreachable code"
- 42
- '(module
- (func (export "main") (result i32)
- (i32.const 42)
- (return)
- (drop))))
- (test-vm "select first"
- 42
- '(module
- (func (export "main") (result i32)
- (i32.const 42)
- (i32.const 13)
- (i32.const 1)
- (select))))
- (test-vm "select second"
- 13
- '(module
- (func (export "main") (result i32)
- (i32.const 42)
- (i32.const 13)
- (i32.const 0)
- (select))))
- (test-vm "select in unreachable code"
- 42
- '(module
- (func (export "main") (result i32)
- (i32.const 42)
- (return)
- (select))))
- (test-vm "select in unreachable code with i32 on top"
- 42
- '(module
- (func (export "main") (result i32)
- (i32.const 42)
- (return)
- (i32.const 0)
- (select))))
- (test-vm "start function"
- 42
- '(module
- (global $foo (mut i32) (i32.const 13))
- (func $init
- (global.set $foo (i32.const 42)))
- (start $init)
- (func (export "main") (result i32)
- (global.get $foo))))
- (test-vm "table.size"
- 2
- '(module
- (table $funcs 2 funcref)
- (func (export "main") (result i32)
- (table.size $funcs))))
- (test-vm "table.grow within limits"
- 2
- '(module
- (table $funcs 2 3 funcref)
- (func $main (export "main") (result i32)
- (ref.func $main)
- (i32.const 1)
- (table.grow $funcs))))
- (test-vm "table.grow outside limits"
- -1
- '(module
- (table $funcs 1 1 funcref)
- (func $main (export "main") (result i32)
- (ref.func $main)
- (i32.const 1)
- (table.grow $funcs))))
- (test-vm "table.grow no-op"
- 1
- '(module
- (table $funcs 1 1 funcref)
- (func $main (export "main") (result i32)
- (ref.func $main)
- (i32.const 0)
- (table.grow $funcs))))
- (test-vm "table.init with passive element segment"
- 1
- '(module
- (table $a 1 funcref)
- (elem $funcs funcref (ref.null func))
- (func $main (export "main") (result i32)
- (table.init $a $funcs
- (i32.const 0)
- (i32.const 0)
- (i32.const 1))
- (ref.is_null (table.get $a (i32.const 0))))))
- (test-vm "table.fill"
- 1
- '(module
- (table $funcs 3 funcref)
- (elem $funcs (i32.const 0) $main)
- (func $main (export "main") (result i32)
- (i32.const 1)
- (ref.func $main)
- (i32.const 2)
- (table.fill $funcs)
- (i32.const 1))))
- (test-vm "table.copy"
- 1
- '(module
- (table $a 3 funcref)
- (table $b 3 funcref)
- (elem $funcs (i32.const 0) $main $main $main)
- (func $main (export "main") (result i32)
- (i32.const 3)
- (i32.const 0)
- (i32.const 0)
- (table.copy $b $a)
- (i32.const 1))))
- (test-vm "elem.drop"
- 1
- '(module
- (table $funcs 1 funcref)
- (elem $foo (i32.const 0) $main)
- (func $main (export "main") (result i32)
- (elem.drop $foo)
- (i32.const 1))))
- (test-vm "call_indirect"
- 42
- '(module
- (table $funcs 1 funcref)
- (type $i32->i32 (func (param i32) (result i32)))
- (func $inc (param $a i32) (result i32)
- (i32.add (local.get $a) (i32.const 1)))
- (elem $funcs (i32.const 0) $inc)
- (func (export "main") (result i32)
- (call_indirect $funcs (type $i32->i32)
- (i32.const 41) (i32.const 0)))))
- (test-vm "call_ref"
- 42
- '(module
- (type $i32->i32 (func (param i32) (result i32)))
- (func $sum-41 (param $x i32) (result i32)
- (i32.add (local.get $x) (i32.const 41)))
- (func (export "main") (result i32)
- (call_ref $i32->i32 (i32.const 1) (ref.func $sum-41)))))
- (test-vm "ref.null + ref.is_null"
- 1
- '(module
- (func (export "main") (result i32)
- (ref.null func)
- (ref.is_null))))
- (test-vm "ref.test true"
- 1
- '(module
- (type $foo (struct (field $bar (ref eq))))
- (func (export "main") (result i32)
- (ref.test $foo (struct.new $foo (ref.i31 (i32.const 42)))))))
- (test-vm "ref.test false"
- 0
- '(module
- (type $foo (struct (field $bar (ref eq))))
- (func (export "main") (result i32)
- (ref.test $foo (ref.null $foo)))))
- (test-vm "ref.as_non_null"
- 42
- '(module
- (type $foo (struct (field $bar i32)))
- (func (export "main") (result i32)
- (struct.get $foo $bar
- (ref.as_non_null
- (struct.new $foo (i32.const 42)))))))
- (test-vm "ref.cast identity non-null"
- 42
- '(module
- (func (export "main") (result i32)
- (ref.i31 (i32.const 42))
- (ref.cast i31)
- (i31.get_s))))
- (test-vm "ref.cast identity null"
- 42
- '(module
- (func (export "main") (result i32)
- (ref.null i31)
- (ref.cast null i31)
- (drop)
- (i32.const 42))))
- (test-vm/error "ref.cast null"
- '(module
- (func (export "main") (result i32)
- (ref.null i31)
- (ref.cast i31)
- (i31.get_s))))
- (test-vm "external reference passthrough"
- '(opaque to wasm)
- '(module
- (func (export "main") (param $foo externref) (result externref)
- (local.get $foo)))
- #:args '((opaque to wasm))
- #:v8? #f)
- (test-vm "i31.get_s"
- -42
- '(module
- (func (export "main") (result i32)
- (i31.get_s (ref.i31 (i32.const -42))))))
- (test-vm "i31.get_u"
- 2147483606
- '(module
- (func (export "main") (result i32)
- (i31.get_u (ref.i31 (i32.const -42))))))
- (test-vm "struct.get"
- 5.0
- '(module
- (type $vec2 (struct (field $x f32) (field $y f32)))
- (func (export "main") (result f32) (local $v (ref $vec2))
- (local.set $v (struct.new $vec2 (f32.const 3.0) (f32.const 4.0)))
- ;; Calculate vector magnitude, for fun.
- (f32.sqrt
- (f32.add (f32.mul (struct.get $vec2 $x (local.get $v))
- (struct.get $vec2 $x (local.get $v)))
- (f32.mul (struct.get $vec2 $y (local.get $v))
- (struct.get $vec2 $y (local.get $v))))))))
- (test-vm "struct.get_s"
- -42
- '(module
- (type $foo (struct (field $bar i8)))
- (func (export "main") (result i32)
- (struct.get_s $foo $bar (struct.new $foo (i32.const -42))))))
- (test-vm "struct.get_u"
- 214
- '(module
- (type $foo (struct (field $bar i8)))
- (func (export "main") (result i32)
- (struct.get_u $foo $bar (struct.new $foo (i32.const -42))))))
- (test-vm "struct.set"
- 42
- '(module
- (type $foo (struct (field $bar (mut i32))))
- (func (export "main") (result i32) (local $a (ref $foo))
- (local.set $a (struct.new $foo (i32.const 0)))
- (struct.set $foo $bar (local.get $a) (i32.const 42))
- (struct.get $foo $bar (local.get $a)))))
- (test-vm "struct subtyping"
- 42
- '(module
- (type $heap-object
- (sub
- (struct
- (field $hash (mut i32)))))
- (type $pair
- (sub $heap-object
- (struct
- (field $hash (mut i32))
- (field $car (mut (ref eq)))
- (field $cdr (mut (ref eq))))))
- (func (export "main") (result i32) (local $a (ref $pair))
- (local.set $a (struct.new $pair (i32.const 1)
- (ref.i31 (i32.const 21))
- (ref.i31 (i32.const 21))))
- (i32.add (i31.get_s (ref.cast i31 (struct.get $pair $car (local.get $a))))
- (i31.get_s (ref.cast i31 (struct.get $pair $cdr (local.get $a))))))))
- (test-vm "struct.new_default"
- 0
- '(module
- (type $foo (struct (field $bar i32)))
- (func (export "main") (result i32)
- (struct.get $foo $bar (struct.new_default $foo)))))
- (test-vm "array.len"
- 3
- '(module
- (type $foo (array i32))
- (func (export "main") (result i32)
- (array.len (array.new $foo (i32.const 0) (i32.const 3))))))
- (test-vm "array.get"
- 42
- '(module
- (type $foo (array i32))
- (func (export "main") (result i32)
- (array.get $foo (array.new $foo (i32.const 42) (i32.const 1)) (i32.const 0)))))
- (test-vm "array.get_s"
- -42
- '(module
- (type $foo (array i8))
- (func (export "main") (result i32)
- (array.get_s $foo (array.new_fixed $foo 1 (i32.const -42)) (i32.const 0)))))
- (test-vm "array.get_u"
- 214
- '(module
- (type $foo (array i8))
- (func (export "main") (result i32)
- (array.get_u $foo (array.new_fixed $foo 1 (i32.const -42)) (i32.const 0)))))
- (test-vm "array.set"
- 42
- '(module
- (type $foo (array (mut i32)))
- (func (export "main") (result i32) (local $a (ref $foo))
- (local.set $a (array.new $foo (i32.const 0) (i32.const 1)))
- (array.set $foo (local.get $a) (i32.const 0) (i32.const 42))
- (array.get $foo (local.get $a) (i32.const 0)))))
- (test-vm "array.new_fixed"
- 42
- '(module
- (type $foo (array i32))
- (func (export "main") (result i32)
- (array.get $foo (array.new_fixed $foo 1 (i32.const 42)) (i32.const 0)))))
- (test-vm "array.new_default"
- 0
- '(module
- (type $foo (array i32))
- (func (export "main") (result i32)
- (array.get $foo (array.new_default $foo (i32.const 1)) (i32.const 0)))))
- (test-vm "array.new_data"
- 4
- '(module
- (type $foo (array i32))
- (data $init #s32(1 2 3 4))
- (func (export "main") (result i32)
- (array.get $foo (array.new_data $foo $init
- (i32.const 0)
- (i32.const 4))
- (i32.const 3)))))
- (test-vm "array.new_elem"
- 4
- '(module
- (type $foo (array (ref i31)))
- (elem $init (ref i31)
- (item (ref.i31 (i32.const 1)))
- (item (ref.i31 (i32.const 2)))
- (item (ref.i31 (i32.const 3)))
- (item (ref.i31 (i32.const 4))))
- (func (export "main") (result i32)
- (i31.get_s
- (array.get $foo (array.new_elem $foo $init
- (i32.const 0)
- (i32.const 4))
- (i32.const 3))))))
- (test-vm "array.init_data"
- 4
- '(module
- (type $foo (array (mut i32)))
- (data $init #s32(1 2 3 4))
- (func (export "main") (result i32)
- (local $a (ref $foo))
- (local.set $a (array.new $foo
- (i32.const 0)
- (i32.const 4)))
- (array.init_data $foo $init
- (local.get $a)
- (i32.const 0)
- (i32.const 0)
- (i32.const 4))
- (array.get $foo (local.get $a) (i32.const 3)))))
- (test-vm "array.init_elem"
- 4
- '(module
- (type $foo (array (mut (ref i31))))
- (elem $init (ref i31)
- (item (ref.i31 (i32.const 1)))
- (item (ref.i31 (i32.const 2)))
- (item (ref.i31 (i32.const 3)))
- (item (ref.i31 (i32.const 4))))
- (func (export "main") (result i32)
- (local $a (ref $foo))
- (local.set $a (array.new $foo
- (ref.i31 (i32.const 0))
- (i32.const 4)))
- (array.init_elem $foo $init
- (local.get $a)
- (i32.const 0)
- (i32.const 0)
- (i32.const 4))
- (i31.get_s
- (array.get $foo (local.get $a) (i32.const 3))))))
- (test-vm "array.fill"
- 42
- '(module
- (type $foo (array (mut i32)))
- (func (export "main") (result i32) (local $a (ref $foo))
- (local.set $a (array.new_default $foo (i32.const 1)))
- (array.fill $foo
- (local.get $a)
- (i32.const 0)
- (i32.const 42)
- (i32.const 1))
- (array.get $foo (local.get $a) (i32.const 0)))))
- (test-vm "array.copy"
- 42
- '(module
- (type $foo (array (mut i32)))
- (func (export "main") (result i32) (local $a (ref $foo))
- (local.set $a (array.new_default $foo (i32.const 1)))
- (array.copy $foo $foo
- (local.get $a)
- (i32.const 0)
- (array.new_fixed $foo 1 (i32.const 42))
- (i32.const 0)
- (i32.const 1))
- (array.get $foo (local.get $a) (i32.const 0)))))
- (test-vm "reference type constants"
- 42
- '(module
- (type $foo (array (ref i31)))
- (global $bar (ref $foo)
- (array.new $foo
- (ref.i31 (i32.const 42))
- (i32.const 1)))
- (func (export "main") (result i32)
- (i31.get_s
- (array.get $foo
- (global.get $bar)
- (i32.const 0))))))
- (test-vm "string.const"
- "Hello, world!"
- '(module
- (func (export "main") (result (ref string))
- (string.const "Hello, world!")))
- #:v8-read get-line)
- (test-vm "string.new_lossy_utf8_array"
- "HELLO"
- '(module
- (type $utf8 (array (mut i8)))
- (func (export "main") (result (ref string))
- (string.new_lossy_utf8_array (array.new_fixed $utf8 5
- (i32.const 72)
- (i32.const 69)
- (i32.const 76)
- (i32.const 76)
- (i32.const 79))
- (i32.const 0)
- (i32.const 5))))
- #:v8-read get-line)
- (test-vm "string.encode_wtf8_array"
- 5
- '(module
- (type $utf8 (array (mut i8)))
- (func (export "main") (result i32)
- (string.encode_wtf8_array (string.const "HELLO")
- (array.new $utf8
- (i32.const 0)
- (i32.const 5))
- (i32.const 0)))))
- (test-vm "string.measure_utf8"
- 5
- '(module
- (func (export "main") (result i32)
- (string.measure_utf8 (string.const "HELLO")))))
- (test-vm "string.measure_wtf8"
- 5
- '(module
- (func (export "main") (result i32)
- (string.measure_wtf8 (string.const "HELLO")))))
- (test-equal "inter-instance function calls"
- 17
- (let* ((wat-a '(module
- (func (export "square") (param $x i32) (result i32)
- (i32.mul (local.get $x) (local.get $x)))))
- (wat-b '(module
- (func $square (import "wasm" "square") (param i32) (result i32))
- (func (export "main") (param $x i32) (result i32)
- (i32.add (call $square (local.get $x)) (i32.const 1)))))
- (wasm-a (wat->wasm* wat-a))
- (wasm-b (wat->wasm* wat-b))
- (inst-a (instantiate-wasm (validate-wasm wasm-a)))
- (square (wasm-instance-export-ref inst-a "square"))
- (inst-b (instantiate-wasm (validate-wasm wasm-b)
- #:imports `(("wasm" .
- (("square" . ,square)))))))
- ((wasm-instance-export-ref inst-b "main") 4)))
- (test-vm "try"
- 111
- '(module
- (tag $foo (param i32))
- (func (export "main") (result i32)
- (try (result i32)
- (do (i32.const 42)
- (throw $foo))
- (catch $foo
- (i32.const 69)
- (i32.add))
- (catch_all
- (unreachable))))))
- (test-vm "try_delegate"
- 111
- '(module
- (tag $foo (param i32))
- (func (export "main") (result i32)
- (try $bloop (result i32)
- (do (try
- (do (i32.const 69)
- (throw $foo))
- (delegate $bloop))
- (unreachable))
- (catch $foo
- (i32.const 42)
- (i32.add))
- (catch_all (i32.const 77))))))
- (test-vm "rethrow"
- 42
- '(module
- (tag $foo)
- (func (export "main") (result i32)
- (try $l1 (result i32)
- (do (try $l2 (result i32)
- (do (throw $foo))
- (catch $foo
- (rethrow $l2))
- (catch_all (unreachable))))
- (catch $foo
- (i32.const 42))
- (catch_all (unreachable))))))
- (test-equal "throw across instances"
- 111
- (let* ((wat-a '(module
- (tag $err (export "err") (param i32))
- (func (export "foo") (param $x i32)
- (throw $err (local.get $x)))))
- (wat-b '(module
- (tag $err (import "other" "err") (param i32))
- (func $foo (import "other" "foo") (param i32))
- (func (export "main") (param $x i32) (result i32)
- (try (result i32)
- (do (call $foo (local.get $x))
- (unreachable))
- (catch $err
- (i32.const 69)
- (i32.add))
- (catch_all (unreachable))))))
- (wasm-a (wat->wasm* wat-a))
- (wasm-b (wat->wasm* wat-b))
- (inst-a (instantiate-wasm (validate-wasm wasm-a)))
- (err (wasm-instance-export-ref inst-a "err"))
- (foo (wasm-instance-export-ref inst-a "foo"))
- (inst-b (instantiate-wasm (validate-wasm wasm-b)
- #:imports `(("other" .
- (("err" . ,err)
- ("foo" . ,foo)))))))
- ((wasm-instance-export-ref inst-b "main") 42)))
- (test-end* "test-vm")
|