Project update
Various updates to bring the project uptodate. - Updated required packages - Removed runtimes that are not being updated - wasmtime is for now the only supported runtime - Implements imports for wasmtime runtime - Fixes a memory access bug for wasmtime runtime - compile_wasm is now optional - runtimes have to implement and call this themselves - Typing fixes - Linting fixes
This commit is contained in:
parent
97b61e3ee1
commit
5c537f712e
2
Makefile
2
Makefile
@ -34,7 +34,7 @@ typecheck: venv/.done
|
|||||||
venv/bin/mypy --strict phasm tests/integration/helpers.py tests/integration/runners.py
|
venv/bin/mypy --strict phasm tests/integration/helpers.py tests/integration/runners.py
|
||||||
|
|
||||||
venv/.done: requirements.txt
|
venv/.done: requirements.txt
|
||||||
python3.10 -m venv venv
|
python3.12 -m venv venv
|
||||||
venv/bin/python3 -m pip install wheel pip --upgrade
|
venv/bin/python3 -m pip install wheel pip --upgrade
|
||||||
venv/bin/python3 -m pip install -r $^
|
venv/bin/python3 -m pip install -r $^
|
||||||
touch $@
|
touch $@
|
||||||
|
|||||||
@ -675,7 +675,7 @@ def _not_implemented(check: Any, msg: str) -> None:
|
|||||||
if not check:
|
if not check:
|
||||||
raise NotImplementedError(msg)
|
raise NotImplementedError(msg)
|
||||||
|
|
||||||
def _raise_static_error(node: Union[ast.mod, ast.stmt, ast.expr], msg: str) -> NoReturn:
|
def _raise_static_error(node: Union[ast.stmt, ast.expr], msg: str) -> NoReturn:
|
||||||
raise StaticError(
|
raise StaticError(
|
||||||
f'Static error on line {node.lineno}: {msg}'
|
f'Static error on line {node.lineno}: {msg}'
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,10 +1,19 @@
|
|||||||
mypy==0.991
|
marko==2.1.3
|
||||||
pygments==2.12.0
|
mypy==1.15.0
|
||||||
pytest==7.2.0
|
pygments==2.19.1
|
||||||
|
pytest==8.3.5
|
||||||
pytest-integration==0.2.2
|
pytest-integration==0.2.2
|
||||||
pywasm==1.0.7
|
ruff==0.11.4
|
||||||
pywasm3==0.5.0
|
|
||||||
ruff==0.1.5
|
|
||||||
wasmer==1.1.0
|
wasmtime==31.0.0
|
||||||
wasmer_compiler_cranelift==1.1.0
|
|
||||||
wasmtime==3.0.0
|
# TODO:
|
||||||
|
# extism?
|
||||||
|
# wasmedge
|
||||||
|
|
||||||
|
# Check 2025-04-05
|
||||||
|
# wasm3: minimal maintenance phase
|
||||||
|
# py-wasm: last updated 6 years ago
|
||||||
|
# wasmer-python: Not compatible with python3.12, last updated 2 years ago
|
||||||
|
# WAVM: Last updated 3 years ago
|
||||||
|
|||||||
@ -16,10 +16,7 @@ class SuiteResult:
|
|||||||
self.returned_value = None
|
self.returned_value = None
|
||||||
|
|
||||||
RUNNER_CLASS_MAP = {
|
RUNNER_CLASS_MAP = {
|
||||||
'pywasm': runners.RunnerPywasm,
|
|
||||||
'pywasm3': runners.RunnerPywasm3,
|
|
||||||
'wasmtime': runners.RunnerWasmtime,
|
'wasmtime': runners.RunnerWasmtime,
|
||||||
'wasmer': runners.RunnerWasmer,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Suite:
|
class Suite:
|
||||||
@ -29,7 +26,7 @@ class Suite:
|
|||||||
def __init__(self, code_py: str) -> None:
|
def __init__(self, code_py: str) -> None:
|
||||||
self.code_py = code_py
|
self.code_py = code_py
|
||||||
|
|
||||||
def run_code(self, *args: Any, runtime: str = 'pywasm3', func_name: str = 'testEntry', imports: runners.Imports = None) -> Any:
|
def run_code(self, *args: Any, runtime: str = 'wasmtime', func_name: str = 'testEntry', imports: runners.Imports = None) -> Any:
|
||||||
"""
|
"""
|
||||||
Compiles the given python code into wasm and
|
Compiles the given python code into wasm and
|
||||||
then runs it
|
then runs it
|
||||||
@ -50,7 +47,6 @@ class Suite:
|
|||||||
write_header(sys.stderr, 'Assembly')
|
write_header(sys.stderr, 'Assembly')
|
||||||
runner.dump_wasm_wat(sys.stderr)
|
runner.dump_wasm_wat(sys.stderr)
|
||||||
|
|
||||||
runner.compile_wasm()
|
|
||||||
runner.interpreter_setup()
|
runner.interpreter_setup()
|
||||||
runner.interpreter_load(imports)
|
runner.interpreter_load(imports)
|
||||||
|
|
||||||
|
|||||||
@ -2,12 +2,8 @@
|
|||||||
Runners to help run WebAssembly code on various interpreters
|
Runners to help run WebAssembly code on various interpreters
|
||||||
"""
|
"""
|
||||||
import ctypes
|
import ctypes
|
||||||
import io
|
|
||||||
from typing import Any, Callable, Dict, Iterable, Optional, TextIO
|
from typing import Any, Callable, Dict, Iterable, Optional, TextIO
|
||||||
|
|
||||||
import pywasm.binary
|
|
||||||
import wasm3
|
|
||||||
import wasmer
|
|
||||||
import wasmtime
|
import wasmtime
|
||||||
|
|
||||||
from phasm import ourlang, wasm
|
from phasm import ourlang, wasm
|
||||||
@ -65,7 +61,7 @@ class RunnerBase:
|
|||||||
"""
|
"""
|
||||||
Compiles the WebAssembly AST into WebAssembly Binary
|
Compiles the WebAssembly AST into WebAssembly Binary
|
||||||
"""
|
"""
|
||||||
self.wasm_bin = wasmer.wat2wasm(self.wasm_asm)
|
raise NotImplementedError
|
||||||
|
|
||||||
def interpreter_setup(self) -> None:
|
def interpreter_setup(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -103,77 +99,6 @@ class RunnerBase:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
class RunnerPywasm(RunnerBase):
|
|
||||||
"""
|
|
||||||
Implements a runner for pywasm
|
|
||||||
|
|
||||||
See https://pypi.org/project/pywasm/
|
|
||||||
"""
|
|
||||||
module: pywasm.binary.Module
|
|
||||||
runtime: pywasm.Runtime
|
|
||||||
|
|
||||||
def interpreter_setup(self) -> None:
|
|
||||||
# Nothing to set up
|
|
||||||
pass
|
|
||||||
|
|
||||||
def interpreter_load(self, imports: Optional[Dict[str, Callable[[Any], Any]]] = None) -> None:
|
|
||||||
if imports is not None:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
bytesio = io.BytesIO(self.wasm_bin)
|
|
||||||
self.module = pywasm.binary.Module.from_reader(bytesio)
|
|
||||||
self.runtime = pywasm.Runtime(self.module, {}, None)
|
|
||||||
|
|
||||||
def interpreter_write_memory(self, offset: int, data: Iterable[int]) -> None:
|
|
||||||
for idx, byt in enumerate(data):
|
|
||||||
self.runtime.store.memory_list[0].data[offset + idx] = byt
|
|
||||||
|
|
||||||
def interpreter_read_memory(self, offset: int, length: int) -> bytes:
|
|
||||||
return self.runtime.store.memory_list[0].data[offset:length]
|
|
||||||
|
|
||||||
def interpreter_dump_memory(self, textio: TextIO) -> None:
|
|
||||||
_dump_memory(textio, self.runtime.store.memory_list[0].data)
|
|
||||||
|
|
||||||
def call(self, function: str, *args: Any) -> Any:
|
|
||||||
return self.runtime.exec(function, [*args])
|
|
||||||
|
|
||||||
class RunnerPywasm3(RunnerBase):
|
|
||||||
"""
|
|
||||||
Implements a runner for pywasm3
|
|
||||||
|
|
||||||
See https://pypi.org/project/pywasm3/
|
|
||||||
"""
|
|
||||||
env: wasm3.Environment
|
|
||||||
rtime: wasm3.Runtime
|
|
||||||
mod: wasm3.Module
|
|
||||||
|
|
||||||
def interpreter_setup(self) -> None:
|
|
||||||
self.env = wasm3.Environment()
|
|
||||||
self.rtime = self.env.new_runtime(1024 * 1024)
|
|
||||||
|
|
||||||
def interpreter_load(self, imports: Optional[Dict[str, Callable[[Any], Any]]] = None) -> None:
|
|
||||||
if imports is not None:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
self.mod = self.env.parse_module(self.wasm_bin)
|
|
||||||
self.rtime.load(self.mod)
|
|
||||||
|
|
||||||
def interpreter_write_memory(self, offset: int, data: Iterable[int]) -> None:
|
|
||||||
memory = self.rtime.get_memory(0)
|
|
||||||
|
|
||||||
for idx, byt in enumerate(data):
|
|
||||||
memory[offset + idx] = byt
|
|
||||||
|
|
||||||
def interpreter_read_memory(self, offset: int, length: int) -> bytes:
|
|
||||||
memory = self.rtime.get_memory(0)
|
|
||||||
return memory[offset:offset + length].tobytes()
|
|
||||||
|
|
||||||
def interpreter_dump_memory(self, textio: TextIO) -> None:
|
|
||||||
_dump_memory(textio, self.rtime.get_memory(0))
|
|
||||||
|
|
||||||
def call(self, function: str, *args: Any) -> Any:
|
|
||||||
return self.rtime.find_function(function)(*args)
|
|
||||||
|
|
||||||
class RunnerWasmtime(RunnerBase):
|
class RunnerWasmtime(RunnerBase):
|
||||||
"""
|
"""
|
||||||
Implements a runner for wasmtime
|
Implements a runner for wasmtime
|
||||||
@ -184,15 +109,44 @@ class RunnerWasmtime(RunnerBase):
|
|||||||
module: wasmtime.Module
|
module: wasmtime.Module
|
||||||
instance: wasmtime.Instance
|
instance: wasmtime.Instance
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def func2type(cls, func: Callable[[Any], Any]) -> wasmtime.FuncType:
|
||||||
|
params: list[wasmtime.ValType] = []
|
||||||
|
|
||||||
|
code = func.__code__
|
||||||
|
for idx in range(code.co_argcount):
|
||||||
|
varname = code.co_varnames[idx]
|
||||||
|
vartype = func.__annotations__[varname]
|
||||||
|
|
||||||
|
if vartype is int:
|
||||||
|
params.append(wasmtime.ValType.i32())
|
||||||
|
else:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
results: list[wasmtime.ValType] = []
|
||||||
|
if func.__annotations__['return'] is None:
|
||||||
|
pass # No return value
|
||||||
|
elif func.__annotations__['return'] is int:
|
||||||
|
results.append(wasmtime.ValType.i32())
|
||||||
|
else:
|
||||||
|
raise NotImplementedError('Return type', func.__annotations__['return'])
|
||||||
|
|
||||||
|
return wasmtime.FuncType(params, results)
|
||||||
|
|
||||||
def interpreter_setup(self) -> None:
|
def interpreter_setup(self) -> None:
|
||||||
self.store = wasmtime.Store()
|
self.store = wasmtime.Store()
|
||||||
|
|
||||||
def interpreter_load(self, imports: Optional[Dict[str, Callable[[Any], Any]]] = None) -> None:
|
def interpreter_load(self, imports: Optional[Dict[str, Callable[[Any], Any]]] = None) -> None:
|
||||||
if imports is not None:
|
functions: list[wasmtime.Func] = []
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
self.module = wasmtime.Module(self.store.engine, self.wasm_bin)
|
if imports is not None:
|
||||||
self.instance = wasmtime.Instance(self.store, self.module, [])
|
functions = [
|
||||||
|
wasmtime.Func(self.store, self.__class__.func2type(f), f)
|
||||||
|
for f in imports.values()
|
||||||
|
]
|
||||||
|
|
||||||
|
self.module = wasmtime.Module(self.store.engine, self.wasm_asm)
|
||||||
|
self.instance = wasmtime.Instance(self.store, self.module, functions)
|
||||||
|
|
||||||
def interpreter_write_memory(self, offset: int, data: Iterable[int]) -> None:
|
def interpreter_write_memory(self, offset: int, data: Iterable[int]) -> None:
|
||||||
exports = self.instance.exports(self.store)
|
exports = self.instance.exports(self.store)
|
||||||
@ -217,8 +171,7 @@ class RunnerWasmtime(RunnerBase):
|
|||||||
data_len = memory.data_len(self.store)
|
data_len = memory.data_len(self.store)
|
||||||
|
|
||||||
raw = ctypes.string_at(data_ptr, data_len)
|
raw = ctypes.string_at(data_ptr, data_len)
|
||||||
|
return raw[offset:offset + length]
|
||||||
return raw[offset:length]
|
|
||||||
|
|
||||||
def interpreter_dump_memory(self, textio: TextIO) -> None:
|
def interpreter_dump_memory(self, textio: TextIO) -> None:
|
||||||
exports = self.instance.exports(self.store)
|
exports = self.instance.exports(self.store)
|
||||||
@ -237,63 +190,6 @@ 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, imports: Optional[Dict[str, Callable[[Any], Any]]] = None) -> None:
|
|
||||||
import_object = wasmer.ImportObject()
|
|
||||||
if imports:
|
|
||||||
import_object.register('imports', {
|
|
||||||
k: wasmer.Function(self.store, v)
|
|
||||||
for k, v in (imports or {}).items()
|
|
||||||
})
|
|
||||||
|
|
||||||
self.module = wasmer.Module(self.store, self.wasm_bin)
|
|
||||||
self.instance = wasmer.Instance(self.module, import_object)
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@ def test_crc32():
|
|||||||
def _crc32_f(crc: u32, byt: u8) -> u32:
|
def _crc32_f(crc: u32, byt: u8) -> u32:
|
||||||
return 16777215 ^ 397917763
|
return 16777215 ^ 397917763
|
||||||
|
|
||||||
|
@exported
|
||||||
def testEntry(data: bytes) -> u32:
|
def testEntry(data: bytes) -> u32:
|
||||||
return 4294967295 ^ _crc32_f(4294967295, data[0])
|
return 4294967295 ^ _crc32_f(4294967295, data[0])
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -102,6 +102,7 @@ def generate_code(markdown, template, settings):
|
|||||||
print()
|
print()
|
||||||
print('from ..helpers import Suite')
|
print('from ..helpers import Suite')
|
||||||
print()
|
print()
|
||||||
|
print()
|
||||||
|
|
||||||
for test in get_tests(template):
|
for test in get_tests(template):
|
||||||
assert len(test) == 4, test
|
assert len(test) == 4, test
|
||||||
@ -121,7 +122,7 @@ def generate_code(markdown, template, settings):
|
|||||||
print('@pytest.mark.integration_test')
|
print('@pytest.mark.integration_test')
|
||||||
print(f'def test_{type_name}_{test_id}():')
|
print(f'def test_{type_name}_{test_id}():')
|
||||||
print(' """')
|
print(' """')
|
||||||
print(' ' + user_story.replace('\n', '\n '))
|
print(' ' + user_story.strip().replace('\n', '\n '))
|
||||||
print(' """')
|
print(' """')
|
||||||
print(' code_py = """')
|
print(' code_py = """')
|
||||||
if 'CODE_HEADER' in settings:
|
if 'CODE_HEADER' in settings:
|
||||||
|
|||||||
@ -3,16 +3,15 @@ import sys
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ..helpers import Suite, write_header
|
from ..helpers import Suite, write_header
|
||||||
from ..runners import RunnerPywasm
|
from ..runners import RunnerWasmtime
|
||||||
|
|
||||||
|
|
||||||
def setup_interpreter(phash_code: str) -> RunnerPywasm:
|
def setup_interpreter(phash_code: str) -> RunnerWasmtime:
|
||||||
runner = RunnerPywasm(phash_code)
|
runner = RunnerWasmtime(phash_code)
|
||||||
|
|
||||||
runner.parse()
|
runner.parse()
|
||||||
runner.compile_ast()
|
runner.compile_ast()
|
||||||
runner.compile_wat()
|
runner.compile_wat()
|
||||||
runner.compile_wasm()
|
|
||||||
runner.interpreter_setup()
|
runner.interpreter_setup()
|
||||||
runner.interpreter_load()
|
runner.interpreter_load()
|
||||||
|
|
||||||
@ -38,16 +37,16 @@ def testEntry(b: bytes) -> u8:
|
|||||||
result = suite.run_code(b'')
|
result = suite.run_code(b'')
|
||||||
assert 128 == result.returned_value
|
assert 128 == result.returned_value
|
||||||
|
|
||||||
result = suite.run_code(b'\x80', runtime='pywasm')
|
result = suite.run_code(b'\x80')
|
||||||
assert 128 == result.returned_value
|
assert 128 == result.returned_value
|
||||||
|
|
||||||
result = suite.run_code(b'\x80\x40', runtime='pywasm')
|
result = suite.run_code(b'\x80\x40')
|
||||||
assert 192 == result.returned_value
|
assert 192 == result.returned_value
|
||||||
|
|
||||||
result = suite.run_code(b'\x80\x40\x20\x10', runtime='pywasm')
|
result = suite.run_code(b'\x80\x40\x20\x10')
|
||||||
assert 240 == result.returned_value
|
assert 240 == result.returned_value
|
||||||
|
|
||||||
result = suite.run_code(b'\x80\x40\x20\x10\x08\x04\x02\x01', runtime='pywasm')
|
result = suite.run_code(b'\x80\x40\x20\x10\x08\x04\x02\x01')
|
||||||
assert 255 == result.returned_value
|
assert 255 == result.returned_value
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
|
|||||||
@ -21,7 +21,6 @@ def testEntry() -> i32:
|
|||||||
return 4238 * mul
|
return 4238 * mul
|
||||||
|
|
||||||
result = Suite(code_py).run_code(
|
result = Suite(code_py).run_code(
|
||||||
runtime='wasmer',
|
|
||||||
imports={
|
imports={
|
||||||
'helper': helper,
|
'helper': helper,
|
||||||
}
|
}
|
||||||
@ -47,7 +46,6 @@ def testEntry() -> None:
|
|||||||
prop = mul
|
prop = mul
|
||||||
|
|
||||||
result = Suite(code_py).run_code(
|
result = Suite(code_py).run_code(
|
||||||
runtime='wasmer',
|
|
||||||
imports={
|
imports={
|
||||||
'helper': helper,
|
'helper': helper,
|
||||||
}
|
}
|
||||||
@ -73,7 +71,6 @@ def testEntry(x: u32) -> u8:
|
|||||||
|
|
||||||
with pytest.raises(Type3Exception, match=r'u32 must be u8 instead'):
|
with pytest.raises(Type3Exception, match=r'u32 must be u8 instead'):
|
||||||
Suite(code_py).run_code(
|
Suite(code_py).run_code(
|
||||||
runtime='wasmer',
|
|
||||||
imports={
|
imports={
|
||||||
'helper': helper,
|
'helper': helper,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ def testEntry() -> {type_}:
|
|||||||
result = Suite(code_py).run_code()
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
assert 13 == result.returned_value
|
assert 13 == result.returned_value
|
||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] is type(result.returned_value)
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.parametrize('type_', FLOAT_TYPES)
|
@pytest.mark.parametrize('type_', FLOAT_TYPES)
|
||||||
@ -40,7 +40,7 @@ def testEntry() -> {type_}:
|
|||||||
result = Suite(code_py).run_code()
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
assert 32.125 == result.returned_value
|
assert 32.125 == result.returned_value
|
||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] is type(result.returned_value)
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.parametrize('type_', INT_TYPES)
|
@pytest.mark.parametrize('type_', INT_TYPES)
|
||||||
@ -54,7 +54,7 @@ def testEntry() -> {type_}:
|
|||||||
result = Suite(code_py).run_code()
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
assert 7 == result.returned_value
|
assert 7 == result.returned_value
|
||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] is type(result.returned_value)
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.parametrize('type_', FLOAT_TYPES)
|
@pytest.mark.parametrize('type_', FLOAT_TYPES)
|
||||||
@ -68,7 +68,7 @@ def testEntry() -> {type_}:
|
|||||||
result = Suite(code_py).run_code()
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
assert 32.125 == result.returned_value
|
assert 32.125 == result.returned_value
|
||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] is type(result.returned_value)
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.skip('TODO: Runtimes return a signed value, which is difficult to test')
|
@pytest.mark.skip('TODO: Runtimes return a signed value, which is difficult to test')
|
||||||
@ -101,7 +101,7 @@ def helper(left: {type_}, right: {type_}) -> {type_}:
|
|||||||
result = Suite(code_py).run_code()
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
assert 22 == result.returned_value
|
assert 22 == result.returned_value
|
||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] is type(result.returned_value)
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.parametrize('type_', FLOAT_TYPES)
|
@pytest.mark.parametrize('type_', FLOAT_TYPES)
|
||||||
@ -118,4 +118,4 @@ def helper(left: {type_}, right: {type_}) -> {type_}:
|
|||||||
result = Suite(code_py).run_code()
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
assert 32.125 == result.returned_value
|
assert 32.125 == result.returned_value
|
||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] is type(result.returned_value)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
import wasmtime
|
||||||
|
|
||||||
from phasm.type3.entry import Type3Exception
|
from phasm.type3.entry import Type3Exception
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ def testEntry(x: u32) -> u8:
|
|||||||
return CONSTANT[x]
|
return CONSTANT[x]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with pytest.raises(RuntimeError):
|
with pytest.raises(wasmtime.Trap):
|
||||||
Suite(code_py).run_code(3)
|
Suite(code_py).run_code(3)
|
||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import sys
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ..helpers import write_header
|
from ..helpers import write_header
|
||||||
from ..runners import RunnerPywasm3 as Runner
|
from ..runners import RunnerWasmtime as Runner
|
||||||
|
|
||||||
|
|
||||||
def setup_interpreter(phash_code: str) -> Runner:
|
def setup_interpreter(phash_code: str) -> Runner:
|
||||||
@ -12,7 +12,6 @@ def setup_interpreter(phash_code: str) -> Runner:
|
|||||||
runner.parse()
|
runner.parse()
|
||||||
runner.compile_ast()
|
runner.compile_ast()
|
||||||
runner.compile_wat()
|
runner.compile_wat()
|
||||||
runner.compile_wasm()
|
|
||||||
runner.interpreter_setup()
|
runner.interpreter_setup()
|
||||||
runner.interpreter_load()
|
runner.interpreter_load()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user