summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-s-parser.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-11-25 15:36:04 -0800
committerGitHub <noreply@github.com>2020-11-25 15:36:04 -0800
commit3c66ad3c7c602416d4cf674b3d7528d9acd6d51f (patch)
treeecf2308d4cbc2c995c66fcc9375b7bab341d6ca0 /src/wasm/wasm-s-parser.cpp
parent72c035e905b3695f2763fdeb21163003d8595887 (diff)
downloadbinaryen-3c66ad3c7c602416d4cf674b3d7528d9acd6d51f.tar.gz
binaryen-3c66ad3c7c602416d4cf674b3d7528d9acd6d51f.tar.bz2
binaryen-3c66ad3c7c602416d4cf674b3d7528d9acd6d51f.zip
[TypedFunctionReferences] Enable call_ref in fuzzer, and fix minor misc fuzz bugs (#3401)
* Count signatures in tuple locals. * Count nested signature types (confirming @aheejin was right, that was missing). * Inlining was using the wrong type. * OptimizeInstructions should return -1 for unhandled types, not error. * The fuzzer should check for ref types as well, not just typed function references, similar to what GC does. * The fuzzer now creates a function if it has no other option for creating a constant expression of a function type, then does a ref.func of that. * Handle unreachability in call_ref binary reading. * S-expression parsing fixes in more places, and add a tiny fuzzer for it. * Switch fuzzer test to just have the metrics, and not print all the fuzz output which changes a lot. Also fix noprint handling which only worked on binaries before. * Fix Properties::getLiteral() to use the specific function type properly, and make Literal's function constructor require that, to prevent future bugs. * Turn all input types into nullable types, for now.
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r--src/wasm/wasm-s-parser.cpp46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index d8d9fa779..434dec9d7 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -536,14 +536,10 @@ SExpressionWasmBuilder::parseParamOrLocal(Element& s, size_t& localIndex) {
}
localIndex++;
Type type;
- if (s[i]->isStr()) {
- type = stringToType(s[i]->str());
- } else {
- type = elementToType(*s[i]);
- if (elementStartsWith(s, PARAM) && type.isTuple()) {
- throw ParseException(
- "params may not have tuple types", s[i]->line, s[i]->col);
- }
+ type = elementToType(*s[i]);
+ if (elementStartsWith(s, PARAM) && type.isTuple()) {
+ throw ParseException(
+ "params may not have tuple types", s[i]->line, s[i]->col);
}
namedParams.emplace_back(name, type);
}
@@ -555,7 +551,7 @@ std::vector<Type> SExpressionWasmBuilder::parseResults(Element& s) {
assert(elementStartsWith(s, RESULT));
std::vector<Type> types;
for (size_t i = 1; i < s.size(); i++) {
- types.push_back(stringToType(s[i]->str()));
+ types.push_back(elementToType(*s[i]));
}
return types;
}
@@ -923,7 +919,7 @@ HeapType SExpressionWasmBuilder::stringToHeapType(const char* str,
Type SExpressionWasmBuilder::elementToType(Element& s) {
if (s.isStr()) {
- return stringToType(s.str(), false, false);
+ return stringToType(s.str());
}
auto& list = s.list();
auto size = list.size();
@@ -942,7 +938,8 @@ Type SExpressionWasmBuilder::elementToType(Element& s) {
throw ParseException(
std::string("invalid reference type qualifier"), s.line, s.col);
}
- bool nullable = false;
+ // FIXME: for now, force all inputs to be nullable
+ bool nullable = true;
size_t i = 1;
if (size == 3) {
nullable = true;
@@ -966,7 +963,7 @@ Type SExpressionWasmBuilder::elementToType(Element& s) {
// It's a tuple.
std::vector<Type> types;
for (size_t i = 0; i < s.size(); ++i) {
- types.push_back(stringToType(list[i]->str()));
+ types.push_back(elementToType(*list[i]));
}
return Type(types);
}
@@ -1911,9 +1908,30 @@ Expression* SExpressionWasmBuilder::makeRefNull(Element& s) {
if (s.size() != 2) {
throw ParseException("invalid heap type reference", s.line, s.col);
}
- auto heapType = stringToHeapType(s[1]->str());
auto ret = allocator.alloc<RefNull>();
- ret->finalize(heapType);
+ if (s[1]->isStr()) {
+ // For example, this parses
+ // (ref.null func)
+ ret->finalize(stringToHeapType(s[1]->str()));
+ } else {
+ // To parse a heap type, create an element around it, and call that method.
+ // That is, given (func) we wrap to (ref (func)).
+ // For example, this parses
+ // (ref.null (func (param i32)))
+ // TODO add a helper method, but this is the only user atm, and we are
+ // waiting on https://github.com/WebAssembly/function-references/issues/42
+ Element wrapper(wasm.allocator);
+ auto& list = wrapper.list();
+ list.resize(3);
+ Element ref(wasm.allocator);
+ ref.setString(REF, false, false);
+ Element null(wasm.allocator);
+ null.setString(NULL_, false, false);
+ list[0] = &ref;
+ list[1] = &null;
+ list[2] = s[1];
+ ret->finalize(elementToType(wrapper));
+ }
return ret;
}