Skip to content

Commit 119525e

Browse files
authored
Validate unique local names, and use validation in wasm2js. Fixes #1885 (#1886)
* Also fixes some bugs in wasm2js tests that did not validate. * Rename FeatureOptions => ToolOptions, as they now contain all the basic stuff each tool needs for commandline options (validation yes or no, and which features if so).
1 parent e63c4a7 commit 119525e

9 files changed

+32
-18
lines changed

src/tools/optimization-options.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,20 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "feature-options.h"
17+
#include "tool-options.h"
1818

1919
//
2020
// Shared optimization options for commandline tools
2121
//
2222

2323
namespace wasm {
2424

25-
struct OptimizationOptions : public FeatureOptions {
25+
struct OptimizationOptions : public ToolOptions {
2626
static constexpr const char* DEFAULT_OPT_PASSES = "O";
2727

2828
std::vector<std::string> passes;
2929

30-
OptimizationOptions(const std::string& command, const std::string& description) : FeatureOptions(command, description) {
30+
OptimizationOptions(const std::string& command, const std::string& description) : ToolOptions(command, description) {
3131
(*this).add("", "-O", "execute default optimization passes",
3232
Options::Arguments::Zero,
3333
[this](Options*, const std::string&) {
@@ -92,11 +92,6 @@ struct OptimizationOptions : public FeatureOptions {
9292
[this](Options* o, const std::string& argument) {
9393
passOptions.shrinkLevel = atoi(argument.c_str());
9494
})
95-
.add("--no-validation", "-n", "Disables validation, assumes inputs are correct",
96-
Options::Arguments::Zero,
97-
[this](Options* o, const std::string& argument) {
98-
passOptions.validate = false;
99-
})
10095
.add("--ignore-implicit-traps", "-iit", "Optimize under the helpful assumption that no surprising traps occur (from load, div/mod, etc.)",
10196
Options::Arguments::Zero,
10297
[this](Options*, const std::string&) {

src/tools/feature-options.h renamed to src/tools/tool-options.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323

2424
namespace wasm {
2525

26-
struct FeatureOptions : public Options {
26+
struct ToolOptions : public Options {
2727
PassOptions passOptions;
2828

29-
FeatureOptions(const std::string& command, const std::string& description)
29+
ToolOptions(const std::string& command, const std::string& description)
3030
: Options(command, description) {
3131
(*this)
3232
.add("--mvp-features", "-mvp", "Disable all non-MVP features",
@@ -83,6 +83,11 @@ struct FeatureOptions : public Options {
8383
[this](Options *o, const std::string& arguments) {
8484
passOptions.features.setSIMD(false);
8585
})
86+
.add("--no-validation", "-n", "Disables validation, assumes inputs are correct",
87+
Options::Arguments::Zero,
88+
[this](Options* o, const std::string& argument) {
89+
passOptions.validate = false;
90+
});
8691
;
8792
}
8893

src/tools/wasm-shell.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323
#include <memory>
2424

2525
#include "execution-results.h"
26-
#include "feature-options.h"
2726
#include "pass.h"
2827
#include "shell-interface.h"
2928
#include "support/file.h"
3029
#include "wasm-interpreter.h"
3130
#include "wasm-printing.h"
3231
#include "wasm-s-parser.h"
3332
#include "wasm-validator.h"
33+
#include "tool-options.h"
3434

3535
using namespace cashew;
3636
using namespace wasm;
@@ -233,7 +233,7 @@ int main(int argc, const char* argv[]) {
233233
Name entry;
234234
std::set<size_t> skipped;
235235

236-
FeatureOptions options("wasm-shell", "Execute .wast files");
236+
ToolOptions options("wasm-shell", "Execute .wast files");
237237
options
238238
.add(
239239
"--entry", "-e", "Call the entry point after parsing the module",

src/tools/wasm2js.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
#include "support/file.h"
2424
#include "wasm-s-parser.h"
2525
#include "wasm2js.h"
26+
#include "tool-options.h"
2627

2728
using namespace cashew;
2829
using namespace wasm;
2930

3031
int main(int argc, const char *argv[]) {
3132
Wasm2JSBuilder::Flags builderFlags;
32-
Options options("wasm2js", "Transform .wasm/.wast files to asm.js");
33+
ToolOptions options("wasm2js", "Transform .wasm/.wast files to asm.js");
3334
options
3435
.add("--output", "-o", "Output file (stdout if not specified)",
3536
Options::Arguments::One,
@@ -97,6 +98,13 @@ int main(int argc, const char *argv[]) {
9798
Fatal() << "error in building module, std::bad_alloc (possibly invalid request for silly amounts of memory)";
9899
}
99100

101+
if (options.passOptions.validate) {
102+
if (!WasmValidator().validate(wasm, options.getFeatures())) {
103+
WasmPrinter::printModule(&wasm);
104+
Fatal() << "error in validating input";
105+
}
106+
}
107+
100108
if (options.debug) std::cerr << "asming..." << std::endl;
101109
Wasm2JSBuilder wasm2js(builderFlags);
102110
asmjs = wasm2js.processWasm(&wasm);

src/wasm/wasm-validator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,12 @@ void FunctionValidator::visitFunction(Function* curr) {
10721072
if (curr->imported()) {
10731073
shouldBeTrue(curr->type.is(), curr->name, "imported functions must have a function type");
10741074
}
1075+
// validate optional local names
1076+
std::set<Name> seen;
1077+
for (auto& pair : curr->localNames) {
1078+
Name name = pair.second;
1079+
shouldBeTrue(seen.insert(name).second, name, "local names must be unique");
1080+
}
10751081
}
10761082

10771083
static bool checkOffset(Expression* curr, Address add, Address max) {

test/passes/optimize-instructions.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@
12411241
(local.get $0)
12421242
)
12431243
)
1244-
(func $almost-sign-ext (; 12 ;) (type $5) (param $0 i32) (param $0 i32)
1244+
(func $almost-sign-ext (; 12 ;) (type $6) (param $0 i32)
12451245
(drop
12461246
(i32.shr_s
12471247
(i32.shl

test/passes/optimize-instructions.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1377,7 +1377,7 @@
13771377
)
13781378
)
13791379
)
1380-
(func $almost-sign-ext (param $0 i32) (param $0 i32)
1380+
(func $almost-sign-ext (param $0 i32)
13811381
(drop
13821382
(i32.shr_s
13831383
(i32.shl

test/wasm2js/grow-memory-tricky.wast

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
(export "f2" (func $1))
88

99
(func $0 (result i32)
10-
(block
10+
(block (result i32)
1111
(i32.store (i32.const 0) (grow_memory (i32.const 1)))
1212
(i32.load (i32.const 0))
1313
)
1414
)
1515

1616
(func $1 (result i32)
17-
(block
17+
(block (result i32)
1818
(i32.store (i32.const 0) (call $grow))
1919
(i32.load (i32.const 0))
2020
)

test/wasm2js/i64-select.wast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
(module
44
(func $p (param $i i32) (result i32) (local.get $i))
5-
(func (param i32) (result i64)
5+
(func (param i32) (result i32)
66
(return
77
(select
88
(call $p (i32.const -1))

0 commit comments

Comments
 (0)