Exemple #1
0
def run_wasm_reduce_tests():
  print('\n[ checking wasm-reduce testcases]\n')

  # fixed testcases
  test_dir = os.path.join(options.binaryen_test, 'reduce')
  for t in os.listdir(test_dir):
    if t.endswith('.wast'):
      print('..', t)
      t = os.path.join(test_dir, t)
      # convert to wasm
      run_command(WASM_AS + [t, '-o', 'a.wasm'])
      run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec -all' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm', '--timeout=4'])
      expected = t + '.txt'
      run_command(WASM_DIS + ['c.wasm', '-o', 'a.wast'])
      with open('a.wast') as seen:
        fail_if_not_identical_to_file(seen.read(), expected)

  # run on a nontrivial fuzz testcase, for general coverage
  # this is very slow in ThreadSanitizer, so avoid it there
  if 'fsanitize=thread' not in str(os.environ):
    print('\n[ checking wasm-reduce fuzz testcase ]\n')

    run_command(WASM_OPT + [os.path.join(options.binaryen_test, 'unreachable-import_wasm-only.asm.js'), '-ttf', '-Os', '-o', 'a.wasm', '-all'])
    before = os.stat('a.wasm').st_size
    run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec -all' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm'])
    after = os.stat('c.wasm').st_size
    assert after < 0.6 * before, [before, after]
Exemple #2
0
def run_wasm_reduce_tests():
    if not shared.has_shell_timeout():
        print('\n[ skipping wasm-reduce testcases]\n')
        return

    print('\n[ checking wasm-reduce testcases]\n')

    # fixed testcases
    for t in shared.get_tests(shared.get_test_dir('reduce'), ['.wast']):
        print('..', os.path.basename(t))
        # convert to wasm
        support.run_command(shared.WASM_AS + [t, '-o', 'a.wasm', '-all'])
        support.run_command(shared.WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec -all ' % shared.WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm', '--timeout=4'])
        expected = t + '.txt'
        support.run_command(shared.WASM_DIS + ['c.wasm', '-o', 'a.wat'])
        with open('a.wat') as seen:
            shared.fail_if_not_identical_to_file(seen.read(), expected)

    # run on a nontrivial fuzz testcase, for general coverage
    # this is very slow in ThreadSanitizer, so avoid it there
    if 'fsanitize=thread' not in str(os.environ):
        print('\n[ checking wasm-reduce fuzz testcase ]\n')
        # TODO: re-enable multivalue once it is better optimized
        support.run_command(shared.WASM_OPT + [os.path.join(shared.options.binaryen_test, 'signext.wast'), '-ttf', '-Os', '-o', 'a.wasm', '--detect-features', '--disable-multivalue'])
        before = os.stat('a.wasm').st_size
        support.run_command(shared.WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec --detect-features' % shared.WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm'])
        after = os.stat('c.wasm').st_size
        # This number is a custom threshold to check if we have shrunk the
        # output sufficiently
        assert after < 0.85 * before, [before, after]
Exemple #3
0
def run_wasm_merge_tests():
    print '\n[ checking wasm-merge... ]\n'

    test_dir = os.path.join(options.binaryen_test, 'merge')
    for t in os.listdir(test_dir):
        if t.endswith(('.wast', '.wasm')):
            print '..', t
            t = os.path.join(test_dir, t)
            u = t + '.toMerge'
            for finalize in [0, 1]:
                for opt in [0, 1]:
                    cmd = WASM_MERGE + [
                        t, u, '-o', 'a.wast', '-S', '--verbose'
                    ]
                    if finalize:
                        cmd += [
                            '--finalize-memory-base=1024',
                            '--finalize-table-base=8'
                        ]
                    if opt: cmd += ['-O']
                    stdout = run_command(cmd)
                    actual = open('a.wast').read()
                    out = t + '.combined'
                    if finalize: out += '.finalized'
                    if opt: out += '.opt'
                    fail_if_not_identical_to_file(actual, out)
                    fail_if_not_identical_to_file(stdout, out + '.stdout')
