Ejemplo n.º 1
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
Ejemplo n.º 2
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'
Ejemplo n.º 3
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
Ejemplo n.º 4
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
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'
Ejemplo n.º 7
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
Ejemplo n.º 8
0
    wasm.components.Start(wasm.components.Ref('func', name='$main', index=1)),
    wasm.components.Func(
        '$main',
        wasm.components.Ref('type', name='$main_sig', index=1),
        [(None, 'f64')], instructions),
)

# Result is exactly the same!
assert wa3.to_bytes() == wa1.to_bytes()


## Recursion ...

# The text representation of a module produces an exact copy
assert wasm.Module(wa1.to_string()).to_bytes() == wa1.to_bytes()

# Using the elements (definitions) of a module to create a new module too
assert wasm.Module(*[d for d in wa1]).to_bytes() == wa1.to_bytes()

# We can reconstruct the module from its binary form
assert wasm.Module(wa1.to_bytes()).to_bytes() == wa1.to_bytes()


## Let's run it

wasm.run_wasm_in_node(wa1)

import webbrowser
wasm.export_wasm_example(__file__[:-3] + '.html', wa1.to_string(), wa1)
webbrowser.open(__file__[:-3] + '.html')
Ejemplo n.º 9
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