import io 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): with NamedTemporaryFile('w+t') as input_fp: input_fp.write(code_wat) input_fp.flush() with NamedTemporaryFile('w+b') as output_fp: result = subprocess.run( [ 'wat2wasm', 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 = [] 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) 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(), {}) result.returned_value = runtime.exec('testEntry', args) return result