Exemple #4
0
                def do_asm2wasm_test():
                    actual = support.run_command(cmd)

                    # verify output
                    if not os.path.exists(wasm):
                        shared.fail_with_error(
                            'output .wast file %s does not exist' % wasm)
                    shared.fail_if_not_identical_to_file(actual, wasm)

                    shared.binary_format_check(wasm, verify_final_result=False)
Exemple #5
0
def run_ctor_eval_tests():
    print('\n[ checking wasm-ctor-eval... ]\n')

    for t in shared.get_tests(shared.get_test_dir('ctor-eval'), ['.wast', '.wasm']):
        print('..', os.path.basename(t))
        ctors = open(t + '.ctors').read().strip()
        cmd = shared.WASM_CTOR_EVAL + [t, '-all', '-o', 'a.wat', '-S', '--ctors', ctors]
        support.run_command(cmd)
        actual = open('a.wat').read()
        out = t + '.out'
        shared.fail_if_not_identical_to_file(actual, out)
Exemple #6
0
def run_gcc_tests():
  print('\n[ checking native gcc testcases...]\n')
  if not NATIVECC or not NATIVEXX:
    fail_with_error('Native compiler (e.g. gcc/g++) was not found in PATH!')
    return

  for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'example'))):
    output_file = 'example'
    cmd = ['-I' + os.path.join(options.binaryen_root, 'src'), '-g', '-pthread', '-o', output_file]
    if t.endswith('.txt'):
      # check if there is a trace in the file, if so, we should build it
      out = subprocess.Popen([os.path.join('scripts', 'clean_c_api_trace.py'), os.path.join(options.binaryen_test, 'example', t)], stdout=subprocess.PIPE).communicate()[0]
      if len(out) == 0:
        print('  (no trace in ', t, ')')
        continue
      print('  (will check trace in ', t, ')')
      src = 'trace.cpp'
      with open(src, 'wb') as o:
        o.write(out)
      expected = os.path.join(options.binaryen_test, 'example', t + '.txt')
    else:
      src = os.path.join(options.binaryen_test, 'example', t)
      expected = os.path.join(options.binaryen_test, 'example', '.'.join(t.split('.')[:-1]) + '.txt')
    if src.endswith(('.c', '.cpp')):
      # build the C file separately
      libpath = os.path.join(os.path.dirname(options.binaryen_bin),  'lib')
      extra = [NATIVECC, src, '-c', '-o', 'example.o',
               '-I' + os.path.join(options.binaryen_root, 'src'), '-g', '-L' + libpath, '-pthread']
      if src.endswith('.cpp'):
        extra += ['-std=c++11']
      if os.environ.get('COMPILER_FLAGS'):
        for f in os.environ.get('COMPILER_FLAGS').split(' '):
          extra.append(f)
      print('build: ', ' '.join(extra))
      subprocess.check_call(extra)
      # Link against the binaryen C library DSO, using an executable-relative rpath
      cmd = ['example.o', '-L' + libpath, '-lbinaryen'] + cmd + ['-Wl,-rpath,' + libpath]
    else:
      continue
    print('  ', t, src, expected)
    if os.environ.get('COMPILER_FLAGS'):
      for f in os.environ.get('COMPILER_FLAGS').split(' '):
        cmd.append(f)
    cmd = [NATIVEXX, '-std=c++11'] + cmd
    print('link: ', ' '.join(cmd))
    subprocess.check_call(cmd)
    print('run...', output_file)
    actual = subprocess.check_output([os.path.abspath(output_file)])
    os.remove(output_file)
    if sys.platform == 'darwin':
      # Also removes debug directory produced on Mac OS
      shutil.rmtree(output_file + '.dSYM')

    fail_if_not_identical_to_file(actual, expected)
Exemple #7
0
def run_wasm_metadce_tests():
    print('\n[ checking wasm-metadce ]\n')

    for t in shared.get_tests(shared.get_test_dir('metadce'), ['.wast', '.wasm']):
        print('..', os.path.basename(t))
        graph = t + '.graph.txt'
        cmd = shared.WASM_METADCE + [t, '--graph-file=' + graph, '-o', 'a.wat', '-S', '-all']
        stdout = support.run_command(cmd)
        expected = t + '.dced'
        with open('a.wat') as seen:
            shared.fail_if_not_identical_to_file(seen.read(), expected)
        shared.fail_if_not_identical_to_file(stdout, expected + '.stdout')
