summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-12-27 15:24:57 -0800
committerGitHub <noreply@github.com>2018-12-27 15:24:57 -0800
commit3f3fc857ff6204517281ed5caa3209cc8f02d4fc (patch)
treeb64969a33874f29d5f35ea546c69eda90f89edf4
parentfdd4cb7b11d43c6ff200c9541f8567000a8d4bcd (diff)
downloadbinaryen-3f3fc857ff6204517281ed5caa3209cc8f02d4fc.tar.gz
binaryen-3f3fc857ff6204517281ed5caa3209cc8f02d4fc.tar.bz2
binaryen-3f3fc857ff6204517281ed5caa3209cc8f02d4fc.zip
Fix fuzzing JS glue code (#1843)
After we added logging to the fuzzer, we forgot to add to the JS glue code the necessary imports so it can be run there too. Also adds legalization for the JS glue code imports and exports. Also adds a missing validator check on imports having a function type (the fuzzing code was missing one). Fixes #1842
-rw-r--r--src/tools/fuzzing.h1
-rw-r--r--src/tools/js-wrapper.h18
-rw-r--r--src/wasm/wasm-validator.cpp3
-rw-r--r--test/passes/emit-js-wrapper=a.js.txt72
-rw-r--r--test/passes/emit-js-wrapper=a.js.wast.js28
-rw-r--r--test/passes/translate-to-fuzz.txt5
6 files changed, 115 insertions, 12 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 1a3da7b22..0bb05a1ed 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -314,6 +314,7 @@ private:
func->base = name;
func->params.push_back(type);
func->result = none;
+ func->type = ensureFunctionType(getSig(func), &wasm)->name;
wasm.addFunction(func);
}
}
diff --git a/src/tools/js-wrapper.h b/src/tools/js-wrapper.h
index cb5c0bd5b..7cf2ffc53 100644
--- a/src/tools/js-wrapper.h
+++ b/src/tools/js-wrapper.h
@@ -22,10 +22,15 @@
namespace wasm {
static std::string generateJSWrapper(Module& wasm) {
+ PassRunner runner(&wasm);
+ runner.add("legalize-js-interface");
+ runner.run();
+
std::string ret;
ret += "if (typeof console === 'undefined') {\n"
" console = { log: print };\n"
"}\n"
+ "var tempRet0;\n"
"var binary;\n"
"if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) {\n"
" var args = process.argv.slice(2);\n"
@@ -44,7 +49,18 @@ static std::string generateJSWrapper(Module& wasm) {
" binary = read(args[0], 'binary');\n"
" }\n"
"}\n"
- "var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {});\n";
+ "var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {\n"
+ " 'fuzzing-support': {\n"
+ " 'log-i32': function(x) { console.log('i32: ' + x) },\n"
+ " 'log-i64': function(x, y) { console.log('i64: ' + x + ', ' + y) },\n"
+ " 'log-f32': function(x) { console.log('f32: ' + x) },\n"
+ " 'log-f64': function(x) { console.log('f64: ' + x) }\n"
+ " },\n"
+ " 'env': {\n"
+ " 'setTempRet0': function(x) { tempRet0 = x },\n"
+ " 'getTempRet0': function() { return tempRet0 },\n"
+ " },\n"
+ "});\n";
for (auto& exp : wasm.exports) {
auto* func = wasm.getFunctionOrNull(exp->value);
if (!func) continue; // something exported other than a function
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index ef4d90fbd..d11d02353 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1069,6 +1069,9 @@ void FunctionValidator::visitFunction(Function* curr) {
shouldBeTrue(ft->params == curr->params, curr->name, "function params must match its declared type");
shouldBeTrue(ft->result == curr->result, curr->name, "function result must match its declared type");
}
+ if (curr->imported()) {
+ shouldBeTrue(curr->type.is(), curr->name, "imported functions must have a function type");
+ }
}
static bool checkOffset(Expression* curr, Address add, Address max) {
diff --git a/test/passes/emit-js-wrapper=a.js.txt b/test/passes/emit-js-wrapper=a.js.txt
index e390a8fbb..508b62f5b 100644
--- a/test/passes/emit-js-wrapper=a.js.txt
+++ b/test/passes/emit-js-wrapper=a.js.txt
@@ -4,25 +4,27 @@
(type $2 (func (param i32 i64 f32 f64)))
(type $3 (func (param i32 f32 f64)))
(type $4 (func (param i32 f32 f64) (result i64)))
+ (type $FUNCSIG$vi (func (param i32)))
+ (import "env" "setTempRet0" (func $setTempRet0 (param i32)))
(memory $0 256 256)
(export "add" (func $add))
(export "no_return" (func $no-return))
- (export "types" (func $types))
- (export "types2" (func $types2))
- (export "types3" (func $types3))
- (func $add (; 0 ;) (type $0) (param $x i32) (param $y i32) (result i32)
+ (export "types" (func $legalstub$types))
+ (export "types2" (func $legalstub$types2))
+ (export "types3" (func $legalstub$types3))
+ (func $add (; 1 ;) (type $0) (param $x i32) (param $y i32) (result i32)
(i32.add
(get_local $x)
(get_local $y)
)
)
- (func $unexported (; 1 ;) (type $0) (param $x i32) (param $y i32) (result i32)
+ (func $unexported (; 2 ;) (type $0) (param $x i32) (param $y i32) (result i32)
(i32.add
(get_local $x)
(get_local $y)
)
)
- (func $no-return (; 2 ;) (type $1) (param $x i32)
+ (func $no-return (; 3 ;) (type $1) (param $x i32)
(drop
(i32.add
(get_local $x)
@@ -30,13 +32,65 @@
)
)
)
- (func $types (; 3 ;) (type $2) (param $x i32) (param $y i64) (param $z f32) (param $w f64)
+ (func $types (; 4 ;) (type $2) (param $x i32) (param $y i64) (param $z f32) (param $w f64)
(nop)
)
- (func $types2 (; 4 ;) (type $3) (param $x i32) (param $z f32) (param $w f64)
+ (func $types2 (; 5 ;) (type $3) (param $x i32) (param $z f32) (param $w f64)
(nop)
)
- (func $types3 (; 5 ;) (type $4) (param $x i32) (param $z f32) (param $w f64) (result i64)
+ (func $types3 (; 6 ;) (type $4) (param $x i32) (param $z f32) (param $w f64) (result i64)
(i64.const 1)
)
+ (func $legalstub$types (; 7 ;) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 f64) (param $4 f64)
+ (call $types
+ (get_local $0)
+ (i64.or
+ (i64.extend_u/i32
+ (get_local $1)
+ )
+ (i64.shl
+ (i64.extend_u/i32
+ (get_local $2)
+ )
+ (i64.const 32)
+ )
+ )
+ (f32.demote/f64
+ (get_local $3)
+ )
+ (get_local $4)
+ )
+ )
+ (func $legalstub$types2 (; 8 ;) (param $0 i32) (param $1 f64) (param $2 f64)
+ (call $types2
+ (get_local $0)
+ (f32.demote/f64
+ (get_local $1)
+ )
+ (get_local $2)
+ )
+ )
+ (func $legalstub$types3 (; 9 ;) (param $0 i32) (param $1 f64) (param $2 f64) (result i32)
+ (local $3 i64)
+ (set_local $3
+ (call $types3
+ (get_local $0)
+ (f32.demote/f64
+ (get_local $1)
+ )
+ (get_local $2)
+ )
+ )
+ (call $setTempRet0
+ (i32.wrap/i64
+ (i64.shr_u
+ (get_local $3)
+ (i64.const 32)
+ )
+ )
+ )
+ (i32.wrap/i64
+ (get_local $3)
+ )
+ )
)
diff --git a/test/passes/emit-js-wrapper=a.js.wast.js b/test/passes/emit-js-wrapper=a.js.wast.js
index 778f43827..f2e828c2b 100644
--- a/test/passes/emit-js-wrapper=a.js.wast.js
+++ b/test/passes/emit-js-wrapper=a.js.wast.js
@@ -1,6 +1,7 @@
if (typeof console === 'undefined') {
console = { log: print };
}
+var tempRet0;
var binary;
if (typeof process === 'object' && typeof require === 'function' /* node.js detection */) {
var args = process.argv.slice(2);
@@ -19,7 +20,18 @@ if (typeof process === 'object' && typeof require === 'function' /* node.js dete
binary = read(args[0], 'binary');
}
}
-var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {});
+var instance = new WebAssembly.Instance(new WebAssembly.Module(binary), {
+ 'fuzzing-support': {
+ 'log-i32': function(x) { console.log('i32: ' + x) },
+ 'log-i64': function(x, y) { console.log('i64: ' + x + ', ' + y) },
+ 'log-f32': function(x) { console.log('f32: ' + x) },
+ 'log-f64': function(x) { console.log('f64: ' + x) }
+ },
+ 'env': {
+ 'setTempRet0': function(x) { tempRet0 = x },
+ 'getTempRet0': function() { return tempRet0 },
+ },
+});
if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer();
try {
console.log('calling: add');
@@ -36,9 +48,23 @@ instance.exports.no_return(0);
}
if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer();
try {
+ console.log('calling: types');
+instance.exports.types(0, 0, 0, 0, 0);
+} catch (e) {
+ console.log(' exception: ' + e);
+}
+if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer();
+try {
console.log('calling: types2');
instance.exports.types2(0, 0, 0);
} catch (e) {
console.log(' exception: ' + e);
}
+if (instance.exports.hangLimitInitializer) instance.exports.hangLimitInitializer();
+try {
+ console.log('calling: types3');
+ console.log(' result: ' + instance.exports.types3(0, 0, 0));
+} catch (e) {
+ console.log(' exception: ' + e);
+}
console.log('done.')
diff --git a/test/passes/translate-to-fuzz.txt b/test/passes/translate-to-fuzz.txt
index c175193cd..32f3fabad 100644
--- a/test/passes/translate-to-fuzz.txt
+++ b/test/passes/translate-to-fuzz.txt
@@ -1,8 +1,11 @@
(module
+ (type $FUNCSIG$vi (func (param i32)))
+ (type $FUNCSIG$vj (func (param i64)))
+ (type $FUNCSIG$vf (func (param f32)))
+ (type $FUNCSIG$vd (func (param f64)))
(type $FUNCSIG$v (func))
(type $FUNCSIG$jddfiV (func (param f64 f64 f32 i32 v128) (result i64)))
(type $FUNCSIG$viViVjV (func (param i32 v128 i32 v128 i64 v128)))
- (type $FUNCSIG$vd (func (param f64)))
(type $FUNCSIG$VVVVVii (func (param v128 v128 v128 v128 i32 i32) (result v128)))
(type $FUNCSIG$fddffj (func (param f64 f64 f32 f32 i64) (result f32)))
(type $FUNCSIG$j (func (result i64)))