Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Witx parser extension in generator module #71

Closed
wants to merge 15 commits into from
Closed
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ site/output
.bloop/


log.txt
*log.txt
*.lck
21 changes: 7 additions & 14 deletions build.sc
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import mill._
import scalalib._
import mill.eval._
import mill.scalalib._
import mill.scalalib.publish._
import mill.scalalib.scalafmt._

import ammonite.ops._
import mill.modules.Jvm.runSubprocess

import coursier.maven.MavenRepository

import $file.jmh
import jmh.Jmh
import $file.headers
import headers.Headers

import $file.mdoc
import mdoc.MdocModule

import $ivy.`com.lihaoyi::mill-contrib-bloop:$MILL_VERSION`
import generator.ivy
import mill.api.PathRef

val swamVersion = "0.6.0-SNAPSHOT"

Expand All @@ -26,6 +24,7 @@ val swamLicense = License.`Apache-2.0`
val swamUrl = "https://github.com/satabin/swam"

val swamDeveloper = Developer("satabin", "Lucas Satabin", "https://github.com/satabin")
val swamContributor = Developer("Jacarte", "Javier Cabrera-Arteaga", "https://github.com/Jacarte")

val fs2Version = "2.0.1"

Expand Down Expand Up @@ -107,7 +106,7 @@ object text extends SwamModule with PublishModule {

object generator extends SwamModule with PublishModule {

def moduleDeps = Seq(core, runtime)
def moduleDeps = Seq(core, runtime, text)

def publishVersion = swamVersion

Expand All @@ -129,19 +128,13 @@ object generator extends SwamModule with PublishModule {
url = swamUrl,
licenses = Seq(swamLicense),
versionControl = VersionControl.github("satabin", "swam"),
developers = Seq(swamDeveloper)
developers = Seq(swamDeveloper, swamContributor)
)

object test extends Tests with ScalafmtModule {
def ivyDeps =
Agg(ivy"com.lihaoyi::utest:0.7.1", ivy"com.github.pathikrit::better-files:3.8.0", ivy"com.lihaoyi::pprint:0.5.5")
}

def moduleDeps = Seq(generator, text, util.test)

def testFrameworks = Seq("swam.util.Framework")
}

}