Exemple #8
0
def run_wasm_dis_tests():
  print '\n[ checking wasm-dis on provided binaries... ]\n'

  for t in tests:
    if t.endswith('.wasm') and not t.startswith('spec'):
      print '..', t
      t = os.path.join(options.binaryen_test, t)
      cmd = WASM_DIS + [t]
      if os.path.isfile(t + '.map'): cmd += ['--source-map', t + '.map']

      actual = run_command(cmd)

      fail_if_not_identical_to_file(actual, t + '.fromBinary')
Exemple #9
0
def run_gcc_tests():
    print('\n[ checking native gcc testcases...]\n')
    if not shared.NATIVECC or not shared.NATIVEXX:
        shared.fail_with_error(
            'Native compiler (e.g. gcc/g++) was not found in PATH!')
        return
    # windows + gcc will need some work
    if shared.skip_if_on_windows('gcc'):
        return

    for t in sorted(os.listdir(shared.get_test_dir('example'))):
        output_file = 'example'
        cmd = [
            '-I' + os.path.join(shared.options.binaryen_root, 't'), '-g',
            '-pthread', '-o', output_file
        ]
        if not t.endswith(('.c', '.cpp')):
            continue
        src = os.path.join(shared.get_test_dir('example'), t)
        expected = os.path.join(shared.get_test_dir('example'),
                                '.'.join(t.split('.')[:-1]) + '.txt')
        # build the C file separately
        libpath = os.path.join(os.path.dirname(shared.options.binaryen_bin),
                               'lib')
        extra = [
            shared.NATIVECC, src, '-c', '-o', 'example.o',
            '-I' + os.path.join(shared.options.binaryen_root, 'src'), '-g',
            '-L' + libpath, '-pthread'
        ]
        if src.endswith('.cpp'):
            extra += ['-std=c++' + str(shared.cxx_standard)]
        if os.environ.get('COMPILER_FLAGS'):
            for f in os.environ.get('COMPILER_FLAGS').split(' '):
                extra.append(f)
        print('build: ', ' '.join(extra))
        subprocess.check_call(extra)
        # Link against the binaryen C library DSO, using an executable-relative rpath
        cmd = ['example.o', '-L' + libpath, '-lbinaryen'
               ] + cmd + ['-Wl,-rpath,' + libpath]
        print('  ', t, src, expected)
        if os.environ.get('COMPILER_FLAGS'):
            for f in os.environ.get('COMPILER_FLAGS').split(' '):
                cmd.append(f)
        cmd = [shared.NATIVEXX, '-std=c++' + str(shared.cxx_standard)] + cmd
        print('link: ', ' '.join(cmd))
        subprocess.check_call(cmd)
        print('run...', output_file)
        actual = subprocess.check_output([os.path.abspath(output_file)
                                          ]).decode('utf-8')
        os.remove(output_file)
        shared.fail_if_not_identical_to_file(actual, expected)
Exemple #10
0
def run_ctor_eval_tests():
    print '\n[ checking wasm-ctor-eval... ]\n'

    test_dir = os.path.join(options.binaryen_test, 'ctor-eval')
    for t in os.listdir(test_dir):
        if t.endswith(('.wast', '.wasm')):
            print '..', t
            t = os.path.join(test_dir, t)
            ctors = open(t + '.ctors').read().strip()
            cmd = WASM_CTOR_EVAL + [t, '-o', 'a.wast', '-S', '--ctors', ctors]
            stdout = run_command(cmd)
            actual = open('a.wast').read()
            out = t + '.out'
            fail_if_not_identical_to_file(actual, out)
Exemple #11
0
def run_wasm_reduce_tests():
  print '\n[ checking wasm-reduce ]\n'

  test_dir = os.path.join(options.binaryen_test, 'reduce')
  for t in os.listdir(test_dir):
    if t.endswith('.wast'):
      print '..', t
      t = os.path.join(test_dir, t)
      # convert to wasm
      run_command(WASM_AS + [t, '-o', 'a.wasm'])
      print run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm'])
      expected = t + '.txt'
      run_command(WASM_DIS + ['c.wasm', '-o', 'a.wast'])
      with open('a.wast') as seen:
        fail_if_not_identical_to_file(seen.read(), expected)
