phasm/tests/integration/helpers.py
2022-05-07 12:14:34 +02:00

114 lines
2.8 KiB
Python

import io
import os
import subprocess
import sys
from tempfile import NamedTemporaryFile
from pywasm import binary
from pywasm import Runtime
from py2wasm.utils import process
def wat2wasm(code_wat):
path = os.environ.get('WAT2WASM', 'wat2wasm')
with NamedTemporaryFile('w+t') as input_fp:
input_fp.write(code_wat)
input_fp.flush()
with 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 SuiteResult:
def __init__(self):
self.log_int32_list = []
self.returned_value = None
def callback_log_int32(self, store, value):
del store # auto passed by pywasm
self.log_int32_list.append(value)
def make_imports(self):
return {
'console': {
'logInt32': self.callback_log_int32,
}
}
class Suite:
def __init__(self, code_py, test_name):
self.code_py = code_py
self.test_name = test_name
def run_code(self, *args):
"""
Compiles the given python code into wasm and
then runs it
Returned is an object with the results set
"""
code_wat = process(self.code_py, self.test_name)
dashes = '-' * 16
sys.stderr.write(f'{dashes} Assembly {dashes}\n')
line_list = code_wat.split('\n')
line_no_width = len(str(len(line_list)))
for line_no, line_txt in enumerate(line_list):
sys.stderr.write('{} {}\n'.format(
str(line_no + 1).zfill(line_no_width),
line_txt,
))
code_wasm = wat2wasm(code_wat)
module = binary.Module.from_reader(io.BytesIO(code_wasm))
result = SuiteResult()
runtime = Runtime(module, result.make_imports(), {})
sys.stderr.write(f'{dashes} Memory (pre run) {dashes}\n')
_dump_memory(runtime.store.mems[0].data)
result.returned_value = runtime.exec('testEntry', args)
sys.stderr.write(f'{dashes} Memory (post run) {dashes}\n')
_dump_memory(runtime.store.mems[0].data)
return result
def _dump_memory(mem):
line_width = 16
prev_line = None
skip = False
for idx in range(0, len(mem), line_width):
line = ''
for idx2 in range(0, line_width):
line += f'{mem[idx + idx2]:02X}'
if idx2 % 2 == 1:
line += ' '
if prev_line == line:
if not skip:
sys.stderr.write('**\n')
skip = True
else:
sys.stderr.write(f'{idx:08x} {line}\n')
prev_line = line