hoot.texi 116 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831
  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 either @url{https://nodejs.org,NodeJS} (version 22+)
  199. or @url{https://v8.dev/,V8} via the @command{d8} tool.
  200. Getting V8 can be tricky, and will most likely require you to
  201. @url{https://v8.dev/docs/build,compile it from source.} It's a pain!
  202. To skip all of that trouble and just run the tests against the
  203. built-in interpreter, run:
  204. @example
  205. make check WASM_HOST=hoot
  206. @end example
  207. @node Tutorial
  208. @section Tutorial
  209. Let's compile some simple Scheme programs and learn how to work with
  210. their compiled Wasm forms.
  211. As we all know, the Answer to the Great and Ultimate Question, of
  212. Life, the Universe, and Everything is simply 42. So, we should make
  213. sure that we can compile 42 to Wasm. To do so, import the @code{(hoot
  214. compile)} module and call the @code{compile} procedure.
  215. @lisp
  216. @verbatim
  217. scheme@(guile-user)> ,use (hoot compile)
  218. scheme@(guile-user)> (define the-answer (compile 42))
  219. @end verbatim
  220. @end lisp
  221. The result is a Wasm module. There is a lot of stuff inside, but
  222. we're not going to focus on that right now. We should load and run
  223. the module to verify that it outputs 42 like we expect. We can do so
  224. from the comfort of our Guile REPL because Hoot includes a Wasm
  225. interpreter. There's no need to use a web browser or other Wasm
  226. runtime to try out small programs.
  227. First, import the @code{(hoot reflect)} module. Then, instantiate
  228. @code{the-answer} to load it into the Wasm interpreter:
  229. @lisp
  230. @verbatim
  231. scheme@(guile-user)> ,use (hoot reflect)
  232. scheme@(guile-user)> (define instance (hoot-instantiate the-answer))
  233. @end verbatim
  234. @end lisp
  235. All that's left to do now is execute the program with
  236. @code{hoot-load}:
  237. @lisp
  238. @verbatim
  239. scheme@(guile-user)> (hoot-load instance)
  240. $5 = 42
  241. @end verbatim
  242. @end lisp
  243. Ta-da! It feels kind of funny to compile a Scheme program to Wasm
  244. only to load it back into Scheme, but it's a quick and easy way to
  245. test things out.
  246. For cases when you simply want to compile an expression and see the
  247. result immediately, there is a faster method. Just use the
  248. @code{compile-value} procedure instead:
  249. @lisp
  250. @verbatim
  251. scheme@(guile-user)> (compile-value '(list 1 2 3))
  252. $6 = #<hoot (1 2 3)>
  253. @end verbatim
  254. @end lisp
  255. With @code{compile-value}, the compiled Wasm module is thrown away,
  256. which is just fine for testing throwaway code.
  257. Lists are cool and 42 is ultimately the answer to everything, but it
  258. would be a shame if we didn't talk about compiling something a little
  259. more complicated. Let's compile a simple, tail-recursive procedure!
  260. How about good ol' factorial?
  261. @lisp
  262. @verbatim
  263. scheme@(guile-user)> (define hoot-factorial
  264. (compile-value
  265. '(let ()
  266. (define (factorial x result)
  267. (if (= x 1)
  268. result
  269. (factorial (- x 1)
  270. (* result x))))
  271. factorial)))
  272. @end verbatim
  273. @end lisp
  274. A Hoot procedure can be called just like a regular procedure:
  275. @lisp
  276. @verbatim
  277. scheme@(guile-user)> (hoot-factorial 5 1)
  278. $7 = 120
  279. @end verbatim
  280. @end lisp
  281. The Hoot reflection in Guile is great for quickly iterating on code,
  282. but what we really want is to get our programs running in a web
  283. browser. We've compiled a couple of things to Wasm now, but the
  284. resulting modules have stayed within the confines of the Guile
  285. process. To make something that can be loaded by a web browser, we
  286. need to use the assembler to create a Wasm binary:
  287. @lisp
  288. @verbatim
  289. scheme@(guile-user)> (define hello (compile "Hello, world!"))
  290. scheme@(guile-user)> ,use (wasm assemble)
  291. scheme@(guile-user)> (define bin (assemble-wasm hello))
  292. @end verbatim
  293. @end lisp
  294. Now, create a new directory for this tutorial:
  295. @example
  296. mkdir hoot-tutorial
  297. @end example
  298. Write the binary to disk in that directory:
  299. @lisp
  300. @verbatim
  301. scheme@(guile-user)> ,use (ice-9 binary-ports)
  302. scheme@(guile-user)> (call-with-output-file "/path/to/hoot-tutorial/hello.wasm"
  303. (lambda (port)
  304. (put-bytevector port bin)))
  305. @end verbatim
  306. @end lisp
  307. To inspect Scheme values from JavaScript, Hoot provides the
  308. @file{reflect-js/reflect.js} library. Copy that file and its
  309. associated Wasm helper modules, @file{reflect-wasm/reflect.wasm} and
  310. @file{reflect-wasm/wtf8.wasm}, to the @file{hoot-tutorial} directory:
  311. @example
  312. cd /path/to/hoot-tutorial
  313. cp /path/to/guile-hoot/reflect-js/reflect.js .
  314. cp /path/to/guile-hoot/reflect-wasm/reflect.wasm .
  315. cp /path/to/guile-hoot/reflect-wasm/wtf8.wasm .
  316. @end example
  317. To run @file{hello.wasm}, we need a little JavaScript glue code.
  318. Let's call this @file{hello.js}:
  319. @example
  320. @verbatim
  321. async function load() {
  322. const [message] = await Scheme.load_main("hello.wasm");
  323. console.log(message);
  324. }
  325. window.addEventListener("load", load);
  326. @end verbatim
  327. @end example
  328. We also need a minimal @file{index.html} web page to bring it all
  329. together:
  330. @example
  331. <!DOCTYPE html>
  332. <html>
  333. <head>
  334. <script type="text/javascript" src="reflect.js"></script>
  335. <script type="text/javascript" src="hello.js"></script>
  336. </head>
  337. <body>
  338. Guile is a hoot!
  339. </body>
  340. </html>
  341. @end example
  342. The file tree in @file{hoot-tutorial} should look like this:
  343. @example
  344. ./reflect.js
  345. ./hello.js
  346. ./index.html
  347. ./hello.wasm
  348. ./reflect.wasm
  349. ./wtf8.wasm
  350. @end example
  351. Finally, we need a local web server to serve the files. Fortunately,
  352. Hoot includes a simple web server for development purposes. Start the
  353. web server like so:
  354. @example
  355. guile -c '((@@ (hoot web-server) serve))'
  356. @end example
  357. Visit @url{http://localhost:8088} in your web browser. If it supports
  358. Wasm GC and tail calls then you should see the text ``Hello, world!''
  359. printed in the developer console.
  360. We hope this tutorial has helped you get started with Hoot! Read on
  361. for full API documentation.
  362. @node Compiling to Wasm
  363. @chapter Compiling to Wasm
  364. @menu
  365. * Invoking the compiler:: Compiling Scheme to Wasm.
  366. * Reflection:: Using Hoot modules from the host environment.
  367. * REPL commands:: Compile and run Scheme from the REPL.
  368. @end menu
  369. @node Invoking the compiler
  370. @section Invoking the compiler
  371. In Guile's compiler tower, Scheme code goes through several
  372. transformations before being compiled to VM bytecode. Scheme is
  373. lowered to @inlinefmtifelse{html,
  374. @url{https://www.gnu.org/software/guile/manual/html_node/Tree_002dIL.html,
  375. Tree-IL}, @ref{Tree-IL,,,Guile Reference}}, which is then lowered to
  376. @inlinefmtifelse{html,
  377. @url{https://www.gnu.org/software/guile/manual/html_node/Continuation_002dPassing-Style.html,
  378. Continuation-passing style}, @ref{Continuation-Passing Style,,,Guile
  379. Reference}}(CPS), and then finally to @inlinefmtifelse{html,
  380. @url{https://www.gnu.org/software/guile/manual/html_node/Bytecode.html,
  381. Bytecode}, @ref{Bytecode,,,Guile Reference}}. Hoot adds an additional
  382. backend that compiles CPS to Wasm.
  383. In contrast to Guile's approach of compiling individual modules, Hoot
  384. is a whole-program compiler. The user program and all imported
  385. modules are part of the same compilation unit and the result is a
  386. single Wasm binary. Currently, Hoot uses the R6RS library system and
  387. does not support Guile's @code{define-module} form or R7RS style
  388. libraries.
  389. For hooking the Hoot compiler up to a build system such as GNU Make,
  390. invoke the @command{guild compile-wasm} tool:
  391. @example
  392. guild compile-wasm --load-path=. --output=foo.wasm foo.scm
  393. @end example
  394. Like Guile's built-in compiler, the Hoot compiler can also be invoked
  395. within Scheme. The @code{(hoot compile)} module provides the
  396. interface to the Wasm compiler backend.
  397. @deffn {Procedure} compile exp [#:import-abi? #f] [#:export-abi? #t] @
  398. [#:imports %default-program-imports] @
  399. [#:include-file %include-from-path] @
  400. [#:extend-load-library (lambda (f) f)] @
  401. [#:load-library (extend-load-library (builtin-module-loader import-abi?))] @
  402. [#:optimization-level (default-optimization-level)] @
  403. [#:warning-level (default-warning-level)] @
  404. [#:dump-cps? #f] [#:dump-wasm? #f] [#:emit-names? #f] @
  405. [#:opts '()]
  406. Compile the Scheme expression @var{exp} to Wasm and return a Wasm
  407. module.
  408. The environment in which @var{exp} is evaluated is defined by
  409. @var{imports}, a list of module names such as @code{(scheme time)} or
  410. @code{(hoot ffi)}. If not specified, a default list of imports will
  411. be used.
  412. When @var{import-abi?} is @code{#t}, the Wasm module will be built
  413. such that it needs to import its ABI from another module. When
  414. @var{export-abi?} is @code{#t}, the Wasm module will be built such
  415. that it exports its ABI functions. A typical use of these flags is to
  416. export the ABI from one ``main'' module and then import that ABI into
  417. any additional modules that are being used.
  418. When @var{emit-names?} is @code{#t} then human-readable names will be
  419. embedded in the resulting Wasm object. By default, this is turned off
  420. as it greatly increases binary size.
  421. Associating module names with source code is handled by
  422. @var{load-library}, a procedure that receives the module name as its
  423. only argument and returns the source code as an s-expression, or
  424. @code{#f} if there is no such module. The default loader is capable
  425. of loading modules from Hoot's standard library. It is generally
  426. recommended to leave @var{load-library} alone and use the default.
  427. To load additional modules, specify @var{extend-load-library} instead.
  428. @var{extend-load-library} is a procedure that receives one argument,
  429. @var{load-library}, and returns a procedure with the same signature as
  430. @var{load-library}. Through this extension mechanism, users can load
  431. their own modules.
  432. Most of the time, loading user modules from the file system is all
  433. that is needed. Hoot has a built-in
  434. @code{library-load-path-extension} extension procedure for this
  435. purpose. To demonstrate, let's first assume that the code below is
  436. saved to @file{example.scm} in the current directory:
  437. @lisp
  438. (library (example)
  439. (export double)
  440. (import (scheme base))
  441. (define (double x) (* x 2)))
  442. @end lisp
  443. The compiler can then be extended to load modules from the current
  444. directory like so:
  445. @lisp
  446. (compile '(double 42)
  447. #:imports '((scheme base) (example))
  448. #:extend-load-library
  449. (library-load-path-extension '(".")))
  450. @end lisp
  451. @inlinefmtifelse{html,
  452. @url{https://www.gnu.org/software/guile/manual/html_node/Compilation.html,
  453. See the Guile manual}, @xref{Compiling Scheme Code,,,Guile Reference}}
  454. for more information about invoking Guile's compiler.
  455. @end deffn
  456. @deffn {Procedure} read-and-compile port [#:import-abi? #f] [#:export-abi? #t] @
  457. [#:include-file %include-from-path] @
  458. [#:extend-load-library (lambda (f) f)] @
  459. [#:load-library (extend-load-library (builtin-module-loader import-abi?))] @
  460. [#:optimization-level (default-optimization-level)] @
  461. [#:warning-level (default-warning-level)] @
  462. [#:dump-cps? #f] [#:dump-wasm? #f] [#:emit-names? #f] @
  463. [#:opts '()]
  464. Like @code{compile}, but read Scheme expressions from @var{port}.
  465. If the first expression is an @code{import} form, then only the
  466. bindings from those modules will be imported into the compilation
  467. unit. If the @code{import} form is omitted, a default set of modules
  468. will be imported. It is highly recommended to be explicit and use
  469. @code{import}.
  470. @end deffn
  471. @deffn {Procedure} compile-file input-file [#:import-abi? #f] [#:export-abi? #t] @
  472. [#:include-file %include-from-path] @
  473. [#:extend-load-library (lambda (f) f)] @
  474. [#:load-library (extend-load-library (builtin-module-loader import-abi?))] @
  475. [#:optimization-level (default-optimization-level)] @
  476. [#:warning-level (default-warning-level)] @
  477. [#:dump-cps? #f] [#:dump-wasm? #f] [#:emit-names? #f] @
  478. [#:opts '()]
  479. Like @code{read-and-compile}, but read the Scheme expression from
  480. @var{input-file}.
  481. @end deffn
  482. @node Reflection
  483. @section Reflection
  484. The @code{(hoot reflect)} module provides an interface for inspecting
  485. and manipulating Scheme values that live within Wasm modules. This is
  486. the primary interface for testing compiler output directly from Guile.
  487. @deffn {Procedure} hoot-instantiate scheme-wasm [imports '()] [reflector]
  488. Instantiate and return a new Hoot module using the compiled Scheme
  489. Wasm module @var{scheme-wasm} and the reflection module
  490. @var{reflector}. If @var{reflector} is not specified, a new reflector
  491. instance will be created.
  492. Optionally, @var{imports} may contain a 2-tier association list
  493. structure of imported functions, globals, tables, and memories:
  494. @lisp
  495. `(("math" . (("random" . ,(lambda (x) (random x))))))
  496. @end lisp
  497. @end deffn
  498. @deffn {Procedure} hoot-load module
  499. Invoke the load thunk of @var{module} and return the reflected
  500. result values.
  501. @end deffn
  502. The following procedures, @code{compile-value} and
  503. @code{compile-call}, are convenience procedures for when you just want
  504. to quickly compile something and see the result and you don't care
  505. about the intermediary Wasm binary.
  506. @deffn {Procedure} compile-value exp [imports %default-program-imports] @
  507. [load-path '()] [wasm-imports '()]
  508. Compile @var{exp} and return the result.
  509. Optionally, @var{imports} may specify a list of Scheme module names to
  510. import. If unspecified, a default set of modules providing a basic
  511. Scheme environment will be imported. @var{load-path} is a list of
  512. file system directories to search for additional user modules.
  513. Optionally, @var{wasm-imports} may contain a 2-tier association list
  514. structure of imported Wasm functions, globals, tables, and memories.
  515. See @code{hoot-instantiate} for an example of such a structure.
  516. @end deffn
  517. @deffn {Procedure} compile-call proc-exp arg-exps ... @
  518. [imports %default-program-imports] @
  519. [load-path '()] [wasm-imports '()]
  520. Compile @var{proc-exp} and all @var{arg-exps}, call the procedure with
  521. the arguments, then return the results.
  522. See @code{compile-value} for an explanation of the keyword arguments.
  523. @end deffn
  524. @deffn {Procedure} hoot-module? obj
  525. Return @code{#t} if @var{obj} is a Hoot module.
  526. @end deffn
  527. @deffn {Procedure} hoot-module-reflector module
  528. Return the reflection module for @var{module}.
  529. @end deffn
  530. @deffn {Procedure} hoot-module-instance module
  531. Return the Wasm instance for @var{module}.
  532. @end deffn
  533. @deffn {Procedure} reflector? obj
  534. Return @code{#t} if @var{obj} is a reflector.
  535. @end deffn
  536. @deffn {Procedure} reflector-instance reflector
  537. Return the Wasm instance of @var{reflector}.
  538. @end deffn
  539. @deffn {Procedure} reflector-abi reflector
  540. Return the association list of ABI imports for @var{reflector}.
  541. @end deffn
  542. Below are the predicates and accessors for various Hoot heap types:
  543. @deffn {Procedure} hoot-object? obj
  544. Return @code{#t} if @var{obj} is a Hoot object.
  545. @end deffn
  546. @deffn {Procedure} hoot-complex? obj
  547. Return @code{#t} if @var{obj} is a Hoot complex number.
  548. @end deffn
  549. @deffn {Procedure} hoot-complex-real complex
  550. Return the real part of @var{complex}.
  551. @end deffn
  552. @deffn {Procedure} hoot-complex-imag complex
  553. Return the imaginary part of @var{complex}.
  554. @end deffn
  555. @deffn {Procedure} hoot-fraction? obj
  556. Return @code{#t} if @var{obj} is a Hoot fraction.
  557. @end deffn
  558. @deffn {Procedure} hoot-fraction-num fraction
  559. Return the numerator of @var{fraction}
  560. @end deffn
  561. @deffn {Procedure} hoot-fraction-denom fraction
  562. Return the denominator of @var{fraction}.
  563. @end deffn
  564. @deffn {Procedure} hoot-pair? obj
  565. Return @code{#t} if @var{obj} is a Hoot pair.
  566. @end deffn
  567. @deffn {Procedure} mutable-hoot-pair? obj
  568. Return @code{#t} if @var{obj} is a mutable Hoot pair.
  569. @end deffn
  570. @deffn {Procedure} hoot-pair-car pair
  571. Return the first element of @var{pair}.
  572. @end deffn
  573. @deffn {Procedure} hoot-pair-cdr pair
  574. Return the second element of @var{pair}.
  575. @end deffn
  576. @deffn {Procedure} hoot-vector? obj
  577. Return @code{#t} if @var{obj} is a Hoot vector.
  578. @end deffn
  579. @deffn {Procedure} mutable-hoot-vector? obj
  580. Return @code{#t} if @var{obj} is a mutable Hoot vector.
  581. @end deffn
  582. @deffn {Procedure} hoot-vector-length vec
  583. Return the length of @var{vec}.
  584. @end deffn
  585. @deffn {Procedure} hoot-vector-ref vec i
  586. Return the @var{i}th element of @var{vec}.
  587. @end deffn
  588. @deffn {Procedure} hoot-bytevector? obj
  589. Return @code{#t} if @var{obj} is a Hoot bytevector.
  590. @end deffn
  591. @deffn {Procedure} mutable-hoot-bytevector? obj
  592. Return @code{#t} if @var{obj} is a mutable Hoot bytevector.
  593. @end deffn
  594. @deffn {Procedure} hoot-bytevector-length bv
  595. Return the length of @var{bv}.
  596. @end deffn
  597. @deffn {Procedure} hoot-bytevector-ref bv i
  598. Return the @var{i}th byte of @var{bv}.
  599. @end deffn
  600. @deffn {Procedure} hoot-bitvector? obj
  601. Return @code{#t} if @var{obj} is a Hoot bitvector.
  602. @end deffn
  603. @deffn {Procedure} mutable-hoot-bitvector? obj
  604. Return @code{#t} if @var{obj} is a mutable Hoot bitvector.
  605. @end deffn
  606. @deffn {Procedure} hoot-bitvector-length bv
  607. Return the length of @var{bv}.
  608. @end deffn
  609. @deffn {Procedure} hoot-bitvector-ref bv i
  610. Return the @var{i}th bit of @var{bv}.
  611. @end deffn
  612. @deffn {Procedure} hoot-symbol? obj
  613. Return @code{#t} if @var{obj} is a Hoot symbol.
  614. @end deffn
  615. @deffn {Procedure} hoot-symbol-name sym
  616. Return the string name of @var{sym}.
  617. @end deffn
  618. @deffn {Procedure} hoot-keyword? obj
  619. Return @code{#t} if @var{obj} is a Hoot keyword.
  620. @end deffn
  621. @deffn {Procedure} hoot-keyword-name keyword
  622. Return the name string of @var{keyword}.
  623. @end deffn
  624. @deffn {Procedure} mutable-hoot-string? obj
  625. Return @code{#t} if @var{obj} is a mutable Hoot string.
  626. @end deffn
  627. @deffn {Procedure} mutable-hoot-string->string str
  628. Return the underlying string for @var{str}.
  629. @end deffn
  630. @deffn {Procedure} hoot-procedure? obj
  631. Return @code{#t} if @var{obj} is a Hoot procedure.
  632. @end deffn
  633. @deffn {Procedure} hoot-apply proc . args
  634. Apply the Hoot procedure @var{proc} with @var{args}.
  635. @end deffn
  636. @deffn {Procedure} hoot-apply-async proc . args
  637. Apply the Hoot procedure @var{proc} in an asynchronous context.
  638. @var{proc} should be a procedure that accepts two additional arguments
  639. (arguments 0 and 1) in addition to @var{args}:
  640. @itemize
  641. @item @code{resolved}:
  642. An opaque external value representing the successful completion of the
  643. async operation.
  644. @item @code{rejected}:
  645. An opaque external value representing the failure of the async
  646. operation.
  647. @end itemize
  648. You almost certainly want to be using this procedure with
  649. @code{call-with-async-result} in the @code{(fibers promises)} module.
  650. @end deffn
  651. @deffn {Procedure} hoot-variable? obj
  652. Return @code{#t} if @var{obj} is a Hoot variable.
  653. @end deffn
  654. @deffn {Procedure} hoot-atomic-box? obj
  655. Return @code{#t} if @var{obj} is a Hoot atomic box.
  656. @end deffn
  657. @deffn {Procedure} hoot-hash-table? obj
  658. Return @code{#t} if @var{obj} is a Hoot hash table.
  659. @end deffn
  660. @deffn {Procedure} hoot-weak-table? obj
  661. Return @code{#t} if @var{obj} is a Hoot weak table.
  662. @end deffn
  663. @deffn {Procedure} hoot-fluid? obj
  664. Return @code{#t} if @var{obj} is a Hoot fluid.
  665. @end deffn
  666. @deffn {Procedure} hoot-dynamic-state? obj
  667. Return @code{#t} if @var{obj} is a Hoot dynamic state.
  668. @end deffn
  669. @deffn {Procedure} hoot-syntax? obj
  670. Return @code{#t} if @var{obj} is a Hoot syntax object.
  671. @end deffn
  672. @deffn {Procedure} hoot-port? obj
  673. Return @code{#t} if @var{obj} is a Hoot port.
  674. @end deffn
  675. @deffn {Procedure} hoot-struct? obj
  676. Return @code{#t} if @var{obj} is a Hoot struct.
  677. @end deffn
  678. @node REPL commands
  679. @section REPL commands
  680. The @code{(hoot repl)} module provides some REPL meta commands to make
  681. it easy to compile Scheme programs and run them in Hoot's Wasm
  682. interpreter.
  683. @deffn {REPL Command} hoot-compile exp [opts ...]
  684. Compile @var{exp} and return a Wasm module.
  685. @var{opts} may specify the keyword arguments to pass to the
  686. @code{compile} procedure (@pxref{Invoking the compiler}).
  687. @end deffn
  688. @deffn {REPL Command} hoot-compile-file file [opts ...]
  689. Compile the source code in @var{file} and return a Wasm module.
  690. @var{opts} may specify the keyword arguments to pass to the
  691. @code{compile-file} procedure (@pxref{Invoking the compiler}).
  692. @end deffn
  693. @deffn {REPL Command} hoot-run exp [opts ...]
  694. Compile and run @var{exp} and return the results.
  695. @end deffn
  696. @deffn {REPL Command} hoot-run-file file [opts ...]
  697. Compile and run the source code in @var{file} and return the results.
  698. @end deffn
  699. @node Web deployment
  700. @chapter Web deployment
  701. On the client-side web, JavaScript is the host environment for Wasm
  702. modules and the
  703. @url{https://developer.mozilla.org/en-US/docs/WebAssembly,WebAssembly}
  704. API is used to load and run them. Hoot includes a JavaScript library,
  705. @file{reflect.js} that wraps the @code{WebAssembly} API and
  706. furthermore can inspect Scheme values and call Scheme procedures.
  707. This chapter documents deploying Hoot artifacts and using the
  708. reflection API to run Scheme in the browser.
  709. @menu
  710. * Web server setup:: Prepare a server to run Hoot programs.
  711. * JavaScript API reference:: JavaScript reflection interface.
  712. @end menu
  713. @node Web server setup
  714. @section Web server setup
  715. In order to run Hoot binaries in the browser, a web server needs to
  716. host a copy of the Hoot JavaScript runtime.
  717. The runtime files can be found in the @file{$prefix/share/guile-hoot/}
  718. directory, where @code{$prefix} is the directory where Hoot was
  719. installed on your system. This is typically @file{/usr} or
  720. @file{/usr/local} on Linux distributions such as Debian, Ubuntu,
  721. Fedora, etc.
  722. Don't forget to upload the Wasm files for the Scheme programs, too!
  723. A bit of JavaScript code is needed to bootstrap a Scheme program using
  724. the @file{reflect-js/reflect.js} library. For example, here's an
  725. example @file{boot.js} file that runs the Scheme program
  726. @file{hello.wasm} and prints the return values:
  727. @example
  728. @verbatim
  729. window.addEventListener("load", async () => {
  730. const results = await Scheme.load_main("/hello.wasm");
  731. console.log(results);
  732. });
  733. @end verbatim
  734. @end example
  735. The @code{Scheme} namespace is defined in @file{reflect.js}.
  736. @xref{JavaScript API reference} for more information.
  737. To run @file{boot.js} on a web page, add @code{<script>} tags for it
  738. and @file{reflect.js}:
  739. @example
  740. <!DOCTYPE html>
  741. <html>
  742. <head>
  743. <script type="text/javascript" src="/reflect.js"></script>
  744. <script type="text/javascript" src="/boot.js"></script>
  745. </head>
  746. <body>
  747. <h1>Hello, Hoot!</h1>
  748. </body>
  749. </html>
  750. @end example
  751. @node JavaScript API reference
  752. @section JavaScript API reference
  753. The @code{Scheme} class is used to load a Hoot binary, start the
  754. program, and initialize reflection.
  755. @deftp {Class} Scheme
  756. A Scheme runtime environment.
  757. @end deftp
  758. @defop {Static method} Scheme load_main path [abi] [reflect_wasm_dir "."] [user_imports @{@}]
  759. Fetch and execute the Hoot Wasm binary at the URL @var{path} and
  760. return an array of Scheme values produced by the program.
  761. The reflection library requires the assistance of some Wasm helper
  762. modules, which are looked up in @var{reflect_wasm_dir}.
  763. The @var{abi} parameter is for more advanced usage where multiple Hoot
  764. binaries share a single application binary interface (ABI). This
  765. should be set to @code{@{@}} when loading the first Scheme binary. It
  766. is better to use the @code{load_extension} method for subsequent
  767. binaries, though.
  768. The @var{user_imports} parameter is for providing concrete
  769. implementations of functions declared using the @ref{Foreign function
  770. interface}. It uses a two-tier nested object structure to map import
  771. names to the functions that implement them.
  772. For example, this Scheme code:
  773. @lisp
  774. (define-foreign make-text-node
  775. "document" "createTextNode"
  776. (ref string) -> (ref null extern))
  777. @end lisp
  778. Could be instantiated like so:
  779. @example
  780. @verbatim
  781. Scheme.load_main("hello.wasm", {
  782. user_imports: {
  783. document: {
  784. createTextNode: Document.prototype.createTextNode.bind(document)
  785. }
  786. }
  787. });
  788. @end verbatim
  789. @end example
  790. @end defop
  791. @defmethod Scheme load_extension path [user_imports @code{@{@}}]
  792. Fetch and load an additional Hoot binary at the URL @var{path} that
  793. shares the ABI of @code{this}. Optionally, a set of user-defined
  794. imported functions can be specified with the @var{user_imports}
  795. parameter.
  796. @end defmethod
  797. All of the fundamental Scheme types have an associated JavaScript
  798. class that can reflect their values. Calling the @code{repr} function
  799. on an instance of a reflected Scheme object will return a Scheme-like
  800. printing of the object.
  801. @example
  802. repr(pair) // => "(1 . 2)"
  803. @end example
  804. @deftp {Class} Char
  805. A Unicode character.
  806. @end deftp
  807. @deftp {Class} Eof
  808. End-of-file object.
  809. @end deftp
  810. @deftp {Class} Null
  811. The empty list.
  812. @end deftp
  813. @deftp {Class} Unspecified
  814. The unspecified value.
  815. @end deftp
  816. @deftp {Class} Complex real imag
  817. Complex number with real part @var{real} and imaginary part
  818. @var{imag}.
  819. @end deftp
  820. @deftp {Class} Fraction num denom
  821. An exact fraction with numerator @var{num} and denominator
  822. @var{denom}.
  823. @end deftp
  824. The @code{HeapObject} class is the parent class of all of the
  825. remaining Scheme types.
  826. @deftp {Class} HeapObject
  827. A Scheme heap object.
  828. @end deftp
  829. @defivar HeapObject reflector
  830. The reflector for @code{this}, an instance of the @code{Scheme} class.
  831. @end defivar
  832. The @code{reflector} property can be used in conjuction with the
  833. @code{load_extension} method to load additional Hoot binaries that
  834. share the same ABI.
  835. @example
  836. heapObject.reflector.load_extension("/helper.wasm")
  837. @end example
  838. @deftp {Class} Procedure
  839. A Scheme procedure.
  840. @end deftp
  841. Procedure instances can be invoked with the @code{call} method to
  842. perform a Javascript to Scheme function call.
  843. @defmethod Procedure call args@dots{}
  844. Call procedure with @var{args} and return an array of result values.
  845. @end defmethod
  846. @defmethod Procedure call_async args@dots{}
  847. Call procedure with @var{args} in an async context and return a
  848. promise to an array of result values. Before the procedure is called,
  849. @var{args} is prepended with two additional arguments: a function that
  850. resolves the promise, and a function that rejects the promise. It is
  851. up to the underlying Scheme procedure to use these values
  852. appropriately to settle the promise.
  853. @end defmethod
  854. @deftp {Class} Pair
  855. An immutable cons cell.
  856. @end deftp
  857. @deftp {Class} MutablePair
  858. A mutable cons cell.
  859. @end deftp
  860. @deftp {Class} Vector
  861. An immutable vector.
  862. @end deftp
  863. @deftp {Class} MutableVector
  864. A mutable vector.
  865. @end deftp
  866. @deftp {Class} Bytevector
  867. An immutable bytevector.
  868. @end deftp
  869. @deftp {Class} MutableBytevector
  870. A mutable bytevector.
  871. @end deftp
  872. @deftp {Class} Bitvector
  873. An immutable bitvector.
  874. @end deftp
  875. @deftp {Class} MutableBitvector
  876. A mutable bitvector.
  877. @end deftp
  878. @deftp {Class} MutableString
  879. A mutable string.
  880. @end deftp
  881. @deftp {Class} Sym
  882. A symbol.
  883. @end deftp
  884. @deftp {Class} Keyword
  885. A keyword.
  886. @end deftp
  887. @deftp {Class} Variable
  888. A mutable variable.
  889. @end deftp
  890. @deftp {Class} AtomicBox
  891. A mutable box with atomic updates.
  892. @end deftp
  893. @deftp {Class} HashTable
  894. A hash table.
  895. @end deftp
  896. @deftp {Class} WeakTable
  897. A weak key hash table.
  898. @end deftp
  899. @deftp {Class} Fluid
  900. A dynamic variable.
  901. @end deftp
  902. @deftp {Class} DynamicState
  903. A set of fluids.
  904. @end deftp
  905. @deftp {Class} Syntax
  906. A syntax object.
  907. @end deftp
  908. @deftp {Class} Port
  909. An I/O port.
  910. @end deftp
  911. @deftp {Class} Struct
  912. A user-defined structure.
  913. @end deftp
  914. @node Scheme reference
  915. @chapter Scheme reference
  916. In addition to supporting standard Scheme features, Hoot includes many
  917. of its own extensions. This chapter documents the APIs of these
  918. extensions.
  919. @menu
  920. * Boxes:: Mutable cells that store a single object.
  921. * Atomics:: Atomic boxes.
  922. * Bitvectors:: Sequences of bits.
  923. * Bytevectors:: Sequences of bytes.
  924. * Control:: Delimited continuations.
  925. * Exceptions:: Error handling.
  926. * Fluids:: Dynamic state.
  927. * Parameters:: Dynamic variables.
  928. * Hashtables:: Mutable key/value data structures.
  929. * Records:: Extensions to standard records.
  930. * Pattern matching:: Object destructuring.
  931. * Foreign function interface:: Call host functions from Scheme.
  932. * Evaluation:: Interpret Scheme programs at runtime.
  933. * Fibers:: Lightweight concurrency.
  934. * Finalization:: Finalization registries.
  935. @end menu
  936. @node Boxes
  937. @section Boxes
  938. The @code{(hoot boxes)} module provides boxes, which are single-value,
  939. mutable cells.
  940. @deffn {Procedure} make-box init
  941. Return a new box with an initial stored value of @var{init}.
  942. @end deffn
  943. @deffn {Procedure} box-ref box
  944. Return the value stored within @var{box}.
  945. @end deffn
  946. @deffn {Procedure} box-set! box val
  947. Set the stored value of @var{box} to @var{val}.
  948. @end deffn
  949. @node Atomics
  950. @section Atomics
  951. The @code{(hoot atomics)} module provides an API compatible with
  952. Guile's @code{(ice-9 atomic)} module. Atomic operations allow for
  953. concurrent access to a resource form many threads without the need to
  954. use thread synchronization constructs like mutexes. Currently,
  955. WebAssembly assumes single-threaded execution, making atomicity
  956. trivial. See @inlinefmtifelse{html,
  957. @url{https://www.gnu.org/software/guile/manual/html_node/Atomics.html,
  958. the Guile manual}, @ref{Atomics,,,Guile Reference}} for more detailed
  959. information.
  960. @deffn {Procedure} make-atomic-box init
  961. Return a new atomic box with an initial stored value of @var{init}.
  962. @end deffn
  963. @deffn {Procedure} atomic-box-ref box
  964. Return the value stored within the atomic box @var{box}.
  965. @end deffn
  966. @deffn {Procedure} atomic-box-set! box val
  967. Store @var{val} into the atomic box @var{box}.
  968. @end deffn
  969. @deffn {Procedure} atomic-box-swap! box val
  970. Store @var{val} into the atomic box @var{box}, and return the value
  971. that was previously stored in the box.
  972. @end deffn
  973. @deffn {Procedure} atomic-box-compare-and-swap! box expected desired
  974. If the value of the atomic box @var{box} is the same as @var{expected}
  975. (in the sense of @code{eq?}), replace the contents of the box with
  976. @var{desired}. Otherwise, the box is not updated. Return the
  977. previous value of the box in either case. You can know if the swap
  978. worked by checking if the return value is @code{eq?} to
  979. @var{expected}.
  980. @end deffn
  981. @node Bitvectors
  982. @section Bitvectors
  983. The @code{(hoot bitvectors)} module provides bitvectors, which are
  984. tightly packed arrays of booleans.
  985. @deffn {Procedure} make-bitvector len [fill #f]
  986. Return a new bitvector of @var{len} bits with all bits initialized to
  987. @var{fill}.
  988. @end deffn
  989. @deffn {Procedure} bitvector? obj
  990. Return @code{#t} if @var{obj} is a bitvector.
  991. @end deffn
  992. @deffn {Procedure} bitvector-length bv
  993. Return the length of the bitvector @var{bv}.
  994. @end deffn
  995. @deffn {Procedure} bitvector-ref bv i
  996. Return the boolean value of bit @var{i} in the bitvector @var{bv}.
  997. @end deffn
  998. @deffn {Procedure} bitvector-set-bit! bv i
  999. Set the bit @var{i} in the bitvector @var{bv} to @code{#t}.
  1000. @end deffn
  1001. @node Bytevectors
  1002. @section Bytevectors
  1003. The @code{(hoot bytevectors)} module provides some of the R6RS
  1004. bytevectors API. Bytevectors are sequences of bytes that are useful
  1005. for low-level manipulation of binary data.
  1006. @deffn {Procedure} make-bytevector len [init 0]
  1007. Return a new bytevector of @var{len} bytes with all bytes initialized
  1008. to @var{init}.
  1009. @end deffn
  1010. @deffn {Procedure} bytevector [byte ...]
  1011. Return a new bytevector containing the sequence @var{byte} @dots{}.
  1012. @end deffn
  1013. @deffn {Procedure} bytevector? obj
  1014. Return @code{#t} if @var{obj} is a bytevector.
  1015. @end deffn
  1016. @deffn {Procedure} bytevector-length bv
  1017. Return the length of @var{bv} in bytes.
  1018. @end deffn
  1019. @deffn {Procedure} bytevector-copy bv [start 0] [end (bytevector-length bv)]
  1020. Return a new bytevector that is a copy of the bytevector @var{bv} from
  1021. byte index @var{start} to @var{end}. @var{start} must be less than or
  1022. equal to @var{end}.
  1023. @end deffn
  1024. @deffn {Procedure} bytevector-copy! to at from [start 0] [end (bytevector-length from)]
  1025. Copy the subsection of bytevector @var{from}, defined by the byte
  1026. range [@var{start}, @var{end}), into the bytevector @var{from}.
  1027. @end deffn
  1028. @deffn {Procedure} bytevector-append [bv ...]
  1029. Return a new bytevector that concatenates all the input bytevectors
  1030. @var{bv} @dots{} in the order given.
  1031. @end deffn
  1032. @deffn {Procedure} bytevector-concatenate bvs
  1033. Return a new bytevector that concatenates all of the bytevectors in
  1034. the list @var{bvs}.
  1035. @end deffn
  1036. @deffn {Procedure} bytevector-concatenate-reverse bvs
  1037. Return a new bytevector that concatenates all of the bytevectors in
  1038. the list @var{bvs} in reverse order.
  1039. @end deffn
  1040. @deffn {Procedure} bytevector-u8-ref bv index
  1041. @deffnx {Procedure} bytevector-s8-ref bv index
  1042. @deffnx {Procedure} bytevector-u16-native-ref bv index
  1043. @deffnx {Procedure} bytevector-s16-native-ref bv index
  1044. @deffnx {Procedure} bytevector-u32-native-ref bv index
  1045. @deffnx {Procedure} bytevector-s32-native-ref bv index
  1046. @deffnx {Procedure} bytevector-u64-native-ref bv index
  1047. @deffnx {Procedure} bytevector-s64-native-ref bv index
  1048. Return the N-bit signed or unsigned integer from the bytevector
  1049. @var{bv} at @var{index} using the host's native endianness.
  1050. @end deffn
  1051. @deffn {Procedure} bytevector-ieee-single-native-ref bv index
  1052. @deffnx {Procedure} bytevector-ieee-double-native-ref bv index
  1053. Return the single or double precision IEEE floating piont number from
  1054. the bytevector @var{bv} at @var{index} using the host's native
  1055. endianness.
  1056. @end deffn
  1057. @deffn {Procedure} bytevector-u8-set! bv index x
  1058. @deffnx {Procedure} bytevector-s8-set! bv index x
  1059. @deffnx {Procedure} bytevector-u16-native-set! bv index x
  1060. @deffnx {Procedure} bytevector-s16-native-set! bv index x
  1061. @deffnx {Procedure} bytevector-u32-native-set! bv index x
  1062. @deffnx {Procedure} bytevector-s32-native-set! bv index x
  1063. @deffnx {Procedure} bytevector-u64-native-set! bv index x
  1064. @deffnx {Procedure} bytevector-s64-native-set! bv index x
  1065. Store @var{x} as an N-bit signed or unsigned integer in the bytevector
  1066. @var{bv} at @var{index} using the host's native endianness.
  1067. @end deffn
  1068. @deffn {Procedure} bytevector-ieee-single-native-set! bv index x
  1069. @deffnx {Procedure} bytevector-ieee-double-native-set! bv index x
  1070. Store @var{x} as a single or double precision IEEE floating piont
  1071. number in the bytevector @var{bv} at @var{index} using the host's
  1072. native endianness.
  1073. @end deffn
  1074. @node Control
  1075. @section Control
  1076. The @code{(hoot control)} module provides an interface for Guile's
  1077. delimited continuation facility known as ``prompts'' and some of the
  1078. @code{(ice-9 control)} API. See @inlinefmtifelse{html,
  1079. @url{https://www.gnu.org/software/guile/manual/html_node/Prompts.html,
  1080. the Guile manual}, @ref{Prompts,,,Guile Reference}} for more detailed
  1081. information.
  1082. @deffn {Procedure} make-prompt-tag [stem ``prompt'']
  1083. Return a new prompt tag that incorporates the value of @var{stem}. A
  1084. prompt tag is simply a unique object.
  1085. @end deffn
  1086. @deffn {Procedure} call-with-prompt tag body handler
  1087. Call the procedure @var{body}, a procedure of 0 arguments or
  1088. ``thunk'', within the context of a prompt marked with @var{tag}.
  1089. Should this prompt be aborted via @code{abort-to-prompt}, the
  1090. procedure @var{handler} is called. The @var{handler} procedure
  1091. receives as arguments a continuation object and any additional
  1092. arguments that were passed to @code{abort-to-prompt}.
  1093. @end deffn
  1094. @deffn {Procedure} abort-to-prompt tag [val ...]
  1095. Unwind the dynamic and control context to the nearest prompt named
  1096. @var{tag}, so passing the additional values @var{val} @dots{}
  1097. @end deffn
  1098. @deffn {Procedure} default-prompt-tag
  1099. Return the default prompt tag.
  1100. @end deffn
  1101. @deffn {Procedure} default-prompt-handler
  1102. Return the default prompt handler procedure.
  1103. @end deffn
  1104. Note that both @code{default-prompt-tag} and
  1105. @code{default-prompt-handler} are parameters, so their values may be
  1106. modified by using @code{parameterize}. @xref{Parameters} for more
  1107. information.
  1108. @deffn {Syntax} % expr
  1109. @deffnx {Syntax} % expr handler
  1110. @deffnx {Syntax} % tag expr handler
  1111. Syntactic sugar for @code{call-with-prompt}. Evaluate @var{expr} in
  1112. the context of a prompt. If @var{tag} is ommitted, the default prompt
  1113. tag will be used. If @var{handler} is omitted, the default prompt
  1114. handler will be used.
  1115. @end deffn
  1116. @node Exceptions
  1117. @section Exceptions
  1118. @node Exception types
  1119. @subsection Exception types
  1120. The @code{(hoot exceptions)} module implements Guile's exception API.
  1121. See @inlinefmtifelse{html,
  1122. @url{https://www.gnu.org/software/guile/manual/html_node/Exceptions.html,
  1123. the Guile manual}, @ref{Exceptions,,,Guile Reference}} for more
  1124. detailed information.
  1125. @deffn {Procedure} make-exception exceptions @dots{}
  1126. Return an exception object composed of @var{exceptions}.
  1127. @end deffn
  1128. @deffn {Procedure} exception? obj
  1129. Return @code{#t} if @var{obj} is an exception object.
  1130. @end deffn
  1131. Below are the built-in exception types and their respective
  1132. constructors, predicates, and accessors.
  1133. @deftp {Exception Type} &exception
  1134. @end deftp
  1135. @deffn {Procedure} simple-exception? obj
  1136. @end deffn
  1137. @deftp {Exception Type} &compound-exception
  1138. @end deftp
  1139. @deffn {Procedure} make-compound-exception components
  1140. @deffnx {Procedure} compound-exception? obj
  1141. @deffnx {Procedure} compound-exception-components compound-exception
  1142. @end deffn
  1143. @deftp {Exception Type} &message
  1144. @end deftp
  1145. @deffn {Procedure} make-exception-with-message message
  1146. @deffnx {Procedure} exception-with-message? obj
  1147. @deffnx {Procedure} exception-message exception
  1148. @end deffn
  1149. @deftp {Exception Type} &warning
  1150. @end deftp
  1151. @deffn {Procedure} make-warning
  1152. @deffnx {Procedure} warning? obj
  1153. @end deffn
  1154. @deftp {Exception Type} &serious
  1155. @end deftp
  1156. @deffn {Procedure} make-serious-exception
  1157. @deffnx {Procedure} serious-exception? obj
  1158. @end deffn
  1159. @deftp {Exception Type} &error
  1160. @end deftp
  1161. @deffn {Procedure} make-error
  1162. @deffnx {Procedure} error? obj
  1163. @end deffn
  1164. @deftp {Exception Type} &violation
  1165. @end deftp
  1166. @deffn {Procedure} make-violation
  1167. @deffnx {Procedure} violation? obj
  1168. @end deffn
  1169. @deftp {Exception Type} &assertion
  1170. @end deftp
  1171. @deffn {Procedure} make-assertion-violation
  1172. @deffnx {Procedure} assertion-violation? obj
  1173. @end deffn
  1174. @deftp {Exception Type} &arity-violation
  1175. @end deftp
  1176. @deffn {Procedure} make-arity-violation
  1177. @deffnx {Procedure} arity-violation? obj
  1178. @end deffn
  1179. @deftp {Exception Type} &implementation-restriction
  1180. @end deftp
  1181. @deffn {Procedure} make-implementation-restriction-violation
  1182. @deffnx {Procedure} implementation-restriction-violation? obj
  1183. @end deffn
  1184. @deftp {Exception Type} &failed-type-check
  1185. @end deftp
  1186. @deffn {Procedure} make-failed-type-check predicate
  1187. @deffnx {Procedure} failed-type-check? obj
  1188. @deffnx {Procedure} failed-type-check-predicate exception
  1189. @end deffn
  1190. @deftp {Exception Type} &non-continuable
  1191. @end deftp
  1192. @deffn {Procedure} make-non-continuable-violation
  1193. @deffnx {Procedure} non-continuable-violation? obj
  1194. @end deffn
  1195. @deftp {Exception Type} &irritants
  1196. @end deftp
  1197. @deffn {Procedure} make-exception-with-irritants irritants
  1198. @deffnx {Procedure} exception-with-irritants? obj
  1199. @deffnx {Procedure} exception-irritants exception
  1200. @end deffn
  1201. @deftp {Exception Type} &origin
  1202. @end deftp
  1203. @deffn {Procedure} make-exception-with-origin origin
  1204. @deffnx {Procedure} exception-with-origin? obj
  1205. @deffnx {Procedure} exception-origin exception
  1206. @end deffn
  1207. @deftp {Exception Type} &lexical
  1208. @end deftp
  1209. @deffn {Procedure} make-lexical-violation
  1210. @deffnx {Procedure} lexical-violation? obj
  1211. @end deffn
  1212. @deftp {Exception Type} &i/o
  1213. @end deftp
  1214. @deffn {Procedure} make-i/o-error
  1215. @deffnx {Procedure} i/o-error?
  1216. @end deffn
  1217. @deftp {Exception Type} &i/o-line-and-column
  1218. @end deftp
  1219. @deffn {Procedure} make-i/o-line-and-column-error line column
  1220. @deffnx {Procedure} i/o-line-and-column-error? obj
  1221. @deffnx {Procedure} i/o-error-line exception
  1222. @deffnx {Procedure} i/o-error-column exception
  1223. @end deffn
  1224. @deftp {Exception Type} &i/o-filename
  1225. @end deftp
  1226. @deffn {Procedure} make-i/o-filename-error filename
  1227. @deffnx {Procedure} i/o-filename-error? obj
  1228. @deffnx {Procedure} i/o-error-filename exception
  1229. @end deffn
  1230. @deftp {Exception Type} &i/o-not-seekable
  1231. @end deftp
  1232. @deffn {Procedure} make-i/o-not-seekable-error
  1233. @deffnx {Procedure} i/o-not-seekable-error? obj
  1234. @end deffn
  1235. @deftp {Exception Type} &i/o-port
  1236. @end deftp
  1237. @deffn {Procedure} make-i/o-port-error port
  1238. @deffnx {Procedure} i/o-port-error? obj
  1239. @deffnx {Procedure} i/o-error-port exception
  1240. @end deffn
  1241. @node Raising and handling exceptions
  1242. @subsection Raising and handling exceptions
  1243. The @code{(hoot errors)} module provides procedures for raising and
  1244. handling exceptions.
  1245. @deffn {Procedure} raise exception
  1246. Raise the non-continuable exception @var{exception} by invoking the
  1247. current exception handler.
  1248. @end deffn
  1249. @deffn {Procedure} raise-continuable exception
  1250. Raise the continuable exception @var{exception} by invoking the
  1251. current exception handler.
  1252. @end deffn
  1253. @deffn {Procedure} raise-exception exception [#:continuable? #f]
  1254. Raise the exception @var{exception} by invoking the current exception
  1255. handler. When @var{continuable?} is @code{#t}, the raised exception
  1256. is continuable.
  1257. @end deffn
  1258. @deffn {Procedure} with-exception-handler handler thunk [#:unwind? #f]
  1259. Call @var{thunk}, a procedure of zero arguments, in a context where
  1260. @var{handler}, a procedure of one argument, is the current exception
  1261. handler. If an exception is raised then @var{handler} will be called
  1262. with the exception obect.
  1263. When @var{unwind?} is @code{#t}, the stack will be unwound before
  1264. @var{handler} is called. The default behavior is not to unwind. When
  1265. the stack is not unwound, it is up to @var{handler} to properly manage
  1266. control flow. Control is allowed to fallthrough @var{handler} and
  1267. resume from where the exception was raised only if the raised
  1268. exception is @emph{continuable}. For non-continuable exceptions,
  1269. @var{handler} should abort to some prompt (@xref{Control}) to escape
  1270. the exception handling context.
  1271. @end deffn
  1272. @node Fluids
  1273. @section Fluids
  1274. A fluid is a variable whose value is associated with the dynamic
  1275. extent of a procedure call. The @code{(hoot fluids)} module
  1276. implements Guile's fluid API. See @inlinefmtifelse{html,
  1277. @url{https://www.gnu.org/software/guile/manual/html_node/Fluids-and-Dynamic-States.html,
  1278. the Guile manual}, @ref{Fluids and Dynamic States,,,Guile Reference}}
  1279. for more detailed information.
  1280. @deffn {Procedure} make-fluid [default #f]
  1281. Return a new fluid whose initial value is @var{default}.
  1282. @end deffn
  1283. @deffn {Procedure} fluid? obj
  1284. Return @code{#t} if @var{obj} is a fluid.
  1285. @end deffn
  1286. @deffn {Procedure} fluid-ref fluid
  1287. Return the value currently stored within @var{fluid}.
  1288. @end deffn
  1289. @deffn {Procedure} fluid-set! fluid val
  1290. Set the contents of @var{fluid} to @var{val}.
  1291. @end deffn
  1292. @deffn {Procedure} with-fluid* fluid val thunk
  1293. Call @var{thunk}, a procedure of zero arguments, in a context where
  1294. the @var{fluid} is set to @var{val}. When control leaves the dynamic
  1295. extent of @var{thunk}, @var{fluid} is set back to its previous value.
  1296. @end deffn
  1297. @deffn {Syntax} with-fluids ((fluid value) ...) body1 body2 ...
  1298. Evaluate @var{body1} @var{body2} @dots{} in a context where each
  1299. @var{fluid} is set to its respective @var{value}.
  1300. @end deffn
  1301. @node Parameters
  1302. @section Parameters
  1303. Parameters are Guile's facility for dynamically bound variables.
  1304. While parameters are part of the default Guile environment, in Hoot
  1305. they are provided by the @code{(hoot parameters)} module. See
  1306. @inlinefmtifelse{html,
  1307. @url{https://www.gnu.org/software/guile/manual/html_node/Parameters.html,
  1308. the Guile manual}, @ref{Parameters,,,Guile Reference}} for more
  1309. detailed information.
  1310. A parameter is a procedure. To retrieve the value of a parameter,
  1311. call it with zero arguments. To set a new value, call it with one
  1312. argument.
  1313. @lisp
  1314. (define counter (make-parameter 0))
  1315. (counter) ; => 0
  1316. (counter 1)
  1317. (counter) ; => 1
  1318. (parameterize ((counter 2))
  1319. (counter)) ; => 2
  1320. (counter) ; => 1
  1321. @end lisp
  1322. @deffn {Procedure} make-parameter init [conv (lambda (x) x)]
  1323. Return a new parameter whose initial value is @var{(conv init)}.
  1324. @var{conv} is a procedure of one argument that transforms an incoming
  1325. value into the value that is actually stored within the parameter.
  1326. The default @var{conv} is an identity function that applies no
  1327. transformation at all.
  1328. @end deffn
  1329. @deffn {Syntax} parameterize ((parameter value) ...) body1 body2 ...
  1330. Evaluate @var{body1} @var{body2} @dots{} in a context where each
  1331. @var{parameter} is set to its respective @var{value}. When control
  1332. leaves the dynamic extent of the body, each @var{parameter} is set
  1333. back to its previous value.
  1334. @end deffn
  1335. @node Hashtables
  1336. @section Hashtables
  1337. There are many mutable hashtable APIs amongst all the various Scheme
  1338. implementations, standards, and SRFIs. From our point of view, there
  1339. is no clear ``best'' hashtable API that has emerged, but we think the
  1340. R6RS interface is OK. Guile's own hashtable API has design issues
  1341. that are best left in the past. So, the @code{(hoot hashtables)}
  1342. module is R6RS-like but with some notable differences.
  1343. @deffn {Procedure} make-hashtable [hash hash] [equiv equal?]
  1344. Return a new, empty hashtable that uses the hash procedure @var{hash}
  1345. and equivalence procedure @var{equiv}.
  1346. @end deffn
  1347. @deffn {Procedure} make-eq-hashtable
  1348. Return a new, empty hashtable that uses @code{eq?} as the equivalence
  1349. function and hashes keys accordingly.
  1350. @end deffn
  1351. @deffn {Procedure} make-eqv-hashtable
  1352. Return a new, empty hashtable that uses @code{eqv?} as the equivalence
  1353. function and hashes keys accordingly.
  1354. @end deffn
  1355. @deffn {Procedure} hashtable? obj
  1356. Return @code{#t} if @var{obj}
  1357. @end deffn
  1358. @deffn {Procedure} hashtable-hash table
  1359. Return the hash function for @var{table}.
  1360. @end deffn
  1361. @deffn {Procedure} hashtable-equiv table
  1362. Return the equivalence function for @var{table}.
  1363. @end deffn
  1364. @deffn {Procedure} hashtable-size table
  1365. Return the current number of key/value pairs in @var{table}.
  1366. @end deffn
  1367. @deffn {Procedure} hashtable-ref table key [default #f]
  1368. Return the value associated with @var{key} in @var{table}, or
  1369. @var{default} if there is no such association.
  1370. @end deffn
  1371. @deffn {Procedure} hashtable-set! table key value
  1372. Associate @var{val} with @var{key} in @var{table}, potentially
  1373. overwriting any previous association with @var{key}.
  1374. @end deffn
  1375. @deffn {Procedure} hashtable-delete! table key
  1376. Remove the association with @var{key} in @var{table}, if one exists.
  1377. @end deffn
  1378. @deffn {Procedure} hashtable-clear! table
  1379. Remove all of the key/value associations in @var{table}.
  1380. @end deffn
  1381. @deffn {Procedure} hashtable-contains? table key
  1382. Return @code{#t} if @var{key} has an associated value in @var{table}.
  1383. @end deffn
  1384. @deffn {Procedure} hashtable-copy table
  1385. Return a copy of @var{table}.
  1386. @end deffn
  1387. @deffn {Procedure} hashtable-keys table
  1388. Return a list of keys in @var{table}.
  1389. @end deffn
  1390. @deffn {Procedure} hashtable-values table
  1391. Return a list of values in @var{table}.
  1392. @end deffn
  1393. @deffn {Procedure} hashtable-for-each proc table
  1394. Apply @var{proc} to each key/value association in @var{table}. Each
  1395. call is of the form @code{(proc key value)}.
  1396. @end deffn
  1397. @deffn {Procedure} hashtable-fold proc init table
  1398. Accumulate a result by applying @var{proc} with each key/value
  1399. association in @var{table} and the result of the previous @var{proc}
  1400. call. Each call is of the form @code{(proc key value prev)}. For the
  1401. first call, @code{prev} is the initial value @var{init}.
  1402. @end deffn
  1403. Hoot also includes weak key hash tables that wrap those of the Wasm
  1404. host platform, such as the @code{WeakMap} JavaScript class on the web.
  1405. @deffn {Procedure} make-weak-key-hashtable
  1406. Return a new weak key hashtable.
  1407. @end deffn
  1408. @deffn {Procedure} weak-key-hashtable? obj
  1409. Return @code{#t} if @var{obj} is a weak key hashtable.
  1410. @end deffn
  1411. @deffn {Procedure} weak-key-hashtable-ref hashtable key [default #f]
  1412. Return the value associated with @var{key} in @var{hashtable} or
  1413. @var{default} if there is no such association.
  1414. @end deffn
  1415. @deffn {Procedure} weak-key-hashtable-set! hashtable key value
  1416. Modify @var{hashtable} to associate @var{key} with @var{value},
  1417. overwriting any previous association that may have existed.
  1418. @end deffn
  1419. @deffn {Procedure} weak-key-hashtable-delete! hashtable key
  1420. Remove the association with @var{key} in @var{hashtable}, if one
  1421. exists.
  1422. @end deffn
  1423. The following hash functions are available:
  1424. @deffn {Procedure} hash key size
  1425. @deffnx {Procedure} hashq key size
  1426. @deffnx {Procedure} hashv key size
  1427. Return a hash value for @var{key} suitable for using in a table
  1428. containing @var{size} buckets. The returned hash value will be in the
  1429. range [0, @var{size}).
  1430. @code{hashq} is the hash function used by @code{make-eq-hashtable},
  1431. and @code{hashv} is used by @code{make-eqv-hashtable}.
  1432. @end deffn
  1433. @node Records
  1434. @section Records
  1435. Hoot extends the R7RS @code{define-record-type} form with additional
  1436. features such as inheritance and opaque types.
  1437. @deffn {Syntax} define-record-type name @
  1438. [#:printer] [#:parent] [#:uid] [#:extensible? #t] [#:opaque? #f] @
  1439. [#:allow-duplicate-field-names? #f] @
  1440. constructor predicate @
  1441. (field field-ref [field-set]) ...
  1442. Define a new record type descriptor bound to @var{name}. Define a
  1443. constructor procedure bound to @var{constructor} and a predicate
  1444. procedure bound to @var{predicate}. For each @var{field}, define an
  1445. accessor procedure @var{field-ref} and, optionally, a modifier
  1446. procedure @var{field-set}.
  1447. The record type will inherit from the record type descriptor bound to
  1448. @var{parent}, as long as @var{parent} is extensible. By default,
  1449. record types are extensible. A record type may be marked as ``final''
  1450. by passing an @var{extensible?} flag of @code{#f}.
  1451. When @var{opaque?} is @code{#t}, instances of this record type will be
  1452. compared for equality by identity @emph{only}. This means that
  1453. @code{(equal? a b)} only returns @code{#t} when @code{a} and @code{b}
  1454. reference the same instance of the record type. In other words, they
  1455. must be @code{eq?}. The default behavior is to perform deep
  1456. structural equality checking by comparing record fields.
  1457. When @var{printer} is specified, that procedure will be used when
  1458. printing instances of this record type rather than the default
  1459. printer.
  1460. @var{uid} should be a unique identifier that will be associated with
  1461. the record type when specified. Record types have no unique id by
  1462. default.
  1463. When @var{allow-duplicate-field-names?} is @code{#t}, field names may
  1464. appear more than once in the fields section.
  1465. @end deffn
  1466. @node Pattern matching
  1467. @section Pattern matching
  1468. Hoot provides a port of Guile's @code{(ice-9 match)} module for
  1469. pattern matching. See @inlinefmtifelse{html,
  1470. @url{https://www.gnu.org/software/guile/manual/html_node/Pattern-Matching.html,
  1471. Pattern Matching} in the Guile manual, @ref{Pattern Matching,,, guile,
  1472. GNU Guile Reference Manual}} for more information.
  1473. @node Foreign function interface
  1474. @section Foreign function interface
  1475. WebAssembly follows the capability security model, which means that
  1476. modules cannot do much on their own. Wasm modules are guests within a
  1477. host. They must be given capabilities by the host in order to
  1478. interact with the outside world. Modules request capabilities by
  1479. declaring imports, which the host then fills out with concrete
  1480. implementations at instantiation time. Hoot provides a foreign
  1481. function interface (FFI) in the @code{(hoot ffi)} module to embed
  1482. these import declarations within Scheme code.
  1483. The @code{define-foreign} form declares an import with a given type
  1484. signature (Wasm is statically typed) and defines a procedure for
  1485. calling it. The FFI takes care of converting Scheme values to Wasm
  1486. values and vice versa. For example, declaring an import for creating
  1487. text nodes in a web browser could look like this:
  1488. @lisp
  1489. (define-foreign make-text-node
  1490. "document" "createTextNode"
  1491. (ref string) -> (ref extern))
  1492. @end lisp
  1493. In the above example, the procedure is bound to the variable
  1494. @code{make-text-node}. In the Wasm binary, this import is named
  1495. ``createTextNode'' and resides in the ``document'' namespace of the
  1496. import table. A Wasm host is expected to satisfy this import by
  1497. providing a function that accepts one argument, a string, and returns
  1498. an arbitary host value which may be null.
  1499. Note that declaring an import @emph{does not} do anything to bind that
  1500. import to an implementation on the host. The Wasm guest cannot grant
  1501. capabilities unto itself. Furthermore, the host could be any Wasm
  1502. runtime, so the actual implementation will vary. In the context of a
  1503. web browser, the JavaScript code that instantiates a module with this
  1504. import could look like this:
  1505. @example
  1506. @verbatim
  1507. Scheme.load_main("hello.wasm", {}, {
  1508. document: {
  1509. createTextNode: (text) => document.createTextNode(text)
  1510. }
  1511. });
  1512. @end verbatim
  1513. @end example
  1514. And here's what it might look like when using the Hoot interpreter:
  1515. @lisp
  1516. (use-modules (hoot reflect))
  1517. (hoot-instantiate (call-with-input-file "hello.wasm" parse-wasm)
  1518. `(("document" .
  1519. (("createTextNode" . ,(lambda (str) `(text ,str)))))))
  1520. @end lisp
  1521. Once defined, @code{make-text-node} can be called like any other
  1522. procedure:
  1523. @lisp
  1524. (define hello (make-text-node "Hello, world!"))
  1525. @end lisp
  1526. Since the return type of @code{make-text-node} is @code{(ref extern}),
  1527. the value of @code{hello} is an @emph{external reference}. To check
  1528. if a value is an external reference, use the @code{external?}
  1529. predicate:
  1530. @lisp
  1531. (external? hello) ; => #t
  1532. @end lisp
  1533. External references may be null, which could indicate failure, a cache
  1534. miss, etc. To check if an external value is null, use the
  1535. @code{external-null?} predicate:
  1536. @lisp
  1537. (external-null? hello) ; => #f
  1538. @end lisp
  1539. Note that we defined the return type of @code{make-text-node} to be
  1540. @code{(ref extern)}, not @code{(ref null extern)}, so @code{hello}
  1541. would never be null in this example.
  1542. A large application will likely need to manipulate many different
  1543. kinds of foreign values. This introduces an opportunity for errors
  1544. because @code{external?} cannot distinguish between them. The
  1545. solution is to wrap external values using disjoint types. To define
  1546. such wrapper types, use @code{define-external-type}:
  1547. @lisp
  1548. (define-external-type <text-node>
  1549. text-node? wrap-text-node unwrap-text-node)
  1550. @end lisp
  1551. @code{make-text-node} could then be reimplemented like this:
  1552. @lisp
  1553. (define-foreign %make-text-node
  1554. "document" "createTextNode"
  1555. (ref string) -> (ref extern))
  1556. (define (make-text-node str)
  1557. (wrap-text-node (%make-text-node str)))
  1558. (define hello (make-text-node "Hello, world!"))
  1559. (external? hello) ; => #f
  1560. (text-node? hello) ; => #t
  1561. (external? (unwrap-text-node hello)) ; => #t
  1562. @end lisp
  1563. We've now explained the basics of using the FFI. Read below for
  1564. detailed API documentation.
  1565. @deffn {Syntax} define-foreign scheme-name namespace import-name param-types ... -> result-type
  1566. Define @var{scheme-name}, a procedure wrapping the Wasm import
  1567. @var{import-name} in the namespace @var{namespace}.
  1568. The signature of the function is specified by @var{param-types} and
  1569. @var{result-type}, which are all Wasm types expressed in WAT form.
  1570. Valid parameter types are:
  1571. @itemize
  1572. @item i32: 32-bit integer
  1573. @item i64: 64-bit integer
  1574. @item f32: 32-bit float
  1575. @item f64: 64-bit float
  1576. @item (ref string): a string
  1577. @item (ref extern): a non-null external value
  1578. @item (ref null extern): a possibly null external value
  1579. @item (ref eq): any Scheme value
  1580. @end itemize
  1581. Valid result types are:
  1582. @itemize
  1583. @item none: no return value
  1584. @item i32: 32-bit integer
  1585. @item i64: 64-bit integer
  1586. @item f32: 32-bit float
  1587. @item f64: 64-bit float
  1588. @item (ref string): a string
  1589. @item (ref null string): a possibly null string
  1590. @item (ref extern): a non-null external value
  1591. @item (ref null extern): a possibly null external value
  1592. @item (ref eq): a Scheme value
  1593. @end itemize
  1594. @end deffn
  1595. @deffn {Procedure} external? obj
  1596. Return @code{#t} if @var{obj} is an external reference.
  1597. @end deffn
  1598. @deffn {Procedure} external-null? extern
  1599. Return @code{#t} if @var{extern} is null.
  1600. @end deffn
  1601. @deffn {Procedure} external-non-null? extern
  1602. Return @code{#t} if @var{extern} is not null.
  1603. @end deffn
  1604. @deffn {Syntax} define-external-type name predicate wrap unwrap
  1605. @deffnx {Syntax} define-external-type name predicate wrap unwrap print
  1606. Define a new record type named @var{name} for the purposes of wrapping
  1607. external values. @var{predicate} is the name of the record type
  1608. predicate. @var{wrap} is the name of the record type constructor.
  1609. @var{unwrap} is the name of the record field accessor that returns the
  1610. wrapped value. Optionally, @var{print} is a procedure that accepts
  1611. two arguments (@code{obj} and @code{port}) and prints a textual
  1612. representation of the wrapped value.
  1613. @end deffn
  1614. @node Evaluation
  1615. @section Evaluation
  1616. Hoot is an ahead-of-time, whole-program compiler, but what if we want
  1617. to evaluate arbitrary Scheme code at runtime? Fortunately, the
  1618. @code{(hoot eval}) module provides a Scheme interpreter for this
  1619. purpose!
  1620. Evaluation happens in the context of an environment. Here's a simple
  1621. example:
  1622. @lisp
  1623. (use-modules (hoot eval) (hoot interaction-environment))
  1624. (eval '(let ((x 1) (y 2)) (+ x y)) (interaction-environment))
  1625. @end lisp
  1626. @deffn {Procedure} eval exp toplevel-env
  1627. Evaluate @code{exp} in the context of the environment
  1628. @var{toplevel-env}.
  1629. @end deffn
  1630. @deffn {Syntax} current-environment
  1631. Expands to code that creates an evaluation environment containing all
  1632. of the available top-level bindings at the location where
  1633. @code{(current-environment)} is used.
  1634. @end deffn
  1635. @deffn {Procedure} make-empty-environment
  1636. Return an empty evaluation environment.
  1637. @end deffn
  1638. The @code{(hoot interaction-environment)} module provides a simple
  1639. environment containing all of Guile's default bindings.
  1640. @deffn {Procedure} interaction-environment
  1641. Return a basic evaluation environment with all of Guile's default
  1642. top-level bindings.
  1643. @end deffn
  1644. @node Fibers
  1645. @section Fibers
  1646. Fibers is a facility for lightweight concurrency in Guile. Hoot's
  1647. built-in fibers API is based on the third-party
  1648. @url{https://github.com/wingo/fibers,fibers library} available for the
  1649. Guile VM.
  1650. @menu
  1651. * Fibers example:: A simple example program.
  1652. * Operations:: Asynchronous events.
  1653. * Channels:: Communication between fibers.
  1654. * Timers:: Sleepy fibers.
  1655. * Conditions:: Send signals between fibers.
  1656. * Promises:: Integrating fibers with the Wasm host.
  1657. @end menu
  1658. @node Fibers example
  1659. @subsection Fibers example
  1660. Running a fibers program is a little different than running a regular
  1661. Scheme program. Fibers programs need to be invoked in an asychronous
  1662. context from the host (usually JavaScript) and need to communicate the
  1663. overall success or failure of the program back to the host.
  1664. To demonstrate, let's make a @emph{very} simple program that sleeps
  1665. for one second before returning the value @code{42}.
  1666. @lisp
  1667. (use-modules (fibers promises)
  1668. (fibers timers))
  1669. (lambda (resolved rejected)
  1670. (call-with-async-result
  1671. resolved rejected
  1672. (lambda ()
  1673. (display "Waiting... ")
  1674. (force-output)
  1675. (sleep 1)
  1676. (display "done!\n")
  1677. (force-output)
  1678. 42)))
  1679. @end lisp
  1680. Note that we've wrapped our program in a @code{lambda} that receives
  1681. @code{resolved} and @code{rejected} arguments. When the Wasm host
  1682. calls this procedure in an asynchronous manner, these arguments will
  1683. be special host values that are used to resolve or reject the promise
  1684. (@pxref{Promises}) that represents the result of our program. The
  1685. @code{call-with-async-result} procedure receives these host values and
  1686. takes care of all the promise plumbing for us.
  1687. To try this out, save the above code to @file{fibers-example.scm} and
  1688. run the following command:
  1689. @example
  1690. guild compile-wasm --run --async fibers-test.scm
  1691. @end example
  1692. The expected output is:
  1693. @example
  1694. Waiting... done!
  1695. (42)
  1696. @end example
  1697. There's just one value returned but since Scheme supports multiple
  1698. return values, the result of the program is a @emph{list} of values.
  1699. To invoke an asynchronous procedure from JavaScript, use the
  1700. @code{call_async} method on a @code{Procedure} object:
  1701. @example
  1702. const [proc] = await Scheme.load_main("fibers-test.wasm");
  1703. proc.call_async();
  1704. @end example
  1705. Read on for the detailed fibers API reference.
  1706. @node Operations
  1707. @subsection Operations
  1708. Operations are first-class abstractions for asynchronous events.
  1709. There are primitive operation types, such as waiting for a timer
  1710. (@pxref{Timers}) or waiting for a message on a channel
  1711. (@pxref{Channels}). Operations can also be combined and transformed
  1712. using the @code{choice-operation} and @code{wrap-operation} from the
  1713. @code{(fibers operations)} module.
  1714. @deffn {Procedure} wrap-operation op f
  1715. Given the operation @var{op}, return a new operation that, if and when
  1716. it succeeds, will apply @var{f} to the values yielded by performing
  1717. @var{op}, and yield the result as the values of the wrapped operation.
  1718. @end deffn
  1719. @deffn {Procedure} choice-operation . ops
  1720. Given the operations @var{ops}, return a new operation that if it
  1721. succeeds, will succeed with one and only one of the sub-operations
  1722. @var{ops}.
  1723. @end deffn
  1724. Finally, once you have an operation, you can perform it using
  1725. @code{perform-operation}.
  1726. @deffn {Procedure} perform-operation op
  1727. Perform the operation @var{op} and return the resulting values. If the
  1728. operation cannot complete directly, block until it can complete.
  1729. @end deffn
  1730. There is also a low-level constructor for other modules that implement
  1731. primitive operation types:
  1732. @deffn {Procedure} make-base-operation wrap-fn try-fn block-fn
  1733. Make a fresh base operation.
  1734. @end deffn
  1735. @node Channels
  1736. @subsection Channels
  1737. Channels are the way to communicate between fibers. To use them, load
  1738. the @code{(fibers channels)} module.
  1739. @deffn {Procedure} make-channel
  1740. Make a fresh channel.
  1741. @end deffn
  1742. @deffn {Procedure} channel? obj
  1743. Return @code{#t} if @var{obj} is a channel, or @code{#f} otherwise.
  1744. @end deffn
  1745. @deffn {Procedure} put-operation channel message
  1746. Make an operation that if and when it completes will rendezvous with a
  1747. receiving operation to send @var{message} over @var{channel}.
  1748. @end deffn
  1749. @deffn {Procedure} get-operation channel
  1750. Make an operation that if and when it completes will rendezvous with a
  1751. sending operation to receive one value from @var{channel}.
  1752. @end deffn
  1753. @deffn {Procedure} put-message channel message
  1754. Send @var{message} on @var{channel}, and return zero values. If there
  1755. is already a receiver waiting to receive a message on this channel,
  1756. give it our message and continue. Otherwise, block until a receiver
  1757. becomes available.
  1758. Equivalent to:
  1759. @lisp
  1760. (perform-operation (put-operation channel message))
  1761. @end lisp
  1762. @end deffn
  1763. @deffn {Procedure} get-message channel
  1764. Receive a message from @var{channel} and return it. If there is
  1765. already a sender waiting to send a message on this channel, take its
  1766. message directly. Otherwise, block until a sender becomes available.
  1767. Equivalent to:
  1768. @lisp
  1769. (perform-operation (get-operation channel))
  1770. @end lisp
  1771. @end deffn
  1772. @node Timers
  1773. @subsection Timers
  1774. Timers are a kind of operation that, you guessed it, let you sleep
  1775. until a certain time. The timer API can be found in the @code{(fibers
  1776. timers)} module.
  1777. @deffn {Procedure} sleep-operation seconds
  1778. Make an operation that will succeed with no values when @var{seconds}
  1779. have elapsed.
  1780. @end deffn
  1781. @deffn {Procedure} timer-operation expiry
  1782. Make an operation that will succeed when the current time is greater
  1783. than or equal to @var{expiry}, expressed in internal time units. The
  1784. operation will succeed with no values.
  1785. @end deffn
  1786. @deffn {Procedure} sleep seconds
  1787. Block the calling fiber until @var{seconds} have elapsed.
  1788. @end deffn
  1789. @node Conditions
  1790. @subsection Conditions
  1791. Condition variables are a simple one-bit form of concurrent
  1792. communication. A condition variable has two states: it starts in the
  1793. @dfn{unsignalled} state and later may transition to the
  1794. @dfn{signalled} state. When a condition becomes signalled, any
  1795. associated waiting operations complete. The following API can be
  1796. found in the @code{(fibers conditions)} module.
  1797. @deffn {Procedure} make-condition
  1798. Make a new condition variable.
  1799. @end deffn
  1800. @deffn {Procedure} condition? obj
  1801. Return @code{#t} if @var{obj} is a condition variable, or @code{#f}
  1802. otherwise.
  1803. @end deffn
  1804. @deffn {Procedure} signal-condition! cvar
  1805. Signal @var{cvar}, notifying all waiting fibers and preventing
  1806. blocking of future fibers waiting on this condition.
  1807. @end deffn
  1808. @deffn {Procedure} wait-operation cvar
  1809. Make an operation that will succeed with no values when @var{cvar}
  1810. becomes signalled.
  1811. @end deffn
  1812. @deffn {Procedure} wait cvar
  1813. Block the calling fiber until @var{cvar} becomes signalled.
  1814. Equivalent to @code{(perform-operation (wait-operation cvar))}.
  1815. @end deffn
  1816. @node Promises
  1817. @subsection Promises
  1818. Promises represent the result of a computation that may or may not
  1819. complete at some later point in time. They are the primitive upon
  1820. which asynchronous concurrency is based in
  1821. @url{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise,JavaScript},
  1822. whether using promises directly or through the
  1823. @url{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function,async}/@url{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await,await}
  1824. syntax.
  1825. Hoot fibers use these host promises under the hood and the
  1826. @code{(fibers promises)} module provides the API for doing so. This
  1827. is @emph{mostly} transparent to the programmer, except at program
  1828. startup. Programs that use fibers must be called in an async context
  1829. in which they receive special values used to resolve or reject the
  1830. promise representing the result of the entire program. @xref{Fibers
  1831. example} for a walkthrough of this process.
  1832. @deffn {Procedure} await-promise-operation promise
  1833. Make an operation that will complete when @var{promise} is resolved.
  1834. Performing the operation produces one value: a thunk which when called
  1835. will either return the value or throw an exception.
  1836. @end deffn
  1837. @deffn {Procedure} await promise
  1838. Suspend the current fiber until @var{promise} is resolved. If the
  1839. promise resolves successfully, one value is returned. Otherwise, an
  1840. exception is thrown.
  1841. @end deffn
  1842. @deffn {Procedure} call-with-async-result resolved rejected thunk
  1843. Call @var{thunk} and resolve the promise with @var{resolved} and the
  1844. returned values. If an exception is thrown, the promise is rejected
  1845. with @var{rejected} and the exception.
  1846. @var{resolved} and @var{rejected} are external host values that are
  1847. obtained by calling a Scheme procedure asynchronously from the host.
  1848. See the @code{Procedure.call_async} method in @ref{JavaScript API
  1849. reference} and the @code{hoot-apply-async} procedure in
  1850. @ref{Reflection} for more information on asynchronous procedure calls.
  1851. @end deffn
  1852. @node Finalization
  1853. @section Finalization
  1854. The @code{(hoot finalization)} module provides an interface for the
  1855. JavaScript
  1856. @url{https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry,FinalizationRegistry}
  1857. class, which notifies user code when a registered object has been
  1858. garbage collected. Finalization registries are quite different from
  1859. Guile's @inlinefmtifelse{html,
  1860. @url{https://www.gnu.org/software/guile/manual/html_node/Guardians.html,
  1861. guardians}, @ref{Guardians,,,Guile Reference}}:
  1862. @itemize
  1863. @item
  1864. Guardians return references to the objects they have protected from
  1865. garbage collection. Finalization registries @emph{do not} protect
  1866. objects from garbage collection at all. Instead, when a registered
  1867. object is garbage collected, the finalization registry passes along a
  1868. user-specified ``held value''. A held value @emph{cannot} be a
  1869. reference to the object being registered for finalization.
  1870. @item
  1871. Guardians are polled, whereas finalization registries use an
  1872. asynchronous callback function.
  1873. @item
  1874. Finalization registries allow objects to be unregistered, whereas
  1875. objects cannot be removed from a guardian once they have been added.
  1876. @end itemize
  1877. The following contrived example will print ``hey'' when the registered
  1878. object is garbage collected:
  1879. @lisp
  1880. (define (cleanup x)
  1881. (display x)
  1882. (newline))
  1883. (define registry (make-finalization-registry cleanup))
  1884. (finalization-registry-register! registry (list 'garbage) 'hey)
  1885. @end lisp
  1886. @deffn {Procedure} make-finalization-registry cleanup
  1887. Return a new finalization registry that will call @var{cleanup} (a
  1888. procedure of one argument) whenever a registered object is garbage
  1889. collected.
  1890. @end deffn
  1891. @deffn {Procedure} finalization-registry? obj
  1892. Return @var{#t} if @var{obj} is a finalization registry.
  1893. @end deffn
  1894. @deffn {Procedure} finalization-registry-register! registry target held-value [unregister-token]
  1895. Register @var{target} with @var{registry}. When @var{target} is
  1896. garbage collected, the cleanup callback will receive @var{held-value}.
  1897. @var{held-value} @emph{cannot} be @code{eq?} to @var{target}.
  1898. If @var{unregister-token} is specified and not @code{#f} then this
  1899. token can be used to unregister @var{target} later.
  1900. @end deffn
  1901. @deffn {Procedure} finalization-registry-unregister! registry unregister-token
  1902. Unregister the objects associated with @var{unregister-token} from
  1903. @var{registry}. Return @var{#t} if at least one object was
  1904. unregistered this way.
  1905. @end deffn
  1906. @node Toolchain reference
  1907. @chapter Toolchain reference
  1908. Hoot is not just a Scheme to Wasm compiler. It's also a
  1909. self-contained and general purpose Wasm toolchain. Hoot does not use
  1910. binaryen, wabt, emscripten, etc. in order to assemble and disassemble
  1911. Wasm. The entire toolchain is implemented as a set of Scheme modules
  1912. that can be used to automate other Wasm targeted build workflows.
  1913. Since everything is implemented in one place, in a single language,
  1914. and because Guile encourages a REPL-driven development workflow, Hoot
  1915. makes a great platform for learning Wasm in a hands-on, interactive
  1916. way!
  1917. @menu
  1918. * Data types:: Core Wasm module data types.
  1919. * GWAT:: Guile-flavored WebAssembly Text format.
  1920. * Resolver:: Lower symbolic identifiers to integer identifiers.
  1921. * Symbolifier:: Lift integer identifiers to symbolic identifiers.
  1922. * Linker:: Add a standard library to a Wasm module.
  1923. * Assembler:: Create Wasm binaries.
  1924. * Binary Parser:: Parse Wasm binaries.
  1925. * Printer:: Print the contents of a Wasm module.
  1926. * Interpreter:: Execute Wasm within Guile.
  1927. * REPL commands:: Run and debug Wasm at the REPL.
  1928. @end menu
  1929. @node Data types
  1930. @section Data types
  1931. The @code{(wasm types)} module contains all the core data types that
  1932. comprise a Wasm module.
  1933. @subsection Modules
  1934. The Wasm module type is the top type, incorporating values of all the
  1935. types that are to follow.
  1936. @deffn {Procedure} wasm? obj
  1937. Return @code{#t} if @var{obj} is a Wasm module.
  1938. @end deffn
  1939. @deffn {Procedure} wasm-id wasm
  1940. Return the symbolic ID of @var{wasm}.
  1941. @end deffn
  1942. @deffn {Procedure} wasm-types wasm
  1943. Return the list of types in @var{wasm}.
  1944. @end deffn
  1945. @deffn {Procedure} wasm-imports wasm
  1946. Return the list of imports in @var{wasm}.
  1947. @end deffn
  1948. @deffn {Procedure} wasm-funcs wasm
  1949. Return the list of functions in @var{wasm}.
  1950. @end deffn
  1951. @deffn {Procedure} wasm-tables wasm
  1952. Return the list of tables in @var{wasm}.
  1953. @end deffn
  1954. @deffn {Procedure} wasm-memories wasm
  1955. Return the list of memories in @var{wasm}.
  1956. @end deffn
  1957. @deffn {Procedure} wasm-globals wasm
  1958. Return the list of globals in @var{wasm}.
  1959. @end deffn
  1960. @deffn {Procedure} wasm-exports wasm
  1961. Return the list of exports in @var{wasm}.
  1962. @end deffn
  1963. @deffn {Procedure} wasm-elems wasm
  1964. Return the list of element segments in @var{wasm}.
  1965. @end deffn
  1966. @deffn {Procedure} wasm-datas wasm
  1967. Return the list of data segments in @var{wasm}.
  1968. @end deffn
  1969. @deffn {Procedure} wasm-tags wasm
  1970. Return the list of tags in @var{wasm}.
  1971. @end deffn
  1972. @deffn {Procedure} wasm-strings wasm
  1973. Return the list of strings in @var{wasm}.
  1974. @end deffn
  1975. @deffn {Procedure} wasm-custom wasm
  1976. Return the list of custom segments in @var{wasm}.
  1977. @end deffn
  1978. @deffn {Procedure} wasm-start wasm
  1979. Return the start function index for @var{wasm}.
  1980. @end deffn
  1981. @subsection Types
  1982. Wasm has four numeric types:
  1983. @enumerate
  1984. @item @code{i32}:
  1985. 32-bit integer (signed or unsigned)
  1986. @item @code{i64}:
  1987. 64-bit integer (signed or unsigned)
  1988. @item @code{f32}:
  1989. 32-bit single precision IEEE floating point number.
  1990. @item @code{f64}:
  1991. 64-bit double precision IEEE floating point number.
  1992. @end enumerate
  1993. There is also the @code{v128} vector type, but it is currently
  1994. unsupported.
  1995. Then there are a number of reference types that fall into 3
  1996. categories: function, external, and internal.
  1997. Function reference types:
  1998. @enumerate
  1999. @item @code{func}:
  2000. Function reference.
  2001. @item @code{nofunc}:
  2002. Bottom type for functions. No function is of type @code{nofunc}.
  2003. @end enumerate
  2004. External reference types:
  2005. @enumerate
  2006. @item @code{extern}:
  2007. External reference introduced by the host.
  2008. @item @code{noextern}:
  2009. Bottom type for external references. No external reference is of type
  2010. @code{noextern}.
  2011. @end enumerate
  2012. Internal reference types:
  2013. @enumerate
  2014. @item @code{any}:
  2015. The top type of all internal reference types.
  2016. @item @code{eq}:
  2017. Structural equivalence type. Subtype of @code{all}.
  2018. @item @code{i31}:
  2019. Used for immediate references (such as the empty list or fixnums in
  2020. Scheme.) Subtype of @code{eq}.
  2021. @item @code{array}:
  2022. Super type of all array types. Subtype of @code{eq}.
  2023. @item @code{struct}:
  2024. Super type of all struct types. Subtype of @code{eq}.
  2025. @item @code{none}:
  2026. The bottom type for internal references. No internal reference is of
  2027. type @code{none}.
  2028. @end enumerate
  2029. Of course, modules may specify their own compound types assembled from
  2030. these primitives.
  2031. The type hierarchy looks like this:
  2032. @verbatim
  2033. .-----. .-------. .---------.
  2034. | any | | func | | extern |
  2035. `-----' `-------' `---------'
  2036. ↓ ↓ ↓
  2037. .-----. .-----------. .-----------.
  2038. .-------- | eq | ------------. | all funcs | | noextern |
  2039. | `-----' | `-----------' `-----------'
  2040. ↓ ↓ ↓ ↓
  2041. .-----. .-------------. .---------. .---------.
  2042. | i31 | | all arrays | | struct | | nofunc |
  2043. `-----' `-------------' `---------' `---------'
  2044. ↓ ↓
  2045. .-----. .-------------.
  2046. | any | | all structs |
  2047. `-----' `-------------'
  2048. @end verbatim
  2049. A collection of type descriptor objects form a type table that
  2050. describes all non-primitive types used within a module. Type objects
  2051. associate an identifier with a function signature or reference type
  2052. descriptor.
  2053. @deffn {Procedure} type? obj
  2054. Return @code{#t} if @var{obj} is a type.
  2055. @end deffn
  2056. @deffn {Procedure} type-id type
  2057. Return the symbolic ID of @var{type}.
  2058. @end deffn
  2059. @deffn {Procedure} type-val type
  2060. Return the type descriptor of @var{type}.
  2061. @end deffn
  2062. Types may also be nested within recursive type groups that allow for
  2063. circular and self references to the types within the group. Types
  2064. @emph{not} within a group can be thought of as belonging to a group of
  2065. one.
  2066. @deffn {Procedure} rec-group? obj
  2067. Return @code{#t} if @var{obj} is a recursive type group.
  2068. @end deffn
  2069. @deffn {Procedure} rec-group-types rec-group
  2070. Return the types within @var{rec-group}.
  2071. @end deffn
  2072. Note that while each Wasm module contains a full inventory of its
  2073. types, structurally identical type groups across Wasm modules are
  2074. canonicalized at runtime and are considered to be identical
  2075. (@code{eq?} in Scheme terms.) This allows for passing references
  2076. between modules.
  2077. Type uses refer to function signatures and are used for specifying the
  2078. type of a @code{block}, @code{loop}, or @code{if} expression.
  2079. @deffn {Procedure} type-use? obj
  2080. Return @code{#t} if @var{obj} is a type use.
  2081. @end deffn
  2082. @deffn {Procedure} type-use-idx type-use
  2083. Return the type index of @var{type-use}.
  2084. @end deffn
  2085. @deffn {Procedure} type-use-sig type-use
  2086. Return the function signature of @var{type-use}.
  2087. @end deffn
  2088. @deffn {Procedure} ref-type? obj
  2089. Return @code{#t} if @var{obj} is a reference type.
  2090. @end deffn
  2091. @deffn {Procedure} ref-type-nullable? ref-type
  2092. Return @var{#t} if @var{ref-type} is nullable.
  2093. @end deffn
  2094. @deffn {Procedure} ref-type-heap-type ref-type
  2095. Return the heap type of @var{ref-type}.
  2096. @end deffn
  2097. As mentioned above, reference types support structural subtyping.
  2098. @deffn {Procedure} sub-type? obj
  2099. Return @code{#t} if @var{obj} is a sub type.
  2100. @end deffn
  2101. @deffn {Procedure} sub-type-final? sub-type
  2102. Return @code{#t} if @var{sub-type} is marked as final.
  2103. @end deffn
  2104. @deffn {Procedure} sub-type-supers sub-type
  2105. Return super types of @var{sub-type}.
  2106. @end deffn
  2107. @deffn {Procedure} sub-type-type sub-type
  2108. Return the concrete type descriptor of @var{sub-type}.
  2109. @end deffn
  2110. Compound types take the form of arrays and structs.
  2111. @deffn {Procedure} array-type? obj
  2112. Return @code{#t} if @var{obj} is an array type.
  2113. @end deffn
  2114. @deffn {Procedure} array-type-mutable? array-type
  2115. Return @code{#t} if @var{array-type} is mutable.
  2116. @end deffn
  2117. @deffn {Procedure} array-type-type array-type
  2118. Retun the element type descriptor of @var{array-type}.
  2119. @end deffn
  2120. @deffn {Procedure} struct-type? obj
  2121. Return @code{#t} if @var{obj} is a struct type.
  2122. @end deffn
  2123. @deffn {Procedure} struct-type-fields struct-type
  2124. Return the field descriptors of @var{struct-type}.
  2125. @end deffn
  2126. Struct types are composed of several fields.
  2127. @deffn {Procedure} field? obj
  2128. Return @code{#t} if @var{obj} is a struct field.
  2129. @end deffn
  2130. @deffn {Procedure} field-id field
  2131. Return the symbolic ID of @var{field}.
  2132. @end deffn
  2133. @deffn {Procedure} field-mutable? field
  2134. Return @code{#t} if @var{field} is mutable.
  2135. @end deffn
  2136. @deffn {Procedure} field-type field
  2137. Return the type descriptor of @var{field}.
  2138. @end deffn
  2139. Both arrays and struct fields allow for packed data using the special
  2140. @code{i8} and @code{i16} data types.
  2141. @subsection Globals
  2142. Wasm supports both mutable and immutable global variables.
  2143. @deffn {Procedure} global? obj
  2144. Return @code{#t} if @var{obj} is a global.
  2145. @end deffn
  2146. @deffn {Procedure} global-id global
  2147. Return the symbloc ID of @var{global}.
  2148. @end deffn
  2149. @deffn {Procedure} global-type global
  2150. Return the type of @var{global}.
  2151. @end deffn
  2152. @deffn {Procedure} global-init global
  2153. Return the initialization instructions of @var{global}. Only constant
  2154. instructions are allowed.
  2155. @end deffn
  2156. @deffn {Procedure} global-type? obj
  2157. Return @code{#t} if @var{obj} is a global type.
  2158. @end deffn
  2159. @deffn {Procedure} global-type-mutable? global-type
  2160. Return @code{#t} if @var{global-type} is mutable.
  2161. @end deffn
  2162. @deffn {Procedure} global-type-type global-type
  2163. Return the type descriptor of @var{global-type}.
  2164. @end deffn
  2165. @subsection Functions
  2166. @deffn {Procedure} func? obj
  2167. Return @code{#t} if @var{obj} is a function.
  2168. @end deffn
  2169. @deffn {Procedure} func-id func
  2170. Return the symbolic ID of @var{func}.
  2171. @end deffn
  2172. @deffn {Procedure} func-type func
  2173. Return the signature of @var{func}.
  2174. @end deffn
  2175. @deffn {Procedure} func-locals func
  2176. Return the locals of @var{func}.
  2177. @end deffn
  2178. @deffn {Procedure} func-body func
  2179. Return the body instructions of @var{func}.
  2180. @end deffn
  2181. The type of a function is its signature. Notably, Wasm supports
  2182. multiple return values, just like Scheme.
  2183. @deffn {Procedure} func-sig? obj
  2184. Return @code{#t} if @var{obj} is a function signature.
  2185. @end deffn
  2186. @deffn {Procedure} func-sig-params func
  2187. Return the parameters of @var{func}.
  2188. @end deffn
  2189. @deffn {Procedure} func-sig-results func
  2190. Return the result types of @var{func}.
  2191. @end deffn
  2192. Function parameters pair a local identifier with its type.
  2193. @deffn {Procedure} param? obj
  2194. Return @code{#t} if @var{obj} is a param.
  2195. @end deffn
  2196. @deffn {Procedure} param-id param
  2197. Return the symbolic ID of @var{param}.
  2198. @end deffn
  2199. @deffn {Procedure} param-type param
  2200. Return the type descriptor of @var{param}.
  2201. @end deffn
  2202. Locals provide additional mutable variables scoped to the body of a
  2203. function.
  2204. @deffn {Procedure} local? obj
  2205. Return @code{#t} if @var{obj} is a function local.
  2206. @end deffn
  2207. @deffn {Procedure} local-id local
  2208. Return the symbolic ID of @var{local}.
  2209. @end deffn
  2210. @deffn {Procedure} local-type local
  2211. Return the type descriptor of @var{local}.
  2212. @end deffn
  2213. @subsection Imports/exports
  2214. Functions, globals, memories, and tables can be imported from the host
  2215. or another Wasm module. They are organized into a two layer
  2216. hierarchy. An import module groups many imports under an umbrella
  2217. name, and then the individual item names distinguish imported data
  2218. within a module.
  2219. @deffn {Procedure} import? obj
  2220. Return @code{#t} if @var{obj} is an import.
  2221. @end deffn
  2222. @deffn {Procedure} import-mod import
  2223. Return the module name string of @var{import}.
  2224. @end deffn
  2225. @deffn {Procedure} import-name import
  2226. Return the name string of @var{import}.
  2227. @end deffn
  2228. @deffn {Procedure} import-kind import
  2229. Return the kind of @var{import}. Either @code{func}, @code{global},
  2230. @code{memory}, or @code{table}.
  2231. @end deffn
  2232. @deffn {Procedure} import-id import
  2233. Return the symbolic ID of @var{import}.
  2234. @end deffn
  2235. @deffn {Procedure} import-type import
  2236. Return the type descriptor of @var{import}.
  2237. @end deffn
  2238. Likewise, functions, globals, memories, and tables can be exported
  2239. from a module to be used by the host or by other modules.
  2240. @deffn {Procedure} export? obj
  2241. Return @code{#t} if @var{obj} is an export.
  2242. @end deffn
  2243. @deffn {Procedure} export-name export
  2244. Return the name string of @var{export}.
  2245. @end deffn
  2246. @deffn {Procedure} export-kind export
  2247. Return the kind of @var{export}. Either @code{func}, @code{global},
  2248. @code{memory}, or @code{table}.
  2249. @end deffn
  2250. @deffn {Procedure} export-idx export
  2251. Return the index of @var{export}.
  2252. @end deffn
  2253. @subsection Linear memory
  2254. Memory objects specify linear chunks of bytes that a module can write
  2255. to/read from at runtime. The size of a memory is specified in terms
  2256. of 64KiB pages. While many memory objects coud be included in a
  2257. module, the Wasm specification currently only allows the use of a
  2258. single memory at index 0.
  2259. @deffn {Procedure} memory? obj
  2260. Return @code{#t} if @var{obj} is a memory.
  2261. @end deffn
  2262. @deffn {Procedure} memory-id memory
  2263. Return the symbolic ID of @var{memory}.
  2264. @end deffn
  2265. The type of a memory currently just specifies the size limitations.
  2266. @deffn {Procedure} memory-type memory
  2267. Return the type of @var{memory}.
  2268. @end deffn
  2269. @deffn {Procedure} mem-type? obj
  2270. Return @code{#t} if @var{obj} is a memory type.
  2271. @end deffn
  2272. @deffn {Procedure} mem-type-limits mem-type
  2273. Return the limits of @var{mem-type}.
  2274. @end deffn
  2275. Instructions that manipulate linear memory use the memory argument
  2276. type to point to a specific offset within a memory.
  2277. @deffn {Procedure} mem-arg? obj
  2278. Return @code{#t} if @var{obj} is a memory argument.
  2279. @end deffn
  2280. @deffn {Procedure} mem-arg-id mem-arg
  2281. Return the symbolic ID of @var{mem-arg}.
  2282. @end deffn
  2283. @deffn {Procedure} mem-arg-offset mem-arg
  2284. Return the offset of @var{mem-arg}.
  2285. @end deffn
  2286. @deffn {Procedure} mem-arg-align mem-arg
  2287. Return the alignment of @var{mem-arg}.
  2288. @end deffn
  2289. @subsection Data segments
  2290. Data segments are static chunks of data used to initialize regions of
  2291. memory. They have two possible modes of use:
  2292. @enumerate
  2293. @item @strong{Active:}
  2294. The data segment is copied into memory during instantiation.
  2295. @item @strong{Passive:}
  2296. The data segment is copied into memory using the @code{memory.init}
  2297. instruction.
  2298. @end enumerate
  2299. @deffn {Procedure} data? obj
  2300. Return @code{#t} if @var{obj} is a data segment.
  2301. @end deffn
  2302. @deffn {Procedure} data-id data
  2303. Return the symbolic ID of @var{data}.
  2304. @end deffn
  2305. @deffn {Procedure} data-mode data
  2306. Return the mode of @var{data}. Either @code{passive} or
  2307. @code{active}.
  2308. @end deffn
  2309. @deffn {Procedure} data-mem data
  2310. Return the memory associated with @var{data}.
  2311. @end deffn
  2312. @deffn {Procedure} data-offset data
  2313. Return the instructions that compute the offset of @var{data}. Only
  2314. constant instructions are allowed.
  2315. @end deffn
  2316. @deffn {Procedure} data-init data
  2317. Return a bytevector containing the initialization data of @var{data}.
  2318. @end deffn
  2319. @subsection Tables
  2320. Tables specify a vector of heap object references of a particular
  2321. reference type.
  2322. @deffn {Procedure} table? obj
  2323. Return @code{#t} if @var{obj} is a reference table.
  2324. @end deffn
  2325. @deffn {Procedure} table-id table
  2326. Return the symbolic ID of @var{table}.
  2327. @end deffn
  2328. @deffn {Procedure} table-type table
  2329. Return the type of @var{table}.
  2330. @end deffn
  2331. Table types specify the reference type of the elements as well as the
  2332. size limitations.
  2333. @deffn {Procedure} table-type? obj
  2334. Return @code{#t} if @var{obj} is a table type.
  2335. @end deffn
  2336. @deffn {Procedure} table-type-limits table-type
  2337. Return the limts of @var{table-type}.
  2338. @end deffn
  2339. @deffn {Procedure} table-type-elem-type table-type
  2340. Return the element type of @var{table-type}.
  2341. @end deffn
  2342. @subsection Element segments
  2343. Element segments are static vectors of references used to initialize
  2344. regions of tables (well, mostly.) They have three possible modes of
  2345. use:
  2346. @enumerate
  2347. @item @strong{Active:}
  2348. The element segment is copied into its associated table during
  2349. instantiation.
  2350. @item @strong{Passive:}
  2351. The element segment is copied into its associated table using the
  2352. @code{table.init} instruction.
  2353. @item @strong{Declarative:}
  2354. The element segment is unavailable at runtime and is instead used for
  2355. forward declarations of types that are used elsewhere in the code.
  2356. @end enumerate
  2357. @deffn {Procedure} elem? obj
  2358. Return @code{#t} if @var{obj} is an element segment.
  2359. @end deffn
  2360. @deffn {Procedure} elem-id elem
  2361. Return the symoblic ID of @var{elem}.
  2362. @end deffn
  2363. @deffn {Procedure} elem-mode elem
  2364. Return the mode of @var{elem}.
  2365. @end deffn
  2366. @deffn {Procedure} elem-table elem
  2367. Return the table associated with @var{elem}.
  2368. @end deffn
  2369. @deffn {Procedure} elem-type elem
  2370. Return the type of @var{elem}.
  2371. @end deffn
  2372. @deffn {Procedure} elem-offset elem
  2373. Return the instructions that compute the offset of @var{elem}. Only
  2374. constant instructions are allowed.
  2375. @end deffn
  2376. @deffn {Procedure} elem-inits elem
  2377. Return a list of initializer instructions for the items of @var{elem}.
  2378. Only constant instructions are allowed.
  2379. @end deffn
  2380. @subsection Limits
  2381. Both memories and tables use limits to constrain their minimum and
  2382. maximum size. A valid limit must have a minimum of at least 1, but
  2383. the maximum may be @code{#f} if unbounded growth is allowed.
  2384. @deffn {Procedure} limits? obj
  2385. Return @code{#t} if @var{obj} is a limits.
  2386. @end deffn
  2387. @deffn {Procedure} limits-min limits
  2388. Return the minimum value of @var{limits}.
  2389. @end deffn
  2390. @deffn {Procedure} limits-max limits
  2391. Return the maximum value of @var{limits} or @code{#f} if there is no
  2392. maximum.
  2393. @end deffn
  2394. @subsection Tags
  2395. Tag segments specify types of runtime errors that may be raised.
  2396. @deffn {Procedure} tag? obj
  2397. Return @code{#t} if @var{obj} is a tag.
  2398. @end deffn
  2399. @deffn {Procedure} tag-id tag
  2400. Return the symbolic ID of @var{tag}.
  2401. @end deffn
  2402. @deffn {Procedure} tag-type tag
  2403. Return the type of @var{tag}.
  2404. @end deffn
  2405. Tag types specify the function signature of the tags. Since tags are
  2406. not truly functions, their signatures must only have parameters and no
  2407. results.
  2408. @deffn {Procedure} tag-type? obj
  2409. Return @code{#t} if @var{obj} is a tag type.
  2410. @end deffn
  2411. @deffn {Procedure} tag-type-attribute tag-type
  2412. Return the symbolic attribute of @var{tag-type}. Currently, there is
  2413. only one valid attribute: @code{exception}.
  2414. @end deffn
  2415. @deffn {Procedure} tag-type-type tag-type
  2416. Return the type of @var{tag-type}. This is expected to be a type use
  2417. object that refers to a function signature.
  2418. @end deffn
  2419. @subsection Custom sections
  2420. Custom sections specify arbitrary data that is not covered by the Wasm
  2421. specification.
  2422. @deffn {Procedure} custom? obj
  2423. Return @code{#t} if @var{obj} is a custom segment.
  2424. @end deffn
  2425. @deffn {Procedure} custom-name custom
  2426. Return the name of @var{custom}.
  2427. @end deffn
  2428. @deffn {Procedure} custom-bytes custom
  2429. Return the bytevector of @var{custom}.
  2430. @end deffn
  2431. There is, however, one custom section that @emph{is} specified: the
  2432. name section. This section contains various ``name maps'' that can be
  2433. used to translate integer identifiers to (hopefully) human-readable
  2434. names for the purposes of debugging.
  2435. Hoot supports the name subsections described in the Wasm core
  2436. specification, the Wasm GC specification, and the extended names
  2437. proposal:
  2438. @enumerate
  2439. @item Module name
  2440. @item Function name map
  2441. @item Function local indirect name map
  2442. @item Block label indirect name map
  2443. @item Type name map
  2444. @item Table name map
  2445. @item Memory name map
  2446. @item Global name map
  2447. @item Element name map
  2448. @item Data name map
  2449. @item Struct field indirect name map
  2450. @item Tag name map
  2451. @end enumerate
  2452. Name maps are represented as association lists mapping integers to
  2453. strings. Indirect name maps are represented as association lists
  2454. mapping integers to name maps.
  2455. @deffn {Procedure} names? obj
  2456. Return @code{#t} if @var{obj} is a name section object.
  2457. @end deffn
  2458. @deffn {Procedure} names-module names
  2459. Return the module name of @var{names}.
  2460. @end deffn
  2461. @deffn {Procedure} names-func names
  2462. Return the function name map of @var{names}.
  2463. @end deffn
  2464. @deffn {Procedure} names-local names
  2465. Return the function local indirect name map of @var{names}.
  2466. @end deffn
  2467. @deffn {Procedure} names-label names
  2468. Return the block label indirect name map of @var{names}.
  2469. @end deffn
  2470. @deffn {Procedure} names-type names
  2471. Return the type name map of @var{names}.
  2472. @end deffn
  2473. @deffn {Procedure} names-table names
  2474. Return the table name map of @var{names}.
  2475. @end deffn
  2476. @deffn {Procedure} names-memory names
  2477. Return the memory name map of @var{names}.
  2478. @end deffn
  2479. @deffn {Procedure} names-global names
  2480. Return the global name map of @var{names}.
  2481. @end deffn
  2482. @deffn {Procedure} names-elem names
  2483. Return the element name map of @var{names}.
  2484. @end deffn
  2485. @deffn {Procedure} names-data names
  2486. Return the data name map of @var{names}.
  2487. @end deffn
  2488. @deffn {Procedure} names-fields names
  2489. Return the struct field indirect name map of @var{names}.
  2490. @end deffn
  2491. @deffn {Procedure} names-tag names
  2492. Return the tag name map of @var{names}.
  2493. @end deffn
  2494. @node GWAT
  2495. @section GWAT
  2496. The @code{(wasm wat)} module provides a parser for a variant of
  2497. WebAssembly Text (WAT) format. Since the WAT uses an s-expression
  2498. syntax that resembles but is distinct from Scheme syntax, Hoot opts to
  2499. represent WAT code as Scheme expressions. This allows for embedding
  2500. WAT directly into Scheme code and programmatically generating WAT code
  2501. via quasiquote templating or other means. We call this variant GWAT
  2502. where the ``G'' stands for ``Guile'', of course.
  2503. The GWAT form has some additional expressive power such as allowing
  2504. string constants, bytevectors for data segments, and i32/i64 constants
  2505. in either the signed or unsigned range.
  2506. WAT has two variants: unfolded and folded. In the unfolded form,
  2507. instruction sequences are linear, as they would be in the resulting
  2508. binary:
  2509. @lisp
  2510. '(module
  2511. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2512. (local.get $a)
  2513. (local.get $b)
  2514. (i32.add)))
  2515. @end lisp
  2516. The folded form allows instructions to be nested within each other:
  2517. @lisp
  2518. '(module
  2519. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2520. (i32.add (local.get $a)
  2521. (local.get $b))))
  2522. @end lisp
  2523. This form looks more like Scheme procedure calls and is generally
  2524. easier to write and reason about.
  2525. @deffn {Procedure} wat->wasm expr
  2526. Parse @var{expr}, a Wasm module expressed as WAT code, and return a
  2527. Wasm module.
  2528. @lisp
  2529. (parse-wat
  2530. '(module
  2531. (func (export "add") (param $a i32) (param $b i32) (result i32)
  2532. (i32.add (local.get $a)
  2533. (local.get $b)))))
  2534. @end lisp
  2535. The returned Wasm module preserves named references, among other
  2536. things, and is thus unsuitable as input to the assembler or
  2537. interpreter. To lower the module into a usable form, see
  2538. @code{resolve-wasm} in @ref{Resolver}.
  2539. @end deffn
  2540. @deffn {Procedure} wasm->wat wasm
  2541. Disassemble @var{wasm} and return its symbolic WAT form. @var{wasm}
  2542. is assumed to be in @emph{symbolified} form (@pxref{Symbolifier}).
  2543. @end deffn
  2544. @node Resolver
  2545. @section Resolver
  2546. The @code{(wasm resolve)} module provides the @code{resolve-wasm}
  2547. procedure which lowers Wasm modules into a form that can be used by
  2548. the assembler or interpreter. The resolver replaces named references
  2549. with their respective integer identifiers, fills out the type table,
  2550. and adjusts i32 and i64 constants into their canonical form.
  2551. @deffn {Procedure} resolve-wasm mod [#:emit-names? #f]
  2552. Lower the Wasm module @var{mod} into a form that can be assembled or
  2553. interpreted. Returns a new Wasm module and does not modify @var{mod}.
  2554. When @var{emit-names?} is @code{#t}, the returned Wasm module will
  2555. include a name map that maps the original, human-readable names to the
  2556. resolved integer identifiers.
  2557. @end deffn
  2558. @node Symbolifier
  2559. @section Symbolifier
  2560. The @code{(wasm symbolify)} module does the opposite of @code{(wasm
  2561. resolve)} by giving symbolic names to all objects in a Wasm module.
  2562. Symbolified Wasm is useful for disassembling binaries (see
  2563. @code{wasm->wat} in @ref{GWAT}).
  2564. @deffn {Procedure} symbolify-wasm wasm
  2565. Return a new Wasm module derived from @var{wasm} where all definitions
  2566. and uses have been given unique symbolic identifiers.
  2567. @end deffn
  2568. @node Linker
  2569. @section Linker
  2570. The @code{(wasm link)} module provides a means for extending a Wasm
  2571. module with the standard library that it needs at runtime. Hoot uses
  2572. the linker to add the Scheme runtime to the compiled form of user
  2573. code. The linker uses a form of tree-shaking to remove anything that
  2574. is not used by the base module.
  2575. @deffn {Procedure} add-stdlib wasm stdlib
  2576. Return a new Wasm module that is the combination of the Wasm module
  2577. @var{wasm} with the Wasm module @var{stdlib}.
  2578. @end deffn
  2579. @node Assembler
  2580. @section Assembler
  2581. The @code{(wasm assemble)} module is used to lower Wasm modules into
  2582. the Wasm binary format.
  2583. @deffn {Procedure} assemble-wasm wasm
  2584. Return a bytevector containing the assembled binary form of the Wasm
  2585. module @var{wasm}.
  2586. @end deffn
  2587. @node Binary Parser
  2588. @section Binary Parser
  2589. The @code{(wasm parse)} module parses the Wasm binary format.
  2590. @deffn {Procedure} parse-wasm port
  2591. Parse the Wasm binary data from @var{port} and return a Wasm module.
  2592. @end deffn
  2593. @node Printer
  2594. @section Printer
  2595. The @code{(wasm dump)} module provides the @code{dump-wasm} procedure
  2596. for generating a detailed print-out of a Wasm module's contents. See
  2597. also @ref{Wasm REPL commands} for the @code{wasm-dump} REPL
  2598. command.
  2599. @deffn {Procedure} dump-wasm mod [#:port] [#:dump-func-defs? #t]
  2600. Write a detailed inventory of the Wasm module @var{mod} to @var{port}
  2601. or the current output port if @var{port} is not specified. If
  2602. @var{dump-func-defs?} is @code{#t}, which is the default, all function
  2603. definitions are printed, including the instructions in the body of
  2604. each. Depending on the size of the module, this may be an
  2605. overwhelming amount of data, thus it is made optional.
  2606. @end deffn
  2607. @node Interpreter
  2608. @section Interpreter
  2609. The @code{(wasm vm)} module provides a virtual machine for
  2610. interpreting Wasm functions. To use the interpreter, a Wasm module is
  2611. first validated for type safety (among other things) and then
  2612. instantiated, at which point exported functions become callable from
  2613. Scheme.
  2614. The interpreter only accepts validated Wasm. The @code{validate-wasm}
  2615. procedure validates and wraps a Wasm module to indicate successful
  2616. validation:
  2617. @lisp
  2618. (use-modules (wasm vm) (wasm resolve))
  2619. (define validated-wasm
  2620. (validate-wasm
  2621. (wat->wasm
  2622. '(module
  2623. (func (export "main") (result i32)
  2624. (i32.const 42))))))
  2625. @end lisp
  2626. When starting with a Wasm binary, the convenient
  2627. @code{load-and-validate-wasm} procedure parses the binary and then
  2628. performs validation:
  2629. @lisp
  2630. (call-with-input-file "hello.wasm" load-and-validate-wasm)
  2631. @end lisp
  2632. Once the Wasm module has been validated, the runtime data needed for
  2633. interpretation can be created by instantiating the module:
  2634. @lisp
  2635. (define instance (instantiate-wasm validated-wasm))
  2636. @end lisp
  2637. Exported Wasm functions then become usable as Scheme procedures:
  2638. @lisp
  2639. (define wasm-main (wasm-instance-export-ref instance "main"))
  2640. (wasm-main) ;; => 42
  2641. @end lisp
  2642. Wasm functions are statically typed, which means that calls from
  2643. Scheme to Wasm require runtime type checking for each call.
  2644. @subsection Validation
  2645. @deffn {Procedure} validate-wasm wasm
  2646. Validate the Wasm module @var{wasm} and return a validated Wasm
  2647. object.
  2648. @end deffn
  2649. @deffn {Procedure} load-and-validate-wasm obj
  2650. Load and validate the Wasm module within @var{obj} then return a
  2651. validated Wasm object. @var{obj} may be a @code{<wasm>} record as
  2652. produced by @code{resolve-wasm} (@pxref{Resolver}), a bytevector
  2653. containing a Wasm binary, or an input port from which to read a Wasm
  2654. binary.
  2655. @end deffn
  2656. @deffn {Procedure} validated-wasm? obj
  2657. Return @code{#t} if @var{obj} is a validated Wasm object.
  2658. @end deffn
  2659. @deffn {Procedure} validated-wasm-ref validated-wasm
  2660. Unbox and return the Wasm module within @var{validated-wasm}.
  2661. @end deffn
  2662. @subsection Instantiation
  2663. @deffn {Procedure} instantiate-wasm wasm [#:imports '()]
  2664. Return a new Wasm instance for the validated Wasm module @var{wasm}.
  2665. @var{imports} is a nested association list of imported functions,
  2666. globals, memories, and tables. Wasm imports are identified by a
  2667. module name and an object name. Consider the following Wasm module
  2668. that computes 2D polar coordinates and prints them to a log:
  2669. @lisp
  2670. (use-modules (wasm resolve) (wasm vm) (wasm wat))
  2671. (define the-module
  2672. (resolve-wasm
  2673. (wat->wasm
  2674. '(module
  2675. (func $logf64 (import "debug" "logf64") (param f64))
  2676. (func $cos (import "math" "cos") (param f64) (result f64))
  2677. (func $sin (import "math" "sin") (param f64) (result f64))
  2678. (func (export "polar") (param $r f64) (param $theta f64)
  2679. (call $logf64 (f64.mul (local.get $r)
  2680. (call $cos (local.get $theta))))
  2681. (call $logf64 (f64.mul (local.get $r)
  2682. (call $sin (local.get $theta)))))))))
  2683. @end lisp
  2684. This module requires three imported functions from two modules. Thus
  2685. the module instantiation code would look like this:
  2686. @lisp
  2687. (define (logf64 x)
  2688. (format #t "f64: ~a\n" x))
  2689. (define the-instance
  2690. (instantiate-wasm (validate-wasm the-module)
  2691. #:imports `(("debug" . (("logf64" . ,logf64)))
  2692. ("math" . (("cos" . ,cos)
  2693. ("sin" . ,sin))))))
  2694. @end lisp
  2695. @end deffn
  2696. @subsection Globals
  2697. @deffn {Procedure} make-wasm-global value mutable?
  2698. Return a new Wasm global containing @var{value}. When @var{mutable?}
  2699. is @code{#f}, the value cannot be modified later.
  2700. @end deffn
  2701. @deffn {Procedure} wasm-global? obj
  2702. Return @code{#t} if @var{obj} is a Wasm global.
  2703. @end deffn
  2704. @deffn {Procedure} wasm-global-ref global
  2705. Return the current value within @var{global}.
  2706. @end deffn
  2707. @deffn {Procedure} wasm-global-set! global val
  2708. Set the value within @var{global} to @var{val}. An exception is
  2709. raised if @var{global} is immutable.
  2710. @end deffn
  2711. @deffn {Procedure} wasm-global-mutable? global
  2712. Return @code{#t} if @var{global} is mutable.
  2713. @end deffn
  2714. @subsection Memories
  2715. @deffn {Procedure} make-wasm-memory size [#:limits (make-limits 1 #f)]
  2716. Return a new Wasm linear memory containing @var{size} 64KiB pages.
  2717. @var{limits} determines the lower and upper bounds of how many pages
  2718. this memory can store. The default limits are a minimum of 1 page and
  2719. no maximum page limit. @xref{Data types} for more information on
  2720. limit objects.
  2721. @end deffn
  2722. @deffn {Procedure} wasm-memory? obj
  2723. Return @code{#t} if @var{obj} is a Wasm memory.
  2724. @end deffn
  2725. @deffn {Procedure} wasm-memory-bytes memory
  2726. Return the current bytevector representing the pages of @var{memory}.
  2727. @end deffn
  2728. @deffn {Procedure} wasm-memory-size memory
  2729. Return the size of @var{memory} in 64KiB pages.
  2730. @end deffn
  2731. @deffn {Procedure} wasm-memory-limits memory
  2732. Return the limits of @var{memory}
  2733. @end deffn
  2734. @deffn {Procedure} wasm-memory-grow! memory n
  2735. Increase the size of @var{memory} by @var{n} pages. An exception is
  2736. raised if growing by @var{n} exceeds the limits of @var{memory}.
  2737. @end deffn
  2738. @subsection Tables
  2739. @deffn {Procedure} make-wasm-table size [#:limits (make-limits 1 #f)]
  2740. Return a new Wasm reference table containing @var{size} element slots.
  2741. @var{limits} determines the lower and upper bounds of how many
  2742. elements this table can store. The default limits are a minimum of 1
  2743. element and no maximum element limit. @xref{Data types} for more
  2744. information on limit objects.
  2745. @end deffn
  2746. @deffn {Procedure} wasm-table?
  2747. Return @code{#t} if @var{obj} is a Wasm table.
  2748. @end deffn
  2749. @deffn {Procedure} wasm-table-size table
  2750. Return the size of @var{table}.
  2751. @end deffn
  2752. @deffn {Procedure} wasm-table-ref table i
  2753. Return the reference at the @var{i}th index in @var{table}.
  2754. @end deffn
  2755. @deffn {Procedure} wasm-table-set! table i x
  2756. Set the @var{i}th element of @var{table} to @var{x}, a Wasm reference
  2757. type.
  2758. @end deffn
  2759. @deffn {Procedure} wasm-table-fill! table start fill length
  2760. Fill the elements of @var{table} from @var{start} to @var{start} +
  2761. @var{length}, exclusive, with the value @var{fill}.
  2762. @end deffn
  2763. @deffn {Procedure} wasm-table-copy! table at elems start length
  2764. Copy the block of elements from vector @var{elems}, from @var{start}
  2765. to @var{start} + @var{length}, exclusive, to @var{table}, starting at
  2766. @var{at}.
  2767. @end deffn
  2768. @deffn {Procedure} wasm-table-grow! table n init
  2769. Increase the size of @var{table} by @var{n} elements. An exception is
  2770. raised if growing by @var{n} exceeds the limits of @var{table}.
  2771. @end deffn
  2772. @subsection Observation
  2773. Every Wasm instruction evaluated by interpreter can be observed via
  2774. the @code{current-instruction-listener} parameter. Use this hook to
  2775. instrument Wasm modules.
  2776. The following instruction listener would print every instruction's
  2777. name on a separate line:
  2778. @lisp
  2779. (define (log-instr instr path instance stack blocks locals)
  2780. (display (car instr))
  2781. (newline))
  2782. (parameterize ((current-instruction-listener log-instr))
  2783. ...)
  2784. @end lisp
  2785. @defvar current-instruction-listener
  2786. The current instruction observation hook which is invoked
  2787. @emph{before} each instruction evaluation. Must be a procedure that
  2788. accepts the following arguments:
  2789. @enumerate
  2790. @item @strong{Instruction:}
  2791. The symbolic Wasm instruction to be evaluated.
  2792. @item @strong{Path:}
  2793. The symbolic location of the instruction within the Wasm module.
  2794. @item @strong{Instance:}
  2795. The instance that is evaluating the instruction.
  2796. @item @strong{Stack:}
  2797. The Wasm value stack.
  2798. @item @strong{Blocks:}
  2799. The Wasm block stack, which is just a list of prompt tags.
  2800. @item @strong{Locals:}
  2801. The Wasm function locals.
  2802. @end enumerate
  2803. @end defvar
  2804. The Wasm value stack is a special data type with the following API:
  2805. @deffn {Procedure} wasm-stack? obj
  2806. Return @code{#t} if @var{obj} is a Wasm value stack.
  2807. @end deffn
  2808. @deffn {Procedure} wasm-stack-items stack
  2809. Return the values on @var{stack} as a list.
  2810. @end deffn
  2811. @node Wasm REPL commands
  2812. @section REPL commands
  2813. The @code{(hoot repl)} module provides a set of REPL commands to
  2814. assist with inspecting and debugging Wasm modules. As a matter of
  2815. course, Hoot's Scheme compiler @emph{should not} cause low-level Wasm
  2816. runtime errors, but when it does, or when working with the Wasm
  2817. toolchain directly, these REPL tools may provide some assistance.
  2818. To install the REPL commands, simply import the module:
  2819. @lisp
  2820. scheme@@(guile-user)> ,use (hoot repl)
  2821. @end lisp
  2822. To see a list of all the Wasm commands, run:
  2823. @lisp
  2824. scheme@@(guile-user)> ,help wasm
  2825. @end lisp
  2826. To demonstrate the debugging features, let's create a trivial module
  2827. with a buggy function:
  2828. @lisp
  2829. @verbatim
  2830. scheme@(guile-user)> (define src
  2831. '(module
  2832. (func (export "main") (param $x i32) (result i32)
  2833. (i32.add (local.get $x)
  2834. (unreachable)))))
  2835. @end verbatim
  2836. @end lisp
  2837. When called, this function will hit the @code{unreachable} instruction
  2838. and throw a runtime error. Let's compile the WAT source, load it into
  2839. the VM, and get a reference to the @code{main} function:
  2840. @lisp
  2841. @verbatim
  2842. scheme@(guile-user)> ,use (wasm resolve) (wasm vm) (wasm wat)
  2843. scheme@(guile-user)> (define wasm (validate-wasm (resolve-wasm (wat->wasm src))))
  2844. scheme@(guile-user)> (define instance (instantiate-wasm wasm))
  2845. scheme@(guile-user)> (define main (wasm-instance-export-ref instance "main"))
  2846. @end verbatim
  2847. @end lisp
  2848. To trap the Wasm runtime error and open a Wasm debugging REPL, the
  2849. @command{wasm-catch} REPL command can be prefixed before an
  2850. expression:
  2851. @lisp
  2852. @verbatim
  2853. scheme@(guile-user)> ,wasm-catch (main 7)
  2854. ice-9/boot-9.scm:1674:22: In procedure raise-exception:
  2855. ERROR:
  2856. 1. &wasm-runtime-error:
  2857. instruction: (unreachable)
  2858. position: (func 0 1)
  2859. instance: #<wasm-instance 140506559041920>
  2860. stack: #<<wasm-stack> items: (7)>
  2861. blocks: ((wasm-block))
  2862. locals: #(7)
  2863. 2. &message: "Wasm runtime error: unreachable"
  2864. 3. &irritants: ()
  2865. Entering Wasm debug prompt. Type `,help wasm' for info or `,q' to continue.
  2866. scheme@(guile-user) [1]>
  2867. @end verbatim
  2868. @end lisp
  2869. Once in a Wasm debug context, many of the other REPL commands become
  2870. usable. To highlight the instruction where execution has paused, use
  2871. @command{wasm-pos}:
  2872. @lisp
  2873. @verbatim
  2874. scheme@(guile-user) [1]> ,wasm-pos
  2875. (func 0 (param $x i32) (result i32)
  2876. (local.get 0)
  2877. <<< (unreachable) >>>
  2878. (i32.add))
  2879. @end verbatim
  2880. @end lisp
  2881. To print the contents of the values stack, use @command{wasm-stack}:
  2882. @lisp
  2883. @verbatim
  2884. scheme@(guile-user) [1]> ,wasm-stack
  2885. Value stack:
  2886. 0: 7
  2887. @end verbatim
  2888. @end lisp
  2889. To print the contents of the function locals, use @command{wasm-locals}:
  2890. @lisp
  2891. @verbatim
  2892. scheme@(guile-user) [1]> ,wasm-locals
  2893. Locals:
  2894. 0: 7
  2895. @end verbatim
  2896. @end lisp
  2897. To evaluate arbitary Wasm instructions in the current context, either
  2898. in an attempt to repair interpreter state or just for fun, use
  2899. @command{wasm-eval}:
  2900. @lisp
  2901. @verbatim
  2902. scheme@(guile-user) [1]> ,wasm-eval '(local.get 0)
  2903. scheme@(guile-user) [1]> ,wasm-stack
  2904. Value stack:
  2905. 0: 7
  2906. 1: 7
  2907. @end verbatim
  2908. @end lisp
  2909. There are now two i32 values on the stack. If we were to proceed with
  2910. execution, the next instruction, @code{i32.add}, should add them
  2911. together and return a result of 14. To resume execution, use
  2912. @command{wasm-continue}:
  2913. @lisp
  2914. @verbatim
  2915. scheme@(guile-user) [1]> ,wasm-continue
  2916. $5 = 14
  2917. @end verbatim
  2918. @end lisp
  2919. Evaluating arbitrary Wasm commands in a debugging context is very
  2920. helpful when trying to understand the nature of a bug, but bear in
  2921. mind that cursed things may happen during the process as there is no
  2922. validation applied. This goes especially for when you try to resume
  2923. execution.
  2924. See @ref{Interpreter} for detailed information on running Wasm within
  2925. Guile and @ref{Toolchain reference} in general for working with Wasm
  2926. directly.
  2927. @deffn {REPL Command} wasm-trace exp
  2928. Evaluate @var{exp} with verbose Wasm tracing enabled. This will print
  2929. out every instruction along with the state of the value stack and
  2930. function locals at the time of evaluation.
  2931. @end deffn
  2932. @deffn {REPL Command} wasm-freq exp
  2933. Evaluate @var{exp} and print out a table showing how many times each
  2934. kind of Wasm instruction was executed as well as a total instruction
  2935. count.
  2936. @end deffn
  2937. @deffn {REPL Command} wasm-catch exp
  2938. Catch and debug Wasm runtime errors that are raised by evaluating
  2939. @var{exp}.
  2940. @end deffn
  2941. The following commands are usable only in the context of a Wasm debug
  2942. REPL:
  2943. @deffn {REPL Command} wasm-stack
  2944. Print the state of the Wasm stack.
  2945. @end deffn
  2946. @deffn {REPL Command} wasm-locals
  2947. Print the state of the Wasm function locals.
  2948. @end deffn
  2949. @deffn {REPL Command} wasm-pos
  2950. Print the current function disassembly and highlight the instruction
  2951. where Wasm execution has paused.
  2952. @end deffn
  2953. @deffn {REPL Command} wasm-eval instr
  2954. Evaluate the Wasm instruction @var{instr} in the current debug
  2955. context. Use this when attempting to fix the state of the Wasm stack
  2956. or locals before attempting to resume with @code{,wasm-continue}.
  2957. @end deffn
  2958. The following commands behave differently depending on if they are run
  2959. within a Wasm debug REPL or not.
  2960. @deffn {REPL Command} wasm-dump [wasm]
  2961. Display information about @var{wasm}, or the current Wasm instance
  2962. when debugging.
  2963. @end deffn
  2964. @deffn {REPL Command} wasm-continue
  2965. When in a debugger, exit and resume Wasm execution. In the event that
  2966. this is run after trapping a runtime error, your warranty is void and
  2967. all bets are off! While it may be dangerous, this does allow one to
  2968. manually fix the Wasm interpreter state manually with
  2969. @code{,wasm-eval} and attempt to proceed, which can come in handy
  2970. sometimes.
  2971. When not in a debugger, set the Wasm execution mode to continue
  2972. without interruption. In other words, deactive the instruction
  2973. stepper if it is active.
  2974. @end deffn
  2975. @deffn {REPL Command} wasm-step
  2976. When in a debugger, resume Wasm execution but pause before the next
  2977. instruction is evaluated.
  2978. When not in a debugger, set Wasm execution to pause before each
  2979. instruction is evaluated.
  2980. @end deffn
  2981. @node Contributing
  2982. @chapter Contributing
  2983. Found a bug? Let us know! Made an improvement? Show us! Issues can
  2984. be filed and pull requests can be submitted on
  2985. @url{https://gitlab.com/spritely/guile-hoot,GitLab}.
  2986. @node License
  2987. @chapter License
  2988. @emph{(C) 2023 David Thompson}
  2989. @emph{Both Guile Hoot and this manual are released under the terms of
  2990. the following license:}
  2991. @include apache-2.0.texi
  2992. @node Index
  2993. @unnumbered Index
  2994. @printindex fn
  2995. @bye