summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--Makefile2
-rwxr-xr-xscripts/travis-test.sh21
-rw-r--r--src/wasm-binary-reader-opcnt.c9
-rw-r--r--src/wasm-binary-reader-opcnt.h5
-rw-r--r--src/wasmopcodecnt.c31
-rw-r--r--test/find_exe.py11
-rw-r--r--test/opcodecnt/basic.txt43
-rwxr-xr-xtest/run-gen-wasm.py2
-rwxr-xr-xtest/run-interp.py2
-rw-r--r--test/run-opcodecnt.py83
-rwxr-xr-xtest/run-roundtrip.py4
-rwxr-xr-xtest/run-tests.py25
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)
diff --git a/Makefile b/Makefile
index 9b82278a..6f9f79d2 100644
--- a/Makefile
+++ b/Makefile
@@ -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)