def test_module_id(): m1 = wasm.Module("(module)") m2 = wasm.Module("(module $foo)") m3 = wasm.Module("(module $bar (func $spam))") assert m1.id is None assert len(m1.definitions) == 0 assert m1.to_string() == '(module)\n' assert m2.id == '$foo' assert m2.to_string() == '(module $foo)\n' assert len(m2.definitions) == 0 assert m3.id == '$bar' assert len(m3.definitions) == 2 # Type and func
def emit_module(): #prog: kast): kast.Module code = '(module (func $main (result i32) (i32.const 42) (return)))' m1 = wasm.Module(code) for d in m1.definitions: print(d) if isinstance(d, wasm.Type): print(d.params) print(d.result) if isinstance(d, wasm.Func): print(d.locals) print(d.instructions) m1 = wasm.Module() # see wasm.instruction_table m1.add_definition(wasm.Type('$main_type', [], ['i32'])) # [(0, 'i32')] main_type = wasm.Ref('type', index=0, name='$main_type') m1.add_definition( wasm.Func( '$main', main_type, [], [wasm.Instruction('i32.const', (42)), wasm.Instruction('return')])) m1.add_definition(wasm.Memory('$0', 1)) m1.add_definition( wasm.Export("memory", "memory", wasm.Ref('memory', index=0, name='$0'))) m1.add_definition( wasm.Export("main", "func", wasm.Ref('func', index=0, name='$main'))) # wasmer.validate() print(m1.to_string()) wasm_bytes = m1.to_bytes() with open('out.wasm', 'wb') as f: f.write(wasm_bytes) instance = wasmer.Instance(wasm_bytes) print(instance.exports) # if 'main' in instance.exports: try: result = instance.exports.main() print(result) except Exception as e: print(e)
def tst_module1(): instructions1 = [ ('loop', None, 'emptyblock'), # print iter ('get_local', 0), ('call', '$print'), # Increase iter ('f64.const', 1), ('get_local', 0), ('f64.add', ), ('tee_local', 0), ('f64.const', 10), ('f64.lt', ), ('br_if', 0), ('end', ), ] instructions2 = [ ('loop', 'emptyblock'), # write iter ('get_local', 0), ('call', '$print'), # Increase iter ('f64.const', 1), ('get_local', 0), ('f64.add', ), ('tee_local', 0), ('f64.const', 10), ('f64.lt', ), ('br_if', 0), ('end', ), ] CODE0 = dedent(""" (module (type $print (func (param f64))) (type $1 (func)) (import "js" "print_ln" (func $print (type $print))) (start $main) (func $main (type $1) (local f64) loop (get_local 0) (call $print) (f64.const 1) (get_local 0) (f64.add) (tee_local 0) (f64.const 10) (f64.lt) (br_if 0) (end) ) ) """) # ----- Test main code m0 = wasm.Module(CODE0) assert m0.to_string() == CODE0 b0 = m0.to_bytes() if wasm.has_node(): assert wasm.run_wasm_in_node(m0, True) == '0\n1\n2\n3\n4\n5\n6\n7\n8\n9' # ----- Abbreviated text m1 = wasm.Module(""" (module (import "js" "print_ln" (func $print (param f64))) (start $main) (func $main (local f64) (loop ;; print iter (get_local 0) (call $print) ;; increase iter (f64.const 1) (get_local 0) (f64.add) (tee_local 0) (f64.const 10) (f64.lt) (br_if 0) ) ) )""") assert m1.to_bytes() == b0 # ------ Tuples with tuple instructions m2 = wasm.Module( '(import "js" "print_ln" (func $print (param f64)))', ('start', '$main'), ('func', '$main', ('local', 'f64')) + tuple(instructions1), ) assert m2.to_bytes() == b0 # ------ Tuples with Instruction instances m3 = wasm.Module( '(import "js" "print_ln" (func $print (param f64)))', ('start', '$main'), ('func', '$main', ('local', 'f64')) + tuple(instructions2), ) assert m3.to_bytes() == b0 # ------ Definition instances with tuple instructions m4 = wasm.Module( wasm.Type('$print_sig', [(0, 'f64')], []), wasm.Type('$main_sig', [], []), wasm.Import( 'js', 'print_ln', 'func', '$print', ('$print_sig', ), ), wasm.Start('$main'), wasm.Func('$main', wasm.Ref('type', name='$main_sig'), [(None, 'f64')], instructions1), ) assert m4.to_bytes() == b0 # ------ Definition instances with Instruction instances m5 = wasm.Module( wasm.Type('$print_sig', [(0, 'f64')], []), wasm.Type('$main_sig', [], []), wasm.Import( 'js', 'print_ln', 'func', '$print', ('$print_sig', ), ), wasm.Start('$main'), wasm.Func('$main', wasm.Ref('type', name='$main_sig'), [(None, 'f64')], instructions2), ) assert m5.to_bytes() == b0 # ------ From module elements m6 = wasm.Module(*m0) assert m6.to_bytes() == b0 # ------ to_string() m7 = wasm.Module(m0.to_string()) assert m7.to_bytes() == b0 # ------ to_bytes() m8 = wasm.Module(b0) assert m8.to_bytes() == b0
import math import logging import time import io import os from ppci import wasm from ppci.utils.reporting import HtmlReportGenerator #logging.basicConfig(level=logging.DEBUG) # this produces so much output that it slows things down a lot logging.basicConfig(level=logging.WARN) # Load the wasm module filename = os.path.join(os.path.dirname(__file__), 'wasm', 'rocket.wasm') game_data = open(filename, 'rb').read() game_module = wasm.Module(game_data) class BaseRocketGame: """ Simple rocket game, text based, without user input. """ def __init__(self, game_module=game_module): # Create import dict from methods env = {} for name in dir(self): if name.startswith('wasm_'): env[name[5:]] = getattr(self, name) self.imports = dict(env=env) # Instantiate game module
import os import time from ppci import wasm from rocket_qt import QtRocketGame # Load the wasm ai modules filename1 = os.path.join(os.path.dirname(__file__), 'wasm', 'ai1.wat') ai_data1 = open(filename1, 'rt').read() ai_module1 = wasm.Module(ai_data1) # filename2 = os.path.join(os.path.dirname(__file__), 'wasm', 'ai2.wasm') ai_data2 = open(filename2, 'rb').read() ai_module2 = wasm.Module(ai_data2) class AiRocketGame(QtRocketGame): def __init__(self, ai_module=ai_module1): super().__init__() self.ai = wasm.instantiate(ai_module, self.imports, target='native') def paintEvent(self, event): super().paintEvent(event) self.ai.exports.update() def wasm_debug(self, a: float, b: float) -> None: print('debug', a, b) ## Imported methods of the AI module, which are exports to the game module def wasm_toggle_shoot(self, b: int) -> None: self.game.exports.toggle_shoot(bool(b))
## Define WASM module using pure WAT # This is great if you like writing WASM by hand. Abbreviations are # automatically resolved (e.g. inline signatures and nested # instructions). wa1 = wasm.Module(""" (module (import "js" "print_ln" (func $print (param f64))) (start $main) (func $main (local f64) (loop ;; print iter (get_local 0) (call $print) ;; increase iter (f64.const 1) (get_local 0) (f64.add) (tee_local 0) (f64.const 10) (f64.lt) (br_if 0) ) ) )""") # Show text and binary representation of the module wa1.show() wa1.show_bytes() ## Define WASM module using tuples
""" Display some info about the WASM module, like imports and exports. """ from ppci import wasm filename = 'rocket.wasm' wasm_data = open(filename, 'rb').read() wasm_module = wasm.Module(wasm_data) print(f'WASM file {filename} is {len(wasm_data)/2**10:0.1f} KiB') wasm_module.show_interface() # types = wasm_module['type'] # imports = wasm_module['import'] # exports = wasm_module['export'] # functions = wasm_module['func'] # # # print('\nImports:') # for c in imports: # #c.show() # assert c.kind == 'func' # we assume only func imports # sig = types[c.info[0].index] # print(f' {c.modname}.{c.name}:'.ljust(20), f'{sig.params} -> {sig.result}') # # print('\nExports:') # for c in exports: # # c.show()
wasm_module = wasm.Module( ('import', 'py', 'add', ('func', '$add', ('param', 'i64', 'i64'), ('result', 'i64'))), ('global', '$g1', ('export', 'var1'), ('mut', 'i64'), ('i64.const', 42)), ( 'func', ('export', 'main'), ('param', 'i64'), ('result', 'i64'), ('local.get', 0), # ('i64.const', 42), ('global.get', '$g1'), ('call', '$add'), ), ( 'func', ('export', 'add'), ('param', 'i64', 'i64'), ('result', 'i64'), ('local.get', 0), ('local.get', 1), ('call', '$add'), ), ( 'memory', ('export', 'mem0ry'), ('data', 'abcd'), ), )