Implements RunnerWasmer, makes uses of its wat2wasm

This commit is contained in:
Johan B.W. de Vries 2022-08-07 14:46:20 +02:00
parent 0edd04c207
commit 41b47e43d6

View File

@ -5,12 +5,10 @@ from typing import Any, Iterable, TextIO
import ctypes import ctypes
import io import io
import os
import subprocess
import tempfile
import pywasm.binary import pywasm.binary
import wasm3 import wasm3
import wasmer
import wasmtime import wasmtime
from phasm.compiler import phasm_compile from phasm.compiler import phasm_compile
@ -18,31 +16,6 @@ from phasm.parser import phasm_parse
from phasm import ourlang from phasm import ourlang
from phasm import wasm from phasm import wasm
def wat2wasm(code_wat: str) -> bytes:
"""
Converts the given WebAssembly Assembly code into WebAssembly Binary
"""
path = os.environ.get('WAT2WASM', 'wat2wasm')
with tempfile.NamedTemporaryFile('w+t') as input_fp:
input_fp.write(code_wat)
input_fp.flush()
with tempfile.NamedTemporaryFile('w+b') as output_fp:
subprocess.run(
[
path,
input_fp.name,
'-o',
output_fp.name,
],
check=True,
)
output_fp.seek(0)
return output_fp.read()
class RunnerBase: class RunnerBase:
""" """
Base class Base class
@ -90,7 +63,7 @@ class RunnerBase:
""" """
Compiles the WebAssembly AST into WebAssembly Binary Compiles the WebAssembly AST into WebAssembly Binary
""" """
self.wasm_bin = wat2wasm(self.wasm_asm) self.wasm_bin = wasmer.wat2wasm(self.wasm_asm)
def interpreter_setup(self) -> None: def interpreter_setup(self) -> None:
""" """
@ -253,6 +226,56 @@ class RunnerWasmtime(RunnerBase):
return func(self.store, *args) return func(self.store, *args)
class RunnerWasmer(RunnerBase):
"""
Implements a runner for wasmer
See https://pypi.org/project/wasmer/
"""
# pylint: disable=E1101
store: wasmer.Store
module: wasmer.Module
instance: wasmer.Instance
def interpreter_setup(self) -> None:
self.store = wasmer.Store()
def interpreter_load(self) -> None:
self.module = wasmer.Module(self.store, self.wasm_bin)
self.instance = wasmer.Instance(self.module)
def interpreter_write_memory(self, offset: int, data: Iterable[int]) -> None:
exports = self.instance.exports
memory = getattr(exports, 'memory')
assert isinstance(memory, wasmer.Memory)
view = memory.uint8_view(offset)
for idx, byt in enumerate(data):
view[idx] = byt
def interpreter_read_memory(self, offset: int, length: int) -> bytes:
exports = self.instance.exports
memory = getattr(exports, 'memory')
assert isinstance(memory, wasmer.Memory)
view = memory.uint8_view(offset)
return bytes(view[offset:length])
def interpreter_dump_memory(self, textio: TextIO) -> None:
exports = self.instance.exports
memory = getattr(exports, 'memory')
assert isinstance(memory, wasmer.Memory)
view = memory.uint8_view()
_dump_memory(textio, view) # type: ignore
def call(self, function: str, *args: Any) -> Any:
exports = self.instance.exports
func = getattr(exports, function)
return func(*args)
def _dump_memory(textio: TextIO, mem: bytes) -> None: def _dump_memory(textio: TextIO, mem: bytes) -> None:
line_width = 16 line_width = 16