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. | i31 | | eq | | struct | | all funcs | | noextern |
  1831. `-----' `-----' `---------' `-----------' `-----------'
  1832. ↓ ↓ ↓
  1833. .-------------. .-------------. .---------.
  1834. | all arrays | | all structs | | nofunc |
  1835. `-------------' `-------------' `---------'
  1836. .-----.
  1837. | any |
  1838. `-----'
  1839. @end verbatim
  1840. A collection of type descriptor objects form a type table that
  1841. describes all non-primitive types used within a module. Type objects
  1842. associate an identifier with a function signature or reference type
  1843. descriptor.
  1844. @deffn {Procedure} type? obj
  1845. Return @code{#t} if @var{obj} is a type.
  1846. @end deffn
  1847. @deffn {Procedure} type-id type
  1848. Return the symbolic ID of @var{type}.
  1849. @end deffn
  1850. @deffn {Procedure} type-val type
  1851. Return the type descriptor of @var{type}.
  1852. @end deffn
  1853. Types may also be nested within recursive type groups that allow for
  1854. circular and self references to the types within the group. Types
  1855. @emph{not} within a group can be thought of as belonging to a group of
  1856. one.
  1857. @deffn {Procedure} rec-group? obj
  1858. Return @code{#t} if @var{obj} is a recursive type group.
  1859. @end deffn
  1860. @deffn {Procedure} rec-group-types rec-group
  1861. Return the types within @var{rec-group}.
  1862. @end deffn
  1863. Note that while each Wasm module contains a full inventory of its
  1864. types, structurally identical type groups across Wasm modules are
  1865. canonicalized at runtime and are considered to be identical
  1866. (@code{eq?} in Scheme terms.) This allows for passing references
  1867. between modules.
  1868. Type uses refer to function signatures and are used for specifying the
  1869. type of a @code{block}, @code{loop}, or @code{if} expression.
  1870. @deffn {Procedure} type-use? obj
  1871. Return @code{#t} if @var{obj} is a type use.
  1872. @end deffn
  1873. @deffn {Procedure} type-use-idx type-use
  1874. Return the type index of @var{type-use}.
  1875. @end deffn
  1876. @deffn {Procedure} type-use-sig type-use
  1877. Return the function signature of @var{type-use}.
  1878. @end deffn
  1879. @deffn {Procedure} ref-type? obj
  1880. Return @code{#t} if @var{obj} is a reference type.
  1881. @end deffn
  1882. @deffn {Procedure} ref-type-nullable? ref-type
  1883. Return @var{#t} if @var{ref-type} is nullable.
  1884. @end deffn
  1885. @deffn {Procedure} ref-type-heap-type ref-type
  1886. Return the heap type of @var{ref-type}.
  1887. @end deffn
  1888. As mentioned above, reference types support structural subtyping.
  1889. @deffn {Procedure} sub-type? obj
  1890. Return @code{#t} if @var{obj} is a sub type.
  1891. @end deffn
  1892. @deffn {Procedure} sub-type-final? sub-type
  1893. Return @code{#t} if @var{sub-type} is marked as final.
  1894. @end deffn
  1895. @deffn {Procedure} sub-type-supers sub-type
  1896. Return super types of @var{sub-type}.
  1897. @end deffn
  1898. @deffn {Procedure} sub-type-type sub-type
  1899. Return the concrete type descriptor of @var{sub-type}.
  1900. @end deffn
  1901. Compound types take the form of arrays and structs.
  1902. @deffn {Procedure} array-type? obj
  1903. Return @code{#t} if @var{obj} is an array type.
  1904. @end deffn
  1905. @deffn {Procedure} array-type-mutable? array-type
  1906. Return @code{#t} if @var{array-type} is mutable.
  1907. @end deffn
  1908. @deffn {Procedure} array-type-type array-type
  1909. Retun the element type descriptor of @var{array-type}.
  1910. @end deffn
  1911. @deffn {Procedure} struct-type? obj
  1912. Return @code{#t} if @var{obj} is a struct type.
  1913. @end deffn
  1914. @deffn {Procedure} struct-type-fields struct-type
  1915. Return the field descriptors of @var{struct-type}.
  1916. @end deffn
  1917. Struct types are composed of several fields.
  1918. @deffn {Procedure} field? obj
  1919. Return @code{#t} if @var{obj} is a struct field.
  1920. @end deffn
  1921. @deffn {Procedure} field-id field
  1922. Return the symbolic ID of @var{field}.
  1923. @end deffn
  1924. @deffn {Procedure} field-mutable? field
  1925. Return @code{#t} if @var{field} is mutable.
  1926. @end deffn
  1927. @deffn {Procedure} field-type field
  1928. Return the type descriptor of @var{field}.
  1929. @end deffn
  1930. Both arrays and struct fields allow for packed data using the special
  1931. @code{i8} and @code{i16} data types.
  1932. @subsection Globals
  1933. Wasm supports both mutable and immutable global variables.
  1934. @deffn {Procedure} global? obj
  1935. Return @code{#t} if @var{obj} is a global.
  1936. @end deffn
  1937. @deffn {Procedure} global-id global
  1938. Return the symbloc ID of @var{global}.
  1939. @end deffn
  1940. @deffn {Procedure} global-type global
  1941. Return the type of @var{global}.
  1942. @end deffn
  1943. @deffn {Procedure} global-init global
  1944. Return the initialization instructions of @var{global}. Only constant
  1945. instructions are allowed.
  1946. @end deffn
  1947. @deffn {Procedure} global-type? obj
  1948. Return @code{#t} if @var{obj} is a global type.
  1949. @end deffn
  1950. @deffn {Procedure} global-type-mutable? global-type
  1951. Return @code{#t} if @var{global-type} is mutable.
  1952. @end deffn
  1953. @deffn {Procedure} global-type-type global-type
  1954. Return the type descriptor of @var{global-type}.
  1955. @end deffn
  1956. @subsection Functions
  1957. @deffn {Procedure} func? obj
  1958. Return @code{#t} if @var{obj} is a function.
  1959. @end deffn
  1960. @deffn {Procedure} func-id func
  1961. Return the symbolic ID of @var{func}.
  1962. @end deffn
  1963. @deffn {Procedure} func-type func
  1964. Return the signature of @var{func}.
  1965. @end deffn
  1966. @deffn {Procedure} func-locals func
  1967. Return the locals of @var{func}.
  1968. @end deffn
  1969. @deffn {Procedure} func-body func
  1970. Return the body instructions of @var{func}.
  1971. @end deffn
  1972. The type of a function is its signature. Notably, Wasm supports
  1973. multiple return values, just like Scheme.
  1974. @deffn {Procedure} func-sig? obj
  1975. Return @code{#t} if @var{obj} is a function signature.
  1976. @end deffn
  1977. @deffn {Procedure} func-sig-params func
  1978. Return the parameters of @var{func}.
  1979. @end deffn
  1980. @deffn {Procedure} func-sig-results func
  1981. Return the result types of @var{func}.
  1982. @end deffn
  1983. Function parameters pair a local identifier with its type.
  1984. @deffn {Procedure} param? obj
  1985. Return @code{#t} if @var{obj} is a param.
  1986. @end deffn
  1987. @deffn {Procedure} param-id param
  1988. Return the symbolic ID of @var{param}.
  1989. @end deffn
  1990. @deffn {Procedure} param-type param
  1991. Return the type descriptor of @var{param}.
  1992. @end deffn
  1993. Locals provide additional mutable variables scoped to the body of a
  1994. function.
  1995. @deffn {Procedure} local? obj
  1996. Return @code{#t} if @var{obj} is a function local.
  1997. @end deffn
  1998. @deffn {Procedure} local-id local
  1999. Return the symbolic ID of @var{local}.
  2000. @end deffn
  2001. @deffn {Procedure} local-type local
  2002. Return the type descriptor of @var{local}.
  2003. @end deffn
  2004. @subsection Imports/exports
  2005. Functions, globals, memories, and tables can be imported from the host
  2006. or another Wasm module. They are organized into a two layer
  2007. hierarchy. An import module groups many imports under an umbrella
  2008. name, and then the individual item names distinguish imported data
  2009. within a module.
  2010. @deffn {Procedure} import? obj
  2011. Return @code{#t} if @var{obj} is an import.
  2012. @end deffn
  2013. @deffn {Procedure} import-mod import
  2014. Return the module name string of @var{import}.
  2015. @end deffn
  2016. @deffn {Procedure} import-name import
  2017. Return the name string of @var{import}.
  2018. @end deffn
  2019. @deffn {Procedure} import-kind import
  2020. Return the kind of @var{import}. Either @code{func}, @code{global},
  2021. @code{memory}, or @code{table}.
  2022. @end deffn
  2023. @deffn {Procedure} import-id import
  2024. Return the symbolic ID of @var{import}.
  2025. @end deffn
  2026. @deffn {Procedure} import-type import
  2027. Return the type descriptor of @var{import}.
  2028. @end deffn
  2029. Likewise, functions, globals, memories, and tables can be exported
  2030. from a module to be used by the host or by other modules.
  2031. @deffn {Procedure} export? obj
  2032. Return @code{#t} if @var{obj} is an export.
  2033. @end deffn
  2034. @deffn {Procedure} export-name export
  2035. Return the name string of @var{export}.
  2036. @end deffn
  2037. @deffn {Procedure} export-kind export
  2038. Return the kind of @var{export}. Either @code{func}, @code{global},
  2039. @code{memory}, or @code{table}.
  2040. @end deffn
  2041. @deffn {Procedure} export-idx export
  2042. Return the index of @var{export}.
  2043. @end deffn
  2044. @subsection Linear memory
  2045. Memory objects specify linear chunks of bytes that a module can write
  2046. to/read from at runtime. The size of a memory is specified in terms
  2047. of 64KiB pages. While many memory objects coud be included in a
  2048. module, the Wasm specification currently only allows the use of a
  2049. single memory at index 0.
  2050. @deffn {Procedure} memory? obj
  2051. Return @code{#t} if @var{obj} is a memory.
  2052. @end deffn
  2053. @deffn {Procedure} memory-id memory
  2054. Return the symbolic ID of @var{memory}.
  2055. @end deffn
  2056. The type of a memory currently just specifies the size limitations.
  2057. @deffn {Procedure} memory-type memory
  2058. Return the type of @var{memory}.
  2059. @end deffn
  2060. @deffn {Procedure} mem-type? obj
  2061. Return @code{#t} if @var{obj} is a memory type.
  2062. @end deffn
  2063. @deffn {Procedure} mem-type-limits mem-type
  2064. Return the limits of @var{mem-type}.
  2065. @end deffn
  2066. Instructions that manipulate linear memory use the memory argument
  2067. type to point to a specific offset within a memory.
  2068. @deffn {Procedure} mem-arg? obj
  2069. Return @code{#t} if @var{obj} is a memory argument.
  2070. @end deffn
  2071. @deffn {Procedure} mem-arg-id mem-arg
  2072. Return the symbolic ID of @var{mem-arg}.
  2073. @end deffn
  2074. @deffn {Procedure} mem-arg-offset mem-arg
  2075. Return the offset of @var{mem-arg}.
  2076. @end deffn
  2077. @deffn {Procedure} mem-arg-align mem-arg
  2078. Return the alignment of @var{mem-arg}.
  2079. @end deffn
  2080. @subsection Data segments
  2081. Data segments are static chunks of data used to initialize regions of
  2082. memory. They have two possible modes of use:
  2083. @enumerate
  2084. @item @strong{Active:}
  2085. The data segment is copied into memory during instantiation.
  2086. @item @strong{Passive:}
  2087. The data segment is copied into memory using the @code{memory.init}
  2088. instruction.
  2089. @end enumerate
  2090. @deffn {Procedure} data? obj
  2091. Return @code{#t} if @var{obj} is a data segment.
  2092. @end deffn
  2093. @deffn {Procedure} data-id data
  2094. Return the symbolic ID of @var{data}.
  2095. @end deffn
  2096. @deffn {Procedure} data-mode data
  2097. Return the mode of @var{data}. Either @code{passive} or
  2098. @code{active}.
  2099. @end deffn
  2100. @deffn {Procedure} data-mem data
  2101. Return the memory associated with @var{data}.
  2102. @end deffn
  2103. @deffn {Procedure} data-offset data
  2104. Return the instructions that compute the offset of @var{data}. Only
  2105. constant instructions are allowed.
  2106. @end deffn
  2107. @deffn {Procedure} data-init data
  2108. Return a bytevector containing the initialization data of @var{data}.
  2109. @end deffn
  2110. @subsection Tables
  2111. Tables specify a vector of heap object references of a particular
  2112. reference type.
  2113. @deffn {Procedure} table? obj
  2114. Return @code{#t} if @var{obj} is a reference table.
  2115. @end deffn
  2116. @deffn {Procedure} table-id table
  2117. Return the symbolic ID of @var{table}.
  2118. @end deffn
  2119. @deffn {Procedure} table-type table
  2120. Return the type of @var{table}.
  2121. @end deffn
  2122. Table types specify the reference type of the elements as well as the
  2123. size limitations.
  2124. @deffn {Procedure} table-type? obj
  2125. Return @code{#t} if @var{obj} is a table type.
  2126. @end deffn
  2127. @deffn {Procedure} table-type-limits table-type
  2128. Return the limts of @var{table-type}.
  2129. @end deffn
  2130. @deffn {Procedure} table-type-elem-type table-type
  2131. Return the element type of @var{table-type}.
  2132. @end deffn
  2133. @subsection Element segments
  2134. Element segments are static vectors of references used to initialize
  2135. regions of tables (well, mostly.) They have three possible modes of
  2136. use:
  2137. @enumerate
  2138. @item @strong{Active:}
  2139. The element segment is copied into its associated table during
  2140. instantiation.
  2141. @item @strong{Passive:}
  2142. The element segment is copied into its associated table using the
  2143. @code{table.init} instruction.
  2144. @item @strong{Declarative:}
  2145. The element segment is unavailable at runtime and is instead used for
  2146. forward declarations of types that are used elsewhere in the code.
  2147. @end enumerate
  2148. @deffn {Procedure} elem? obj
  2149. Return @code{#t} if @var{obj} is an element segment.
  2150. @end deffn
  2151. @deffn {Procedure} elem-id elem
  2152. Return the symoblic ID of @var{elem}.
  2153. @end deffn
  2154. @deffn {Procedure} elem-mode elem
  2155. Return the mode of @var{elem}.
  2156. @end deffn
  2157. @deffn {Procedure} elem-table elem
  2158. Return the table associated with @var{elem}.
  2159. @end deffn
  2160. @deffn {Procedure} elem-type elem
  2161. Return the type of @var{elem}.
  2162. @end deffn
  2163. @deffn {Procedure} elem-offset elem
  2164. Return the instructions that compute the offset of @var{elem}. Only
  2165. constant instructions are allowed.
  2166. @end deffn
  2167. @deffn {Procedure} elem-inits elem
  2168. Return a list of initializer instructions for the items of @var{elem}.
  2169. Only constant instructions are allowed.
  2170. @end deffn
  2171. @subsection Limits
  2172. Both memories and tables use limits to constrain their minimum and
  2173. maximum size. A valid limit must have a minimum of at least 1, but
  2174. the maximum may be @code{#f} if unbounded growth is allowed.
  2175. @deffn {Procedure} limits? obj
  2176. Return @code{#t} if @var{obj} is a limits.
  2177. @end deffn
  2178. @deffn {Procedure} limits-min limits
  2179. Return the minimum value of @var{limits}.
  2180. @end deffn
  2181. @deffn {Procedure} limits-max limits
  2182. Return the maximum value of @var{limits} or @code{#f} if there is no
  2183. maximum.
  2184. @end deffn
  2185. @subsection Tags
  2186. Tag segments specify types of runtime errors that may be raised.
  2187. @deffn {Procedure} tag? obj
  2188. Return @code{#t} if @var{obj} is a tag.
  2189. @end deffn
  2190. @deffn {Procedure} tag-id tag
  2191. Return the symbolic ID of @var{tag}.
  2192. @end deffn
  2193. @deffn {Procedure} tag-type tag
  2194. Return the type of @var{tag}.
  2195. @end deffn
  2196. Tag types specify the function signature of the tags. Since tags are
  2197. not truly functions, their signatures must only have parameters and no
  2198. results.
  2199. @deffn {Procedure} tag-type? obj
  2200. Return @code{#t} if @var{obj} is a tag type.
  2201. @end deffn
  2202. @deffn {Procedure} tag-type-attribute tag-type
  2203. Return the symbolic attribute of @var{tag-type}. Currently, there is
  2204. only one valid attribute: @code{exception}.
  2205. @end deffn
  2206. @deffn {Procedure} tag-type-type tag-type
  2207. Return the type of @var{tag-type}. This is expected to be a type use
  2208. object that refers to a function signature.
  2209. @end deffn
  2210. @subsection Custom sections
  2211. Custom sections specify arbitrary data that is not covered by the Wasm
  2212. specification.
  2213. @deffn {Procedure} custom? obj
  2214. Return @code{#t} if @var{obj} is a custom segment.
  2215. @end deffn
  2216. @deffn {Procedure} custom-name custom
  2217. Return the name of @var{custom}.
  2218. @end deffn
  2219. @deffn {Procedure} custom-bytes custom
  2220. Return the bytevector of @var{custom}.
  2221. @end deffn
  2222. There is, however, one custom section that @emph{is} specified: the
  2223. name section. This section contains various ``name maps'' that can be
  2224. used to translate integer identifiers to (hopefully) human-readable
  2225. names for the purposes of debugging.
  2226. Hoot supports the name subsections described in the Wasm core
  2227. specification, the Wasm GC specification, and the extended names
  2228. proposal:
  2229. @enumerate
  2230. @item Module name
  2231. @item Function name map
  2232. @item Function local indirect name map
  2233. @item Block label indirect name map
  2234. @item Type name map
  2235. @item Table name map
  2236. @item Memory name map
  2237. @item Global name map
  2238. @item Element name map
  2239. @item Data name map
  2240. @item Struct field indirect name map
  2241. @item Tag name map
  2242. @end enumerate
  2243. Name maps are represented as association lists mapping integers to
  2244. strings. Indirect name maps are represented as association lists
  2245. mapping integers to name maps.
  2246. @deffn {Procedure} names? obj
  2247. Return @code{#t} if @var{obj} is a name section object.
  2248. @end deffn
  2249. @deffn {Procedure} names-module names
  2250. Return the module name of @var{names}.
  2251. @end deffn
  2252. @deffn {Procedure} names-func names
  2253. Return the function name map of @var{names}.
  2254. @end deffn
  2255. @deffn {Procedure} names-local names
  2256. Return the function local indirect name map of @var{names}.
  2257. @end deffn
  2258. @deffn {Procedure} names-label names
  2259. Return the block label indirect name map of @var{names}.
  2260. @end deffn
  2261. @deffn {Procedure} names-type names
  2262. Return the type name map of @var{names}.
  2263. @end deffn
  2264. @deffn {Procedure} names-table names
  2265. Return the table name map of @var{names}.
  2266. @end deffn
  2267. @deffn {Procedure} names-memory names
  2268. Return the memory name map of @var{names}.
  2269. @end deffn
  2270. @deffn {Procedure} names-global names
  2271. Return the global name map of @var{names}.
  2272. @end deffn
  2273. @deffn {Procedure} names-elem names
  2274. Return the element name map of @var{names}.
  2275. @end deffn
  2276. @deffn {Procedure} names-data names
  2277. Return the data name map of @var{names}.
  2278. @end deffn
  2279. @deffn {Procedure} names-fields names
  2280. Return the struct field indirect name map of @var{names}.
  2281. @end deffn
  2282. @deffn {Procedure} names-tag names
  2283. Return the tag name map of @var{names}.
  2284. @end deffn
  2285. @node GWAT
  2286. @section GWAT
  2287. The @code{(wasm wat)} module provides a parser for a variant of
  2288. WebAssembly Text (WAT) format. Since the WAT uses an s-expression
  2289. syntax that resembles but is distinct from Scheme syntax, Hoot opts to
  2290. represent WAT code as Scheme expressions. This allows for embedding
  2291. WAT directly into Scheme code and programmatically generating WAT code
  2292. via quasiquote templating or other means. We call this variant GWAT
  2293. where the ``G'' stands for ``Guile'', of course.
  2294. The GWAT form has some additional expressive power such as allowing
  2295. string constants, bytevectors for data segments, and i32/i64 constants
  2296. in either the signed or unsigned range.
  2297. WAT has two variants: unfolded and folded. In the unfolded form,
  2298. instruction sequences are linear, as they would be in the resulting
  2299. binary:
  2300. @lisp
  2301. '(module
  2302. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2303. (local.get $a)
  2304. (local.get $b)
  2305. (i32.add)))
  2306. @end lisp
  2307. The folded form allows instructions to be nested within each other:
  2308. @lisp
  2309. '(module
  2310. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2311. (i32.add (local.get $a)
  2312. (local.get $b))))
  2313. @end lisp
  2314. This form looks more like Scheme procedure calls and is generally
  2315. easier to write and reason about.
  2316. @deffn {Procedure} wat->wasm expr
  2317. Parse @var{expr}, a Wasm module expressed as WAT code, and return a
  2318. Wasm module.
  2319. @lisp
  2320. (parse-wat
  2321. '(module
  2322. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2323. (i32.add (local.get $a)
  2324. (local.get $b)))))
  2325. @end lisp
  2326. The returned Wasm module preserves named references, among other
  2327. things, and is thus unsuitable as input to the assembler or
  2328. interpreter. To lower the module into a usable form, see
  2329. @code{resolve-wasm} in @ref{Resolver}.
  2330. @end deffn
  2331. @deffn {Procedure} wasm->wat wasm
  2332. Disassemble @var{wasm} and return its symbolic WAT form.
  2333. @end deffn
  2334. @node Resolver
  2335. @section Resolver
  2336. The @code{(wasm resolve)} module provides the @code{resolve-wasm}
  2337. procedure which lowers Wasm modules into a form that can be used by
  2338. the assembler or interpreter. The resolver replaces named references
  2339. with their respective integer identifiers, fills out the type table,
  2340. and adjusts i32 and i64 constants into their canonical form.
  2341. @deffn {Procedure} resolve-wasm mod [#:emit-names? #f]
  2342. Lower the Wasm module @var{mod} into a form that can be assembled or
  2343. interpreted. Returns a new Wasm module and does not modify @var{mod}.
  2344. When @var{emit-names?} is @code{#t}, the returned Wasm module will
  2345. include a name map that maps the original, human-readable names to the
  2346. resolved integer identifiers.
  2347. @end deffn
  2348. @node Linker
  2349. @section Linker
  2350. The @code{(wasm link)} module provides a means for extending a Wasm
  2351. module with the standard library that it needs at runtime. Hoot uses
  2352. the linker to add the Scheme runtime to the compiled form of user
  2353. code. The linker uses a form of tree-shaking to remove anything that
  2354. is not used by the base module.
  2355. @deffn {Procedure} add-stdlib wasm stdlib
  2356. Return a new Wasm module that is the combination of the Wasm module
  2357. @var{wasm} with the Wasm module @var{stdlib}.
  2358. @end deffn
  2359. @node Assembler
  2360. @section Assembler
  2361. The @code{(wasm assemble)} module is used to lower Wasm modules into
  2362. the Wasm binary format.
  2363. @deffn {Procedure} assemble-wasm wasm
  2364. Return a bytevector containing the assembled binary form of the Wasm
  2365. module @var{wasm}.
  2366. @end deffn
  2367. @node Binary Parser
  2368. @section Binary Parser
  2369. The @code{(wasm parse)} module parses the Wasm binary format.
  2370. @deffn {Procedure} parse-wasm port
  2371. Parse the Wasm binary data from @var{port} and return a Wasm module.
  2372. @end deffn
  2373. @node Printer
  2374. @section Printer
  2375. The @code{(wasm dump)} module provides the @code{dump-wasm} procedure
  2376. for generating a detailed print-out of a Wasm module's contents. See
  2377. also @ref{Low-level development tools} for the @code{wasm-dump} REPL
  2378. command.
  2379. @deffn {Procedure} dump-wasm mod [#:port] [#:dump-func-defs? #t]
  2380. Write a detailed inventory of the Wasm module @var{mod} to @var{port}
  2381. or the current output port if @var{port} is not specified. If
  2382. @var{dump-func-defs?} is @code{#t}, which is the default, all function
  2383. definitions are printed, including the instructions in the body of
  2384. each. Depending on the size of the module, this may be an
  2385. overwhelming amount of data, thus it is made optional.
  2386. @end deffn
  2387. @node Interpreter
  2388. @section Interpreter
  2389. The @code{(wasm vm)} module provides a virtual machine for
  2390. interpreting Wasm functions. To use the interpreter, a Wasm module is
  2391. first validated for type safety (among other things) and then
  2392. instantiated, at which point exported functions become callable from
  2393. Scheme.
  2394. The interpreter only accepts validated Wasm. The @code{validate-wasm}
  2395. procedure validates and wraps a Wasm module to indicate successful
  2396. validation:
  2397. @lisp
  2398. (use-modules (wasm vm) (wasm resolve))
  2399. (define validated-wasm
  2400. (validate-wasm
  2401. (wat->wasm
  2402. '(module
  2403. (func (export "main") (result i32)
  2404. (i32.const 42))))))
  2405. @end lisp
  2406. When starting with a Wasm binary, the convenient
  2407. @code{load-and-validate-wasm} procedure parses the binary and then
  2408. performs validation:
  2409. @lisp
  2410. (call-with-input-file "hello.wasm" load-and-validate-wasm)
  2411. @end lisp
  2412. Once the Wasm module has been validated, the runtime data needed for
  2413. interpretation can be created by instantiating the module:
  2414. @lisp
  2415. (define instance (instantiate-wasm validated-wasm))
  2416. @end lisp
  2417. Exported Wasm functions then become usable as Scheme procedures:
  2418. @lisp
  2419. (define wasm-main (wasm-instance-export-ref instance "main"))
  2420. (wasm-main) ;; => 42
  2421. @end lisp
  2422. Wasm functions are statically typed, which means that calls from
  2423. Scheme to Wasm require runtime type checking for each call.
  2424. @subsection Validation
  2425. @deffn {Procedure} validate-wasm wasm
  2426. Validate the Wasm module @var{wasm} and return a validated Wasm
  2427. object.
  2428. @end deffn
  2429. @deffn {Procedure} load-and-validate-wasm obj
  2430. Load and validate the Wasm module within @var{obj} then return a
  2431. validated Wasm object. @var{obj} may be a @code{<wasm>} record as
  2432. produced by @code{resolve-wasm} (@pxref{Resolver}), a bytevector
  2433. containing a Wasm binary, or an input port from which to read a Wasm
  2434. binary.
  2435. @end deffn
  2436. @deffn {Procedure} validated-wasm? obj
  2437. Return @code{#t} if @var{obj} is a validated Wasm object.
  2438. @end deffn
  2439. @deffn {Procedure} validated-wasm-ref validated-wasm
  2440. Unbox and return the Wasm module within @var{validated-wasm}.
  2441. @end deffn
  2442. @subsection Instantiation
  2443. @deffn {Procedure} instantiate-wasm wasm [#:imports '()]
  2444. Return a new Wasm instance for the validated Wasm module @var{wasm}.
  2445. @var{imports} is a nested association list of imported functions,
  2446. globals, memories, and tables. Wasm imports are identified by a
  2447. module name and an object name. Consider the following Wasm module
  2448. that computes 2D polar coordinates and prints them to a log:
  2449. @lisp
  2450. (use-modules (wasm resolve) (wasm vm) (wasm wat))
  2451. (define the-module
  2452. (resolve-wasm
  2453. (wat->wasm
  2454. '(module
  2455. (func $logf64 (import "debug" "logf64") (param f64))
  2456. (func $cos (import "math" "cos") (param f64) (result f64))
  2457. (func $sin (import "math" "sin") (param f64) (result f64))
  2458. (func (export "polar") (param $r f64) (param $theta f64)
  2459. (call $logf64 (f64.mul (local.get $r)
  2460. (call $cos (local.get $theta))))
  2461. (call $logf64 (f64.mul (local.get $r)
  2462. (call $sin (local.get $theta)))))))))
  2463. @end lisp
  2464. This module requires three imported functions from two modules. Thus
  2465. the module instantiation code would look like this:
  2466. @lisp
  2467. (define (logf64 x)
  2468. (format #t "f64: ~a\n" x))
  2469. (define the-instance
  2470. (instantiate-wasm (validate-wasm the-module)
  2471. #:imports `(("debug" . (("logf64" . ,logf64)))
  2472. ("math" . (("cos" . ,cos)
  2473. ("sin" . ,sin))))))
  2474. @end lisp
  2475. @end deffn
  2476. @subsection Globals
  2477. @deffn {Procedure} make-wasm-global value mutable?
  2478. Return a new Wasm global containing @var{value}. When @var{mutable?}
  2479. is @code{#f}, the value cannot be modified later.
  2480. @end deffn
  2481. @deffn {Procedure} wasm-global? obj
  2482. Return @code{#t} if @var{obj} is a Wasm global.
  2483. @end deffn
  2484. @deffn {Procedure} wasm-global-ref global
  2485. Return the current value within @var{global}.
  2486. @end deffn
  2487. @deffn {Procedure} wasm-global-set! global val
  2488. Set the value within @var{global} to @var{val}. An exception is
  2489. raised if @var{global} is immutable.
  2490. @end deffn
  2491. @deffn {Procedure} wasm-global-mutable? global
  2492. Return @code{#t} if @var{global} is mutable.
  2493. @end deffn
  2494. @subsection Memories
  2495. @deffn {Procedure} make-wasm-memory size [#:limits (make-limits 1 #f)]
  2496. Return a new Wasm linear memory containing @var{size} 64KiB pages.
  2497. @var{limits} determines the lower and upper bounds of how many pages
  2498. this memory can store. The default limits are a minimum of 1 page and
  2499. no maximum page limit. @xref{Data types} for more information on
  2500. limit objects.
  2501. @end deffn
  2502. @deffn {Procedure} wasm-memory? obj
  2503. Return @code{#t} if @var{obj} is a Wasm memory.
  2504. @end deffn
  2505. @deffn {Procedure} wasm-memory-bytes memory
  2506. Return the current bytevector representing the pages of @var{memory}.
  2507. @end deffn
  2508. @deffn {Procedure} wasm-memory-size memory
  2509. Return the size of @var{memory} in 64KiB pages.
  2510. @end deffn
  2511. @deffn {Procedure} wasm-memory-limits memory
  2512. Return the limits of @var{memory}
  2513. @end deffn
  2514. @deffn {Procedure} wasm-memory-grow! memory n
  2515. Increase the size of @var{memory} by @var{n} pages. An exception is
  2516. raised if growing by @var{n} exceeds the limits of @var{memory}.
  2517. @end deffn
  2518. @subsection Tables
  2519. @deffn {Procedure} make-wasm-table size [#:limits (make-limits 1 #f)]
  2520. Return a new Wasm reference table containing @var{size} element slots.
  2521. @var{limits} determines the lower and upper bounds of how many
  2522. elements this table can store. The default limits are a minimum of 1
  2523. element and no maximum element limit. @xref{Data types} for more
  2524. information on limit objects.
  2525. @end deffn
  2526. @deffn {Procedure} wasm-table?
  2527. Return @code{#t} if @var{obj} is a Wasm table.
  2528. @end deffn
  2529. @deffn {Procedure} wasm-table-size table
  2530. Return the size of @var{table}.
  2531. @end deffn
  2532. @deffn {Procedure} wasm-table-ref table i
  2533. Return the reference at the @var{i}th index in @var{table}.
  2534. @end deffn
  2535. @deffn {Procedure} wasm-table-set! table i x
  2536. Set the @var{i}th element of @var{table} to @var{x}, a Wasm reference
  2537. type.
  2538. @end deffn
  2539. @deffn {Procedure} wasm-table-fill! table start fill length
  2540. Fill the elements of @var{table} from @var{start} to @var{start} +
  2541. @var{length}, exclusive, with the value @var{fill}.
  2542. @end deffn
  2543. @deffn {Procedure} wasm-table-copy! table at elems start length
  2544. Copy the block of elements from vector @var{elems}, from @var{start}
  2545. to @var{start} + @var{length}, exclusive, to @var{table}, starting at
  2546. @var{at}.
  2547. @end deffn
  2548. @deffn {Procedure} wasm-table-grow! table n init
  2549. Increase the size of @var{table} by @var{n} elements. An exception is
  2550. raised if growing by @var{n} exceeds the limits of @var{table}.
  2551. @end deffn
  2552. @subsection Observation
  2553. Every Wasm instruction evaluated by interpreter can be observed via
  2554. the @code{current-instruction-listener} parameter. Use this hook to
  2555. instrument Wasm modules.
  2556. The following instruction listener would print every instruction's
  2557. name on a separate line:
  2558. @lisp
  2559. (define (log-instr instr path instance stack blocks locals)
  2560. (display (car instr))
  2561. (newline))
  2562. (parameterize ((current-instruction-listener log-instr))
  2563. ...)
  2564. @end lisp
  2565. @defvar current-instruction-listener
  2566. The current instruction observation hook which is invoked
  2567. @emph{before} each instruction evaluation. Must be a procedure that
  2568. accepts the following arguments:
  2569. @enumerate
  2570. @item @strong{Instruction:}
  2571. The symbolic Wasm instruction to be evaluated.
  2572. @item @strong{Path:}
  2573. The symbolic location of the instruction within the Wasm module.
  2574. @item @strong{Instance:}
  2575. The instance that is evaluating the instruction.
  2576. @item @strong{Stack:}
  2577. The Wasm value stack.
  2578. @item @strong{Blocks:}
  2579. The Wasm block stack, which is just a list of prompt tags.
  2580. @item @strong{Locals:}
  2581. The Wasm function locals.
  2582. @end enumerate
  2583. @end defvar
  2584. The Wasm value stack is a special data type with the following API:
  2585. @deffn {Procedure} wasm-stack? obj
  2586. Return @code{#t} if @var{obj} is a Wasm value stack.
  2587. @end deffn
  2588. @deffn {Procedure} wasm-stack-items stack
  2589. Return the values on @var{stack} as a list.
  2590. @end deffn
  2591. @node Contributing
  2592. @chapter Contributing
  2593. Found a bug? Let us know! Made an improvement? Show us! Issues can
  2594. be filed and pull requests can be submitted on
  2595. @url{https://gitlab.com/spritely/guile-hoot,GitLab}.
  2596. @node License
  2597. @chapter License
  2598. @emph{(C) 2023 David Thompson}
  2599. @emph{Both Guile Hoot and this manual are released under the terms of
  2600. the following license:}
  2601. @include apache-2.0.texi
  2602. @node Index
  2603. @unnumbered Index
  2604. @printindex fn
  2605. @bye