Exemple #12
0
def run_wasm_metadce_tests():
  print('\n[ checking wasm-metadce ]\n')

  test_dir = os.path.join(options.binaryen_test, 'metadce')
  for t in os.listdir(test_dir):
    if t.endswith(('.wast', '.wasm')):
      print('..', t)
      t = os.path.join(test_dir, t)
      graph = t + '.graph.txt'
      cmd = WASM_METADCE + [t, '--graph-file=' + graph, '-o', 'a.wast', '-S']
      stdout = run_command(cmd)
      expected = t + '.dced'
      with open('a.wast') as seen:
        fail_if_not_identical_to_file(seen.read(), expected)
      fail_if_not_identical_to_file(stdout, expected + '.stdout')
Exemple #13
0
def run_wasm_dis_tests():
    print('\n[ checking wasm-dis on provided binaries... ]\n')

    for t in shared.get_tests(shared.options.binaryen_test, ['.wasm']):
        print('..', os.path.basename(t))
        cmd = shared.WASM_DIS + [t]
        if os.path.isfile(t + '.map'):
            cmd += ['--source-map', t + '.map']

        actual = support.run_command(cmd)
        shared.fail_if_not_identical_to_file(actual, t + '.fromBinary')

        # also verify there are no validation errors
        def check():
            cmd = shared.WASM_OPT + [t, '-all']
            support.run_command(cmd)

        shared.with_pass_debug(check)
Exemple #14
0
def test_asserts_output():
    for wasm in assert_tests:
        print('..', wasm)

        asserts = os.path.basename(wasm).replace('.wast.asserts', '.asserts.js')
        traps = os.path.basename(wasm).replace('.wast.asserts', '.traps.js')
        asserts_expected_file = os.path.join(shared.options.binaryen_test, asserts)
        traps_expected_file = os.path.join(shared.options.binaryen_test, traps)

        wasm = os.path.join(shared.get_test_dir('wasm2js'), wasm)
        cmd = shared.WASM2JS + [wasm, '--allow-asserts', '-all',
                                '--disable-exception-handling']
        out = support.run_command(cmd)
        shared.fail_if_not_identical_to_file(out, asserts_expected_file)

        cmd += ['--pedantic']
        out = support.run_command(cmd)
        shared.fail_if_not_identical_to_file(out, traps_expected_file)
Exemple #15
0
def run_wasm_dis_tests():
  print '\n[ checking wasm-dis on provided binaries... ]\n'

  for t in tests:
    if t.endswith('.wasm') and not t.startswith('spec'):
      print '..', t
      t = os.path.join(options.binaryen_test, t)
      cmd = WASM_DIS + [t]
      if os.path.isfile(t + '.map'):
        cmd += ['--source-map', t + '.map']

      actual = run_command(cmd)
      fail_if_not_identical_to_file(actual, t + '.fromBinary')

      # also verify there are no validation errors
      def check():
        cmd = WASM_OPT + [t, '-all']
        run_command(cmd)

      with_pass_debug(check)
