hoot.texi 99 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352
  1. \input texinfo @c -*- texinfo -*-
  2. @c %**start of header
  3. @setfilename hoot.info
  4. @settitle Guile Hoot
  5. @documentencoding UTF-8
  6. @documentlanguage en
  7. @syncodeindex pg cp
  8. @c %**end of header
  9. @dircategory The Algorithmic Language Scheme
  10. @direntry
  11. * Hoot: (hoot). Scheme to Wasm compiler backend for Guile and Wasm toolchain.
  12. @end direntry
  13. @finalout
  14. @titlepage
  15. @title Guile Hoot
  16. @author David Thompson (@email{dave@@spritely.institute})
  17. @author The Spritely Institute
  18. @end titlepage
  19. @contents
  20. @ifnottex
  21. @node Top
  22. @top Guile Hoot
  23. This is the manual for Guile Hoot, a Scheme to WebAssembly compiler
  24. backend for @url{https://gnu.org/software/guile,GNU Guile} and general
  25. purpose Wasm toolchain.
  26. Both this manual and Guile Hoot itself are released under Apache v2.
  27. See @ref{License} for more information.
  28. @end ifnottex
  29. @menu
  30. * Introduction:: What's the deal with Wasm, anyway?
  31. * Compiling to Wasm:: Using the compiler and development tools.
  32. * Web deployment:: Scheme in the browser!
  33. * Scheme reference:: Hoot-specific Scheme extensions.
  34. * Toolchain reference:: General purpose Wasm tools.
  35. * Contributing:: Lend a hand!
  36. * License:: Copying, distributing, and using this text.
  37. * Index::
  38. @end menu
  39. @node Introduction
  40. @chapter Introduction
  41. Guile Hoot is a Scheme to WebAssembly (henceforth referred to as
  42. @emph{Wasm}) compiler backend for
  43. @url{https://gnu.org/software/guile,GNU Guile} and a general purpose
  44. Wasm toolchain. Wasm is an abstract but low-level binary compilation
  45. target that can run on all major web browsers, and increasingly in
  46. other, more ``native'' contexts, as well. For over two decades,
  47. JavaScript has been @emph{the} official language of the web, and while
  48. the language has improved a lot over the years, its design leaves much
  49. to be desired. Thus web developers looked for ways to bring their
  50. preferred language to the browser to use instead. In the past, the
  51. only option available was to @emph{compile that language to
  52. JavaScript!} This approach worked in some sense but it was unideal
  53. because many languages do not map cleanly to JavaScript. In the case
  54. of Scheme, for example, the lack of a tail call facility makes
  55. compiling tail-recursive Scheme code unpleasant. At long last, thanks
  56. to Wasm, it has become possible to use an alternative language with
  57. fewer compromises and better performance. Hoot aims to bring Guile's
  58. ``whole self'' to the web, as well as to other Wasm GC runtimes.
  59. Hoot is being developed by the
  60. @url{https://spritely.institute,Spritely Institute} in collaboration
  61. with @url{https://www.igalia.com/,Igalia} to advance Spritely's
  62. mission to build the infrastructure for a completely decentralized
  63. social Internet. And for that mission, what better platform to target
  64. than the web browser?
  65. @url{https://spritely.institute/goblins/,Goblins}, Spritely's
  66. distributed object programming environment, is primarily written in
  67. Guile. So, to meet users where they are at @emph{and} not use
  68. JavaScript at the same time, Spritely needs a Guile to Wasm compiler!
  69. A secondary goal of Hoot is to advocate for all dynamic programming
  70. languages' (Python, Ruby, etc.) rightful place on the client-side web.
  71. The Wasm 1.0 specification was not a habitable environment for
  72. languages that require a garbage collector. The Wasm GC proposal,
  73. among others, has made it possible for dynamic languages to target
  74. Wasm in a real way. However, such advances are not without their
  75. detractors. Without the necessary support, a useful proposal will
  76. never make it into the core specification. For example, strings are a
  77. particularly controversial subject in the WebAssembly Community Group
  78. and proposals that would greatly benefit Hoot and other languages have
  79. not reached consensus. Implementing and targeting emergent and useful
  80. Wasm proposals helps those proposals find their way into the core
  81. specification. A rising tide lifts all boats, as they say, and while
  82. we may be little schemers, we want our work to help advance the Wasm
  83. standard for all dynamic languages.
  84. @menu
  85. * Status:: What works. What doesn't.
  86. * Installation:: Setting up Hoot.
  87. * Tutorial:: Compiling your first Scheme program to Wasm.
  88. @end menu
  89. @node Status
  90. @section Status
  91. Hoot's Wasm output is compatible with Google Chrome starting with
  92. version 119 and Mozilla Firefox starting with version 121. As of
  93. writing, WebKit/Apple Safari is not yet compatible.
  94. Hoot is still in an early phase of active development and its API
  95. should be considered unstable and subject to change in future
  96. releases. Hoot currently supports a subset of the R7RS-small Scheme
  97. specification, along with a small set of Guile-specific functionality
  98. such as @inlinefmtifelse{html,
  99. @url{https://www.gnu.org/software/guile/manual/html_node/Prompts.html,
  100. prompts}, @ref{Prompts,,,Guile Reference}}.
  101. The largest missing pieces from Hoot's R7RS-small support are
  102. environments and evaluation (@code{environment}, @code{eval}, etc.)
  103. which would allow for runtime interpretation of Scheme. Future
  104. releases will add support for all of R7RS-small and eventually full
  105. Guile-flavored Scheme.
  106. To compile Scheme to Wasm, Hoot takes advantage of several new Wasm
  107. proposals. The most important of these new features are tail calls
  108. and GC reference types. The @code{return_call} family of instructions
  109. has made the implementation of Scheme's tail recursive procedure call
  110. semantics relatively straightforward. GC reference type instructions
  111. allow for heap allocated objects (and immediates via the @code{i31}
  112. type) that are managed by the Wasm runtime. This allows Hoot to take
  113. advantage of production garbage collectors already present in web
  114. browsers, obviating the need to implement and ship our own which would
  115. be both inferior to the host's and a major source of binary bloat.
  116. There's an additional Wasm proposal that Hoot has been built on that
  117. has, unfortunately, not found its way into the core Wasm
  118. specification: stringref. We still emit stringref, but it is reduced
  119. to being an intermediate form. A lowering pass replaces stringref
  120. instructions with something resembling the JS String Builtins
  121. proposal.
  122. @node Installation
  123. @section Installation
  124. @node Binary installation
  125. @subsection Binary installation
  126. Currently, Hoot is available from only one GNU/Linux distribution:
  127. @url{https://guix.gnu.org,GNU Guix}. Guix may also be used as an
  128. additional package manager on top of another distribution such as
  129. Debian.
  130. If you have Guix, trying Hoot is easy:
  131. @example
  132. guix shell guile-next guile-hoot
  133. @end example
  134. This will create a temporary shell environment in which you can try
  135. Hoot. It's important that the @code{guile-next} package is included
  136. because Hoot currently relies upon features in Guile that have not yet
  137. made it into a stable release.
  138. @node Building from source
  139. @subsection Building from source
  140. The @emph{easiest} way to get everything necessary to build Hoot is by
  141. using the @url{https://guix.gnu.org,GNU Guix} package manager for
  142. which we provide a @file{guix.scm} file ready for use with
  143. @command{guix shell}:
  144. @example
  145. cd guile-hoot/
  146. guix shell
  147. @end example
  148. @command{guix shell} will download/compile all required dependencies
  149. and start an interactive shell that is ready to use for building Hoot.
  150. To use Hoot without Guix requires building Guile from source. Hoot is
  151. currently undergoing a lot of development and requires a bleeding-edge
  152. Guile built against the @code{main} branch. Eventually Hoot will just
  153. require a stable release of Guile.
  154. With a sufficiently fresh Guile, via Guix or otherwise, the build can
  155. begin. If you are building from a Git checkout rather than an
  156. official release tarball, the first step is to bootstrap the build
  157. system:
  158. @example
  159. ./bootstrap.sh
  160. @end example
  161. Release tarballs have a pre-bootstrapped build system and do not
  162. require the above step.
  163. Now, build Hoot:
  164. @example
  165. ./configure
  166. make
  167. @end example
  168. If you'd like to install Hoot onto your system, run:
  169. @example
  170. sudo make install
  171. @end example
  172. The GNU build system defaults to @file{/usr/local} as the installation
  173. prefix. This can be changed by re-running the configure script:
  174. @example
  175. ./configure --prefix=/some/where/else
  176. sudo make install
  177. @end example
  178. To try out Hoot without installing it, use the @file{pre-inst-env}
  179. wrapper to launch Guile in the context of the Hoot build directory:
  180. @example
  181. ./pre-inst-env guile
  182. @end example
  183. If you installed Guile to your system, simply run @command{guile}.
  184. If everything went well, you will be greeted with a Guile REPL prompt.
  185. Regardless of installation status, to verify that Guile can find the
  186. Hoot modules, run:
  187. @lisp
  188. scheme@@(guile-user)> ,use (hoot compile)
  189. @end lisp
  190. If there is no error then congratulations! Your setup is correct.
  191. Proceed to the tutorial for a crash course in how to use Hoot, or see
  192. later chapters for an API reference.
  193. @subsubsection Running the test suite
  194. This is entirely optional, but if you'd like further verification that
  195. your build is good (or perhaps you're packaging Hoot for
  196. distribution), the test suite can be run via @command{make check}. By
  197. default, the tests are run against two Wasm runtimes: Hoot's own Wasm
  198. interpreter and @url{https://v8.dev/,V8} via the @command{d8} tool.
  199. Getting V8 can be tricky, and will most likely require you to
  200. @url{https://v8.dev/docs/build,compile it from source.} It's a pain!
  201. To skip all of that trouble and just run the tests against the
  202. built-in interpreter, run:
  203. @example
  204. make check Wasm_HOST=hoot
  205. @end example
  206. @node Tutorial
  207. @section Tutorial
  208. Let's compile some simple Scheme programs and learn how to work with
  209. their compiled Wasm forms.
  210. As we all know, the answer to everything is simply 42. So, we should
  211. make sure that we can compile 42 to Wasm. To do so, import the
  212. @code{(hoot compile)} module and call the @code{compile} procedure.
  213. @lisp
  214. @verbatim
  215. scheme@(guile-user)> ,use (hoot compile)
  216. scheme@(guile-user)> (define the-answer (compile 42))
  217. @end verbatim
  218. @end lisp
  219. The result is a Wasm module. There is a lot of stuff inside, but
  220. we're not going to focus on that right now. We should load and run
  221. the module to verify that it outputs 42 like we expect. We can do so
  222. from the comfort of our Guile REPL because Hoot includes a Wasm
  223. interpreter. There's no need to use a web browser or other Wasm
  224. runtime to try out small programs.
  225. First, import the @code{(hoot reflect)} module. Then, instantiate
  226. @code{the-answer} to load it into the Wasm interpreter:
  227. @lisp
  228. @verbatim
  229. scheme@(guile-user)> ,use (hoot reflect)
  230. scheme@(guile-user)> (define instance (hoot-instantiate the-answer))
  231. @end verbatim
  232. @end lisp
  233. All that's left to do now is execute the program with
  234. @code{hoot-load}:
  235. @lisp
  236. @verbatim
  237. scheme@(guile-user)> (hoot-load instance)
  238. $5 = 42
  239. @end verbatim
  240. @end lisp
  241. Ta-da! It feels kind of funny to compile a Scheme program to Wasm
  242. only to load it back into Scheme, but it's a quick and easy way to
  243. test things out.
  244. For cases when you simply want to compile an expression and see the
  245. result immediately, there is a faster method. Just use the
  246. @code{compile-value} procedure instead:
  247. @lisp
  248. @verbatim
  249. scheme@(guile-user)> (compile-value '(list 1 2 3))
  250. $6 = #<hoot (1 2 3)>
  251. @end verbatim
  252. @end lisp
  253. With @code{compile-value}, the compiled Wasm module is thrown away,
  254. which is just fine for testing throwaway code.
  255. Lists are cool and 42 is ultimately the answer to everything, but it
  256. would be a shame if we didn't talk about compiling something a little
  257. more complicated. Let's compile a simple, tail-recursive procedure!
  258. How about good ol' factorial?
  259. @lisp
  260. @verbatim
  261. scheme@(guile-user)> (define hoot-factorial
  262. (compile-value
  263. '(let ()
  264. (define (factorial x result)
  265. (if (= x 1)
  266. result
  267. (factorial (- x 1)
  268. (* result x))))
  269. factorial)))
  270. @end verbatim
  271. @end lisp
  272. A Hoot procedure can be called just like a regular procedure:
  273. @lisp
  274. @verbatim
  275. scheme@(guile-user)> (hoot-factorial 5 1)
  276. $7 = 120
  277. @end verbatim
  278. @end lisp
  279. The Hoot reflection in Guile is great for quickly iterating on code,
  280. but what we really want is to get our programs running in a web
  281. browser. We've compiled a couple of things to Wasm now, but the
  282. resulting modules have stayed within the confines of the Guile
  283. process. To make something that can be loaded by a web browser, we
  284. need to use the assembler to create a Wasm binary:
  285. @lisp
  286. @verbatim
  287. scheme@(guile-user)> (define hello (compile "Hello, world!"))
  288. scheme@(guile-user)> ,use (wasm assemble)
  289. scheme@(guile-user)> (define bin (assemble-wasm hello))
  290. @end verbatim
  291. @end lisp
  292. Now, create a new directory for this tutorial:
  293. @example
  294. mkdir hoot-tutorial
  295. @end example
  296. Write the binary to disk in that directory:
  297. @lisp
  298. @verbatim
  299. scheme@(guile-user)> ,use (ice-9 binary-ports)
  300. scheme@(guile-user)> (call-with-output-file "/path/to/hoot-tutorial/hello.wasm"
  301. (lambda (port)
  302. (put-bytevector port bin)))
  303. @end verbatim
  304. @end lisp
  305. To inspect Scheme values from JavaScript, Hoot provides the
  306. @file{js-runtime/reflect.js} library. Copy that file and its
  307. associated Wasm helper modules, @file{js-runtime/reflect.wasm} and
  308. @file{js-runtime/wtf8.wasm}, to the @file{hoot-tutorial} directory:
  309. @example
  310. cd /path/to/hoot-tutorial
  311. cp /path/to/guile-hoot/js-runtime/reflect.js .
  312. mkdir js-runtime
  313. cp /path/to/guile-hoot/js-runtime/reflect.wasm js-runtime/
  314. cp /path/to/guile-hoot/js-runtime/wtf8.wasm js-runtime/
  315. @end example
  316. To run @file{hello.wasm}, we need a little JavaScript glue code.
  317. Let's call this @file{hello.js}:
  318. @example
  319. @verbatim
  320. async function load() {
  321. const [message] = await Scheme.load_main("hello.wasm", {});
  322. console.log(message);
  323. }
  324. window.addEventListener("load", load);
  325. @end verbatim
  326. @end example
  327. We also need a minimal @file{index.html} web page to bring it all
  328. together:
  329. @example
  330. <!DOCTYPE html>
  331. <html>
  332. <head>
  333. <script type="text/javascript" src="reflect.js"></script>
  334. <script type="text/javascript" src="hello.js"></script>
  335. </head>
  336. <body>
  337. Guile is a hoot!
  338. </body>
  339. </html>
  340. @end example
  341. The file tree in @file{hoot-tutorial} should look like this:
  342. @example
  343. ./js-runtime
  344. ./js-runtime/wtf8.wasm
  345. ./js-runtime/reflect.wasm
  346. ./reflect.js
  347. ./hello.js
  348. ./index.html
  349. ./hello.wasm
  350. @end example
  351. Finally, we need a local web server to serve the files. Fortunately,
  352. Guile includes all the building blocks we need to make a minimal one
  353. for the purposes of this tutorial. Save the following to
  354. @file{web-server.scm}:
  355. @lisp
  356. (use-modules (ice-9 binary-ports) (ice-9 format) (ice-9 match)
  357. (web server) (web request) (web response) (web uri))
  358. (define (extension file)
  359. (match (string-split file #\.)
  360. (() #f)
  361. ((_ ... ext) ext)))
  362. (define (mime-type file-name)
  363. (or (assoc-ref '(("js" . application/javascript)
  364. ("html" . text/html)
  365. ("wasm" . application/wasm))
  366. (extension file-name))
  367. 'text/plain))
  368. (define (render-file file-name)
  369. (values `((content-type . (,(mime-type file-name))))
  370. (call-with-input-file file-name get-bytevector-all)))
  371. (define (not-found path)
  372. (values (build-response #:code 404) (string-append "Not found: " path)))
  373. (define (directory? file-name)
  374. (eq? (stat:type (stat file-name)) 'directory))
  375. (define (serve-file path)
  376. (let ((f (string-append (getcwd) (uri-decode path))))
  377. (if (and (file-exists? f) (not (directory? f)))
  378. (render-file f)
  379. (not-found path))))
  380. (define (handle-request request body)
  381. (let ((method (request-method request))
  382. (path (uri-path (request-uri request))))
  383. (format #t "~a ~a\n" method path)
  384. (serve-file path)))
  385. (run-server handle-request 'http '(#:port 8080))
  386. @end lisp
  387. Start the web server like so:
  388. @example
  389. guile web-server.scm
  390. @end example
  391. Visit @url{http://localhost:8080/index.html} in your web browser, and
  392. if it is new enough to have Wasm GC enabled, you should see the text
  393. ``Hello, world!'' printed in the developer console.
  394. We hope this tutorial has helped you get started with Hoot! Read on
  395. for full API documentation.
  396. @node Compiling to Wasm
  397. @chapter Compiling to Wasm
  398. @menu
  399. * Invoking the compiler:: Compiling a Hoot module.
  400. * High-level development tools:: Using Hoot modules from the host environment.
  401. * Low-level development tools:: Inspecting and debugging Wasm.
  402. @end menu
  403. @node Invoking the compiler
  404. @section Invoking the compiler
  405. In Guile's compiler tower, Scheme code goes through several
  406. transformations before being compiled to VM bytecode. Scheme is
  407. lowered to @inlinefmtifelse{html,
  408. @url{https://www.gnu.org/software/guile/manual/html_node/Tree_002dIL.html,
  409. Tree-IL}, @ref{Tree-IL,,,Guile Reference}}, which is then lowered to
  410. @inlinefmtifelse{html,
  411. @url{https://www.gnu.org/software/guile/manual/html_node/Continuation_002dPassing-Style.html,
  412. Continuation-passing style}, @ref{Continuation-Passing Style,,,Guile
  413. Reference}}(CPS), and then finally to @inlinefmtifelse{html,
  414. @url{https://www.gnu.org/software/guile/manual/html_node/Bytecode.html,
  415. Bytecode}, @ref{Bytecode,,,Guile Reference}}. Hoot adds an additional
  416. backend that compiles CPS to Wasm.
  417. In contrast to Guile's approach of compiling individual modules, Hoot
  418. is a whole-program compiler. The user program and all imported
  419. modules are part of the same compilation unit and the result is a
  420. single Wasm binary. Currently, Hoot uses the R6RS library system and
  421. does not support Guile's @code{define-module} form or R7RS style
  422. libraries.
  423. For hooking the Hoot compiler up to a build system such as GNU Make,
  424. invoke the @command{guild compile-wasm} tool:
  425. @example
  426. guild compile-wasm -o foo.wasm foo.scm
  427. @end example
  428. Like Guile's built-in compiler, the Hoot compiler can also be invoked
  429. within Scheme. The @code{(hoot compile)} module provides the
  430. interface to the Wasm compiler backend.
  431. @deffn {Procedure} compile exp [#:import-abi? #f] [#:export-abi? #t] @
  432. [#:from (current-language)] @
  433. [#:imports %default-program-imports] @
  434. [#:optimization-level (default-optimization-level)] @
  435. [#:warning-level (default-warning-level)] @
  436. [#:dump-cps? #f] [#:dump-wasm? #f] [#:emit-names? #f] @
  437. [#:opts '()]
  438. Compile the Scheme expression @var{exp} to Wasm and return a Wasm
  439. module.
  440. The environment in which @var{exp} is evaluated is defined by
  441. @var{imports}, a list of module names such as @code{(scheme time)} or
  442. @code{(hoot ffi)}.
  443. When @var{import-abi?} is @code{#t}, the Wasm module will be built
  444. such that it needs to import its ABI from another module. When
  445. @var{export-abi?} is @code{#t}, the Wasm module will be built such
  446. that it exports its ABI functions. A typical use of these flags is to
  447. export the ABI from one ``main'' module and then import that ABI into
  448. any additional modules that are being used.
  449. When @var{emit-names?} is @code{#t} then human-readable names will be
  450. embedded in the resulting Wasm object. By default, this is turned off
  451. as it greatly increases binary size.
  452. @inlinefmtifelse{html,
  453. @url{https://www.gnu.org/software/guile/manual/html_node/Compilation.html,
  454. See the Guile manual}, @xref{Compiling Scheme Code,,,Guile Reference}}
  455. for more information about invoking Guile's compiler.
  456. @end deffn
  457. @deffn {Procedure} read-and-compile port [#:import-abi? #f] [#:export-abi? #t] @
  458. [#:from (current-language)] @
  459. [#:optimization-level (default-optimization-level)] @
  460. [#:warning-level (default-warning-level)] @
  461. [#:dump-cps? #f] [#:dump-wasm? #f] [#:emit-names? #f] @
  462. [#:opts '()]
  463. Like @code{compile}, but read Scheme expressions from @var{port}.
  464. If the first expression is an @code{import} form, then only the
  465. bindings from those modules will be imported into the compilation
  466. unit. If the @code{import} form is omitted, a default set of modules
  467. will be imported. It is highly recommended to be explicit and use
  468. @code{import}.
  469. @end deffn
  470. @deffn {Procedure} compile-file input-file [#:import-abi? #f] @
  471. [#:export-abi? #t] @
  472. [#:from (current-language)] @
  473. [#:optimization-level (default-optimization-level)] @
  474. [#:warning-level (default-warning-level)] @
  475. [#:dump-cps? #f] [#:dump-wasm? #f] [#:emit-names? #f] @
  476. [#:opts '()]
  477. Like @code{read-and-compile}, but read the Scheme expression from
  478. @var{input-file}.
  479. @end deffn
  480. @node High-level development tools
  481. @section High-level development tools
  482. The @code{(hoot reflect)} module provides an interface for inspecting
  483. and manipulating Scheme values that live within Wasm modules. This is
  484. the primary interface for testing compiler output directly from Guile.
  485. @deffn {Procedure} hoot-instantiate scheme-wasm [imports '()] [reflector]
  486. Instantiate and return a new Hoot module using the compiled Scheme
  487. Wasm module @var{scheme-wasm} and the reflection module
  488. @var{reflector}. If @var{reflector} is not specified, a new reflector
  489. instance will be created.
  490. Optionally, @var{imports} may contain a 2-tier association list
  491. structure of imported functions, globals, tables, and memories:
  492. @lisp
  493. `(("math" . (("random" . ,(lambda (x) (random x))))))
  494. @end lisp
  495. @end deffn
  496. @deffn {Procedure} hoot-load module
  497. Invoke the load thunk of @var{module} and return the reflected
  498. result values.
  499. @end deffn
  500. @deffn {Procedure} compile-value exp [imports %default-program-imports] @
  501. [load-path '()] [wasm-imports '()]
  502. Compile @var{exp} and return the result.
  503. Optionally, @var{imports} may specify a list of Scheme module names to
  504. import. If unspecified, a default set of modules providing a basic
  505. Scheme environment will be imported. @var{load-path} is a list of
  506. file system directories to search for additional user modules.
  507. Optionally, @var{wasm-imports} may contain a 2-tier association list
  508. structure of imported Wasm functions, globals, tables, and memories.
  509. See @code{hoot-instantiate} for an example of such a structure.
  510. @end deffn
  511. @deffn {Procedure} compile-call proc-exp arg-exps ... @
  512. [imports %default-program-imports] @
  513. [load-path '()] [wasm-imports '()]
  514. Compile @var{proc-exp} and all @var{arg-exps}, call the procedure with
  515. the arguments, then return the results.
  516. See @code{compile-value} for an explanation of the keyword arguments.
  517. @end deffn
  518. @deffn {Procedure} hoot-module? obj
  519. Return @code{#t} if @var{obj} is a Hoot module.
  520. @end deffn
  521. @deffn {Procedure} hoot-module-reflector module
  522. Return the reflection module for @var{module}.
  523. @end deffn
  524. @deffn {Procedure} hoot-module-instance module
  525. Return the Wasm instance for @var{module}.
  526. @end deffn
  527. @deffn {Procedure} reflector? obj
  528. Return @code{#t} if @var{obj} is a reflector.
  529. @end deffn
  530. @deffn {Procedure} reflector-instance reflector
  531. Return the Wasm instance of @var{reflector}.
  532. @end deffn
  533. @deffn {Procedure} reflector-abi reflector
  534. Return the association list of ABI imports for @var{reflector}.
  535. @end deffn
  536. Below are the predicates and accessors for various Hoot heap types:
  537. @deffn {Procedure} hoot-object? obj
  538. Return @code{#t} if @var{obj} is a Hoot object.
  539. @end deffn
  540. @deffn {Procedure} hoot-complex? obj
  541. Return @code{#t} if @var{obj} is a Hoot complex number.
  542. @end deffn
  543. @deffn {Procedure} hoot-complex-real complex
  544. Return the real part of @var{complex}.
  545. @end deffn
  546. @deffn {Procedure} hoot-complex-imag complex
  547. Return the imaginary part of @var{complex}.
  548. @end deffn
  549. @deffn {Procedure} hoot-fraction? obj
  550. Return @code{#t} if @var{obj} is a Hoot fraction.
  551. @end deffn
  552. @deffn {Procedure} hoot-fraction-num fraction
  553. Return the numerator of @var{fraction}
  554. @end deffn
  555. @deffn {Procedure} hoot-fraction-denom fraction
  556. Return the denominator of @var{fraction}.
  557. @end deffn
  558. @deffn {Procedure} hoot-pair? obj
  559. Return @code{#t} if @var{obj} is a Hoot pair.
  560. @end deffn
  561. @deffn {Procedure} mutable-hoot-pair? obj
  562. Return @code{#t} if @var{obj} is a mutable Hoot pair.
  563. @end deffn
  564. @deffn {Procedure} hoot-pair-car pair
  565. Return the first element of @var{pair}.
  566. @end deffn
  567. @deffn {Procedure} hoot-pair-cdr pair
  568. Return the second element of @var{pair}.
  569. @end deffn
  570. @deffn {Procedure} hoot-vector? obj
  571. Return @code{#t} if @var{obj} is a Hoot vector.
  572. @end deffn
  573. @deffn {Procedure} mutable-hoot-vector? obj
  574. Return @code{#t} if @var{obj} is a mutable Hoot vector.
  575. @end deffn
  576. @deffn {Procedure} hoot-vector-length vec
  577. Return the length of @var{vec}.
  578. @end deffn
  579. @deffn {Procedure} hoot-vector-ref vec i
  580. Return the @var{i}th element of @var{vec}.
  581. @end deffn
  582. @deffn {Procedure} hoot-bytevector? obj
  583. Return @code{#t} if @var{obj} is a Hoot bytevector.
  584. @end deffn
  585. @deffn {Procedure} mutable-hoot-bytevector? obj
  586. Return @code{#t} if @var{obj} is a mutable Hoot bytevector.
  587. @end deffn
  588. @deffn {Procedure} hoot-bytevector-length bv
  589. Return the length of @var{bv}.
  590. @end deffn
  591. @deffn {Procedure} hoot-bytevector-ref bv i
  592. Return the @var{i}th byte of @var{bv}.
  593. @end deffn
  594. @deffn {Procedure} hoot-bitvector? obj
  595. Return @code{#t} if @var{obj} is a Hoot bitvector.
  596. @end deffn
  597. @deffn {Procedure} mutable-hoot-bitvector? obj
  598. Return @code{#t} if @var{obj} is a mutable Hoot bitvector.
  599. @end deffn
  600. @deffn {Procedure} hoot-bitvector-length bv
  601. Return the length of @var{bv}.
  602. @end deffn
  603. @deffn {Procedure} hoot-bitvector-ref bv i
  604. Return the @var{i}th bit of @var{bv}.
  605. @end deffn
  606. @deffn {Procedure} hoot-symbol? obj
  607. Return @code{#t} if @var{obj} is a Hoot symbol.
  608. @end deffn
  609. @deffn {Procedure} hoot-symbol-name sym
  610. Return the string name of @var{sym}.
  611. @end deffn
  612. @deffn {Procedure} hoot-keyword? obj
  613. Return @code{#t} if @var{obj} is a Hoot keyword.
  614. @end deffn
  615. @deffn {Procedure} hoot-keyword-name keyword
  616. Return the name string of @var{keyword}.
  617. @end deffn
  618. @deffn {Procedure} mutable-hoot-string? obj
  619. Return @code{#t} if @var{obj} is a mutable Hoot string.
  620. @end deffn
  621. @deffn {Procedure} mutable-hoot-string->string str
  622. Return the underlying string for @var{str}.
  623. @end deffn
  624. @deffn {Procedure} hoot-procedure? obj
  625. Return @code{#t} if @var{obj} is a Hoot procedure.
  626. @end deffn
  627. @deffn {Procedure} hoot-variable? obj
  628. Return @code{#t} if @var{obj} is a Hoot variable.
  629. @end deffn
  630. @deffn {Procedure} hoot-atomic-box? obj
  631. Return @code{#t} if @var{obj} is a Hoot atomic box.
  632. @end deffn
  633. @deffn {Procedure} hoot-hash-table? obj
  634. Return @code{#t} if @var{obj} is a Hoot hash table.
  635. @end deffn
  636. @deffn {Procedure} hoot-weak-table? obj
  637. Return @code{#t} if @var{obj} is a Hoot weak table.
  638. @end deffn
  639. @deffn {Procedure} hoot-fluid? obj
  640. Return @code{#t} if @var{obj} is a Hoot fluid.
  641. @end deffn
  642. @deffn {Procedure} hoot-dynamic-state? obj
  643. Return @code{#t} if @var{obj} is a Hoot dynamic state.
  644. @end deffn
  645. @deffn {Procedure} hoot-syntax? obj
  646. Return @code{#t} if @var{obj} is a Hoot syntax object.
  647. @end deffn
  648. @deffn {Procedure} hoot-port? obj
  649. Return @code{#t} if @var{obj} is a Hoot port.
  650. @end deffn
  651. @deffn {Procedure} hoot-struct? obj
  652. Return @code{#t} if @var{obj} is a Hoot struct.
  653. @end deffn
  654. @node Low-level development tools
  655. @section Low-level development tools
  656. The @code{(hoot repl)} module provides a set of REPL commands to
  657. assist with inspecting and debugging Wasm modules. As a matter of
  658. course, Hoot's Scheme compiler @emph{should not} cause low-level Wasm
  659. runtime errors, but when it does, or when working with the Wasm
  660. toolchain directly, these REPL tools may provide some assistance.
  661. To install the REPL commands, simply import the module:
  662. @lisp
  663. scheme@@(guile-user)> ,use (hoot repl)
  664. @end lisp
  665. To see a list of all the Wasm commands, run:
  666. @lisp
  667. scheme@@(guile-user)> ,help wasm
  668. @end lisp
  669. To demonstrate the debugging features, let's create a trivial module
  670. with a buggy function:
  671. @lisp
  672. @verbatim
  673. scheme@(guile-user)> (define src
  674. '(module
  675. (func (export "main") (param $x i32) (result i32)
  676. (i32.add (local.get $x)
  677. (unreachable)))))
  678. @end verbatim
  679. @end lisp
  680. When called, this function will hit the @code{unreachable} instruction
  681. and throw a runtime error. Let's compile the WAT source, load it into
  682. the VM, and get a reference to the @code{main} function:
  683. @lisp
  684. @verbatim
  685. scheme@(guile-user)> ,use (wasm resolve) (wasm vm) (wasm wat)
  686. scheme@(guile-user)> (define wasm (validate-wasm (resolve-wasm (wat->wasm src))))
  687. scheme@(guile-user)> (define instance (instantiate-wasm wasm))
  688. scheme@(guile-user)> (define main (wasm-instance-export-ref instance "main"))
  689. @end verbatim
  690. @end lisp
  691. To trap the Wasm runtime error and open a Wasm debugging REPL, the
  692. @command{wasm-catch} REPL command can be prefixed before an
  693. expression:
  694. @lisp
  695. @verbatim
  696. scheme@(guile-user)> ,wasm-catch (main 7)
  697. ice-9/boot-9.scm:1674:22: In procedure raise-exception:
  698. ERROR:
  699. 1. &wasm-runtime-error:
  700. instruction: (unreachable)
  701. position: (func 0 1)
  702. instance: #<wasm-instance 140506559041920>
  703. stack: #<<wasm-stack> items: (7)>
  704. blocks: ((wasm-block))
  705. locals: #(7)
  706. 2. &message: "Wasm runtime error: unreachable"
  707. 3. &irritants: ()
  708. Entering Wasm debug prompt. Type `,help wasm' for info or `,q' to continue.
  709. scheme@(guile-user) [1]>
  710. @end verbatim
  711. @end lisp
  712. Once in a Wasm debug context, many of the other REPL commands become
  713. usable. To highlight the instruction where execution has paused, use
  714. @command{wasm-pos}:
  715. @lisp
  716. @verbatim
  717. scheme@(guile-user) [1]> ,wasm-pos
  718. (func 0 (param $x i32) (result i32)
  719. (local.get 0)
  720. <<< (unreachable) >>>
  721. (i32.add))
  722. @end verbatim
  723. @end lisp
  724. To print the contents of the values stack, use @command{wasm-stack}:
  725. @lisp
  726. @verbatim
  727. scheme@(guile-user) [1]> ,wasm-stack
  728. Value stack:
  729. 0: 7
  730. @end verbatim
  731. @end lisp
  732. To print the contents of the function locals, use @command{wasm-locals}:
  733. @lisp
  734. @verbatim
  735. scheme@(guile-user) [1]> ,wasm-locals
  736. Locals:
  737. 0: 7
  738. @end verbatim
  739. @end lisp
  740. To evaluate arbitary Wasm instructions in the current context, either
  741. in an attempt to repair interpreter state or just for fun, use
  742. @command{wasm-eval}:
  743. @lisp
  744. @verbatim
  745. scheme@(guile-user) [1]> ,wasm-eval '(local.get 0)
  746. scheme@(guile-user) [1]> ,wasm-stack
  747. Value stack:
  748. 0: 7
  749. 1: 7
  750. @end verbatim
  751. @end lisp
  752. There are now two i32 values on the stack. If we were to proceed with
  753. execution, the next instruction, @code{i32.add}, should add them
  754. together and return a result of 14. To resume execution, use
  755. @command{wasm-continue}:
  756. @lisp
  757. @verbatim
  758. scheme@(guile-user) [1]> ,wasm-continue
  759. $5 = 14
  760. @end verbatim
  761. @end lisp
  762. Evaluating arbitrary Wasm commands in a debugging context is very
  763. helpful when trying to understand the nature of a bug, but bear in
  764. mind that cursed things may happen during the process as there is no
  765. validation applied. This goes especially for when you try to resume
  766. execution.
  767. See @ref{Interpreter} for detailed information on running Wasm within
  768. Guile and @ref{Toolchain reference} in general for working with Wasm
  769. directly.
  770. @deffn {REPL Command} wasm-trace exp
  771. Evaluate @var{exp} with verbose Wasm tracing enabled. This will print
  772. out every instruction along with the state of the value stack and
  773. function locals at the time of evaluation.
  774. @end deffn
  775. @deffn {REPL Command} wasm-freq exp
  776. Evaluate @var{exp} and print out a table showing how many times each
  777. kind of Wasm instruction was executed as well as a total instruction
  778. count.
  779. @end deffn
  780. @deffn {REPL Command} wasm-catch exp
  781. Catch and debug Wasm runtime errors that are raised by evaluating
  782. @var{exp}.
  783. @end deffn
  784. The following commands are usable only in the context of a Wasm debug
  785. REPL:
  786. @deffn {REPL Command} wasm-stack
  787. Print the state of the Wasm stack.
  788. @end deffn
  789. @deffn {REPL Command} wasm-locals
  790. Print the state of the Wasm function locals.
  791. @end deffn
  792. @deffn {REPL Command} wasm-pos
  793. Print the current function disassembly and highlight the instruction
  794. where Wasm execution has paused.
  795. @end deffn
  796. @deffn {REPL Command} wasm-eval instr
  797. Evaluate the Wasm instruction @var{instr} in the current debug
  798. context. Use this when attempting to fix the state of the Wasm stack
  799. or locals before attempting to resume with @code{,wasm-continue}.
  800. @end deffn
  801. The following commands behave differently depending on if they are run
  802. within a Wasm debug REPL or not.
  803. @deffn {REPL Command} wasm-dump [wasm]
  804. Display information about @var{wasm}, or the current Wasm instance
  805. when debugging.
  806. @end deffn
  807. @deffn {REPL Command} wasm-continue
  808. When in a debugger, exit and resume Wasm execution. In the event that
  809. this is run after trapping a runtime error, your warranty is void and
  810. all bets are off! While it may be dangerous, this does allow one to
  811. manually fix the Wasm interpreter state manually with
  812. @code{,wasm-eval} and attempt to proceed, which can come in handy
  813. sometimes.
  814. When not in a debugger, set the Wasm execution mode to continue
  815. without interruption. In other words, deactive the instruction
  816. stepper if it is active.
  817. @end deffn
  818. @deffn {REPL Command} wasm-step
  819. When in a debugger, resume Wasm execution but pause before the next
  820. instruction is evaluated.
  821. When not in a debugger, set Wasm execution to pause before each
  822. instruction is evaluated.
  823. @end deffn
  824. @node Web deployment
  825. @chapter Web deployment
  826. On the client-side web, JavaScript is the host environment for Wasm
  827. modules and the
  828. @url{https://developer.mozilla.org/en-US/docs/WebAssembly,WebAssembly}
  829. API is used to load and run them. Hoot includes a JavaScript library,
  830. @file{reflect.js} that wraps the @code{WebAssembly} API and
  831. furthermore can inspect Scheme values and call Scheme procedures.
  832. This chapter documents deploying Hoot artifacts and using the
  833. reflection API to run Scheme in the browser.
  834. @menu
  835. * Web server setup:: Prepare a server to run Hoot programs.
  836. * JavaScript API reference:: JavaScript reflection interface.
  837. @end menu
  838. @node Web server setup
  839. @section Web server setup
  840. In order to run Hoot binaries in the browser, a web server needs to
  841. host a copy of the Hoot JavaScript runtime.
  842. The runtime files can be found in the
  843. @file{$prefix/share/guile-hoot/js-runtime} directory, where
  844. @code{$prefix} is the directory where Hoot was installed on your
  845. system. This is typically @file{/usr} or @file{/usr/local} on Linux
  846. distributions such as Debian, Ubuntu, Fedora, etc.
  847. Don't forget to upload the Wasm files for the Scheme programs, too!
  848. A bit of JavaScript code is needed to bootstrap a Scheme program using
  849. the @file{js-runtime/reflect.js} library. For example, here's an
  850. example @file{boot.js} file that runs the Scheme program
  851. @file{hello.wasm} and prints the return values:
  852. @example
  853. @verbatim
  854. window.addEventListener("load", async () => {
  855. const results = await Scheme.load_main("/hello.wasm", {});
  856. console.log(results);
  857. });
  858. @end verbatim
  859. @end example
  860. The @code{Scheme} namespace is defined in @file{reflect.js}.
  861. @xref{JavaScript API reference} for more information.
  862. To run @file{boot.js} on a web page, add @code{<script>} tags for it
  863. and @file{reflect.js}:
  864. @example
  865. <!DOCTYPE html>
  866. <html>
  867. <head>
  868. <script type="text/javascript" src="/js-runtime/reflect.js"></script>
  869. <script type="text/javascript" src="/boot.js"></script>
  870. </head>
  871. <body>
  872. <h1>Hello, Hoot!</h1>
  873. </body>
  874. </html>
  875. @end example
  876. @node JavaScript API reference
  877. @section JavaScript API reference
  878. The @code{Scheme} class is used to load a Hoot binary, start the
  879. program, and initialize reflection.
  880. @deftp {Class} Scheme
  881. A Scheme runtime environment.
  882. @end deftp
  883. @defop {Static method} Scheme load_main path abi [user_imports @code{@{@}}]
  884. Fetch and execute the Hoot Wasm binary at the URL @var{path} and
  885. return an array of Scheme values produced by the program.
  886. The @var{abi} parameter is for more advanced usage where multiple Hoot
  887. binaries share a single application binary interface (ABI). This
  888. should be set to @code{@{@}} when loading the first Scheme binary. It
  889. is better to use the @code{load_extension} method for subsequent
  890. binaries, though.
  891. The @var{user_imports} parameter is for providing concrete
  892. implementations of functions declared using the @ref{Foreign function
  893. interface}. It uses a two-tier nested object structure to map import
  894. names to the functions that implement them.
  895. For example, this Scheme code:
  896. @lisp
  897. (define-foreign make-text-node
  898. "document" "createTextNode"
  899. (ref string) -> (ref null extern))
  900. @end lisp
  901. Could be instantiated like so:
  902. @example
  903. @verbatim
  904. Scheme.load_main("hello.wasm", {}, {
  905. document: {
  906. createTextNode: Document.prototype.createTextNode.bind(document)
  907. }
  908. });
  909. @end verbatim
  910. @end example
  911. @end defop
  912. @defmethod Scheme load_extension path [user_imports @code{@{@}}]
  913. Fetch and load an additional Hoot binary at the URL @var{path} that
  914. shares the ABI of @code{this}. Optionally, a set of user-defined
  915. imported functions can be specified with the @var{user_imports}
  916. parameter.
  917. @end defmethod
  918. All of the fundamental Scheme types have an associated JavaScript
  919. class that can reflect their values. Calling the @code{repr} function
  920. on an instance of a reflected Scheme object will return a Scheme-like
  921. printing of the object.
  922. @example
  923. repr(pair) // => "(1 . 2)"
  924. @end example
  925. @deftp {Class} Char
  926. A Unicode character.
  927. @end deftp
  928. @deftp {Class} Eof
  929. End-of-file object.
  930. @end deftp
  931. @deftp {Class} Null
  932. The empty list.
  933. @end deftp
  934. @deftp {Class} Unspecified
  935. The unspecified value.
  936. @end deftp
  937. @deftp {Class} Complex real imag
  938. Complex number with real part @var{real} and imaginary part
  939. @var{imag}.
  940. @end deftp
  941. @deftp {Class} Fraction num denom
  942. An exact fraction with numerator @var{num} and denominator
  943. @var{denom}.
  944. @end deftp
  945. The @code{HeapObject} class is the parent class of all of the
  946. remaining Scheme types.
  947. @deftp {Class} HeapObject
  948. A Scheme heap object.
  949. @end deftp
  950. @defivar HeapObject reflector
  951. The reflector for @code{this}, an instance of the @code{Scheme} class.
  952. @end defivar
  953. The @code{reflector} property can be used in conjuction with the
  954. @code{load_extension} method to load additional Hoot binaries that
  955. share the same ABI.
  956. @example
  957. heapObject.reflector.load_extension("/helper.wasm")
  958. @end example
  959. @deftp {Class} Procedure
  960. A Scheme procedure.
  961. @end deftp
  962. Procedure instances can be invoked with the @code{call} method to
  963. perform a Javascript to Scheme function call.
  964. @defmethod Procedure call args@dots{}
  965. Call procedure with @var{args} and return an array of result values.
  966. @end defmethod
  967. @deftp {Class} Pair
  968. An immutable cons cell.
  969. @end deftp
  970. @deftp {Class} MutablePair
  971. A mutable cons cell.
  972. @end deftp
  973. @deftp {Class} Vector
  974. An immutable vector.
  975. @end deftp
  976. @deftp {Class} MutableVector
  977. A mutable vector.
  978. @end deftp
  979. @deftp {Class} Bytevector
  980. An immutable bytevector.
  981. @end deftp
  982. @deftp {Class} MutableBytevector
  983. A mutable bytevector.
  984. @end deftp
  985. @deftp {Class} Bitvector
  986. An immutable bitvector.
  987. @end deftp
  988. @deftp {Class} MutableBitvector
  989. A mutable bitvector.
  990. @end deftp
  991. @deftp {Class} MutableString
  992. A mutable string.
  993. @end deftp
  994. @deftp {Class} Sym
  995. A symbol.
  996. @end deftp
  997. @deftp {Class} Keyword
  998. A keyword.
  999. @end deftp
  1000. @deftp {Class} Variable
  1001. A mutable variable.
  1002. @end deftp
  1003. @deftp {Class} AtomicBox
  1004. A mutable box with atomic updates.
  1005. @end deftp
  1006. @deftp {Class} HashTable
  1007. A hash table.
  1008. @end deftp
  1009. @deftp {Class} WeakTable
  1010. A weak key hash table.
  1011. @end deftp
  1012. @deftp {Class} Fluid
  1013. A dynamic variable.
  1014. @end deftp
  1015. @deftp {Class} DynamicState
  1016. A set of fluids.
  1017. @end deftp
  1018. @deftp {Class} Syntax
  1019. A syntax object.
  1020. @end deftp
  1021. @deftp {Class} Port
  1022. An I/O port.
  1023. @end deftp
  1024. @deftp {Class} Struct
  1025. A user-defined structure.
  1026. @end deftp
  1027. @node Scheme reference
  1028. @chapter Scheme reference
  1029. In addition to supporting standard Scheme features, Hoot includes many
  1030. of its own extensions. This chapter documents the APIs of these
  1031. extensions.
  1032. @menu
  1033. * Boxes:: Mutable cells that store a single object.
  1034. * Atomics:: Atomic boxes.
  1035. * Bitvectors:: Sequences of bits.
  1036. * Bytevectors:: Sequences of bytes.
  1037. * Control:: Delimited continuations.
  1038. * Exceptions:: Error handling.
  1039. * Fluids:: Dynamic state.
  1040. * Parameters:: Dynamic variables.
  1041. * Hash tables:: Mutable key/value data structures.
  1042. * Records:: Extensions to standard records.
  1043. * Pattern matching:: Object destructuring.
  1044. * Foreign function interface:: Call host functions from Scheme.
  1045. @end menu
  1046. @node Boxes
  1047. @section Boxes
  1048. The @code{(hoot boxes)} module provides boxes, which are single-value,
  1049. mutable cells.
  1050. @deffn {Procedure} make-box init
  1051. Return a new box with an initial stored value of @var{init}.
  1052. @end deffn
  1053. @deffn {Procedure} box-ref box
  1054. Return the value stored within @var{box}.
  1055. @end deffn
  1056. @deffn {Procedure} box-set! box val
  1057. Set the stored value of @var{box} to @var{val}.
  1058. @end deffn
  1059. @node Atomics
  1060. @section Atomics
  1061. The @code{(hoot atomics)} module provides an API compatible with
  1062. Guile's @code{(ice-9 atomic)} module. Atomic operations allow for
  1063. concurrent access to a resource form many threads without the need to
  1064. use thread synchronization constructs like mutexes. Currently,
  1065. WebAssembly assumes single-threaded execution, making atomicity
  1066. trivial. See @inlinefmtifelse{html,
  1067. @url{https://www.gnu.org/software/guile/manual/html_node/Atomics.html,
  1068. the Guile manual}, @ref{Atomics,,,Guile Reference}} for more detailed
  1069. information.
  1070. @deffn {Procedure} make-atomic-box init
  1071. Return a new atomic box with an initial stored value of @var{init}.
  1072. @end deffn
  1073. @deffn {Procedure} atomic-box-ref box
  1074. Return the value stored within the atomic box @var{box}.
  1075. @end deffn
  1076. @deffn {Procedure} atomic-box-set! box val
  1077. Store @var{val} into the atomic box @var{box}.
  1078. @end deffn
  1079. @deffn {Procedure} atomic-box-swap! box val
  1080. Store @var{val} into the atomic box @var{box}, and return the value
  1081. that was previously stored in the box.
  1082. @end deffn
  1083. @deffn {Procedure} atomic-box-compare-and-swap! box expected desired
  1084. If the value of the atomic box @var{box} is the same as @var{expected}
  1085. (in the sense of @code{eq?}), replace the contents of the box with
  1086. @var{desired}. Otherwise, the box is not updated. Return the
  1087. previous value of the box in either case. You can know if the swap
  1088. worked by checking if the return value is @code{eq?} to
  1089. @var{expected}.
  1090. @end deffn
  1091. @node Bitvectors
  1092. @section Bitvectors
  1093. The @code{(hoot bitvectors)} module provides bitvectors, which are
  1094. tightly packed arrays of booleans.
  1095. @deffn {Procedure} make-bitvector len [fill #f]
  1096. Return a new bitvector of @var{len} bits with all bits initialized to
  1097. @var{fill}.
  1098. @end deffn
  1099. @deffn {Procedure} bitvector? obj
  1100. Return @code{#t} if @var{obj} is a bitvector.
  1101. @end deffn
  1102. @deffn {Procedure} bitvector-length bv
  1103. Return the length of the bitvector @var{bv}.
  1104. @end deffn
  1105. @deffn {Procedure} bitvector-ref bv i
  1106. Return the boolean value of bit @var{i} in the bitvector @var{bv}.
  1107. @end deffn
  1108. @deffn {Procedure} bitvector-set-bit! bv i
  1109. Set the bit @var{i} in the bitvector @var{bv} to @code{#t}.
  1110. @end deffn
  1111. @node Bytevectors
  1112. @section Bytevectors
  1113. The @code{(hoot bytevectors)} module provides some of the R6RS
  1114. bytevectors API. Bytevectors are sequences of bytes that are useful
  1115. for low-level manipulation of binary data.
  1116. @deffn {Procedure} make-bytevector len [init 0]
  1117. Return a new bytevector of @var{len} bytes with all bytes initialized
  1118. to @var{init}.
  1119. @end deffn
  1120. @deffn {Procedure} bytevector [byte ...]
  1121. Return a new bytevector containing the sequence @var{byte} @dots{}.
  1122. @end deffn
  1123. @deffn {Procedure} bytevector? obj
  1124. Return @code{#t} if @var{obj} is a bytevector.
  1125. @end deffn
  1126. @deffn {Procedure} bytevector-length bv
  1127. Return the length of @var{bv} in bytes.
  1128. @end deffn
  1129. @deffn {Procedure} bytevector-copy bv [start 0] [end (bytevector-length bv)]
  1130. Return a new bytevector that is a copy of the bytevector @var{bv} from
  1131. byte index @var{start} to @var{end}. @var{start} must be less than or
  1132. equal to @var{end}.
  1133. @end deffn
  1134. @deffn {Procedure} bytevector-copy! to at from [start 0] [end (bytevector-length from)]
  1135. Copy the subsection of bytevector @var{from}, defined by the byte
  1136. range [@var{start}, @var{end}), into the bytevector @var{from}.
  1137. @end deffn
  1138. @deffn {Procedure} bytevector-append [bv ...]
  1139. Return a new bytevector that concatenates all the input bytevectors
  1140. @var{bv} @dots{} in the order given.
  1141. @end deffn
  1142. @deffn {Procedure} bytevector-concatenate bvs
  1143. Return a new bytevector that concatenates all of the bytevectors in
  1144. the list @var{bvs}.
  1145. @end deffn
  1146. @deffn {Procedure} bytevector-concatenate-reverse bvs
  1147. Return a new bytevector that concatenates all of the bytevectors in
  1148. the list @var{bvs} in reverse order.
  1149. @end deffn
  1150. @deffn {Procedure} bytevector-u8-ref bv index
  1151. @deffnx {Procedure} bytevector-s8-ref bv index
  1152. @deffnx {Procedure} bytevector-u16-native-ref bv index
  1153. @deffnx {Procedure} bytevector-s16-native-ref bv index
  1154. @deffnx {Procedure} bytevector-u32-native-ref bv index
  1155. @deffnx {Procedure} bytevector-s32-native-ref bv index
  1156. @deffnx {Procedure} bytevector-u64-native-ref bv index
  1157. @deffnx {Procedure} bytevector-s64-native-ref bv index
  1158. Return the N-bit signed or unsigned integer from the bytevector
  1159. @var{bv} at @var{index} using the host's native endianness.
  1160. @end deffn
  1161. @deffn {Procedure} bytevector-ieee-single-native-ref bv index
  1162. @deffnx {Procedure} bytevector-ieee-double-native-ref bv index
  1163. Return the single or double precision IEEE floating piont number from
  1164. the bytevector @var{bv} at @var{index} using the host's native
  1165. endianness.
  1166. @end deffn
  1167. @deffn {Procedure} bytevector-u8-set! bv index x
  1168. @deffnx {Procedure} bytevector-s8-set! bv index x
  1169. @deffnx {Procedure} bytevector-u16-native-set! bv index x
  1170. @deffnx {Procedure} bytevector-s16-native-set! bv index x
  1171. @deffnx {Procedure} bytevector-u32-native-set! bv index x
  1172. @deffnx {Procedure} bytevector-s32-native-set! bv index x
  1173. @deffnx {Procedure} bytevector-u64-native-set! bv index x
  1174. @deffnx {Procedure} bytevector-s64-native-set! bv index x
  1175. Store @var{x} as an N-bit signed or unsigned integer in the bytevector
  1176. @var{bv} at @var{index} using the host's native endianness.
  1177. @end deffn
  1178. @deffn {Procedure} bytevector-ieee-single-native-set! bv index x
  1179. @deffnx {Procedure} bytevector-ieee-double-native-set! bv index x
  1180. Store @var{x} as a single or double precision IEEE floating piont
  1181. number in the bytevector @var{bv} at @var{index} using the host's
  1182. native endianness.
  1183. @end deffn
  1184. @node Control
  1185. @section Control
  1186. The @code{(hoot control)} module provides an interface for Guile's
  1187. delimited continuation facility known as ``prompts'' and some of the
  1188. @code{(ice-9 control)} API. See @inlinefmtifelse{html,
  1189. @url{https://www.gnu.org/software/guile/manual/html_node/Prompts.html,
  1190. the Guile manual}, @ref{Prompts,,,Guile Reference}} for more detailed
  1191. information.
  1192. @deffn {Procedure} make-prompt-tag [stem ``prompt'']
  1193. Return a new prompt tag that incorporates the value of @var{stem}. A
  1194. prompt tag is simply a unique object.
  1195. @end deffn
  1196. @deffn {Procedure} call-with-prompt tag body handler
  1197. Call the procedure @var{body}, a procedure of 0 arguments or
  1198. ``thunk'', within the context of a prompt marked with @var{tag}.
  1199. Should this prompt be aborted via @code{abort-to-prompt}, the
  1200. procedure @var{handler} is called. The @var{handler} procedure
  1201. receives as arguments a continuation object and any additional
  1202. arguments that were passed to @code{abort-to-prompt}.
  1203. @end deffn
  1204. @deffn {Procedure} abort-to-prompt tag [val ...]
  1205. Unwind the dynamic and control context to the nearest prompt named
  1206. @var{tag}, so passing the additional values @var{val} @dots{}
  1207. @end deffn
  1208. @deffn {Procedure} default-prompt-tag
  1209. Return the default prompt tag.
  1210. @end deffn
  1211. @deffn {Procedure} default-prompt-handler
  1212. Return the default prompt handler procedure.
  1213. @end deffn
  1214. Note that both @code{default-prompt-tag} and
  1215. @code{default-prompt-handler} are parameters, so their values may be
  1216. modified by using @code{parameterize}. @xref{Parameters} for more
  1217. information.
  1218. @deffn {Syntax} % expr
  1219. @deffnx {Syntax} % expr handler
  1220. @deffnx {Syntax} % tag expr handler
  1221. Syntactic sugar for @code{call-with-prompt}. Evaluate @var{expr} in
  1222. the context of a prompt. If @var{tag} is ommitted, the default prompt
  1223. tag will be used. If @var{handler} is omitted, the default prompt
  1224. handler will be used.
  1225. @end deffn
  1226. @node Exceptions
  1227. @section Exceptions
  1228. @node Exception types
  1229. @subsection Exception types
  1230. The @code{(hoot exceptions)} module implements Guile's exception API.
  1231. See @inlinefmtifelse{html,
  1232. @url{https://www.gnu.org/software/guile/manual/html_node/Exceptions.html,
  1233. the Guile manual}, @ref{Exceptions,,,Guile Reference}} for more
  1234. detailed information.
  1235. @deffn {Procedure} make-exception exceptions
  1236. Return an exception object composed of @var{exceptions}, a list of
  1237. simple and/or compound exceptions.
  1238. @end deffn
  1239. @deffn {Procedure} exception? obj
  1240. Return @code{#t} if @var{obj} is an exception object.
  1241. @end deffn
  1242. Below are the built-in exception types and their respective
  1243. constructors, predicates, and accessors.
  1244. @deftp {Exception Type} &exception
  1245. @end deftp
  1246. @deffn {Procedure} simple-exception? obj
  1247. @end deffn
  1248. @deftp {Exception Type} &compound-exception
  1249. @end deftp
  1250. @deffn {Procedure} make-compound-exception components
  1251. @deffnx {Procedure} compound-exception? obj
  1252. @deffnx {Procedure} compound-exception-components compound-exception
  1253. @end deffn
  1254. @deftp {Exception Type} &message
  1255. @end deftp
  1256. @deffn {Procedure} make-exception-with-message message
  1257. @deffnx {Procedure} exception-with-message? obj
  1258. @deffnx {Procedure} exception-message exception
  1259. @end deffn
  1260. @deftp {Exception Type} &warning
  1261. @end deftp
  1262. @deffn {Procedure} make-warning
  1263. @deffnx {Procedure} warning? obj
  1264. @end deffn
  1265. @deftp {Exception Type} &serious
  1266. @end deftp
  1267. @deffn {Procedure} make-serious-exception
  1268. @deffnx {Procedure} serious-exception? obj
  1269. @end deffn
  1270. @deftp {Exception Type} &error
  1271. @end deftp
  1272. @deffn {Procedure} make-error
  1273. @deffnx {Procedure} error? obj
  1274. @end deffn
  1275. @deftp {Exception Type} &violation
  1276. @end deftp
  1277. @deffn {Procedure} make-violation
  1278. @deffnx {Procedure} violation? obj
  1279. @end deffn
  1280. @deftp {Exception Type} &assertion
  1281. @end deftp
  1282. @deffn {Procedure} make-assertion-violation
  1283. @deffnx {Procedure} assertion-violation? obj
  1284. @end deffn
  1285. @deftp {Exception Type} &arity-violation
  1286. @end deftp
  1287. @deffn {Procedure} make-arity-violation
  1288. @deffnx {Procedure} arity-violation? obj
  1289. @end deffn
  1290. @deftp {Exception Type} &implementation-restriction
  1291. @end deftp
  1292. @deffn {Procedure} make-implementation-restriction-violation
  1293. @deffnx {Procedure} implementation-restriction-violation? obj
  1294. @end deffn
  1295. @deftp {Exception Type} &failed-type-check
  1296. @end deftp
  1297. @deffn {Procedure} make-failed-type-check predicate
  1298. @deffnx {Procedure} failed-type-check? obj
  1299. @deffnx {Procedure} failed-type-check-predicate exception
  1300. @end deffn
  1301. @deftp {Exception Type} &non-continuable
  1302. @end deftp
  1303. @deffn {Procedure} make-non-continuable-violation
  1304. @deffnx {Procedure} non-continuable-violation? obj
  1305. @end deffn
  1306. @deftp {Exception Type} &irritants
  1307. @end deftp
  1308. @deffn {Procedure} make-exception-with-irritants irritants
  1309. @deffnx {Procedure} exception-with-irritants? obj
  1310. @deffnx {Procedure} exception-irritants exception
  1311. @end deffn
  1312. @deftp {Exception Type} &origin
  1313. @end deftp
  1314. @deffn {Procedure} make-exception-with-origin origin
  1315. @deffnx {Procedure} exception-with-origin? obj
  1316. @deffnx {Procedure} exception-origin exception
  1317. @end deffn
  1318. @deftp {Exception Type} &lexical
  1319. @end deftp
  1320. @deffn {Procedure} make-lexical-violation
  1321. @deffnx {Procedure} lexical-violation? obj
  1322. @end deffn
  1323. @deftp {Exception Type} &i/o
  1324. @end deftp
  1325. @deffn {Procedure} make-i/o-error
  1326. @deffnx {Procedure} i/o-error?
  1327. @end deffn
  1328. @deftp {Exception Type} &i/o-line-and-column
  1329. @end deftp
  1330. @deffn {Procedure} make-i/o-line-and-column-error line column
  1331. @deffnx {Procedure} i/o-line-and-column-error? obj
  1332. @deffnx {Procedure} i/o-error-line exception
  1333. @deffnx {Procedure} i/o-error-column exception
  1334. @end deffn
  1335. @deftp {Exception Type} &i/o-filename
  1336. @end deftp
  1337. @deffn {Procedure} make-i/o-filename-error filename
  1338. @deffnx {Procedure} i/o-filename-error? obj
  1339. @deffnx {Procedure} i/o-error-filename exception
  1340. @end deffn
  1341. @deftp {Exception Type} &i/o-not-seekable
  1342. @end deftp
  1343. @deffn {Procedure} make-i/o-not-seekable-error
  1344. @deffnx {Procedure} i/o-not-seekable-error? obj
  1345. @end deffn
  1346. @deftp {Exception Type} &i/o-port
  1347. @end deftp
  1348. @deffn {Procedure} make-i/o-port-error port
  1349. @deffnx {Procedure} i/o-port-error? obj
  1350. @deffnx {Procedure} i/o-error-port exception
  1351. @end deffn
  1352. @node Raising and handling exceptions
  1353. @subsection Raising and handling exceptions
  1354. The @code{(hoot errors)} module provides procedures for raising and
  1355. handling exceptions.
  1356. @deffn {Procedure} raise exception
  1357. Raise the non-continuable exception @var{exception} by invoking the
  1358. current exception handler.
  1359. @end deffn
  1360. @deffn {Procedure} raise-continuable exception
  1361. Raise the continuable exception @var{exception} by invoking the
  1362. current exception handler.
  1363. @end deffn
  1364. @deffn {Procedure} raise-exception exception [#:continuable? #f]
  1365. Raise the exception @var{exception} by invoking the current exception
  1366. handler. When @var{continuable?} is @code{#t}, the raised exception
  1367. is continuable.
  1368. @end deffn
  1369. @deffn {Procedure} with-exception-handler handler thunk [#:unwind? #f]
  1370. Call @var{thunk}, a procedure of zero arguments, in a context where
  1371. @var{handler}, a procedure of one argument, is the current exception
  1372. handler. If an exception is raised then @var{handler} will be called
  1373. with the exception obect.
  1374. When @var{unwind?} is @code{#t}, the stack will be unwound before
  1375. @var{handler} is called. The default behavior is not to unwind. When
  1376. the stack is not unwound, it is up to @var{handler} to properly manage
  1377. control flow. Control is allowed to fallthrough @var{handler} and
  1378. resume from where the exception was raised only if the raised
  1379. exception is @emph{continuable}. For non-continuable exceptions,
  1380. @var{handler} should abort to some prompt (@xref{Control}) to escape
  1381. the exception handling context.
  1382. @end deffn
  1383. @node Fluids
  1384. @section Fluids
  1385. A fluid is a variable whose value is associated with the dynamic
  1386. extent of a procedure call. The @code{(hoot fluids)} module
  1387. implements Guile's fluid API. See @inlinefmtifelse{html,
  1388. @url{https://www.gnu.org/software/guile/manual/html_node/Fluids-and-Dynamic-States.html,
  1389. the Guile manual}, @ref{Fluids and Dynamic States,,,Guile Reference}}
  1390. for more detailed information.
  1391. @deffn {Procedure} make-fluid [default #f]
  1392. Return a new fluid whose initial value is @var{default}.
  1393. @end deffn
  1394. @deffn {Procedure} fluid-ref fluid
  1395. Return the value currently stored within @var{fluid}.
  1396. @end deffn
  1397. @deffn {Procedure} fluid-set! fluid val
  1398. Set the contents of @var{fluid} to @var{val}.
  1399. @end deffn
  1400. @deffn {Procedure} with-fluid* fluid val thunk
  1401. Call @var{thunk}, a procedure of zero arguments, in a context where
  1402. the @var{fluid} is set to @var{val}. When control leaves the dynamic
  1403. extent of @var{thunk}, @var{fluid} is set back to its previous value.
  1404. @end deffn
  1405. @deffn {Syntax} with-fluids ((fluid value) ...) body1 body2 ...
  1406. Evaluate @var{body1} @var{body2} @dots{} in a context where each
  1407. @var{fluid} is set to its respective @var{value}.
  1408. @end deffn
  1409. @node Parameters
  1410. @section Parameters
  1411. Parameters are Guile's facility for dynamically bound variables.
  1412. While parameters are part of the default Guile environment, in Hoot
  1413. they are provided by the @code{(hoot parameters)} module. See
  1414. @inlinefmtifelse{html,
  1415. @url{https://www.gnu.org/software/guile/manual/html_node/Parameters.html,
  1416. the Guile manual}, @ref{Parameters,,,Guile Reference}} for more
  1417. detailed information.
  1418. A parameter is a procedure. To retrieve the value of a parameter,
  1419. call it with zero arguments. To set a new value, call it with one
  1420. argument.
  1421. @lisp
  1422. (define counter (make-parameter 0))
  1423. (counter) ; => 0
  1424. (counter 1)
  1425. (counter) ; => 1
  1426. (parameterize ((counter 2))
  1427. (counter)) ; => 2
  1428. (counter) ; => 1
  1429. @end lisp
  1430. @deffn {Procedure} make-parameter init [conv (lambda (x) x)]
  1431. Return a new parameter whose initial value is @var{(conv init)}.
  1432. @var{conv} is a procedure of one argument that transforms an incoming
  1433. value into the value that is actually stored within the parameter.
  1434. The default @var{conv} is an identity function that applies no
  1435. transformation at all.
  1436. @end deffn
  1437. @deffn {Syntax} parameterize ((parameter value) ...) body1 body2 ...
  1438. Evaluate @var{body1} @var{body2} @dots{} in a context where each
  1439. @var{parameter} is set to its respective @var{value}. When control
  1440. leaves the dynamic extent of the body, each @var{parameter} is set
  1441. back to its previous value.
  1442. @end deffn
  1443. @node Hash tables
  1444. @section Hash tables
  1445. There are many mutable hashtable APIs amongst all the various Scheme
  1446. implementations, standards, and SRFIs. From our point of view, there
  1447. is no clear ``best'' hashtable API that has emerged, but we think the
  1448. R6RS interface is OK. Guile's own hashtable API has design issues
  1449. that are best left in the past. So, the @code{(hoot hashtables)}
  1450. module is R6RS-like.
  1451. Currently, this interface supports keys hashed by object identity
  1452. (@code{eq?}) only. The object equivalence (@code{eqv?}) and deep
  1453. object equality (@code{equal?}) hashing strategies are not yet
  1454. implemented.
  1455. @deffn {Procedure} make-eq-hashtable
  1456. Return a new, empty hash table.
  1457. @end deffn
  1458. @deffn {Procedure} hashtable? obj
  1459. Return @code{#t} if @var{obj}
  1460. @end deffn
  1461. @deffn {Procedure} hashtable-size hashtable
  1462. Return the number of key/value pairs in @var{hashtable}.
  1463. @end deffn
  1464. @deffn {Procedure} hashtable-ref hashtable key default
  1465. Return the value associated with @var{key} in @var{hashtable} or
  1466. @var{default} if there is no such association.
  1467. @end deffn
  1468. @deffn {Procedure} hashtable-set! hashtable key value
  1469. Modify @var{hashtable} to associate @var{key} with @var{value},
  1470. overwriting any previous association that may have existed.
  1471. @end deffn
  1472. @deffn {Procedure} hashtable-delete! hashtable key
  1473. Remove the association with @var{key} in @var{hashtable}, if one
  1474. exists.
  1475. @end deffn
  1476. @deffn {Procedure} hashtable-clear! hashtable
  1477. Remove all of the key/value associations in @var{hashtable}.
  1478. @end deffn
  1479. @deffn {Procedure} hashtable-contains? hashtable key
  1480. Return @code{#t} if @var{key} has an associated value in
  1481. @var{hashtable}.
  1482. @end deffn
  1483. @deffn {Procedure} hashtable-copy hashtable
  1484. Return a copy of @var{hashtable}.
  1485. @end deffn
  1486. @deffn {Procedure} hashtable-keys hashtable
  1487. Return a vector of keys in @var{hashtable}.
  1488. @end deffn
  1489. @deffn {Procedure} hashtable-entries hashtable
  1490. Return a vector of values in @var{hashtable}.
  1491. @end deffn
  1492. @deffn {Procedure} hashtable-for-each proc hashtable
  1493. For each key/value pair in @var{hashtable}, call @var{proc} with two
  1494. arguments: the key and the value.
  1495. @end deffn
  1496. Hoot also includes weak key hash tables that wrap those of the Wasm
  1497. host platform, such as the @code{WeakMap} JavaScript class on the web.
  1498. @deffn {Procedure} make-weak-key-hashtable
  1499. Return a new weak key hashtable.
  1500. @end deffn
  1501. @deffn {Procedure} weak-key-hashtable? obj
  1502. Return @code{#t} if @var{obj} is a weak key hashtable.
  1503. @end deffn
  1504. @deffn {Procedure} weak-key-hashtable-ref hashtable key [default #f]
  1505. Return the value associated with @var{key} in @var{hashtable} or
  1506. @var{default} if there is no such association.
  1507. @end deffn
  1508. @deffn {Procedure} weak-key-hashtable-set! hashtable key value
  1509. Modify @var{hashtable} to associate @var{key} with @var{value},
  1510. overwriting any previous association that may have existed.
  1511. @end deffn
  1512. @deffn {Procedure} weak-key-hashtable-delete! hashtable key
  1513. Remove the association with @var{key} in @var{hashtable}, if one
  1514. exists.
  1515. @end deffn
  1516. @node Records
  1517. @section Records
  1518. Hoot extends the R7RS @code{define-record-type} form with additional
  1519. features such as inheritance and opaque types.
  1520. @deffn {Syntax} define-record-type name constructor predicate @
  1521. (field field-ref [field-set]) ... @
  1522. [#:printer] [#:parent] [#:uid] [#:extensible? #t] [#:opaque? #f] @
  1523. [#:allow-duplicate-field-names? #f]
  1524. Define a new record type descriptor bound to @var{name}. Define a
  1525. constructor procedure bound to @var{constructor} and a predicate
  1526. procedure bound to @var{predicate}. For each @var{field}, define an
  1527. accessor procedure @var{field-ref} and, optionally, a modifier
  1528. procedure @var{field-set}.
  1529. The record type will inherit from the record type descriptor bound to
  1530. @var{parent}, as long as @var{parent} is extensible. By default,
  1531. record types are extensible. A record type may be marked as ``final''
  1532. by passing an @var{extensible?} flag of @code{#f}.
  1533. When @var{opaque?} is @code{#t}, instances of this record type will be
  1534. compared for equality by identity @emph{only}. This means that
  1535. @code{(equal? a b)} only returns @code{#t} when @code{a} and @code{b}
  1536. reference the same instance of the record type. In other words, they
  1537. must be @code{eq?}. The default behavior is to perform deep
  1538. structural equality checking by comparing record fields.
  1539. When @var{printer} is specified, that procedure will be used when
  1540. printing instances of this record type rather than the default
  1541. printer.
  1542. @var{uid} should be a unique identifier that will be associated with
  1543. the record type when specified. Record types have no unique id by
  1544. default.
  1545. When @var{allow-duplicate-field-names?} is @code{#t}, field names may
  1546. appear more than once in the fields section.
  1547. @end deffn
  1548. @node Pattern matching
  1549. @section Pattern matching
  1550. The @code{(hoot match)} module provides a @code{match} form that
  1551. supports a subset of what Guile's @code{(ice-9 match)} can do. See
  1552. @inlinefmtifelse{html,
  1553. @url{https://www.gnu.org/software/guile/manual/html_node/Pattern-Matching.html,
  1554. the Guile manual}, @ref{Pattern Matching,,,Guile Reference}} for more
  1555. detailed information.
  1556. @deffn {Syntax} match exp clause1 clause2 ...
  1557. Match object @var{exp} against the patterns in @var{clause1}
  1558. @var{clause2} @dots{} in the order in which they appear. Return the
  1559. value produced by the first matching clause. If no clause matches,
  1560. throw a match error.
  1561. Each clause has the form @code{(pattern body1 body2 ...)}.
  1562. The following patterns are supported:
  1563. @table @code
  1564. @item identifier
  1565. Matches anything and binds @code{identifier}.
  1566. @item _
  1567. Matches anything.
  1568. @item ()
  1569. Matches the empty list.
  1570. @item #t
  1571. Matches @code{#t}.
  1572. @item #f
  1573. Matches @code{#f}.
  1574. @item 'symbol
  1575. Matches a symbol.
  1576. @item fixnum
  1577. Matches a fixnum such as @code{42}.
  1578. @item (not pattern)
  1579. Matches if sub-pattern does not match.
  1580. @item (and pattern ...)
  1581. Matches if every sub-pattern matches.
  1582. @item (or pattern ...)
  1583. Matches if any sub-pattern matches.
  1584. @item (? predicate)
  1585. Matches if @code{(predicate exp)} returns true.
  1586. @item (? predicate identifier)
  1587. Matches if @code{(predicate exp)} returns true and binds
  1588. @code{identifier}.
  1589. @item (car-pattern . cdr-pattern)
  1590. Matches a pair if the car/cdr match their respective sub-patterns.
  1591. @item #(pattern ...)
  1592. Matches a vector of n elements if each element matches its respective
  1593. sub-pattern.
  1594. @end table
  1595. @end deffn
  1596. @node Foreign function interface
  1597. @section Foreign function interface
  1598. WebAssembly follows the capability security model, which means that
  1599. modules cannot do much on their own. Wasm modules are guests within a
  1600. host. They must be given capabilities by the host in order to
  1601. interact with the outside world. Modules request capabilities by
  1602. declaring imports, which the host then fills out with concrete
  1603. implementations at instantiation time. Hoot provides a foreign
  1604. function interface (FFI) in the @code{(hoot ffi)} module to embed
  1605. these import declarations within Scheme code.
  1606. The @code{define-foreign} form declares an import with a given type
  1607. signature (Wasm is statically typed) and defines a procedure for
  1608. calling it. The FFI takes care of converting Scheme values to Wasm
  1609. values and vice versa. For example, declaring an import for creating
  1610. text nodes in a web browser could look like this:
  1611. @lisp
  1612. (define-foreign make-text-node
  1613. "document" "createTextNode"
  1614. (ref string) -> (ref null extern))
  1615. @end lisp
  1616. In the above example, the procedure is bound to the variable
  1617. @code{make-text-node}. In the Wasm binary, this import is named
  1618. ``createTextNode'' and resides in the ``document'' namespace of the
  1619. import table. A Wasm host is expected to satisfy this import by
  1620. providing a function that accepts one argument, a string, and returns
  1621. an arbitary host value which may be null.
  1622. Note that declaring an import @emph{does not} do anything to bind that
  1623. import to an implementation on the host. The Wasm guest cannot grant
  1624. capabilities unto itself. Furthermore, the host could be any Wasm
  1625. runtime, so the actual implementation will vary. In the context of a
  1626. web browser, the JavaScript code that instantiates a module with this
  1627. import could look like this:
  1628. @example
  1629. @verbatim
  1630. Scheme.load_main("hello.wasm", {}, {
  1631. document: {
  1632. createTextNode: Document.prototype.createTextNode.bind(document)
  1633. }
  1634. });
  1635. @end verbatim
  1636. @end example
  1637. And here's what it might look like when using the Hoot interpreter:
  1638. @lisp
  1639. (use-modules (hoot reflect))
  1640. (hoot-instantiate (call-with-input-file "hello.wasm" parse-wasm)
  1641. `(("document" .
  1642. (("createTextNode" . ,(lambda (str) `(text ,str)))))))
  1643. @end lisp
  1644. Once defined, @code{make-text-node} can be called like any other
  1645. procedure:
  1646. @lisp
  1647. (define text-node (make-text-node "Hello, world!"))
  1648. @end lisp
  1649. Since the return type of @code{make-text-node} is @code{(ref null
  1650. extern}), the value of @code{text-node} is an @emph{external
  1651. reference}. To check if a value is an external reference, use the
  1652. @code{external?} predicate:
  1653. @lisp
  1654. (external? text-node) ; => #t
  1655. @end lisp
  1656. External references may be null, which could indicate failure, a cache
  1657. miss, etc. To check if an external value is null, use the
  1658. @code{external-null?} predicate:
  1659. @lisp
  1660. (if (external-null? text-node) 'yay 'uh-oh)
  1661. @end lisp
  1662. @deffn {Syntax} define-foreign scheme-name namespace import-name param-types ... -> result-type
  1663. Define @var{scheme-name}, a procedure wrapping the Wasm import
  1664. @var{import-name} in the namespace @var{namespace}.
  1665. The signature of the function is specified by @var{param-types} and
  1666. @var{result-type}, which are all Wasm types expressed in WAT form.
  1667. Valid parameter types are:
  1668. @itemize
  1669. @item i32: 32-bit integer
  1670. @item i64: 64-bit integer
  1671. @item f32: 32-bit float
  1672. @item f64: 64-bit float
  1673. @item (ref string): a string
  1674. @item (ref extern): a non-null external value
  1675. @item (ref null extern): a possible null external value
  1676. @item (ref eq): any Scheme value
  1677. @end itemize
  1678. Valid result types are:
  1679. @itemize
  1680. @item none: no return value
  1681. @item i32: 32-bit integer
  1682. @item i64: 64-bit integer
  1683. @item f32: 32-bit float
  1684. @item f64: 64-bit float
  1685. @item (ref string): a string
  1686. @item (ref extern): a non-null external value
  1687. @item (ref null extern): a possibly null external value
  1688. @item (ref eq): a Scheme value
  1689. @end itemize
  1690. @end deffn
  1691. @deffn {Procedure} external? obj
  1692. Return @code{#t} if @var{obj} is an external reference.
  1693. @end deffn
  1694. @deffn {Procedure} external-null? extern
  1695. Return @code{#t} if @var{extern} is null.
  1696. @end deffn
  1697. @deffn {Procedure} external-non-null? extern
  1698. Return @code{#t} if @var{extern} is not null.
  1699. @end deffn
  1700. @node Toolchain reference
  1701. @chapter Toolchain reference
  1702. Hoot is not just a Scheme to Wasm compiler. It's also a
  1703. self-contained and general purpose Wasm toolchain. Hoot does not use
  1704. binaryen, wabt, emscripten, etc. in order to assemble and disassemble
  1705. Wasm. The entire toolchain is implemented as a set of Scheme modules
  1706. that can be used to automate other Wasm targeted build workflows.
  1707. Since everything is implemented in one place, in a single language,
  1708. and because Guile encourages a REPL-driven development workflow, Hoot
  1709. makes a great platform for learning Wasm in a hands-on, interactive
  1710. way!
  1711. @menu
  1712. * Data types:: Core Wasm module data types.
  1713. * GWAT:: Guile-flavored WebAssembly Text format.
  1714. * Resolver:: Lower human-readable identifiers to index values.
  1715. * Linker:: Add a standard library to a Wasm module.
  1716. * Assembler:: Create Wasm binaries.
  1717. * Binary Parser:: Parse Wasm binaries.
  1718. * Printer:: Print the contents of a Wasm module.
  1719. * Interpreter:: Execute Wasm within Guile.
  1720. @end menu
  1721. @node Data types
  1722. @section Data types
  1723. The @code{(wasm types)} module contains all the core data types that
  1724. comprise a Wasm module.
  1725. @subsection Modules
  1726. The Wasm module type is the top type, incorporating values of all the
  1727. types that are to follow.
  1728. @deffn {Procedure} wasm? obj
  1729. Return @code{#t} if @var{obj} is a Wasm module.
  1730. @end deffn
  1731. @deffn {Procedure} wasm-id wasm
  1732. Return the symbolic ID of @var{wasm}.
  1733. @end deffn
  1734. @deffn {Procedure} wasm-types wasm
  1735. Return the list of types in @var{wasm}.
  1736. @end deffn
  1737. @deffn {Procedure} wasm-imports wasm
  1738. Return the list of imports in @var{wasm}.
  1739. @end deffn
  1740. @deffn {Procedure} wasm-funcs wasm
  1741. Return the list of functions in @var{wasm}.
  1742. @end deffn
  1743. @deffn {Procedure} wasm-tables wasm
  1744. Return the list of tables in @var{wasm}.
  1745. @end deffn
  1746. @deffn {Procedure} wasm-memories wasm
  1747. Return the list of memories in @var{wasm}.
  1748. @end deffn
  1749. @deffn {Procedure} wasm-globals wasm
  1750. Return the list of globals in @var{wasm}.
  1751. @end deffn
  1752. @deffn {Procedure} wasm-exports wasm
  1753. Return the list of exports in @var{wasm}.
  1754. @end deffn
  1755. @deffn {Procedure} wasm-elems wasm
  1756. Return the list of element segments in @var{wasm}.
  1757. @end deffn
  1758. @deffn {Procedure} wasm-datas wasm
  1759. Return the list of data segments in @var{wasm}.
  1760. @end deffn
  1761. @deffn {Procedure} wasm-tags wasm
  1762. Return the list of tags in @var{wasm}.
  1763. @end deffn
  1764. @deffn {Procedure} wasm-strings wasm
  1765. Return the list of strings in @var{wasm}.
  1766. @end deffn
  1767. @deffn {Procedure} wasm-custom wasm
  1768. Return the list of custom segments in @var{wasm}.
  1769. @end deffn
  1770. @deffn {Procedure} wasm-start wasm
  1771. Return the start function index for @var{wasm}.
  1772. @end deffn
  1773. @subsection Types
  1774. Wasm has four numeric types:
  1775. @enumerate
  1776. @item @code{i32}:
  1777. 32-bit integer (signed or unsigned)
  1778. @item @code{i64}:
  1779. 64-bit integer (signed or unsigned)
  1780. @item @code{f32}:
  1781. 32-bit single precision IEEE floating point number.
  1782. @item @code{f64}:
  1783. 64-bit double precision IEEE floating point number.
  1784. @end enumerate
  1785. There is also the @code{v128} vector type, but it is currently
  1786. unsupported.
  1787. Then there are a number of reference types that fall into 3
  1788. categories: function, external, and internal.
  1789. Function reference types:
  1790. @enumerate
  1791. @item @code{func}:
  1792. Function reference.
  1793. @item @code{nofunc}:
  1794. Bottom type for functions. No function is of type @code{nofunc}.
  1795. @end enumerate
  1796. External reference types:
  1797. @enumerate
  1798. @item @code{extern}:
  1799. External reference introduced by the host.
  1800. @item @code{noextern}:
  1801. Bottom type for external references. No external reference is of type
  1802. @code{noextern}.
  1803. @end enumerate
  1804. Internal reference types:
  1805. @enumerate
  1806. @item @code{any}:
  1807. The top type of all internal reference types.
  1808. @item @code{eq}:
  1809. Structural equivalence type. Subtype of @code{all}.
  1810. @item @code{i31}:
  1811. Used for immediate references (such as the empty list or fixnums in
  1812. Scheme.) Subtype of @code{eq}.
  1813. @item @code{array}:
  1814. Super type of all array types. Subtype of @code{eq}.
  1815. @item @code{struct}:
  1816. Super type of all struct types. Subtype of @code{eq}.
  1817. @item @code{none}:
  1818. The bottom type for internal references. No internal reference is of
  1819. type @code{none}.
  1820. @end enumerate
  1821. Of course, modules may specify their own compound types assembled from
  1822. these primitives.
  1823. The type hierarchy looks like this:
  1824. @verbatim
  1825. .-----. .-------. .---------.
  1826. | any | | func | | extern |
  1827. `-----' `-------' `---------'
  1828. ↓ ↓ ↓
  1829. .-----. .-----------. .-----------.
  1830. .-------- | eq | ------------. | all funcs | | noextern |
  1831. | `-----' | `-----------' `-----------'
  1832. ↓ ↓ ↓ ↓
  1833. .-----. .-------------. .---------. .---------.
  1834. | i31 | | all arrays | | struct | | nofunc |
  1835. `-----' `-------------' `---------' `---------'
  1836. ↓ ↓
  1837. .-----. .-------------.
  1838. | any | | all structs |
  1839. `-----' `-------------'
  1840. @end verbatim
  1841. A collection of type descriptor objects form a type table that
  1842. describes all non-primitive types used within a module. Type objects
  1843. associate an identifier with a function signature or reference type
  1844. descriptor.
  1845. @deffn {Procedure} type? obj
  1846. Return @code{#t} if @var{obj} is a type.
  1847. @end deffn
  1848. @deffn {Procedure} type-id type
  1849. Return the symbolic ID of @var{type}.
  1850. @end deffn
  1851. @deffn {Procedure} type-val type
  1852. Return the type descriptor of @var{type}.
  1853. @end deffn
  1854. Types may also be nested within recursive type groups that allow for
  1855. circular and self references to the types within the group. Types
  1856. @emph{not} within a group can be thought of as belonging to a group of
  1857. one.
  1858. @deffn {Procedure} rec-group? obj
  1859. Return @code{#t} if @var{obj} is a recursive type group.
  1860. @end deffn
  1861. @deffn {Procedure} rec-group-types rec-group
  1862. Return the types within @var{rec-group}.
  1863. @end deffn
  1864. Note that while each Wasm module contains a full inventory of its
  1865. types, structurally identical type groups across Wasm modules are
  1866. canonicalized at runtime and are considered to be identical
  1867. (@code{eq?} in Scheme terms.) This allows for passing references
  1868. between modules.
  1869. Type uses refer to function signatures and are used for specifying the
  1870. type of a @code{block}, @code{loop}, or @code{if} expression.
  1871. @deffn {Procedure} type-use? obj
  1872. Return @code{#t} if @var{obj} is a type use.
  1873. @end deffn
  1874. @deffn {Procedure} type-use-idx type-use
  1875. Return the type index of @var{type-use}.
  1876. @end deffn
  1877. @deffn {Procedure} type-use-sig type-use
  1878. Return the function signature of @var{type-use}.
  1879. @end deffn
  1880. @deffn {Procedure} ref-type? obj
  1881. Return @code{#t} if @var{obj} is a reference type.
  1882. @end deffn
  1883. @deffn {Procedure} ref-type-nullable? ref-type
  1884. Return @var{#t} if @var{ref-type} is nullable.
  1885. @end deffn
  1886. @deffn {Procedure} ref-type-heap-type ref-type
  1887. Return the heap type of @var{ref-type}.
  1888. @end deffn
  1889. As mentioned above, reference types support structural subtyping.
  1890. @deffn {Procedure} sub-type? obj
  1891. Return @code{#t} if @var{obj} is a sub type.
  1892. @end deffn
  1893. @deffn {Procedure} sub-type-final? sub-type
  1894. Return @code{#t} if @var{sub-type} is marked as final.
  1895. @end deffn
  1896. @deffn {Procedure} sub-type-supers sub-type
  1897. Return super types of @var{sub-type}.
  1898. @end deffn
  1899. @deffn {Procedure} sub-type-type sub-type
  1900. Return the concrete type descriptor of @var{sub-type}.
  1901. @end deffn
  1902. Compound types take the form of arrays and structs.
  1903. @deffn {Procedure} array-type? obj
  1904. Return @code{#t} if @var{obj} is an array type.
  1905. @end deffn
  1906. @deffn {Procedure} array-type-mutable? array-type
  1907. Return @code{#t} if @var{array-type} is mutable.
  1908. @end deffn
  1909. @deffn {Procedure} array-type-type array-type
  1910. Retun the element type descriptor of @var{array-type}.
  1911. @end deffn
  1912. @deffn {Procedure} struct-type? obj
  1913. Return @code{#t} if @var{obj} is a struct type.
  1914. @end deffn
  1915. @deffn {Procedure} struct-type-fields struct-type
  1916. Return the field descriptors of @var{struct-type}.
  1917. @end deffn
  1918. Struct types are composed of several fields.
  1919. @deffn {Procedure} field? obj
  1920. Return @code{#t} if @var{obj} is a struct field.
  1921. @end deffn
  1922. @deffn {Procedure} field-id field
  1923. Return the symbolic ID of @var{field}.
  1924. @end deffn
  1925. @deffn {Procedure} field-mutable? field
  1926. Return @code{#t} if @var{field} is mutable.
  1927. @end deffn
  1928. @deffn {Procedure} field-type field
  1929. Return the type descriptor of @var{field}.
  1930. @end deffn
  1931. Both arrays and struct fields allow for packed data using the special
  1932. @code{i8} and @code{i16} data types.
  1933. @subsection Globals
  1934. Wasm supports both mutable and immutable global variables.
  1935. @deffn {Procedure} global? obj
  1936. Return @code{#t} if @var{obj} is a global.
  1937. @end deffn
  1938. @deffn {Procedure} global-id global
  1939. Return the symbloc ID of @var{global}.
  1940. @end deffn
  1941. @deffn {Procedure} global-type global
  1942. Return the type of @var{global}.
  1943. @end deffn
  1944. @deffn {Procedure} global-init global
  1945. Return the initialization instructions of @var{global}. Only constant
  1946. instructions are allowed.
  1947. @end deffn
  1948. @deffn {Procedure} global-type? obj
  1949. Return @code{#t} if @var{obj} is a global type.
  1950. @end deffn
  1951. @deffn {Procedure} global-type-mutable? global-type
  1952. Return @code{#t} if @var{global-type} is mutable.
  1953. @end deffn
  1954. @deffn {Procedure} global-type-type global-type
  1955. Return the type descriptor of @var{global-type}.
  1956. @end deffn
  1957. @subsection Functions
  1958. @deffn {Procedure} func? obj
  1959. Return @code{#t} if @var{obj} is a function.
  1960. @end deffn
  1961. @deffn {Procedure} func-id func
  1962. Return the symbolic ID of @var{func}.
  1963. @end deffn
  1964. @deffn {Procedure} func-type func
  1965. Return the signature of @var{func}.
  1966. @end deffn
  1967. @deffn {Procedure} func-locals func
  1968. Return the locals of @var{func}.
  1969. @end deffn
  1970. @deffn {Procedure} func-body func
  1971. Return the body instructions of @var{func}.
  1972. @end deffn
  1973. The type of a function is its signature. Notably, Wasm supports
  1974. multiple return values, just like Scheme.
  1975. @deffn {Procedure} func-sig? obj
  1976. Return @code{#t} if @var{obj} is a function signature.
  1977. @end deffn
  1978. @deffn {Procedure} func-sig-params func
  1979. Return the parameters of @var{func}.
  1980. @end deffn
  1981. @deffn {Procedure} func-sig-results func
  1982. Return the result types of @var{func}.
  1983. @end deffn
  1984. Function parameters pair a local identifier with its type.
  1985. @deffn {Procedure} param? obj
  1986. Return @code{#t} if @var{obj} is a param.
  1987. @end deffn
  1988. @deffn {Procedure} param-id param
  1989. Return the symbolic ID of @var{param}.
  1990. @end deffn
  1991. @deffn {Procedure} param-type param
  1992. Return the type descriptor of @var{param}.
  1993. @end deffn
  1994. Locals provide additional mutable variables scoped to the body of a
  1995. function.
  1996. @deffn {Procedure} local? obj
  1997. Return @code{#t} if @var{obj} is a function local.
  1998. @end deffn
  1999. @deffn {Procedure} local-id local
  2000. Return the symbolic ID of @var{local}.
  2001. @end deffn
  2002. @deffn {Procedure} local-type local
  2003. Return the type descriptor of @var{local}.
  2004. @end deffn
  2005. @subsection Imports/exports
  2006. Functions, globals, memories, and tables can be imported from the host
  2007. or another Wasm module. They are organized into a two layer
  2008. hierarchy. An import module groups many imports under an umbrella
  2009. name, and then the individual item names distinguish imported data
  2010. within a module.
  2011. @deffn {Procedure} import? obj
  2012. Return @code{#t} if @var{obj} is an import.
  2013. @end deffn
  2014. @deffn {Procedure} import-mod import
  2015. Return the module name string of @var{import}.
  2016. @end deffn
  2017. @deffn {Procedure} import-name import
  2018. Return the name string of @var{import}.
  2019. @end deffn
  2020. @deffn {Procedure} import-kind import
  2021. Return the kind of @var{import}. Either @code{func}, @code{global},
  2022. @code{memory}, or @code{table}.
  2023. @end deffn
  2024. @deffn {Procedure} import-id import
  2025. Return the symbolic ID of @var{import}.
  2026. @end deffn
  2027. @deffn {Procedure} import-type import
  2028. Return the type descriptor of @var{import}.
  2029. @end deffn
  2030. Likewise, functions, globals, memories, and tables can be exported
  2031. from a module to be used by the host or by other modules.
  2032. @deffn {Procedure} export? obj
  2033. Return @code{#t} if @var{obj} is an export.
  2034. @end deffn
  2035. @deffn {Procedure} export-name export
  2036. Return the name string of @var{export}.
  2037. @end deffn
  2038. @deffn {Procedure} export-kind export
  2039. Return the kind of @var{export}. Either @code{func}, @code{global},
  2040. @code{memory}, or @code{table}.
  2041. @end deffn
  2042. @deffn {Procedure} export-idx export
  2043. Return the index of @var{export}.
  2044. @end deffn
  2045. @subsection Linear memory
  2046. Memory objects specify linear chunks of bytes that a module can write
  2047. to/read from at runtime. The size of a memory is specified in terms
  2048. of 64KiB pages. While many memory objects coud be included in a
  2049. module, the Wasm specification currently only allows the use of a
  2050. single memory at index 0.
  2051. @deffn {Procedure} memory? obj
  2052. Return @code{#t} if @var{obj} is a memory.
  2053. @end deffn
  2054. @deffn {Procedure} memory-id memory
  2055. Return the symbolic ID of @var{memory}.
  2056. @end deffn
  2057. The type of a memory currently just specifies the size limitations.
  2058. @deffn {Procedure} memory-type memory
  2059. Return the type of @var{memory}.
  2060. @end deffn
  2061. @deffn {Procedure} mem-type? obj
  2062. Return @code{#t} if @var{obj} is a memory type.
  2063. @end deffn
  2064. @deffn {Procedure} mem-type-limits mem-type
  2065. Return the limits of @var{mem-type}.
  2066. @end deffn
  2067. Instructions that manipulate linear memory use the memory argument
  2068. type to point to a specific offset within a memory.
  2069. @deffn {Procedure} mem-arg? obj
  2070. Return @code{#t} if @var{obj} is a memory argument.
  2071. @end deffn
  2072. @deffn {Procedure} mem-arg-id mem-arg
  2073. Return the symbolic ID of @var{mem-arg}.
  2074. @end deffn
  2075. @deffn {Procedure} mem-arg-offset mem-arg
  2076. Return the offset of @var{mem-arg}.
  2077. @end deffn
  2078. @deffn {Procedure} mem-arg-align mem-arg
  2079. Return the alignment of @var{mem-arg}.
  2080. @end deffn
  2081. @subsection Data segments
  2082. Data segments are static chunks of data used to initialize regions of
  2083. memory. They have two possible modes of use:
  2084. @enumerate
  2085. @item @strong{Active:}
  2086. The data segment is copied into memory during instantiation.
  2087. @item @strong{Passive:}
  2088. The data segment is copied into memory using the @code{memory.init}
  2089. instruction.
  2090. @end enumerate
  2091. @deffn {Procedure} data? obj
  2092. Return @code{#t} if @var{obj} is a data segment.
  2093. @end deffn
  2094. @deffn {Procedure} data-id data
  2095. Return the symbolic ID of @var{data}.
  2096. @end deffn
  2097. @deffn {Procedure} data-mode data
  2098. Return the mode of @var{data}. Either @code{passive} or
  2099. @code{active}.
  2100. @end deffn
  2101. @deffn {Procedure} data-mem data
  2102. Return the memory associated with @var{data}.
  2103. @end deffn
  2104. @deffn {Procedure} data-offset data
  2105. Return the instructions that compute the offset of @var{data}. Only
  2106. constant instructions are allowed.
  2107. @end deffn
  2108. @deffn {Procedure} data-init data
  2109. Return a bytevector containing the initialization data of @var{data}.
  2110. @end deffn
  2111. @subsection Tables
  2112. Tables specify a vector of heap object references of a particular
  2113. reference type.
  2114. @deffn {Procedure} table? obj
  2115. Return @code{#t} if @var{obj} is a reference table.
  2116. @end deffn
  2117. @deffn {Procedure} table-id table
  2118. Return the symbolic ID of @var{table}.
  2119. @end deffn
  2120. @deffn {Procedure} table-type table
  2121. Return the type of @var{table}.
  2122. @end deffn
  2123. Table types specify the reference type of the elements as well as the
  2124. size limitations.
  2125. @deffn {Procedure} table-type? obj
  2126. Return @code{#t} if @var{obj} is a table type.
  2127. @end deffn
  2128. @deffn {Procedure} table-type-limits table-type
  2129. Return the limts of @var{table-type}.
  2130. @end deffn
  2131. @deffn {Procedure} table-type-elem-type table-type
  2132. Return the element type of @var{table-type}.
  2133. @end deffn
  2134. @subsection Element segments
  2135. Element segments are static vectors of references used to initialize
  2136. regions of tables (well, mostly.) They have three possible modes of
  2137. use:
  2138. @enumerate
  2139. @item @strong{Active:}
  2140. The element segment is copied into its associated table during
  2141. instantiation.
  2142. @item @strong{Passive:}
  2143. The element segment is copied into its associated table using the
  2144. @code{table.init} instruction.
  2145. @item @strong{Declarative:}
  2146. The element segment is unavailable at runtime and is instead used for
  2147. forward declarations of types that are used elsewhere in the code.
  2148. @end enumerate
  2149. @deffn {Procedure} elem? obj
  2150. Return @code{#t} if @var{obj} is an element segment.
  2151. @end deffn
  2152. @deffn {Procedure} elem-id elem
  2153. Return the symoblic ID of @var{elem}.
  2154. @end deffn
  2155. @deffn {Procedure} elem-mode elem
  2156. Return the mode of @var{elem}.
  2157. @end deffn
  2158. @deffn {Procedure} elem-table elem
  2159. Return the table associated with @var{elem}.
  2160. @end deffn
  2161. @deffn {Procedure} elem-type elem
  2162. Return the type of @var{elem}.
  2163. @end deffn
  2164. @deffn {Procedure} elem-offset elem
  2165. Return the instructions that compute the offset of @var{elem}. Only
  2166. constant instructions are allowed.
  2167. @end deffn
  2168. @deffn {Procedure} elem-inits elem
  2169. Return a list of initializer instructions for the items of @var{elem}.
  2170. Only constant instructions are allowed.
  2171. @end deffn
  2172. @subsection Limits
  2173. Both memories and tables use limits to constrain their minimum and
  2174. maximum size. A valid limit must have a minimum of at least 1, but
  2175. the maximum may be @code{#f} if unbounded growth is allowed.
  2176. @deffn {Procedure} limits? obj
  2177. Return @code{#t} if @var{obj} is a limits.
  2178. @end deffn
  2179. @deffn {Procedure} limits-min limits
  2180. Return the minimum value of @var{limits}.
  2181. @end deffn
  2182. @deffn {Procedure} limits-max limits
  2183. Return the maximum value of @var{limits} or @code{#f} if there is no
  2184. maximum.
  2185. @end deffn
  2186. @subsection Tags
  2187. Tag segments specify types of runtime errors that may be raised.
  2188. @deffn {Procedure} tag? obj
  2189. Return @code{#t} if @var{obj} is a tag.
  2190. @end deffn
  2191. @deffn {Procedure} tag-id tag
  2192. Return the symbolic ID of @var{tag}.
  2193. @end deffn
  2194. @deffn {Procedure} tag-type tag
  2195. Return the type of @var{tag}.
  2196. @end deffn
  2197. Tag types specify the function signature of the tags. Since tags are
  2198. not truly functions, their signatures must only have parameters and no
  2199. results.
  2200. @deffn {Procedure} tag-type? obj
  2201. Return @code{#t} if @var{obj} is a tag type.
  2202. @end deffn
  2203. @deffn {Procedure} tag-type-attribute tag-type
  2204. Return the symbolic attribute of @var{tag-type}. Currently, there is
  2205. only one valid attribute: @code{exception}.
  2206. @end deffn
  2207. @deffn {Procedure} tag-type-type tag-type
  2208. Return the type of @var{tag-type}. This is expected to be a type use
  2209. object that refers to a function signature.
  2210. @end deffn
  2211. @subsection Custom sections
  2212. Custom sections specify arbitrary data that is not covered by the Wasm
  2213. specification.
  2214. @deffn {Procedure} custom? obj
  2215. Return @code{#t} if @var{obj} is a custom segment.
  2216. @end deffn
  2217. @deffn {Procedure} custom-name custom
  2218. Return the name of @var{custom}.
  2219. @end deffn
  2220. @deffn {Procedure} custom-bytes custom
  2221. Return the bytevector of @var{custom}.
  2222. @end deffn
  2223. There is, however, one custom section that @emph{is} specified: the
  2224. name section. This section contains various ``name maps'' that can be
  2225. used to translate integer identifiers to (hopefully) human-readable
  2226. names for the purposes of debugging.
  2227. Hoot supports the name subsections described in the Wasm core
  2228. specification, the Wasm GC specification, and the extended names
  2229. proposal:
  2230. @enumerate
  2231. @item Module name
  2232. @item Function name map
  2233. @item Function local indirect name map
  2234. @item Block label indirect name map
  2235. @item Type name map
  2236. @item Table name map
  2237. @item Memory name map
  2238. @item Global name map
  2239. @item Element name map
  2240. @item Data name map
  2241. @item Struct field indirect name map
  2242. @item Tag name map
  2243. @end enumerate
  2244. Name maps are represented as association lists mapping integers to
  2245. strings. Indirect name maps are represented as association lists
  2246. mapping integers to name maps.
  2247. @deffn {Procedure} names? obj
  2248. Return @code{#t} if @var{obj} is a name section object.
  2249. @end deffn
  2250. @deffn {Procedure} names-module names
  2251. Return the module name of @var{names}.
  2252. @end deffn
  2253. @deffn {Procedure} names-func names
  2254. Return the function name map of @var{names}.
  2255. @end deffn
  2256. @deffn {Procedure} names-local names
  2257. Return the function local indirect name map of @var{names}.
  2258. @end deffn
  2259. @deffn {Procedure} names-label names
  2260. Return the block label indirect name map of @var{names}.
  2261. @end deffn
  2262. @deffn {Procedure} names-type names
  2263. Return the type name map of @var{names}.
  2264. @end deffn
  2265. @deffn {Procedure} names-table names
  2266. Return the table name map of @var{names}.
  2267. @end deffn
  2268. @deffn {Procedure} names-memory names
  2269. Return the memory name map of @var{names}.
  2270. @end deffn
  2271. @deffn {Procedure} names-global names
  2272. Return the global name map of @var{names}.
  2273. @end deffn
  2274. @deffn {Procedure} names-elem names
  2275. Return the element name map of @var{names}.
  2276. @end deffn
  2277. @deffn {Procedure} names-data names
  2278. Return the data name map of @var{names}.
  2279. @end deffn
  2280. @deffn {Procedure} names-fields names
  2281. Return the struct field indirect name map of @var{names}.
  2282. @end deffn
  2283. @deffn {Procedure} names-tag names
  2284. Return the tag name map of @var{names}.
  2285. @end deffn
  2286. @node GWAT
  2287. @section GWAT
  2288. The @code{(wasm wat)} module provides a parser for a variant of
  2289. WebAssembly Text (WAT) format. Since the WAT uses an s-expression
  2290. syntax that resembles but is distinct from Scheme syntax, Hoot opts to
  2291. represent WAT code as Scheme expressions. This allows for embedding
  2292. WAT directly into Scheme code and programmatically generating WAT code
  2293. via quasiquote templating or other means. We call this variant GWAT
  2294. where the ``G'' stands for ``Guile'', of course.
  2295. The GWAT form has some additional expressive power such as allowing
  2296. string constants, bytevectors for data segments, and i32/i64 constants
  2297. in either the signed or unsigned range.
  2298. WAT has two variants: unfolded and folded. In the unfolded form,
  2299. instruction sequences are linear, as they would be in the resulting
  2300. binary:
  2301. @lisp
  2302. '(module
  2303. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2304. (local.get $a)
  2305. (local.get $b)
  2306. (i32.add)))
  2307. @end lisp
  2308. The folded form allows instructions to be nested within each other:
  2309. @lisp
  2310. '(module
  2311. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2312. (i32.add (local.get $a)
  2313. (local.get $b))))
  2314. @end lisp
  2315. This form looks more like Scheme procedure calls and is generally
  2316. easier to write and reason about.
  2317. @deffn {Procedure} wat->wasm expr
  2318. Parse @var{expr}, a Wasm module expressed as WAT code, and return a
  2319. Wasm module.
  2320. @lisp
  2321. (parse-wat
  2322. '(module
  2323. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2324. (i32.add (local.get $a)
  2325. (local.get $b)))))
  2326. @end lisp
  2327. The returned Wasm module preserves named references, among other
  2328. things, and is thus unsuitable as input to the assembler or
  2329. interpreter. To lower the module into a usable form, see
  2330. @code{resolve-wasm} in @ref{Resolver}.
  2331. @end deffn
  2332. @deffn {Procedure} wasm->wat wasm
  2333. Disassemble @var{wasm} and return its symbolic WAT form.
  2334. @end deffn
  2335. @node Resolver
  2336. @section Resolver
  2337. The @code{(wasm resolve)} module provides the @code{resolve-wasm}
  2338. procedure which lowers Wasm modules into a form that can be used by
  2339. the assembler or interpreter. The resolver replaces named references
  2340. with their respective integer identifiers, fills out the type table,
  2341. and adjusts i32 and i64 constants into their canonical form.
  2342. @deffn {Procedure} resolve-wasm mod [#:emit-names? #f]
  2343. Lower the Wasm module @var{mod} into a form that can be assembled or
  2344. interpreted. Returns a new Wasm module and does not modify @var{mod}.
  2345. When @var{emit-names?} is @code{#t}, the returned Wasm module will
  2346. include a name map that maps the original, human-readable names to the
  2347. resolved integer identifiers.
  2348. @end deffn
  2349. @node Linker
  2350. @section Linker
  2351. The @code{(wasm link)} module provides a means for extending a Wasm
  2352. module with the standard library that it needs at runtime. Hoot uses
  2353. the linker to add the Scheme runtime to the compiled form of user
  2354. code. The linker uses a form of tree-shaking to remove anything that
  2355. is not used by the base module.
  2356. @deffn {Procedure} add-stdlib wasm stdlib
  2357. Return a new Wasm module that is the combination of the Wasm module
  2358. @var{wasm} with the Wasm module @var{stdlib}.
  2359. @end deffn
  2360. @node Assembler
  2361. @section Assembler
  2362. The @code{(wasm assemble)} module is used to lower Wasm modules into
  2363. the Wasm binary format.
  2364. @deffn {Procedure} assemble-wasm wasm
  2365. Return a bytevector containing the assembled binary form of the Wasm
  2366. module @var{wasm}.
  2367. @end deffn
  2368. @node Binary Parser
  2369. @section Binary Parser
  2370. The @code{(wasm parse)} module parses the Wasm binary format.
  2371. @deffn {Procedure} parse-wasm port
  2372. Parse the Wasm binary data from @var{port} and return a Wasm module.
  2373. @end deffn
  2374. @node Printer
  2375. @section Printer
  2376. The @code{(wasm dump)} module provides the @code{dump-wasm} procedure
  2377. for generating a detailed print-out of a Wasm module's contents. See
  2378. also @ref{Low-level development tools} for the @code{wasm-dump} REPL
  2379. command.
  2380. @deffn {Procedure} dump-wasm mod [#:port] [#:dump-func-defs? #t]
  2381. Write a detailed inventory of the Wasm module @var{mod} to @var{port}
  2382. or the current output port if @var{port} is not specified. If
  2383. @var{dump-func-defs?} is @code{#t}, which is the default, all function
  2384. definitions are printed, including the instructions in the body of
  2385. each. Depending on the size of the module, this may be an
  2386. overwhelming amount of data, thus it is made optional.
  2387. @end deffn
  2388. @node Interpreter
  2389. @section Interpreter
  2390. The @code{(wasm vm)} module provides a virtual machine for
  2391. interpreting Wasm functions. To use the interpreter, a Wasm module is
  2392. first validated for type safety (among other things) and then
  2393. instantiated, at which point exported functions become callable from
  2394. Scheme.
  2395. The interpreter only accepts validated Wasm. The @code{validate-wasm}
  2396. procedure validates and wraps a Wasm module to indicate successful
  2397. validation:
  2398. @lisp
  2399. (use-modules (wasm vm) (wasm resolve))
  2400. (define validated-wasm
  2401. (validate-wasm
  2402. (wat->wasm
  2403. '(module
  2404. (func (export "main") (result i32)
  2405. (i32.const 42))))))
  2406. @end lisp
  2407. When starting with a Wasm binary, the convenient
  2408. @code{load-and-validate-wasm} procedure parses the binary and then
  2409. performs validation:
  2410. @lisp
  2411. (call-with-input-file "hello.wasm" load-and-validate-wasm)
  2412. @end lisp
  2413. Once the Wasm module has been validated, the runtime data needed for
  2414. interpretation can be created by instantiating the module:
  2415. @lisp
  2416. (define instance (instantiate-wasm validated-wasm))
  2417. @end lisp
  2418. Exported Wasm functions then become usable as Scheme procedures:
  2419. @lisp
  2420. (define wasm-main (wasm-instance-export-ref instance "main"))
  2421. (wasm-main) ;; => 42
  2422. @end lisp
  2423. Wasm functions are statically typed, which means that calls from
  2424. Scheme to Wasm require runtime type checking for each call.
  2425. @subsection Validation
  2426. @deffn {Procedure} validate-wasm wasm
  2427. Validate the Wasm module @var{wasm} and return a validated Wasm
  2428. object.
  2429. @end deffn
  2430. @deffn {Procedure} load-and-validate-wasm obj
  2431. Load and validate the Wasm module within @var{obj} then return a
  2432. validated Wasm object. @var{obj} may be a @code{<wasm>} record as
  2433. produced by @code{resolve-wasm} (@pxref{Resolver}), a bytevector
  2434. containing a Wasm binary, or an input port from which to read a Wasm
  2435. binary.
  2436. @end deffn
  2437. @deffn {Procedure} validated-wasm? obj
  2438. Return @code{#t} if @var{obj} is a validated Wasm object.
  2439. @end deffn
  2440. @deffn {Procedure} validated-wasm-ref validated-wasm
  2441. Unbox and return the Wasm module within @var{validated-wasm}.
  2442. @end deffn
  2443. @subsection Instantiation
  2444. @deffn {Procedure} instantiate-wasm wasm [#:imports '()]
  2445. Return a new Wasm instance for the validated Wasm module @var{wasm}.
  2446. @var{imports} is a nested association list of imported functions,
  2447. globals, memories, and tables. Wasm imports are identified by a
  2448. module name and an object name. Consider the following Wasm module
  2449. that computes 2D polar coordinates and prints them to a log:
  2450. @lisp
  2451. (use-modules (wasm resolve) (wasm vm) (wasm wat))
  2452. (define the-module
  2453. (resolve-wasm
  2454. (wat->wasm
  2455. '(module
  2456. (func $logf64 (import "debug" "logf64") (param f64))
  2457. (func $cos (import "math" "cos") (param f64) (result f64))
  2458. (func $sin (import "math" "sin") (param f64) (result f64))
  2459. (func (export "polar") (param $r f64) (param $theta f64)
  2460. (call $logf64 (f64.mul (local.get $r)
  2461. (call $cos (local.get $theta))))
  2462. (call $logf64 (f64.mul (local.get $r)
  2463. (call $sin (local.get $theta)))))))))
  2464. @end lisp
  2465. This module requires three imported functions from two modules. Thus
  2466. the module instantiation code would look like this:
  2467. @lisp
  2468. (define (logf64 x)
  2469. (format #t "f64: ~a\n" x))
  2470. (define the-instance
  2471. (instantiate-wasm (validate-wasm the-module)
  2472. #:imports `(("debug" . (("logf64" . ,logf64)))
  2473. ("math" . (("cos" . ,cos)
  2474. ("sin" . ,sin))))))
  2475. @end lisp
  2476. @end deffn
  2477. @subsection Globals
  2478. @deffn {Procedure} make-wasm-global value mutable?
  2479. Return a new Wasm global containing @var{value}. When @var{mutable?}
  2480. is @code{#f}, the value cannot be modified later.
  2481. @end deffn
  2482. @deffn {Procedure} wasm-global? obj
  2483. Return @code{#t} if @var{obj} is a Wasm global.
  2484. @end deffn
  2485. @deffn {Procedure} wasm-global-ref global
  2486. Return the current value within @var{global}.
  2487. @end deffn
  2488. @deffn {Procedure} wasm-global-set! global val
  2489. Set the value within @var{global} to @var{val}. An exception is
  2490. raised if @var{global} is immutable.
  2491. @end deffn
  2492. @deffn {Procedure} wasm-global-mutable? global
  2493. Return @code{#t} if @var{global} is mutable.
  2494. @end deffn
  2495. @subsection Memories
  2496. @deffn {Procedure} make-wasm-memory size [#:limits (make-limits 1 #f)]
  2497. Return a new Wasm linear memory containing @var{size} 64KiB pages.
  2498. @var{limits} determines the lower and upper bounds of how many pages
  2499. this memory can store. The default limits are a minimum of 1 page and
  2500. no maximum page limit. @xref{Data types} for more information on
  2501. limit objects.
  2502. @end deffn
  2503. @deffn {Procedure} wasm-memory? obj
  2504. Return @code{#t} if @var{obj} is a Wasm memory.
  2505. @end deffn
  2506. @deffn {Procedure} wasm-memory-bytes memory
  2507. Return the current bytevector representing the pages of @var{memory}.
  2508. @end deffn
  2509. @deffn {Procedure} wasm-memory-size memory
  2510. Return the size of @var{memory} in 64KiB pages.
  2511. @end deffn
  2512. @deffn {Procedure} wasm-memory-limits memory
  2513. Return the limits of @var{memory}
  2514. @end deffn
  2515. @deffn {Procedure} wasm-memory-grow! memory n
  2516. Increase the size of @var{memory} by @var{n} pages. An exception is
  2517. raised if growing by @var{n} exceeds the limits of @var{memory}.
  2518. @end deffn
  2519. @subsection Tables
  2520. @deffn {Procedure} make-wasm-table size [#:limits (make-limits 1 #f)]
  2521. Return a new Wasm reference table containing @var{size} element slots.
  2522. @var{limits} determines the lower and upper bounds of how many
  2523. elements this table can store. The default limits are a minimum of 1
  2524. element and no maximum element limit. @xref{Data types} for more
  2525. information on limit objects.
  2526. @end deffn
  2527. @deffn {Procedure} wasm-table?
  2528. Return @code{#t} if @var{obj} is a Wasm table.
  2529. @end deffn
  2530. @deffn {Procedure} wasm-table-size table
  2531. Return the size of @var{table}.
  2532. @end deffn
  2533. @deffn {Procedure} wasm-table-ref table i
  2534. Return the reference at the @var{i}th index in @var{table}.
  2535. @end deffn
  2536. @deffn {Procedure} wasm-table-set! table i x
  2537. Set the @var{i}th element of @var{table} to @var{x}, a Wasm reference
  2538. type.
  2539. @end deffn
  2540. @deffn {Procedure} wasm-table-fill! table start fill length
  2541. Fill the elements of @var{table} from @var{start} to @var{start} +
  2542. @var{length}, exclusive, with the value @var{fill}.
  2543. @end deffn
  2544. @deffn {Procedure} wasm-table-copy! table at elems start length
  2545. Copy the block of elements from vector @var{elems}, from @var{start}
  2546. to @var{start} + @var{length}, exclusive, to @var{table}, starting at
  2547. @var{at}.
  2548. @end deffn
  2549. @deffn {Procedure} wasm-table-grow! table n init
  2550. Increase the size of @var{table} by @var{n} elements. An exception is
  2551. raised if growing by @var{n} exceeds the limits of @var{table}.
  2552. @end deffn
  2553. @subsection Observation
  2554. Every Wasm instruction evaluated by interpreter can be observed via
  2555. the @code{current-instruction-listener} parameter. Use this hook to
  2556. instrument Wasm modules.
  2557. The following instruction listener would print every instruction's
  2558. name on a separate line:
  2559. @lisp
  2560. (define (log-instr instr path instance stack blocks locals)
  2561. (display (car instr))
  2562. (newline))
  2563. (parameterize ((current-instruction-listener log-instr))
  2564. ...)
  2565. @end lisp
  2566. @defvar current-instruction-listener
  2567. The current instruction observation hook which is invoked
  2568. @emph{before} each instruction evaluation. Must be a procedure that
  2569. accepts the following arguments:
  2570. @enumerate
  2571. @item @strong{Instruction:}
  2572. The symbolic Wasm instruction to be evaluated.
  2573. @item @strong{Path:}
  2574. The symbolic location of the instruction within the Wasm module.
  2575. @item @strong{Instance:}
  2576. The instance that is evaluating the instruction.
  2577. @item @strong{Stack:}
  2578. The Wasm value stack.
  2579. @item @strong{Blocks:}
  2580. The Wasm block stack, which is just a list of prompt tags.
  2581. @item @strong{Locals:}
  2582. The Wasm function locals.
  2583. @end enumerate
  2584. @end defvar
  2585. The Wasm value stack is a special data type with the following API:
  2586. @deffn {Procedure} wasm-stack? obj
  2587. Return @code{#t} if @var{obj} is a Wasm value stack.
  2588. @end deffn
  2589. @deffn {Procedure} wasm-stack-items stack
  2590. Return the values on @var{stack} as a list.
  2591. @end deffn
  2592. @node Contributing
  2593. @chapter Contributing
  2594. Found a bug? Let us know! Made an improvement? Show us! Issues can
  2595. be filed and pull requests can be submitted on
  2596. @url{https://gitlab.com/spritely/guile-hoot,GitLab}.
  2597. @node License
  2598. @chapter License
  2599. @emph{(C) 2023 David Thompson}
  2600. @emph{Both Guile Hoot and this manual are released under the terms of
  2601. the following license:}
  2602. @include apache-2.0.texi
  2603. @node Index
  2604. @unnumbered Index
  2605. @printindex fn
  2606. @bye