diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | scripts/travis-test.sh | 21 | ||||
-rw-r--r-- | src/wasm-binary-reader-opcnt.c | 9 | ||||
-rw-r--r-- | src/wasm-binary-reader-opcnt.h | 5 | ||||
-rw-r--r-- | src/wasmopcodecnt.c | 31 | ||||
-rw-r--r-- | test/find_exe.py | 11 | ||||
-rw-r--r-- | test/opcodecnt/basic.txt | 43 | ||||
-rwxr-xr-x | test/run-gen-wasm.py | 2 | ||||
-rwxr-xr-x | test/run-interp.py | 2 | ||||
-rw-r--r-- | test/run-opcodecnt.py | 83 | ||||
-rwxr-xr-x | test/run-roundtrip.py | 4 | ||||
-rwxr-xr-x | test/run-tests.py | 25 |
13 files changed, 192 insertions, 48 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a75eaa2b..79b776e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -326,4 +326,4 @@ add_custom_target(run-tests ) # install -install(TARGETS wast2wasm wasm2wast wasm-interp DESTINATION bin) +install(TARGETS wast2wasm wasm2wast wasm-interp wasmopcodecnt DESTINATION bin) @@ -32,7 +32,7 @@ COMPILERS := GCC GCC_I686 GCC_FUZZ CLANG EMSCRIPTEN BUILD_TYPES := DEBUG RELEASE SANITIZERS := ASAN MSAN LSAN UBSAN CONFIGS := NORMAL $(SANITIZERS) NO_RE2C_BISON NO_TESTS -EXECUTABLES := wast2wasm wasm2wast wasm-interp hexfloat_test +EXECUTABLES := wast2wasm wasm2wast wasm-interp wasmopcodecnt hexfloat_test # directory names GCC_DIR := gcc/ diff --git a/scripts/travis-test.sh b/scripts/travis-test.sh index 5ab519a6..cb4d5834 100755 --- a/scripts/travis-test.sh +++ b/scripts/travis-test.sh @@ -30,32 +30,13 @@ run_tests() { (cd ${ROOT_DIR} && log_and_run test/run-tests.py ${RUN_TEST_ARGS} $* --timeout=10) } -check_and_add_flag() { - local FLAG=$1 - local NAME=$2 - if [ ! -e ${NAME} ]; then - echo "${NAME} doesn't exist; skipping test." - return 1 - fi - RUN_TEST_ARGS="${RUN_TEST_ARGS} ${FLAG} ${NAME}" - return 0 -} - set_run_test_args() { local COMPILER=$1 local BUILD_TYPE=$2 local CONFIG=${3:-} - RUN_TEST_ARGS="" local EXE_DIR=out/${COMPILER}/${BUILD_TYPE}/${CONFIG} - - WAST2WASM=${EXE_DIR}/wast2wasm - WASM2WAST=${EXE_DIR}/wasm2wast - WASM_INTERP=${EXE_DIR}/wasm-interp - - check_and_add_flag "--wast2wasm-executable" ${WAST2WASM} && \ - check_and_add_flag "--wasm2wast-executable" ${WASM2WAST} && \ - check_and_add_flag "--wasm-interp-executable" ${WASM_INTERP} + RUN_TEST_ARGS="--exe-dir ${EXE_DIR}" } if [ ${CC} = "gcc" ]; then diff --git a/src/wasm-binary-reader-opcnt.c b/src/wasm-binary-reader-opcnt.c index 74e34c93..1a6a4ff7 100644 --- a/src/wasm-binary-reader-opcnt.c +++ b/src/wasm-binary-reader-opcnt.c @@ -149,11 +149,10 @@ static WasmBinaryReader s_binary_reader = { .on_store_expr = on_store_expr }; -WasmOpcntData* wasm_new_opcnt_data(struct WasmAllocator* allocator) { - WasmOpcntData* result = wasm_alloc_zero(allocator, sizeof(WasmOpcntData), - WASM_DEFAULT_ALIGN); - result->allocator = allocator; - return result; +void wasm_init_opcnt_data(struct WasmAllocator* allocator, + WasmOpcntData* data) { + WASM_ZERO_MEMORY(*data); + data->allocator = allocator; } void wasm_destroy_opcnt_data(struct WasmAllocator* allocator, diff --git a/src/wasm-binary-reader-opcnt.h b/src/wasm-binary-reader-opcnt.h index e2ab1493..426772b3 100644 --- a/src/wasm-binary-reader-opcnt.h +++ b/src/wasm-binary-reader-opcnt.h @@ -52,10 +52,9 @@ typedef struct WasmOpcntData { WasmIntPairCounterVector i32_store_vec; } WasmOpcntData; -WasmOpcntData* wasm_new_opcnt_data(struct WasmAllocator* allocator); - +void wasm_init_opcnt_data(struct WasmAllocator* allocator, WasmOpcntData* data); void wasm_destroy_opcnt_data(struct WasmAllocator* allocator, - WasmOpcntData* Data); + WasmOpcntData* data); WasmResult wasm_read_binary_opcnt(struct WasmAllocator* allocator, const void* data, diff --git a/src/wasmopcodecnt.c b/src/wasmopcodecnt.c index 7d4aeb80..0aeaaf7e 100644 --- a/src/wasmopcodecnt.c +++ b/src/wasmopcodecnt.c @@ -193,6 +193,8 @@ static void display_int_counter_vector( const char* opcode_name) { size_t i; for (i = 0; i < vec->size; ++i) { + if (vec->data[i].count == 0) + continue; if (opcode_name) fprintf(out, "(%s ", opcode_name); display_fcn(out, vec->data[i].value); @@ -208,6 +210,8 @@ static void display_int_pair_counter_vector( const char* opcode_name) { size_t i; for (i = 0; i < vec->size; ++i) { + if (vec->data[i].count == 0) + continue; if (opcode_name) fprintf(out, "(%s ", opcode_name); display_first_fcn(out, vec->data[i].first); @@ -305,6 +309,9 @@ static void display_sorted_int_counter_vector( FILE* out, const char* title, struct WasmAllocator* allocator, WasmIntCounterVector* vec, int_counter_lt_fcn lt_fcn, display_name_fcn display_fcn, const char* opcode_name) { + if (vec->size == 0) + return; + /* First filter out values less than cutoff. This speeds up sorting. */ WasmIntCounterVector filtered_vec; WASM_ZERO_MEMORY(filtered_vec); @@ -329,6 +336,9 @@ static void display_sorted_int_pair_counter_vector( WasmIntPairCounterVector* vec, int_pair_counter_lt_fcn lt_fcn, display_name_fcn display_first_fcn, display_name_fcn display_second_fcn, const char* opcode_name) { + if (vec->size == 0) + return; + WasmIntPairCounterVector filtered_vec; WASM_ZERO_MEMORY(filtered_vec); WasmIntPairCounterVector sorted_vec; @@ -381,40 +391,41 @@ int main(int argc, char** argv) { result = WASM_ERROR; } if (WASM_SUCCEEDED(result)) { - WasmOpcntData* opcnt_data = wasm_new_opcnt_data(allocator); + WasmOpcntData opcnt_data; + wasm_init_opcnt_data(allocator, &opcnt_data); result = wasm_read_binary_opcnt( allocator, data, size, &s_read_binary_options, &s_error_handler, - opcnt_data); + &opcnt_data); if (WASM_SUCCEEDED(result)) { display_sorted_int_counter_vector( - out, "Opcode counts:", allocator, &opcnt_data->opcode_vec, + out, "Opcode counts:", allocator, &opcnt_data.opcode_vec, opcode_counter_gt, display_opcode_name, NULL); display_sorted_int_counter_vector( - out, "\ni32.const", allocator, &opcnt_data->i32_const_vec, + out, "\ni32.const:", allocator, &opcnt_data.i32_const_vec, int_counter_gt, display_intmax, wasm_get_opcode_name(WASM_OPCODE_I32_CONST)); display_sorted_int_counter_vector( - out, "\nget_local:\n", allocator, &opcnt_data->get_local_vec, + out, "\nget_local:", allocator, &opcnt_data.get_local_vec, int_counter_gt, display_intmax, wasm_get_opcode_name(WASM_OPCODE_GET_LOCAL)); display_sorted_int_counter_vector( - out, "\nset_local:\n", allocator, &opcnt_data->set_local_vec, + out, "\nset_local:", allocator, &opcnt_data.set_local_vec, int_counter_gt, display_intmax, wasm_get_opcode_name(WASM_OPCODE_SET_LOCAL)); display_sorted_int_counter_vector( - out, "\ntee_local:\n", allocator, &opcnt_data->tee_local_vec, + out, "\ntee_local:", allocator, &opcnt_data.tee_local_vec, int_counter_gt, display_intmax, wasm_get_opcode_name(WASM_OPCODE_TEE_LOCAL)); display_sorted_int_pair_counter_vector( - out, "\ni32.load:\n", allocator, &opcnt_data->i32_load_vec, + out, "\ni32.load:", allocator, &opcnt_data.i32_load_vec, int_pair_counter_gt, display_intmax, display_intmax, wasm_get_opcode_name(WASM_OPCODE_I32_LOAD)); display_sorted_int_pair_counter_vector( - out, "\ni32.store:\n", allocator, &opcnt_data->i32_store_vec, + out, "\ni32.store:", allocator, &opcnt_data.i32_store_vec, int_pair_counter_gt, display_intmax, display_intmax, wasm_get_opcode_name(WASM_OPCODE_I32_STORE)); } - wasm_destroy_opcnt_data(allocator, opcnt_data); + wasm_destroy_opcnt_data(allocator, &opcnt_data); } wasm_free(allocator, data); wasm_print_allocator_stats(allocator); diff --git a/test/find_exe.py b/test/find_exe.py index 7b169f71..0c3d3e9b 100644 --- a/test/find_exe.py +++ b/test/find_exe.py @@ -26,12 +26,14 @@ REPO_ROOT_DIR = os.path.dirname(SCRIPT_DIR) DEFAULT_WAST2WASM_EXE = os.path.join(REPO_ROOT_DIR, 'out', 'wast2wasm') DEFAULT_WASM2WAST_EXE = os.path.join(REPO_ROOT_DIR, 'out', 'wasm2wast') DEFAULT_WASM_INTERP_EXE = os.path.join(REPO_ROOT_DIR, 'out', 'wasm-interp') +DEFAULT_WASMOPCODECNT_EXE = os.path.join(REPO_ROOT_DIR, 'out', 'wasmopcodecnt') if IS_WINDOWS: DEFAULT_WAST2WASM_EXE += '.exe' DEFAULT_WASM2WAST_EXE += '.exe' DEFAULT_WASM_INTERP_EXE += '.exe' + DEFAULT_WASMOPCODECNT_EXE += '.exe' def FindExeWithFallback(name, default_exe_list, override_exe=None): @@ -52,13 +54,18 @@ def FindExeWithFallback(name, default_exe_list, override_exe=None): '\n'.join('search path: %s' % path for path in default_exe_list))) -def GetSexprWasmExecutable(override=None): +def GetWast2WasmExecutable(override=None): return FindExeWithFallback('wast2wasm', [DEFAULT_WAST2WASM_EXE], override) -def GetWasmWastExecutable(override=None): +def GetWasm2WastExecutable(override=None): return FindExeWithFallback('wasm2wast', [DEFAULT_WASM2WAST_EXE], override) def GetWasmInterpExecutable(override=None): return FindExeWithFallback('wasm-interp', [DEFAULT_WASM_INTERP_EXE], override) + + +def GetWasmOpcodeCntExecutable(override=None): + return FindExeWithFallback('wasmopcodecnt', [DEFAULT_WASMOPCODECNT_EXE], + override) diff --git a/test/opcodecnt/basic.txt b/test/opcodecnt/basic.txt new file mode 100644 index 00000000..1a9cfbfa --- /dev/null +++ b/test/opcodecnt/basic.txt @@ -0,0 +1,43 @@ +;;; TOOL: run-opcodecnt +(module + (memory (data "hello, world")) + (func + (local i32 i32) + i32.const 1 + i32.const 2 + get_local 0 + get_local 0 + get_local 0 + get_local 1 + get_local 1 + br 0) + + (func + i32.const 0 + i32.load + f32.const 1 + f32.const 2 + f32.add + br 0)) +(;; STDOUT ;;; +Opcode counts: +get_local: 5 +i32.const: 3 +f32.const: 2 +end: 2 +br: 2 +i32.load: 1 +f32.add: 1 + +i32.const: +(i32.const 2): 1 +(i32.const 1): 1 +(i32.const 0): 1 + +get_local: +(get_local 0): 3 +(get_local 1): 2 + +i32.load: +(i32.load 2 0): 1 +;;; STDOUT ;;) diff --git a/test/run-gen-wasm.py b/test/run-gen-wasm.py index 708785d0..c6480c66 100755 --- a/test/run-gen-wasm.py +++ b/test/run-gen-wasm.py @@ -54,7 +54,7 @@ def main(args): sys.executable, GEN_WASM_PY, error_cmdline=options.error_cmdline) wasm2wast = utils.Executable( - find_exe.GetWasmWastExecutable(options.wasm2wast_executable), + find_exe.GetWasm2WastExecutable(options.wasm2wast_executable), error_cmdline=options.error_cmdline) wasm2wast.AppendOptionalArgs({ '--debug-names': options.debug_names, diff --git a/test/run-interp.py b/test/run-interp.py index 274aa0c0..1b6297bb 100755 --- a/test/run-interp.py +++ b/test/run-interp.py @@ -50,7 +50,7 @@ def main(args): options = parser.parse_args(args) wast2wasm = utils.Executable( - find_exe.GetSexprWasmExecutable(options.wast2wasm_executable), + find_exe.GetWast2WasmExecutable(options.wast2wasm_executable), error_cmdline=options.error_cmdline) wast2wasm.AppendOptionalArgs({ '-v': options.verbose, diff --git a/test/run-opcodecnt.py b/test/run-opcodecnt.py new file mode 100644 index 00000000..05268453 --- /dev/null +++ b/test/run-opcodecnt.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# +# Copyright 2016 WebAssembly Community Group participants +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import argparse +import os +import subprocess +import sys + +import find_exe +import utils +from utils import Error + +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) + + +def main(args): + parser = argparse.ArgumentParser() + parser.add_argument('-o', '--out-dir', metavar='PATH', + help='output directory for files.') + parser.add_argument('--wast2wasm-executable', metavar='PATH', + help='override wast2wasm executable.') + parser.add_argument('--wasmopcodecnt-executable', metavar='PATH', + help='override wasmopcodecnt executable.') + parser.add_argument('-v', '--verbose', help='print more diagnotic messages.', + action='store_true') + parser.add_argument('--no-error-cmdline', + help='don\'t display the subprocess\'s commandline when' + + ' an error occurs', dest='error_cmdline', + action='store_false') + parser.add_argument('--print-cmd', help='print the commands that are run.', + action='store_true') + parser.add_argument('--use-libc-allocator', action='store_true') + parser.add_argument('file', help='test file.') + options = parser.parse_args(args) + + wast2wasm = utils.Executable( + find_exe.GetWast2WasmExecutable(options.wast2wasm_executable), + error_cmdline=options.error_cmdline) + wast2wasm.AppendOptionalArgs({ + '-v': options.verbose, + '--use-libc-allocator': options.use_libc_allocator + }) + + wasmopcodecnt = utils.Executable(find_exe.GetWasmOpcodeCntExecutable( + options.wasmopcodecnt_executable), + error_cmdline=options.error_cmdline) + wasmopcodecnt.AppendOptionalArgs({ + '--use-libc-allocator': options.use_libc_allocator + }) + + wast2wasm.verbose = options.print_cmd + wasmopcodecnt.verbose = options.print_cmd + + with utils.TempDirectory(options.out_dir, 'run-opcodecnt-') as out_dir: + out_file = utils.ChangeDir(utils.ChangeExt(options.file, '.wasm'), out_dir) + wast2wasm.RunWithArgs(options.file, '-o', out_file) + wasmopcodecnt.RunWithArgs(out_file) + + return 0 + + +if __name__ == '__main__': + try: + sys.exit(main(sys.argv[1:])) + except Error as e: + sys.stderr.write(str(e) + '\n') + sys.exit(1) + + diff --git a/test/run-roundtrip.py b/test/run-roundtrip.py index 08d5cbd4..21dfdb15 100755 --- a/test/run-roundtrip.py +++ b/test/run-roundtrip.py @@ -120,7 +120,7 @@ def main(args): options = parser.parse_args(args) wast2wasm = utils.Executable( - find_exe.GetSexprWasmExecutable(options.wast2wasm_executable), + find_exe.GetWast2WasmExecutable(options.wast2wasm_executable), error_cmdline=options.error_cmdline) wast2wasm.AppendOptionalArgs({ '--debug-names': options.debug_names, @@ -128,7 +128,7 @@ def main(args): }) wasm2wast = utils.Executable( - find_exe.GetWasmWastExecutable(options.wasm2wast_executable), + find_exe.GetWasm2WastExecutable(options.wasm2wast_executable), error_cmdline=options.error_cmdline) wasm2wast.AppendOptionalArgs({ '--debug-names': options.debug_names, diff --git a/test/run-tests.py b/test/run-tests.py index dd6d2f19..08faaf12 100755 --- a/test/run-tests.py +++ b/test/run-tests.py @@ -130,6 +130,20 @@ TOOLS = { ]), '-v' ] + }, + 'run-opcodecnt': { + 'EXE': 'test/run-opcodecnt.py', + 'FLAGS': ' '.join([ + '--wast2wasm-executable=%(wast2wasm)s', + '--wasmopcodecnt-executable=%(wasmopcodecnt)s', + '--no-error-cmdline', + ]), + 'VERBOSE-FLAGS': [ + ' '.join([ + '--print-cmd', + ]), + '-v' + ] } } @@ -670,6 +684,8 @@ def main(args): help='override wasm2wast executable.') parser.add_argument('--wasm-interp-executable', metavar='PATH', help='override wasm-interp executable.') + parser.add_argument('--wasmopcodecnt-executable', metavar='PATH', + help='override wasmopcodecnt executable.') parser.add_argument('-v', '--verbose', help='print more diagnotic messages.', action='store_true') parser.add_argument('-f', '--fail-fast', @@ -726,12 +742,17 @@ def main(args): if not options.wasm_interp_executable: options.wasm_interp_executable = os.path.join(options.exe_dir, 'wasm-interp') + if not options.wasmopcodecnt_executable: + options.wasmopcodecnt_executable = os.path.join(options.exe_dir, + 'wasmopcodecnt') variables = { - 'wast2wasm': find_exe.GetSexprWasmExecutable(options.wast2wasm_executable), - 'wasm2wast': find_exe.GetWasmWastExecutable(options.wasm2wast_executable), + 'wast2wasm': find_exe.GetWast2WasmExecutable(options.wast2wasm_executable), + 'wasm2wast': find_exe.GetWasm2WastExecutable(options.wasm2wast_executable), 'wasm-interp': find_exe.GetWasmInterpExecutable(options.wasm_interp_executable), + 'wasmopcodecnt': + find_exe.GetWasmOpcodeCntExecutable(options.wasmopcodecnt_executable), } status = Status(options.verbose) |