Exemple #16
0
def run_wasm_opt_tests():
    print '\n[ checking wasm-opt -o notation... ]\n'

    for extra_args in [[], ['--no-validation']]:
        wast = os.path.join(options.binaryen_test, 'hello_world.wast')
        delete_from_orbit('a.wast')
        cmd = WASM_OPT + [wast, '-o', 'a.wast', '-S'] + extra_args
        run_command(cmd)
        fail_if_not_identical_to_file(open('a.wast').read(), wast)

    print '\n[ checking wasm-opt binary reading/writing... ]\n'

    shutil.copyfile(os.path.join(options.binaryen_test, 'hello_world.wast'),
                    'a.wast')
    delete_from_orbit('a.wasm')
    delete_from_orbit('b.wast')
    run_command(WASM_OPT + ['a.wast', '-o', 'a.wasm'])
    assert open('a.wasm', 'rb').read()[0] == '\0', 'we emit binary by default'
    run_command(WASM_OPT + ['a.wasm', '-o', 'b.wast', '-S'])
    assert open('b.wast', 'rb').read()[0] != '\0', 'we emit text with -S'

    print '\n[ checking wasm-opt passes... ]\n'

    for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'passes'))):
        if t.endswith(('.wast', '.wasm')):
            print '..', t
            binary = '.wasm' in t
            base = os.path.basename(t).replace('.wast',
                                               '').replace('.wasm', '')
            passname = base
            if passname.isdigit():
                passname = open(
                    os.path.join(options.binaryen_test, 'passes',
                                 passname + '.passes')).read().strip()
            opts = [('--' + p if not p.startswith('O') else '-' + p)
                    for p in passname.split('_')]
            t = os.path.join(options.binaryen_test, 'passes', t)
            actual = ''
            for module, asserts in split_wast(t):
                assert len(asserts) == 0
                with open('split.wast', 'w') as o:
                    o.write(module)
                cmd = WASM_OPT + opts + ['split.wast', '--print']
                curr = run_command(cmd)
                actual += curr
                # also check debug mode output is valid
                debugged = run_command(cmd + ['--debug'],
                                       stderr=subprocess.PIPE)
                fail_if_not_contained(actual, debugged)

                # also check pass-debug mode
                def check():
                    pass_debug = run_command(cmd)
                    fail_if_not_identical(curr, pass_debug)

                with_pass_debug(check)

            expected_file = os.path.join(
                options.binaryen_test, 'passes',
                base + ('.bin' if binary else '') + '.txt')
            fail_if_not_identical_to_file(actual, expected_file)

            if 'emit-js-wrapper' in t:
                with open('a.js') as actual:
                    fail_if_not_identical_to_file(actual.read(), t + '.js')
            if 'emit-spec-wrapper' in t:
                with open('a.wat') as actual:
                    fail_if_not_identical_to_file(actual.read(), t + '.wat')

    print '\n[ checking wasm-opt parsing & printing... ]\n'

    for t in sorted(os.listdir(os.path.join(options.binaryen_test, 'print'))):
        if t.endswith('.wast'):
            print '..', t
            wasm = os.path.basename(t).replace('.wast', '')
            cmd = WASM_OPT + [
                os.path.join(options.binaryen_test, 'print', t), '--print'
            ]
            print '    ', ' '.join(cmd)
            actual, err = subprocess.Popen(
                cmd, stdout=subprocess.PIPE,
                stderr=subprocess.PIPE).communicate()
            expected_file = os.path.join(options.binaryen_test, 'print',
                                         wasm + '.txt')
            fail_if_not_identical_to_file(actual, expected_file)
            cmd = WASM_OPT + [
                os.path.join(options.binaryen_test, 'print', t),
                '--print-minified'
            ]
            print '    ', ' '.join(cmd)
            actual, err = subprocess.Popen(
                cmd, stdout=subprocess.PIPE,
                stderr=subprocess.PIPE).communicate()
            fail_if_not_identical(
                actual.strip(),
                open(
                    os.path.join(options.binaryen_test, 'print',
                                 wasm + '.minified.txt')).read().strip())

    print '\n[ checking wasm-opt testcases... ]\n'

    for t in tests:
        if t.endswith('.wast') and not t.startswith('spec'):
            print '..', t
            t = os.path.join(options.binaryen_test, t)
            f = t + '.from-wast'
            cmd = WASM_OPT + [t, '--print']
            actual = run_command(cmd)
            actual = actual.replace('printing before:\n', '')

            fail_if_not_identical_to_file(actual, f)

            binary_format_check(t, wasm_as_args=['-g'])  # test with debuginfo
            binary_format_check(t,
                                wasm_as_args=[],
                                binary_suffix='.fromBinary.noDebugInfo'
                                )  # test without debuginfo

            minify_check(t)
