summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-11-05 13:22:15 -0800
committerGitHub <noreply@github.com>2018-11-05 13:22:15 -0800
commitfce199ca454fcac97237273062dd48032899018f (patch)
tree69247bc2f093e70fabc496a42520a5f1174efbe3
parente20bd90c841a1cf227275055d4f213a74c7036a9 (diff)
downloadbinaryen-fce199ca454fcac97237273062dd48032899018f.tar.gz
binaryen-fce199ca454fcac97237273062dd48032899018f.tar.bz2
binaryen-fce199ca454fcac97237273062dd48032899018f.zip
add support for new call_indirect syntax ; fixes #1724 (#1725)
-rw-r--r--src/wasm/wasm-s-parser.cpp37
-rw-r--r--test/newsyntax.wast10
-rw-r--r--test/newsyntax.wast.from-wast19
-rw-r--r--test/newsyntax.wast.fromBinary20
-rw-r--r--test/newsyntax.wast.fromBinary.noDebugInfo20
5 files changed, 98 insertions, 8 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index ee37f23f3..b81b32ad6 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1384,14 +1384,35 @@ Expression* SExpressionWasmBuilder::makeCall(Element& s) {
Expression* SExpressionWasmBuilder::makeCallIndirect(Element& s) {
if (!wasm.table.exists) throw ParseException("no table");
auto ret = allocator.alloc<CallIndirect>();
- Element& typeElement = *s[1];
- if (typeElement[0]->str() != "type") throw ParseException("expected 'type' in call_indirect", s.line, s.col);
- IString type = typeElement[1]->str();
- auto* fullType = wasm.getFunctionTypeOrNull(type);
- if (!fullType) throw ParseException("invalid call_indirect type", s.line, s.col);
- ret->fullType = fullType->name;
- ret->type = fullType->result;
- parseCallOperands(s, 2, s.size() - 1, ret);
+ Index i = 1;
+ Element& typeElement = *s[i];
+ if (typeElement[0]->str() == "type") {
+ // type name given
+ IString type = typeElement[1]->str();
+ auto* fullType = wasm.getFunctionTypeOrNull(type);
+ if (!fullType) throw ParseException("invalid call_indirect type", s.line, s.col);
+ ret->fullType = fullType->name;
+ i++;
+ } else {
+ // inline type
+ FunctionType type;
+ while (1) {
+ Element& curr = *s[i];
+ if (curr[0]->str() == PARAM) {
+ for (size_t j = 1; j < curr.size(); j++) {
+ type.params.push_back(stringToType(curr[j]->str()));
+ }
+ } else if (curr[0]->str() == RESULT) {
+ type.result = stringToType(curr[1]->str());
+ } else {
+ break;
+ }
+ i++;
+ }
+ ret->fullType = ensureFunctionType(getSig(&type), &wasm)->name;
+ }
+ ret->type = wasm.getFunctionType(ret->fullType)->result;
+ parseCallOperands(s, i, s.size() - 1, ret);
ret->target = parseExpression(s[s.size() - 1]);
ret->finalize();
return ret;
diff --git a/test/newsyntax.wast b/test/newsyntax.wast
new file mode 100644
index 000000000..aba263d24
--- /dev/null
+++ b/test/newsyntax.wast
@@ -0,0 +1,10 @@
+(module
+ (import "env" "table" (table 9 9 anyfunc))
+ (func "call_indirect"
+ (drop
+ (call_indirect (param i32) (param f64) (result i32) (i32.const 10) (f64.const 20) (i32.const 30))
+ )
+ (call_indirect (i32.const 1))
+ )
+)
+
diff --git a/test/newsyntax.wast.from-wast b/test/newsyntax.wast.from-wast
new file mode 100644
index 000000000..bf77b7e46
--- /dev/null
+++ b/test/newsyntax.wast.from-wast
@@ -0,0 +1,19 @@
+(module
+ (type $0 (func))
+ (type $FUNCSIG$iid (func (param i32 f64) (result i32)))
+ (type $FUNCSIG$v (func))
+ (import "env" "table" (table $0 9 9 anyfunc))
+ (export "call_indirect" (func $0))
+ (func $0 (; 0 ;) (type $0)
+ (drop
+ (call_indirect (type $FUNCSIG$iid)
+ (i32.const 10)
+ (f64.const 20)
+ (i32.const 30)
+ )
+ )
+ (call_indirect (type $FUNCSIG$v)
+ (i32.const 1)
+ )
+ )
+)
diff --git a/test/newsyntax.wast.fromBinary b/test/newsyntax.wast.fromBinary
new file mode 100644
index 000000000..392e3eccd
--- /dev/null
+++ b/test/newsyntax.wast.fromBinary
@@ -0,0 +1,20 @@
+(module
+ (type $0 (func))
+ (type $1 (func (param i32 f64) (result i32)))
+ (type $2 (func))
+ (import "env" "table" (table $timport$0 9 9 anyfunc))
+ (export "call_indirect" (func $0))
+ (func $0 (; 0 ;) (type $0)
+ (drop
+ (call_indirect (type $1)
+ (i32.const 10)
+ (f64.const 20)
+ (i32.const 30)
+ )
+ )
+ (call_indirect (type $2)
+ (i32.const 1)
+ )
+ )
+)
+
diff --git a/test/newsyntax.wast.fromBinary.noDebugInfo b/test/newsyntax.wast.fromBinary.noDebugInfo
new file mode 100644
index 000000000..392e3eccd
--- /dev/null
+++ b/test/newsyntax.wast.fromBinary.noDebugInfo
@@ -0,0 +1,20 @@
+(module
+ (type $0 (func))
+ (type $1 (func (param i32 f64) (result i32)))
+ (type $2 (func))
+ (import "env" "table" (table $timport$0 9 9 anyfunc))
+ (export "call_indirect" (func $0))
+ (func $0 (; 0 ;) (type $0)
+ (drop
+ (call_indirect (type $1)
+ (i32.const 10)
+ (f64.const 20)
+ (i32.const 30)
+ )
+ )
+ (call_indirect (type $2)
+ (i32.const 1)
+ )
+ )
+)
+