object runtime extends SwamModule with PublishModule {

Expand Down
4 changes: 3 additions & 1 deletion examples/docs/fibo.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import java.nio.file.Paths

val tcompiler = Compiler[IO]

val engine = Engine[IO]
val engine = Engine[IO]()

implicit val cs = IO.contextShift(scala.concurrent.ExecutionContext.global)

implicit val cs = IO.contextShift(scala.concurrent.ExecutionContext.global)

Expand Down
75 changes: 75 additions & 0 deletions examples/docs/generator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: Boilerplates Generator
---

It is possible in swam to generate code boilerplates to implement imports for WebAssembly binaries execution. The module `generator` provides a cli tool to do so. To check available options in the `generator` cli, run `mill generator.run --help`.


## Generating scala code boilerplate for WASM binaries

For instance, let’s have a WASM binary called `posix.wasm`. Running `run generator.run posix.wasm` will generate the following output.

```
import cats.effect.IO
import swam.runtime.imports.{AsInstance, AsInterface, Imports, TCMap}
import swam.runtime.formats._
import swam.runtime.formats.DefaultFormatters._

trait GeneratedImports {
type AsIIO[T] = AsInterface[T, IO]
type AsIsIO[T] = AsInstance[T, IO]

def wasi_unstableFd_write(p0: Int, p1: Int, p2: Int, p3: Int): IO[Int]
def wasi_unstableFd_close(p0: Int): IO[Int]
def wasi_unstableFd_fdstat_get(p0: Int, p1: Int): IO[Int]
def wasi_unstableFd_seek(p0: Int, p1: Long, p2: Int, p3: Int): IO[Int]
def imports() = {
Imports[IO](
TCMap[String, AsIsIO](
"wasi_unstable" -> TCMap[String, AsIIO]("fd_write" -> wasi_unstableFd_write _,
"fd_close" -> wasi_unstableFd_close _,
"fd_fdstat_get" -> wasi_unstableFd_fdstat_get _,
"fd_seek" -> wasi_unstableFd_seek _))
)
}
}

```

By default, the generator cli will find imported functions, then it generates a Scala language boilerplate. The generated template represents a Scala trait by default as you can see in the snippet.

The cli supports several WASM binaries as arguments, generating then, the composition of all function imports.


## Replacing the trait template

We generate the funcion imports based trait using the [mustache template engine](https://mustache.github.io/). Mustache context is usually a dictionary. We provide the context in the following format.

```ts
{
"module" : str,
"comma" : boolean,
"fields" :
{
"name": str,
"return": str,
"params": str,
"nameCapital": str,
"comma": boolean
}[]
}[]

```

To print the context provided in json format, run the command `mill generator.run -c true <wasm file>`. The used mustache template can be replaced, using the `--template <value>` option.

## Parsing WITX



> The [WITX](https://github.com/WebAssembly/WASI/blob/master/docs/witx.md)
file format is an experimental format which is based on the module types text format (wit), (which is in turn based on the wat format, which is based on S-expressions). It adds some features using the same syntax as interface types, some features with syntax similar to gc types, as well as a few special features of its own. witx is actively evolving. Expect backwards-incompatible changes, particularly in the areas where witx differs from wit. The initial goal for witx is just to have a language suitable for expressing WASI APIs in, to serve as the vocabulary for proposing changes to existing APIs and proposing new APIs. Initially, while it uses some of the syntax and concepts from interface types, it doesn't currently imply the full interface types specification, or the use of the interface types custom sections. We expect that eventually we will transition to using the full interface types specification. Until then, the goals here are to remain aligned with interface types and other relevant WebAssembly standards and proposals wherever practical, and to be an input into the design process of interface types.

The generator cli also provides the way to parse witx files and generate the boilerplate project. To generate the boilerplate, run `mill generator.run -x true -p <create_project_at> <witx_file>`. This command will generate two scala files, `Types.cala` and `Module.scala`, containing th types definitions and abstract function declarations, respectively.

The `text` module provides the core implementation to parse this kind of files, specifically, the `swam.witx.WitxParser` class. This core component provides a small AST structure from the witx file. The components of this AST can be seen in `swam.witx.unresolved.Declarations` class. Therefore, this AST can be translated to any target, for instance, the generator cli implements the AST traversers to generate the scala files for the boilerplate given a witx file.
4 changes: 3 additions & 1 deletion examples/docs/logged.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import java.nio.file.Paths

val tcompiler = Compiler[IO]

val engine = Engine[IO]
val engine = Engine[IO]()

implicit val cs = IO.contextShift(scala.concurrent.ExecutionContext.global)

implicit val cs = IO.contextShift(scala.concurrent.ExecutionContext.global)

Expand Down
4 changes: 3 additions & 1 deletion examples/docs/string.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import java.nio.file.Paths

val tcompiler = Compiler[IO]

val engine = Engine[IO]
val engine = Engine[IO]()

implicit val cs = IO.contextShift(scala.concurrent.ExecutionContext.global)

implicit val cs = IO.contextShift(scala.concurrent.ExecutionContext.global)

Expand Down
1 change: 1 addition & 0 deletions generator/resources/import_template.mustache
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import cats.effect.IO
import swam.runtime.imports.{AsInstance, AsInterface, Imports, TCMap}
import swam.runtime.formats._
import swam.runtime.formats.DefaultFormatters._
Expand Down
2 changes: 2 additions & 0 deletions generator/resources/wasi_witx/get.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
wget https://raw.githubusercontent.com/WebAssembly/WASI/master/phases/snapshot/witx/wasi_snapshot_preview1.witx
wget https://raw.githubusercontent.com/WebAssembly/WASI/master/phases/snapshot/witx/typenames.witx
Loading