Exemple #17
0
def run_wasm_opt_tests():
    print('\n[ checking wasm-opt -o notation... ]\n')

    for extra_args in [[], ['--no-validation']]:
        wast = os.path.join(shared.options.binaryen_test, 'hello_world.wat')
        shared.delete_from_orbit('a.wat')
        out = 'a.wat'
        cmd = shared.WASM_OPT + [wast, '-o', out, '-S'] + extra_args
        support.run_command(cmd)
        shared.fail_if_not_identical_to_file(open(out).read(), wast)

    print('\n[ checking wasm-opt binary reading/writing... ]\n')

    shutil.copyfile(
        os.path.join(shared.options.binaryen_test, 'hello_world.wat'), 'a.wat')
    shared.delete_from_orbit('a.wasm')
    shared.delete_from_orbit('b.wast')
    support.run_command(shared.WASM_OPT + ['a.wat', '-o', 'a.wasm'])
    assert open('a.wasm', 'rb').read()[0] == 0, 'we emit binary by default'
    support.run_command(shared.WASM_OPT + ['a.wasm', '-o', 'b.wast', '-S'])
    assert open('b.wast', 'rb').read()[0] != 0, 'we emit text with -S'

    print('\n[ checking wasm-opt passes... ]\n')

    for t in shared.get_tests(shared.get_test_dir('passes'),
                              ['.wast', '.wasm']):
        print('..', os.path.basename(t))
        binary = '.wasm' in t
        base = os.path.basename(t).replace('.wast', '').replace('.wasm', '')
        passname = base
        passes_file = os.path.join(shared.get_test_dir('passes'),
                                   passname + '.passes')
        if os.path.exists(passes_file):
            passname = open(passes_file).read().strip()
        opts = [('--' + p if not p.startswith('O') and p != 'g' else '-' + p)
                for p in passname.split('_')]
        actual = ''
        for module, asserts in support.split_wast(t):
            assert len(asserts) == 0
            support.write_wast('split.wast', module)
            cmd = shared.WASM_OPT + opts + ['split.wast', '--print']
            curr = support.run_command(cmd)
            actual += curr
            # also check debug mode output is valid
            debugged = support.run_command(cmd + ['--debug'],
                                           stderr=subprocess.PIPE)
            shared.fail_if_not_contained(actual, debugged)

            # also check pass-debug mode
            def check():
                pass_debug = support.run_command(cmd)
                shared.fail_if_not_identical(curr, pass_debug)

            shared.with_pass_debug(check)

        expected_file = os.path.join(
            shared.get_test_dir('passes'),
            base + ('.bin' if binary else '') + '.txt')
        shared.fail_if_not_identical_to_file(actual, expected_file)

        if 'emit-js-wrapper' in t:
            with open('a.js') as actual:
                shared.fail_if_not_identical_to_file(actual.read(), t + '.js')
        if 'emit-spec-wrapper' in t:
            with open('a.wat') as actual:
                shared.fail_if_not_identical_to_file(actual.read(), t + '.wat')

    print('\n[ checking wasm-opt parsing & printing... ]\n')

    for t in shared.get_tests(shared.get_test_dir('print'), ['.wast']):
        print('..', os.path.basename(t))
        wasm = os.path.basename(t).replace('.wast', '')
        cmd = shared.WASM_OPT + [t, '--print', '-all']
        print('    ', ' '.join(cmd))
        actual, err = subprocess.Popen(cmd,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       universal_newlines=True).communicate()
        expected_file = os.path.join(shared.get_test_dir('print'),
                                     wasm + '.txt')
        shared.fail_if_not_identical_to_file(actual, expected_file)
        cmd = shared.WASM_OPT + [
            os.path.join(shared.get_test_dir('print'), t), '--print-minified',
            '-all'
        ]
        print('    ', ' '.join(cmd))
        actual, err = subprocess.Popen(cmd,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE,
                                       universal_newlines=True).communicate()
        shared.fail_if_not_identical(
            actual.strip(),
            open(
                os.path.join(shared.get_test_dir('print'),
                             wasm + '.minified.txt')).read().strip())

    print('\n[ checking wasm-opt testcases... ]\n')

    for t in shared.get_tests(shared.options.binaryen_test, ['.wast']):
        print('..', os.path.basename(t))
        f = t + '.from-wast'
        cmd = shared.WASM_OPT + [t, '--print', '-all']
        actual = support.run_command(cmd)
        actual = actual.replace('printing before:\n', '')

        shared.fail_if_not_identical_to_file(actual, f)

        # FIXME Remove this condition after nullref is implemented in V8
        if 'reference-types.wast' not in t:
            shared.binary_format_check(t,
                                       wasm_as_args=['-g'
                                                     ])  # test with debuginfo
            shared.binary_format_check(t,
                                       wasm_as_args=[],
                                       binary_suffix='.fromBinary.noDebugInfo'
                                       )  # test without debuginfo

        shared.minify_check(t)

    print('\n[ checking wasm-opt debugInfo read-write... ]\n')

    for t in shared.get_tests(shared.options.binaryen_test, ['.fromasm']):
        if 'debugInfo' not in t:
            continue
        print('..', os.path.basename(t))
        f = t + '.read-written'
        support.run_command(shared.WASM_AS +
                            [t, '--source-map=a.map', '-o', 'a.wasm', '-g'])
        support.run_command(shared.WASM_OPT + [
            'a.wasm', '--input-source-map=a.map', '-o', 'b.wasm',
            '--output-source-map=b.map', '-g'
        ])
        actual = support.run_command(shared.WASM_DIS +
                                     ['b.wasm', '--source-map=b.map'])
        shared.fail_if_not_identical_to_file(actual, f)
