Skip to content

Commit 24d2749

Browse files
authored
Update spec test suite (#2484)
This updates spec test suite to that of the current up-to-date version of https://github.com/WebAssembly/spec repo. - All failing tests are added in `BLACKLIST` in shared.py with reasons. - For tests that already existed and was passing and started failing after the update, we add the new test to the blacklist and preserve the old file by renaming it to 'old_[FILENAME].wast' not to lose test coverage. When the cause of the error is fixed or the unsupported construct gets support so the new test passes, we can delete the corresponding 'old_[FILENAME].wast' file. - Adds support for `spectest.print_[type] style imports.
1 parent 8c97dc6 commit 24d2749

File tree

110 files changed

+43753
-6167
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+43753
-6167
lines changed

check.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,9 @@ def check_expected(actual, expected):
314314
check_expected(actual, expected)
315315

316316
# skip binary checks for tests that reuse previous modules by name, as that's a wast-only feature
317-
if os.path.basename(wast) in ['exports.wast']: # FIXME
317+
if 'exports.wast' in os.path.basename(wast): # FIXME
318318
continue
319319

320-
# we must ignore some binary format splits
321-
splits_to_skip = {
322-
'func.wast': [2],
323-
'return.wast': [2]
324-
}
325-
326320
# check binary format. here we can verify execution of the final
327321
# result, no need for an output verification
328322
# some wast files cannot be split:
@@ -332,11 +326,6 @@ def check_expected(actual, expected):
332326
split_num = 0
333327
actual = ''
334328
for module, asserts in support.split_wast(wast):
335-
skip = splits_to_skip.get(os.path.basename(wast)) or []
336-
if split_num in skip:
337-
print(' skipping split module', split_num - 1)
338-
split_num += 1
339-
continue
340329
print(' testing split module', split_num)
341330
split_num += 1
342331
support.write_wast('split.wast', module, asserts)

scripts/test/shared.py

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,67 @@ def get_tests(test_dir, extensions=[]):
402402
else:
403403
options.spec_tests = options.spec_tests[:]
404404

405+
# 11/27/2019: We updated the spec test suite to upstream spec repo. For some
406+
# files that started failing after this update, we added the new files to this
407+
# blacklist and preserved old ones by renaming them to 'old_[FILENAME].wast'
408+
# not to lose coverage. When the cause of the error is fixed or the unsupported
409+
# construct gets support so the new test passes, we can delete the
410+
# corresponding 'old_[FILENAME].wast' file. When you fix the new file and
411+
# delete the old file, make sure you rename the corresponding .wast.log file in
412+
# expected-output/ if any.
405413
SPEC_TEST_BLACKLIST = [
406-
'binary.wast', # Cannot parse binary modules
407-
'linking.wast', # No support for 'register' command
408-
'nop.wast', # Stacky code
409-
'stack.wast', # Stacky code
410-
'unwind.wast' # Stacky code
414+
# Stacky code / notation
415+
'block.wast',
416+
'call.wast',
417+
'float_exprs.wast',
418+
'globals.wast',
419+
'loop.wast',
420+
'nop.wast',
421+
'select.wast',
422+
'stack.wast',
423+
'unwind.wast',
424+
425+
# Binary module
426+
'binary.wast',
427+
'binary-leb128.wast',
428+
'custom.wast',
429+
430+
# Empty 'then' or 'else' in 'if'
431+
'if.wast',
432+
'local_set.wast',
433+
'store.wast',
434+
435+
# No module in a file
436+
'token.wast',
437+
'utf8-custom-section-id.wast',
438+
'utf8-import-field.wast',
439+
'utf8-import-module.wast',
440+
'utf8-invalid-encoding.wast',
441+
442+
# 'register' command
443+
'imports.wast',
444+
'linking.wast',
445+
446+
# Misc. unsupported constructs
447+
'call_indirect.wast', # Empty (param) and (result)
448+
'const.wast', # Unparenthesized expression
449+
'data.wast', # Various unsupported (data) notations
450+
'elem.wast', # Unsupported 'offset' syntax in (elem)
451+
'exports.wast', # Multiple inlined exports for a function
452+
'func.wast', # Forward named type reference
453+
'skip-stack-guard-page.wast', # Hexadecimal style (0x..) in memory offset
454+
455+
# Untriaged: We don't know the cause of the error yet
456+
'address.wast', # wasm2js 'assert_return' failure
457+
'br_if.wast', # Validation error
458+
'float_literals.wast', # 'assert_return' failure
459+
'int_literals.wast', # 'assert_return' failure
460+
'local_tee.wast', # Validation failure
461+
'memory_grow.wast', # 'assert_return' failure
462+
'start.wast', # Assertion failure
463+
'type.wast', # 'assertion_invalid' failure
464+
'unreachable.wast', # Validation failure
465+
'unreached-invalid.wast' # 'assert_invalid' failure
411466
]
412467
options.spec_tests = [t for t in options.spec_tests if os.path.basename(t) not
413468
in SPEC_TEST_BLACKLIST]

scripts/test/spectest.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1-
export function print(...args) {
2-
console.log(...args);
1+
export function print() {
2+
console.log();
3+
}
4+
export function print_i32(arg) {
5+
console.log(arg, ' : i32');
6+
}
7+
export function print_f32(arg) {
8+
console.log(arg, ' : f32');
9+
}
10+
export function print_f64(arg) {
11+
console.log(arg, ' : f64');
12+
}
13+
export function print_i32_f32(arg0, arg1) {
14+
console.log(arg0, ' : i32');
15+
console.log(arg1, ' : f32');
16+
}
17+
export function print_f64_f64(arg0, arg1) {
18+
console.log(arg0, ' : f64');
19+
console.log(arg1, ' : f64');
320
}

scripts/test/wasm2js.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from scripts.test import support
2121

2222
tests = shared.get_tests(shared.options.binaryen_test)
23-
spec_tests = shared.get_tests(shared.get_test_dir('spec'), ['.wast'])
23+
spec_tests = shared.options.spec_tests
2424
spec_tests = [t for t in spec_tests if '.fail' not in t]
2525
wasm2js_tests = shared.get_tests(shared.get_test_dir('wasm2js'), ['.wast'])
2626
assert_tests = ['wasm2js.wast.asserts']

src/emscripten-optimizer/istring.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ struct IString {
151151
bool startsWith(const char* prefix) const {
152152
return stripPrefix(prefix) != nullptr;
153153
}
154+
bool startsWith(const IString& prefix) const {
155+
return startsWith(prefix.str);
156+
}
154157

155158
size_t size() const { return str ? strlen(str) : 0; }
156159
};

src/shell-interface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
9898
void importGlobals(std::map<Name, Literal>& globals, Module& wasm) override {
9999
// add spectest globals
100100
ModuleUtils::iterImportedGlobals(wasm, [&](Global* import) {
101-
if (import->module == SPECTEST && import->base == GLOBAL) {
101+
if (import->module == SPECTEST && import->base.startsWith(GLOBAL)) {
102102
switch (import->type) {
103103
case i32:
104104
globals[import->name] = Literal(int32_t(666));
@@ -133,7 +133,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface {
133133
}
134134

135135
Literal callImport(Function* import, LiteralList& arguments) override {
136-
if (import->module == SPECTEST && import->base == PRINT) {
136+
if (import->module == SPECTEST && import->base.startsWith(PRINT)) {
137137
for (auto argument : arguments) {
138138
std::cout << argument << " : " << argument.type << '\n';
139139
}

src/tools/wasm-shell.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void run_asserts(Name moduleName,
164164
};
165165
ModuleUtils::iterImportedGlobals(wasm, reportUnknownImport);
166166
ModuleUtils::iterImportedFunctions(wasm, [&](Importable* import) {
167-
if (import->module == SPECTEST && import->base == PRINT) {
167+
if (import->module == SPECTEST && import->base.startsWith(PRINT)) {
168168
// We can handle it.
169169
} else {
170170
reportUnknownImport(import);
@@ -181,7 +181,7 @@ static void run_asserts(Name moduleName,
181181
// spec tests consider it illegal to use spectest.print in a table
182182
if (auto* import = wasm.getFunction(name)) {
183183
if (import->imported() && import->module == SPECTEST &&
184-
import->base == PRINT) {
184+
import->base.startsWith(PRINT)) {
185185
std::cerr << "cannot put spectest.print in table\n";
186186
invalid = true;
187187
}

test/spec/README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
1-
This repository holds a mirror of the spec testsuite which is maintained
2-
[here](https://github.com/WebAssembly/spec/tree/master/ml-proto/test).
1+
This directory contains tests for the core WebAssembly semantics, as described in [Semantics.md](https://github.com/WebAssembly/design/blob/master/Semantics.md) and specified by the [spec interpreter](https://github.com/WebAssembly/spec/blob/master/interpreter).
2+
3+
Tests are written in the [S-Expression script format](https://github.com/WebAssembly/spec/blob/master/interpreter/README.md#s-expression-syntax) defined by the interpreter.
4+
5+
The test suite can be run with the spec interpreter as follows:
6+
```
7+
./run.py --wasm <path-to-wasm-interpreter>
8+
```
9+
where the path points to the spec interpreter executable (or a tool that understands similar options). If the binary is in the working directory, this option can be omitted.
10+
11+
In addition, the option `--js <path-to-js-interpreter>` can be given to point to a stand-alone JavaScript interpreter supporting the WebAssembly API. If provided, all tests are also executed in JavaScript.

0 commit comments

Comments
 (0)