Beispiel #1
0
def test_read_wat():

    for text in (TEXT1, TEXT2):
        m = Module(text)
        m.to_string()
        b = m.to_bytes()
        assert isinstance(b, bytes)
Beispiel #2
0
def test_type1():
    """ Test canoncocal form of import and func and inline typedefs.
    """

    # The canonical form
    CODE0 = dedent("""
    (module
        (type $0 (func (param i32)))
        (type $1 (func (param i32 i32) (result i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $0)))
        (start $main)
        (func $add (type $1)
            (get_local 0)
            (get_local 1)
            (i32.add)
        )
        (func $main (type $2)
            (i32.const 4)
            (i32.const 3)
            (call $add)
            (call $print)
        )
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0
    if has_node():
        assert run_wasm_in_node(m0, True) == '7'

    # Abbreviation: inline typedefs
    CODE1 = """
    (module
        (import "js" "print_ln" (func $print (param i32)))
        (start $main)
        (func $add (param i32 i32) (result i32)
            (get_local 0)
            (get_local 1)
            (i32.add)
        )
        (func $main
            (i32.const 4)
            (i32.const 3)
            (call $add)
            (call $print)
        )
    )
    """
    m1 = Module(CODE1)
    assert m1.to_string() == CODE0
    assert m1.to_bytes() == b0
Beispiel #3
0
def test_memory_i32_load_behavior(load_op, mem):
    source = ('module', ('func', ('export', 'my_func'), ('result', 'i32'),
                         load_op), ('memory', 1), ('data', ('i32.const', 0),
                                                   mem))

    m = Module(source)
    assert_equal_behavior(m)
Beispiel #4
0
def test_memory_i64_store_behavior(store_op, mem):
    source = ('module', ('func', ('export', 'my_func'), store_op),
              ('memory', ('export', 'mem'), 1), ('data', ('i32.const', 0),
                                                 mem))

    m = Module(source)
    assert_equal_memory(m)
Beispiel #5
0
def tst_expression_behavior(v64, mem):
    # assume(s != 0)
    # print('code', v64, v32)

    source = ('module',
        # ('func', '$func3', ('result', 'i32'),
        #     v64,
        #     ('i32.wrap_i64',)
        # ),
        # ('func', '$func2', ('result', 'i64'),
        #     expr32,
        #     ('i64.extend_i32_s',),
        # ),
        ('func', ('export', 'my_func'), ('result', 'i64'),
            v64
            # ('i64.const', s),
            # ('i64.const', s),
            # ('i64.add'),
            # ('i64.const', s),
            # ('i64.mul'),
            # ('i64.const', s),
            # ('i64.sub'),
            # ('i64.const', s),
            # ('i64.rem_u'),
        ),
        ('memory', 2),
        ('data', ('i32.const', 0), mem)
    )

    # Create wasm module
    m = Module(source)
    assert_equal_behavior(m)
Beispiel #6
0
def test_coremark_crc16(v1, v2):
    coremark_wasm_snippet = r"""
    (module
      (func $crc8 (param i32 i32) (result i32)
        local.get 0
        local.get 1
        i32.add)

      (func (export "crc16") (param i32 i32) (result i32)
        local.get 0
        i32.const 16
        i32.shr_u
        local.get 0
        i32.const 65535
        i32.and
        local.get 1
        call $crc8
        call $crc8)
    )
    """
    m = Module(coremark_wasm_snippet)
    py_inst = instantiate(m, target='python')
    native_inst = instantiate(m, target='native')
    res1 = py_inst.exports['crc16'](v1, v2)
    res2 = native_inst.exports['crc16'](v1, v2)
    print('results', res1, 'should be equal to', res2)
    assert res1 == res2
Beispiel #7
0
    def take_root(self, bits, target):
        # Function parameters and result:
        a = 4.0
        b = 9.0
        expected_result = 6.0

        # Python cross check:
        python_result = math.sqrt(a) * math.sqrt(b)
        assert math.isclose(python_result, expected_result, rel_tol=0.0001, abs_tol=0.0000001)

        # Now via wasm instantiation:
        module = Module(src)
        # report_filename = 'root_{}_{}.html'.format(bits, target)
        # with html_reporter(report_filename) as reporter:
        #, reporter=reporter)
        instance = instantiate(module, target=target)

        # print('root ', bits, 'instance', inst, 'for target', target)

        funcname = 'f{}.mul_sqrts'.format(bits)
        res = instance.exports[funcname](a, b)
        
        # print('Result:', res, 'expected=', expected_result, 'python says', python_result)
        
        assert math.isclose(res, expected_result, rel_tol=0.0001, abs_tol=0.0000001)
Beispiel #8
0
def test_export1():

    # The canonical form
    CODE0 = dedent("""
    (module
        (type $sig (func))
        (table $t1 2 anyfunc)
        (memory $m1 1)
        (global $g1 i32 (i32.const 7))
        (export "bar_table1" (table $t1))
        (export "bar_mem1" (memory $m1))
        (export "bar_global" (global $g1))
        (export "bar_func1" (func $f1))
        (export "bar_func2" (func $f1))
        (func $f1 (type $sig)
        
        )
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    print(m0.to_string())
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0

    # Export abbreviations: definitions of func/memory/table/global
    # that are really exports.

    CODE1 = dedent("""
    (module
        (type $sig (func))
        (table $t1 (export "bar_table1") 2 anyfunc)
        (memory $m1 (export "bar_mem1") 1)
        (global $g1 (export "bar_global") i32 (i32.const 7))
        (func $f1
            (export "bar_func1") (export "bar_func2")
            (type $sig)
        )
    )
    """)

    m1 = Module(CODE1)
    assert m1.to_string() == CODE0
    assert m1.to_bytes() == b0
Beispiel #9
0
def test_i64_comparison_behavior(cmp_op, v1, v2):
    opcode = 'i64.' + cmp_op
    source = (
        'module',
        ('func', ('export', 'my_func'), ('result', 'i32'), (opcode, v1, v2)),
    )

    m = Module(source)
    assert_equal_behavior(m)
Beispiel #10
0
def test_import1():

    # The canonical form
    CODE0 = dedent("""
    (module
      (type $bar_func (func))
      (import "foo" "bar_func" (func $bar_func (type $bar_func)))
      (import "foo" "bar_table1" (table $t1 2 funcref))
      (import "foo" "bar_mem1" (memory $m1 1))
      (import "foo" "bar_mem2" (memory $m2 1 2))
      (import "foo" "bar_global" (global $bar_global i32))
    )
    """)
    # (import "foo" "bar_table" (table $bar_table (type $bar_func)))

    # Test main code
    m0 = Module(CODE0)
    print(m0.to_string())
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0

    # Import abbreviations: definitions of func/memory/table/global
    # that are really imports.

    CODE1 = dedent("""
    (module
        (type $bar_func (func))
        (func $bar_func (import "foo" "bar_func") (type $bar_func))
        (table $t1 (import "foo" "bar_table1") 2 funcref)
        (memory $m1 (import "foo" "bar_mem1") 1)
        (memory $m2 (import "foo" "bar_mem2") 1 2)
        (global $bar_global (import "foo" "bar_global") i32)
    )
    """)

    m1 = Module(CODE1)
    assert m1.to_string() == CODE0
    assert m1.to_bytes() == b0
Beispiel #11
0
def test_global1():

    CODE0 = dedent(r"""
    (module
      (type $print (func (param i32)))
      (type $2 (func))
      (import "js" "print_ln" (func $print (type $print)))
      (global $foo i32 i32.const 7)
      (start $main)
      (func $main (type $2)
        global.get $foo
        call $print)
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    assert m0.to_string() == CODE0
    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0
    if has_node():
        assert run_wasm_in_node(m0, True) == '7'
Beispiel #12
0
    def test_callbacks(self):
        """ Test various stuff around wasm instantiation.
        See examples/wasm/callbacks.py
        """
        module = 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),
                ('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'),
            ),
        )

        def my_add(x: int, y: int) -> int:
            print('my add called', x, y)
            return x + y + 1

        imports = {
            'py_add': my_add
        }

        instance = instantiate(
            module,
            imports={
                'py': {
                    'add': my_add,
                }
            })

        self.assertEqual(1380, instance.exports.main(1337))
        self.assertEqual(85, instance.exports.add(42, 42))
        self.assertEqual(3, instance.exports['add'](1, 1))
        self.assertEqual(42, instance.exports.var1.read())
        instance.exports.var1.write(7)
        self.assertEqual(7, instance.exports.var1.read())
        self.assertEqual(1345, instance.exports.main(1337))
        self.assertEqual(b"abcd", instance.exports.mem0ry[0:4])
        instance.exports.mem0ry[1:3] = bytes([1,2])
        self.assertEqual(b'a\x01\x02d', instance.exports.mem0ry[0:4])
Beispiel #13
0
    def parse_module(self, s_expr):
        if 'binary' in s_expr:
            # We have (module binary "")

            # Iterate:
            elems = iter(s_expr)

            # Skip to binary tag:
            while next(elems) != 'binary':
                pass

            # fetch data from last tuple elements:
            parts = []
            for elem in elems:
                data = datastring2bytes(elem)
                parts.append(data)
            data = reduce(add, parts)

            # Load module from binary data:
            m1 = Module(data)

            # Go back
            data2 = m1.to_bytes()

            # Wont always be the same, e.g. some tests use non-minimal LEB ints
            # assert data == data2

            data3 = Module(data2).to_bytes()

            # Check that reading it in result in the same module ...
            assert data2 == data3

        else:
            # Load module from tuples:
            m1 = Module(s_expr)

            # # Convert module to text form and parse again
            # # This should yield the same binary form:
            # m2 = Module(m1.to_string())
            # assert m1.to_bytes() == m2.to_bytes()

            # NOTE: going to string format and back does not
            # guarantee that parsing was correct.

            self.reporter.dump_wasm(m1)

        self.logger.debug('loaded wasm module %s (id=%s)', m1, m1.id)
        return m1
Beispiel #14
0
def test_func1():

    # The canonical form
    CODE0 = dedent("""
    (module
        (type $0 (func (param i32)))
        (type $1 (func (param i32 i32) (result i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $0)))
        (start $main)
        (func $add (type $1)
            (get_local 0)
            (get_local 1)
            (i32.add)
        )
        (func $main (type $2) (local $foo i32)
            (i32.const 4)
            (i32.const 3)
            (call $add)
            (set_local $foo)
            (get_local $foo)
            (call $print)
        )
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0

    # TODO: figure out what is wrong below:
    if False:
        printed_numbers = []

        def print_ln(x: int) -> None:
            printed_numbers.append(x)

        imports = {
            'js': {
                'print_ln': print_ln,
            },
        }
        instantiate(m0, imports, target='python')
        assert [7] == printed_numbers

    if has_node():
        assert run_wasm_in_node(m0, True) == '7'

    # Abbreviation: inline typedefs
    CODE1 = """
    (module
        (import "js" "print_ln" (func $print (param i32)))
        (start $main)
        (func $add (param i32 i32) (result i32)
            (get_local 0)
            (get_local 1)
            (i32.add)
        )
        (func $main (local $foo i32)
            (set_local $foo
                (call $add
                    (i32.const 4)
                    (i32.const 3)
                )
            )
            (call $print
                (get_local $foo)
            )
        )
    )
    """
    m1 = Module(CODE1)
    assert m1.to_string() == CODE0  # look at the indentation!
    assert m1.to_bytes() == b0
Beispiel #15
0
def test_instructions1():
    """ Test canoncocal form of import and func and inline typedefs.
    """

    # The canonical form
    CODE0 = dedent("""
    (module
        (type $print (func (param i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $print)))
        (start $main)
        (func $main (type $2)
            (i32.const 1)
            (if)
                (i32.const 4)
                (i32.const 3)
                (i32.add)
                (call $print)
            (else)
                (i32.const 5)
                (call $print)
            (end)
        )
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0
    if has_node():
        assert run_wasm_in_node(m0, True) == '7'

    # Variant 1 - no inentation, nested test for if
    CODE1 = dedent("""
    (module
        (type $print (func (param i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $print)))
        (start $main)
        (func $main (type $2)
            (if (i32.const 1))
            (i32.const 4)
            (i32.const 3)
            (i32.add)
            (call $print)
            (else)
            (i32.const 5)
            (call $print)
            (end)
        )
    )
    """)

    m1 = Module(CODE1)
    assert m1.to_string() == CODE0
    assert m1.to_bytes() == b0

    # Variant 2 - nesting all the way
    CODE2 = dedent("""
    (module
        (type $print (func (param i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $print)))
        (start $main)
        (func $main (type $2)
            (if (i32.const 1)
                (i32.const 4)
                (i32.const 3)
                (i32.add)
                (call $print)
            (else)
                (i32.const 5)
                (call $print)
            )
        )
    )
    """)

    m2 = Module(CODE2)
    assert m2.to_string() == CODE0
    assert m2.to_bytes() == b0

    # Variant 3 - leave out the else clause
    # This is described as an "abbreviation", but it seems that we don't
    # have to always output an else clause in binary form either.
    CODE3 = dedent("""
    (module
        (type $print (func (param i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $print)))
        (start $main)
        (func $main (type $2)
            (if (i32.const 1)
                (i32.const 4)
                (i32.const 3)
                (i32.add)
                (call $print)
            )
        )
    )
    """)

    m3 = Module(CODE3)
    assert m3.to_string() != CODE0
    assert m3.to_bytes() != b0
    if has_node():
        assert run_wasm_in_node(m3, True) == '7'
Beispiel #16
0
            f.write(data)


files = [
    'clang.wasm',
    'clang-format.wasm',
    'runtime.wasm',
]

for local_filename in files:
    url = 'https://tbfleming.github.io/cib/{}'.format(local_filename)
    if not os.path.exists(local_filename):
        download_file(url, local_filename)

with open('runtime.wasm', 'rb') as f:
    # with open('clang-format.wasm', 'rb') as f:
    wasm_module = Module(f.read())

print(wasm_module)

wasm_module.show_interface()

arch = get_arch('x86_64')
ptr_info = arch.info.get_type_info('ptr')
ir_module = wasm_to_ir(wasm_module, ptr_info)

print(ir_module)
print(ir_module.stats())

obj = ir_to_object([ir_module], arch)
Beispiel #17
0
    def load_module(self, s_expr):
        if 'binary' in s_expr:
            # We have (module binary "")

            # Iterate:
            elems = iter(s_expr)

            # Skip to binary tag:
            while next(elems) != 'binary':
                pass

            # fetch data from last tuple elements:
            parts = []
            for elem in elems:
                data = datastring2bytes(elem)
                parts.append(data)
            data = reduce(add, parts)

            # Load module from binary data:
            m1 = Module(data)

            # Go back
            data2 = m1.to_bytes()

            # Wont always be the same, e.g. some tests use non-minimal LEB ints
            # assert data == data2

            data3 = Module(data2).to_bytes()

            # Check that reading it in result in the same module ...
            assert data2 == data3

        else:
            # Load module from tuples:
            m1 = Module(s_expr)

            # # Convert module to text form and parse again
            # # This should yield the same binary form:
            # m2 = Module(m1.to_string())
            # assert m1.to_bytes() == m2.to_bytes()

            # NOTE: going to string format and back does not
            # guarantee that parsing was correct.

            self.reporter.dump_wasm(m1)

        self.logger.debug('loaded wasm module %s', m1)

        # Next step: Instantiate:
        if self.target:
            def my_print() -> None:
                pass

            def print_i32(x: int) -> None:
                pass

            imports = {
               'spectest': {
                   'print_i32': print_i32,
                   'print': my_print,
               }
            }
            self.mod_instance = instantiate(
                m1, imports, target=self.target, reporter=self.reporter)
            self.logger.debug('Instantiated wasm module %s', self.mod_instance)
        else:
            self.mod_instance = None
Beispiel #18
0
def do_func(fname):
    """ Test parsing on a single test file.
    Its great to call this at the botton during dev!
    """

    print('Testing {} - "{}"'.format(fname,
                                     os.path.join(get_spec_suite_dir(),
                                                  fname)))

    for text in get_test_script_parts(fname):
        sexpr = parse_sexpr(text)

        # Assert that the toplevel expression makes sense
        assert sexpr[0] in (
            'module',
            'invoke',
            'register',
            'assert_return',
            'assert_invalid',
            'assert_trap',
            'assert_malformed',
            'assert_exhaustion',
            'assert_unlinkable',
            'assert_return_canonical_nan',
            'assert_return_arithmetic_nan',
            'func',
            'memory',  # inline-module.wast
        ), '{}: unexpected expression in'.format(fname)

        # But in this script we only do modules
        if sexpr[0] != 'module':
            continue
        if 'binary' in sexpr:
            continue

        # todo: skipping a few here, for now
        if fname in (
                'names.wast',
                'comments.wast',  # because sending Unicode over Pipes seems to go wrong
        ):
            continue

        wasm_bin0 = wabt.wat2wasm(text)

        m1 = Module(wasm_bin0)
        m2 = Module(text)
        m3 = Module(sexpr)

        wasm_bin1 = m1.to_bytes()
        wasm_bin2 = m2.to_bytes()
        wasm_bin3 = m3.to_bytes()

        assert wasm_bin0 == wasm_bin1, '{}: our binary parsing is broken'.format(
            fname)
        assert wasm_bin2 == wasm_bin3, '{}: our text/tuple paring differs'.format(
            fname)
        assert wasm_bin0 == wasm_bin2, '{}: our text parsing is broken'.format(
            fname)

        if False:  # debug helpers
            print(len(wasm_bin1), len(wasm_bin2))
            print(len(m1.definitions), len(m2.definitions))
            hexdump(wasm_bin1)
            print()
            hexdump(wasm_bin2)
Beispiel #19
0
def test_memory1():

    # The canonical form
    CODE0 = dedent(r"""
    (module
      (type $print (func (param i32)))
      (type $2 (func))
      (import "js" "print_ln" (func $print (type $print)))
      (memory $0 1 1)
      (start $main)
      (func $main (type $2)
        i32.const 0
        i32.load8_u
        call $print
        i32.const 1
        i32.load8_u
        call $print)
      (data i32.const 0 "\04\03\02")
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0

    printed_numbers = []
    def print_ln(x: int) -> None:
        printed_numbers.append(x)
    imports = {
        'js': {
            'print_ln': print_ln,
        }
    }
    instantiate(m0, imports=imports, target='python')
    assert [4, 3] == printed_numbers

    if has_node():
        assert run_wasm_in_node(m0, True) == '4\n3'

    # Abbreviation: imported memory
    m3 = Module('(module (memory $m1 (import "foo" "bar_mem1") 1) )')
    assert m3.to_string() == dedent("""
    (module
      (import "foo" "bar_mem1" (memory $m1 1))
    )
    """)

    m3 = Module('(module (memory (import "foo" "bar_mem1") 2 3) )')
    assert m3.to_string() == dedent("""
    (module
      (import "foo" "bar_mem1" (memory 2 3))
    )
    """)


    # Abbeviation: inline data and unspecified (default) alignment
    CODE1 = r"""
    (module
        (type $print (func (param i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $print)))
        (memory (data "\04\03\02"))
        (start $main)
        (func $main (type $2)
            i32.const 0
            i32.load8_u
            call $print
            i32.const 1
            i32.load8_u
            call $print
        )
    )
    """
    m1 = Module(CODE1)
    assert m1.to_string() == CODE0
    assert m1.to_bytes() == b0
Beispiel #20
0
def test_table1():

    # The canonical form
    CODE0 = dedent(r"""
    (module
      (type $print (func (param i32)))
      (type $2 (func))
      (import "js" "print_ln" (func $print (type $print)))
      (table $0 2 2 funcref)
      (start $main)
      (elem i32.const 0 $f1 $f2)
      (func $f1 (type $2)
        i32.const 101
        call $print)
      (func $f2 (type $2)
        i32.const 102
        call $print)
      (func $main (type $2)
        i32.const 0
        call_indirect (type $2)
        i32.const 1
        call_indirect (type $2))
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    assert Module(b0).to_bytes() == b0

    html_report = 'table_and_element_compilation_report.html'
    with open(html_report, 'w') as f, HtmlReportGenerator(f) as reporter:
        printed_numbers = []

        def print_ln(x: int) -> None:
            printed_numbers.append(x)

        imports = {
            'js': {
                'print_ln': print_ln,
            },
        }
        instantiate(m0, imports, target='python', reporter=reporter)
        assert [101, 102] == printed_numbers

        if is_platform_supported():
            printed_numbers = []

            def print_ln(x: int) -> None:
                printed_numbers.append(x)

            imports = {
                'js': {
                    'print_ln': print_ln,
                },
            }
            instantiate(m0, imports, target='native', reporter=reporter)
            assert [101, 102] == printed_numbers

    if has_node():
        assert run_wasm_in_node(m0, True) == '101\n102'

    # Abbreviation: imported table
    m3 = Module('(module (table $t1 (import "foo" "bar_table1") funcref) )')
    assert m3.to_string() == dedent("""
    (module
      (import "foo" "bar_table1" (table $t1 funcref))
    )
    """)

    m3 = Module('(module (table (import "foo" "bar_table1") 2 3 funcref) )')
    assert m3.to_string() == dedent("""
    (module
      (import "foo" "bar_table1" (table 2 3 funcref))
    )
    """)

    # Abbeviation: inline data and unspecified (default) alignment
    CODE1 = r"""
    (module
        (type $print (func (param i32)))
        (type $2 (func))
        (import "js" "print_ln" (func $print (type $print)))
        (table funcref (elem $f1 $f2))
        (start $main)
        (func $f1 (type $2)
            (i32.const 101)
            (call $print)
        )
        (func $f2 (type $2)
            (i32.const 102)
            (call $print)
        )
        (func $main (type $2)
            (i32.const 0)
            (call_indirect (type $2))
            (i32.const 1)
            (call_indirect (type $2))
        )
    )
    """
    m1 = Module(CODE1)
    assert m1.to_string() == CODE0
    assert m1.to_bytes() == b0
Beispiel #21
0
def test_type2():
    """ Test inline typedefs with various number of args and results.
    """

    # Canonical form
    CODE0 = dedent("""
    (module
        (type $0 (func (param i32)))
        (type $1 (func (param i32) (result i32)))
        (type $2 (func (result i32)))
        (type $3 (func))
        (import "js" "print_ln" (func $print (type $0)))
        (start $main)
        (func $test_11 (type $1)
            (i32.const 111)
            (call $print)
            (i32.const 0)
        )
        (func $test_10 (type $0)
            (i32.const 110)
            (call $print)
        )
        (func $test_01 (type $2)
            (i32.const 101)
            (call $print)
            (i32.const 0)
        )
        (func $test_00 (type $3)
            (i32.const 100)
            (call $print)
        )
        (func $main (type $3)
            (i32.const 0)
            (call $test_11)
            (drop)
            (i32.const 0)
            (call $test_10)
            (call $test_01)
            (drop)
            (call $test_00)
        )
    )
    """)

    # Test main code
    m0 = Module(CODE0)
    assert m0.to_string() == CODE0

    b0 = m0.to_bytes()
    if has_node():
        assert run_wasm_in_node(m0, True) == '111\n110\n101\n100'

    # Abbreviated
    CODE1 = """
    (module
        (import "js" "print_ln" (func $print (param i32)))
        (start $main)
        (func $test_11 (param i32) (result i32)
            (i32.const 111)
            (call $print)
            (i32.const 0)
        )
        (func $test_10 (param i32)
            (i32.const 110)
            (call $print)
        )
        (func $test_01 (result i32)
            (i32.const 101)
            (call $print)
            (i32.const 0)
        )
        (func $test_00
            (i32.const 100)
            (call $print)
        )
        (func $main
            (i32.const 0) (call $test_11) (drop)
            (i32.const 0) (call $test_10)
            (call $test_01) (drop)
            (call $test_00)
        )
    )
    """

    m1 = Module(CODE1)
    assert m1.to_string() == CODE0
    assert m1.to_bytes() == b0
Beispiel #22
0
  (func $fac-f32 (export "fac-f32") (type $over-f32)
    (if (result f32) (f32.eq (local.get 0) (f32.const 0.0))
      (then (f32.const 1.0))
      (else
        (f32.mul
          (local.get 0)

          (call $fac-f32
            (f32.sub (local.get 0) (f32.const 1.0))
          )
        )
      )
    )
  )
)
"""
m = Module(src)

obj = api.wasmcompile(src, 'x86_64', opt_level=0)
api.objcopy(obj, None, 'elf', 'fac_f32.o')

print(m.to_string())

inst = instantiate(m, {})
inst2 = instantiate(m, {}, target='python')

for number in [1.0, 5.0, 10.0]:
    print('number', number, 'fac', inst.exports['fac-f32'](number),
          'fac_python', inst2.exports['fac-f32'](number))
Beispiel #23
0
import argparse

import numpy as np
import pygame
from pygame.locals import QUIT

from ppci.wasm import Module, instantiate
from ppci.utils import reporting

parser = argparse.ArgumentParser()
parser.add_argument('--rom', default='cpu_instrs.gb')
args = parser.parse_args()
logging.basicConfig(level=logging.INFO)

with open('wasmboy.wasm', 'rb') as f:
    wasm_module = Module(f)


def log(a: int, b: int, c: int, d: int, e: int, f: int, g: int) -> None:
    print('Log:', a, b, c, d, e, f, g)


this_dir = os.path.dirname(os.path.abspath(__file__))
html_report = os.path.join(this_dir, 'wasmboy_report.html')
with reporting.html_reporter(html_report) as reporter:
    wasm_boy = instantiate(wasm_module,
                           imports={'env': {
                               'log': log
                           }},
                           target='native',
                           reporter=reporter)
Beispiel #24
0
def do_func(fname):
    """ Test running on a single test file.
    Its great to call this at the botton during dev!
    """

    print('Testing {} - "{}"'.format(fname,
                                     os.path.join(get_spec_suite_dir(),
                                                  fname)))

    mod = None

    for text in get_test_script_parts(fname):
        sexpr = parse_sexpr(text)
        exp_kind = sexpr[0]

        # Triage over toplevel expressions
        # https://github.com/WebAssembly/spec/blob/master/interpreter/README.md#s-expression-syntax

        if exp_kind == 'module':
            if 'binary' in sexpr:
                # Combine binary parts
                parts = None
                for elem in sexpr:
                    if parts is None:
                        if elem == 'binary':
                            parts = []
                    else:
                        parts.append(datastring2bytes(elem))
                data = b''.join(parts)
                # Load module from binary data
                mod = Module(data)
            else:
                # Load module from text, via wabt
                data = wabt.wat2wasm(text)
                mod = Module(data)

        elif exp_kind == 'register':
            raise NotImplementedError(
                'I suppose we need this, but not sure how to do it yet.')

        elif exp_kind == 'invoke':
            raise NotImplementedError()

        elif exp_kind == 'assert_return':
            assert len(sexpr) == 3 and sexpr[1][0] == 'invoke'
            _, func_id, params = sexpr[1]
            expected_result = sexpr[2]
            raise NotImplementedError()

        elif expr_kind in (
                'assert_invalid',
                'assert_trap',
                'assert_malformed',
                'assert_exhaustion',
                'assert_unlinkable',
                'assert_return_canonical_nan',
                'assert_return_arithmetic_nan',
                'func',
                'memory',  # inline-module.wast
        ):
            pass  # not implemented yet

        else:
            assert False, '{}: unexpected expression in'.format(fname)