Exemple #18
0
def test_asm2wasm():
    print('[ checking asm2wasm testcases... ]\n')

    for asm in shared.get_tests(shared.options.binaryen_test, ['.asm.js']):
        basename = os.path.basename(asm)
        for precise in [0, 1, 2]:
            for opts in [1, 0]:
                cmd = shared.ASM2WASM + [asm]
                if 'threads' in asm:
                    cmd += ['--enable-threads']
                wasm = asm.replace('.asm.js', '.fromasm')
                if not precise:
                    cmd += ['--trap-mode=allow', '--ignore-implicit-traps']
                    wasm += '.imprecise'
                elif precise == 2:
                    cmd += ['--trap-mode=clamp']
                    wasm += '.clamp'
                if not opts:
                    wasm += '.no-opts'
                    if precise:
                        cmd += ['-O0']  # test that -O0 does nothing
                else:
                    cmd += ['-O']
                if 'debugInfo' in basename:
                    cmd += ['-g']
                if 'noffi' in basename:
                    cmd += ['--no-legalize-javascript-ffi']
                if precise and opts:
                    # test mem init importing
                    open('a.mem', 'w').write(basename)
                    cmd += ['--mem-init=a.mem']
                    if basename[0] == 'e':
                        cmd += ['--mem-base=1024']
                if '4GB' in basename:
                    cmd += ['--mem-max=4294967296']
                if 'i64' in basename or 'wasm-only' in basename or 'noffi' in basename:
                    cmd += ['--wasm-only']
                print('..', basename, os.path.basename(wasm))

                def do_asm2wasm_test():
                    actual = support.run_command(cmd)

                    # verify output
                    if not os.path.exists(wasm):
                        shared.fail_with_error(
                            'output .wast file %s does not exist' % wasm)
                    shared.fail_if_not_identical_to_file(actual, wasm)

                    shared.binary_format_check(wasm, verify_final_result=False)

                # test both normally and with pass debug (so each inter-pass state
                # is validated)
                old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
                try:
                    os.environ['BINARYEN_PASS_DEBUG'] = '1'
                    print("With BINARYEN_PASS_DEBUG=1:")
                    do_asm2wasm_test()
                    del os.environ['BINARYEN_PASS_DEBUG']
                    print("With BINARYEN_PASS_DEBUG disabled:")
                    do_asm2wasm_test()
                finally:
                    if old_pass_debug is not None:
                        os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
                    else:
                        if 'BINARYEN_PASS_DEBUG' in os.environ:
                            del os.environ['BINARYEN_PASS_DEBUG']

                # verify in wasm
                if shared.options.interpreter:
                    # remove imports, spec interpreter doesn't know what to do with them
                    subprocess.check_call(shared.WASM_OPT +
                                          ['--remove-imports', wasm],
                                          stdout=open('ztemp.wast', 'w'),
                                          stderr=subprocess.PIPE)
                    proc = subprocess.Popen(
                        [shared.options.interpreter, 'ztemp.wast'],
                        stderr=subprocess.PIPE)
                    out, err = proc.communicate()
                    if proc.returncode != 0:
                        try:  # to parse the error
                            reported = err.split(':')[1]
                            start, end = reported.split('-')
                            start_line, start_col = map(int, start.split('.'))
                            lines = open('ztemp.wast').read().split('\n')
                            print()
                            print('=' * 80)
                            print(lines[start_line - 1])
                            print((' ' * (start_col - 1)) + '^')
                            print((' ' * (start_col - 2)) + '/_\\')
                            print('=' * 80)
                            print(err)
                        except Exception:
                            # failed to pretty-print
                            shared.fail_with_error('wasm interpreter error: ' +
                                                   err)
                        shared.fail_with_error('wasm interpreter error')

                # verify debug info
                if 'debugInfo' in asm:
                    jsmap = 'a.wasm.map'
                    cmd += [
                        '--source-map', jsmap, '--source-map-url',
                        'http://example.org/' + jsmap, '-o', 'a.wasm'
                    ]
                    support.run_command(cmd)
                    if not os.path.isfile(jsmap):
                        shared.fail_with_error(
                            'Debug info map not created: %s' % jsmap)
                    with open(jsmap, 'rb') as actual:
                        shared.fail_if_not_identical_to_file(
                            actual.read(), wasm + '.map')
                    with open('a.wasm', 'rb') as binary:
                        url_section_name = bytes([16]) + bytes(
                            'sourceMappingURL', 'utf-8')
                        url = 'http://example.org/' + jsmap
                        assert len(url) < 256, 'name too long'
                        url_section_contents = bytes([len(url)]) + bytes(
                            url, 'utf-8')
                        print(url_section_name)
                        binary_contents = binary.read()
                        if url_section_name not in binary_contents:
                            shared.fail_with_error(
                                'source map url section not found in binary')
                        url_section_index = binary_contents.index(
                            url_section_name)
                        if url_section_contents not in binary_contents[
                                url_section_index:]:
                            shared.fail_with_error(
                                'source map url not found in url section')
