MVP #1
@ -3,6 +3,7 @@ Runners to help run WebAssembly code on various interpreters
|
||||
"""
|
||||
from typing import Any, Iterable, TextIO
|
||||
|
||||
import ctypes
|
||||
import io
|
||||
import os
|
||||
import subprocess
|
||||
@ -10,6 +11,7 @@ import tempfile
|
||||
|
||||
import pywasm.binary
|
||||
import wasm3
|
||||
import wasmtime
|
||||
|
||||
from phasm.compiler import phasm_compile
|
||||
from phasm.parser import phasm_parse
|
||||
@ -191,6 +193,66 @@ class RunnerPywasm3(RunnerBase):
|
||||
def call(self, function: str, *args: Any) -> Any:
|
||||
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:
|
||||
line_width = 16
|
||||
|
||||
|
||||
@ -3,10 +3,10 @@ import sys
|
||||
import pytest
|
||||
|
||||
from .helpers import DASHES
|
||||
from .runners import RunnerPywasm3
|
||||
from .runners import RunnerPywasm3 as Runner
|
||||
|
||||
def setup_interpreter(phash_code: str) -> RunnerPywasm3:
|
||||
runner = RunnerPywasm3(phash_code)
|
||||
def setup_interpreter(phash_code: str) -> Runner:
|
||||
runner = Runner(phash_code)
|
||||
|
||||
runner.parse()
|
||||
runner.compile_ast()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user