-
-
Notifications
You must be signed in to change notification settings - Fork 10
Interface
The Instance
class is the way to interact with instances of WebAssembly modules. To create an instance for a given module, one has to provide a list of imports
required by that module to work correctly.
Once we get an instance, the main object in it to get access to module features is exports
.
In the exports
, client code may ask to particular exported objects. WebAssembly is strongly typed, and this is reflected in the Instance
interface.
All elements that may be exposed by Scala code to WebAssembly instances and from WebAssembly instances to Scala code are strongly typed as well. Basically all imports or exports are of this form:
// type F encapsulates the effect
sealed trait Interface[F[_], +T <: Type] {
def tpe: T
}
trait Function[F[_]] extends Interface[F, FuncType] {
// interface of `invoke` must match the declared `tpe`
def invoke(parameters: Vector[Value]): F[Option[Value]]
}
trait Global[F[_]] extends Interface[F, GlobalType] {
def get: Value
def set(v: Value): F[Unit]
}
trait Table[F[_]] extends Interface[F, TableType] {
def apply(idx: Int): F[Function[F]]
def update(idx: Int, f: Function[F]): F[Unit]
}
trait Memory[F[_]] extends Interface[F, MemType] {
def size: Int
def grow(by: Int): F[Boolean]
def readByte(offset: Int): F[Byte]
def writeByte(offset: Int, v: Byte): F[Unit]
// and all variants for other primitive types Short, Int, Long, Float, and Double
}
Swam has its own specializations of these elements for the instances it manages, and it is possible for everyone to implement them in Scala to provide them to new instances. They define the minimum feature required by Swam to work properly.
The interfaces above are a bit simplified, as they do not mention de Typeclass instances required for F
. Typical value for F
is IO
.
The base Interface
trait is sealed to ensure that all instances are of one of the 4 subtypes. The Swam code only checks for these 4 types and assumes specializations behave correctly.