Exemple #19
0
def test_wasm2js_output():
    for opt in (0, 1):
        for t in tests + spec_tests + wasm2js_tests:
            basename = os.path.basename(t)
            if basename in wasm2js_blacklist:
                continue

            asm = basename.replace('.wast', '.2asm.js')
            expected_file = os.path.join(shared.get_test_dir('wasm2js'), asm)
            if opt:
                expected_file += '.opt'

            if not os.path.exists(expected_file):
                continue

            print('..', os.path.basename(t))

            all_out = []

            for module, asserts in support.split_wast(t):
                support.write_wast('split.wast', module, asserts)

                cmd = shared.WASM2JS + ['split.wast', '-all']
                if opt:
                    cmd += ['-O']
                if 'emscripten' in t:
                    cmd += ['--emscripten']
                out = support.run_command(cmd)
                all_out.append(out)

                if not shared.NODEJS and not shared.MOZJS:
                    print('No JS interpreters. Skipping spec tests.')
                    continue

                open('a.2asm.mjs', 'w').write(out)

                cmd += ['--allow-asserts']
                out = support.run_command(cmd)
                # also verify it passes pass-debug verifications
                shared.with_pass_debug(lambda: support.run_command(cmd))

                open('a.2asm.asserts.mjs', 'w').write(out)

                # verify asm.js is valid js, note that we're using --experimental-modules
                # to enable ESM syntax and we're also passing a custom loader to handle the
                # `spectest` and `env` modules in our tests.
                if shared.NODEJS:
                    loader = os.path.join(shared.options.binaryen_root,
                                          'scripts', 'test',
                                          'node-esm-loader.mjs')
                    node = [
                        shared.NODEJS, '--experimental-modules', '--loader',
                        loader
                    ]
                    cmd = node[:]
                    cmd.append('a.2asm.mjs')
                    out = support.run_command(cmd)
                    shared.fail_if_not_identical(out, '')
                    cmd = node[:]
                    cmd.append('a.2asm.asserts.mjs')
                    out = support.run_command(cmd,
                                              expected_err='',
                                              err_ignore='ExperimentalWarning')
                    shared.fail_if_not_identical(out, '')

            shared.fail_if_not_identical_to_file(''.join(all_out),
                                                 expected_file)