Adds RunnerWasmtime

This commit is contained in:
Johan B.W. de Vries 2022-08-07 14:12:37 +02:00
parent 58424cf2a0
commit 0edd04c207
2 changed files with 65 additions and 3 deletions

View File

@ -3,6 +3,7 @@ Runners to help run WebAssembly code on various interpreters
""" """
from typing import Any, Iterable, TextIO from typing import Any, Iterable, TextIO
import ctypes
import io import io
import os import os
import subprocess import subprocess
@ -10,6 +11,7 @@ import tempfile
import pywasm.binary import pywasm.binary
import wasm3 import wasm3
import wasmtime
from phasm.compiler import phasm_compile from phasm.compiler import phasm_compile
from phasm.parser import phasm_parse from phasm.parser import phasm_parse
@ -191,6 +193,66 @@ class RunnerPywasm3(RunnerBase):
def call(self, function: str, *args: Any) -> Any: def call(self, function: str, *args: Any) -> Any:
return self.rtime.find_function(function)(*args) return self.rtime.find_function(function)(*args)
class RunnerWasmtime(RunnerBase):
"""
Implements a runner for wasmtime
See https://pypi.org/project/wasmtime/
"""
store: wasmtime.Store
module: wasmtime.Module
instance: wasmtime.Instance
def interpreter_setup(self) -> None:
self.store = wasmtime.Store()
def interpreter_load(self) -> None:
self.module = wasmtime.Module(self.store.engine, self.wasm_bin)
self.instance = wasmtime.Instance(self.store, self.module, [])
def interpreter_write_memory(self, offset: int, data: Iterable[int]) -> None:
exports = self.instance.exports(self.store)
memory = exports['memory']
assert isinstance(memory, wasmtime.Memory) # type hint
data_ptr = memory.data_ptr(self.store)
data_len = memory.data_len(self.store)
idx = offset
for byt in data:
assert idx < data_len
data_ptr[idx] = ctypes.c_ubyte(byt)
idx += 1
def interpreter_read_memory(self, offset: int, length: int) -> bytes:
exports = self.instance.exports(self.store)
memory = exports['memory']
assert isinstance(memory, wasmtime.Memory) # type hint
data_ptr = memory.data_ptr(self.store)
data_len = memory.data_len(self.store)
raw = ctypes.string_at(data_ptr, data_len)
return raw[offset:length]
def interpreter_dump_memory(self, textio: TextIO) -> None:
exports = self.instance.exports(self.store)
memory = exports['memory']
assert isinstance(memory, wasmtime.Memory) # type hint
data_ptr = memory.data_ptr(self.store)
data_len = memory.data_len(self.store)
_dump_memory(textio, ctypes.string_at(data_ptr, data_len))
def call(self, function: str, *args: Any) -> Any:
exports = self.instance.exports(self.store)
func = exports[function]
assert isinstance(func, wasmtime.Func)
return func(self.store, *args)
def _dump_memory(textio: TextIO, mem: bytes) -> None: def _dump_memory(textio: TextIO, mem: bytes) -> None:
line_width = 16 line_width = 16

View File

@ -3,10 +3,10 @@ import sys
import pytest import pytest
from .helpers import DASHES from .helpers import DASHES
from .runners import RunnerPywasm3 from .runners import RunnerPywasm3 as Runner
def setup_interpreter(phash_code: str) -> RunnerPywasm3: def setup_interpreter(phash_code: str) -> Runner:
runner = RunnerPywasm3(phash_code) runner = Runner(phash_code)
runner.parse() runner.parse()
runner.compile_ast() runner.compile_ast()