diff --git a/src/feature.def b/src/feature.def index 79d8d4949e..7c5e2abca2 100644 --- a/src/feature.def +++ b/src/feature.def @@ -32,3 +32,4 @@ WABT_FEATURE(multi_value, "multi-value", false, "Multi-value" WABT_FEATURE(tail_call, "tail-call", false, "Tail-call support") WABT_FEATURE(bulk_memory, "bulk-memory", false, "Bulk-memory operations") WABT_FEATURE(reference_types, "reference-types", false, "Reference types (anyref)") +WABT_FEATURE(annotations, "annotations", false, "Custom annotation syntax") diff --git a/src/token.def b/src/token.def index 5bcc66dd13..005e2b458d 100644 --- a/src/token.def +++ b/src/token.def @@ -137,6 +137,7 @@ WABT_TOKEN_LAST(Opcode, Unreachable) /* Tokens with string data. */ WABT_TOKEN(AlignEqNat, "align=") +WABT_TOKEN(LparAnn, "Annotation") WABT_TOKEN(OffsetEqNat, "offset=") WABT_TOKEN(Reserved, "Reserved") WABT_TOKEN(Text, "TEXT") diff --git a/src/wast-lexer.cc b/src/wast-lexer.cc index f6037bdd9f..c8274406d9 100644 --- a/src/wast-lexer.cc +++ b/src/wast-lexer.cc @@ -64,6 +64,10 @@ Token WastLexer::GetToken(WastParser* parser) { continue; } return BareToken(TokenType::Eof); + } else if (MatchString("(@")) { + ReadReservedChars(); + // offset=2 to skip the "(@" prefix + return TextToken(TokenType::LparAnn, 2); } else { ReadChar(); return BareToken(TokenType::Lpar); diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 820fe79a6c..c8eb3fbc05 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -391,8 +391,35 @@ Location WastParser::GetLocation() { } TokenType WastParser::Peek(size_t n) { - while (tokens_.size() <= n) - tokens_.push_back(lexer_->GetToken(this)); + while (tokens_.size() <= n) { + Token cur = lexer_->GetToken(this); + if (cur.token_type() != TokenType::LparAnn) { + tokens_.push_back(cur); + } else { + // Custom annotation. For now, discard until matching Rpar + if (!options_->features.annotations_enabled()) { + Error(cur.loc, "annotations not enabled: %s", cur.to_string().c_str()); + return TokenType::Invalid; + } + int indent = 1; + while (indent > 0) { + cur = lexer_->GetToken(this); + switch (cur.token_type()) { + case TokenType::Lpar: + case TokenType::LparAnn: + indent++; + break; + + case TokenType::Rpar: + indent--; + break; + + default: + break; + } + } + } + } return tokens_.at(n).token_type(); } diff --git a/test/help/spectest-interp.txt b/test/help/spectest-interp.txt index 2fa2f98a6f..c06564f4d5 100644 --- a/test/help/spectest-interp.txt +++ b/test/help/spectest-interp.txt @@ -22,6 +22,7 @@ options: --enable-tail-call Enable Tail-call support --enable-bulk-memory Enable Bulk-memory operations --enable-reference-types Enable Reference types (anyref) + --enable-annotations Enable Custom annotation syntax -V, --value-stack-size=SIZE Size in elements of the value stack -C, --call-stack-size=SIZE Size in elements of the call stack -t, --trace Trace execution diff --git a/test/help/wasm-interp.txt b/test/help/wasm-interp.txt index 6b3f27aca8..05264173b9 100644 --- a/test/help/wasm-interp.txt +++ b/test/help/wasm-interp.txt @@ -33,6 +33,7 @@ options: --enable-tail-call Enable Tail-call support --enable-bulk-memory Enable Bulk-memory operations --enable-reference-types Enable Reference types (anyref) + --enable-annotations Enable Custom annotation syntax -V, --value-stack-size=SIZE Size in elements of the value stack -C, --call-stack-size=SIZE Size in elements of the call stack -t, --trace Trace execution diff --git a/test/help/wasm-validate.txt b/test/help/wasm-validate.txt index 3cb0843199..0e03e1ceb2 100644 --- a/test/help/wasm-validate.txt +++ b/test/help/wasm-validate.txt @@ -22,6 +22,7 @@ options: --enable-tail-call Enable Tail-call support --enable-bulk-memory Enable Bulk-memory operations --enable-reference-types Enable Reference types (anyref) + --enable-annotations Enable Custom annotation syntax --no-debug-names Ignore debug names in the binary file --ignore-custom-section-errors Ignore errors in custom sections ;;; STDOUT ;;) diff --git a/test/help/wasm2wat.txt b/test/help/wasm2wat.txt index f5bedf121b..780e306fa4 100644 --- a/test/help/wasm2wat.txt +++ b/test/help/wasm2wat.txt @@ -28,6 +28,7 @@ options: --enable-tail-call Enable Tail-call support --enable-bulk-memory Enable Bulk-memory operations --enable-reference-types Enable Reference types (anyref) + --enable-annotations Enable Custom annotation syntax --inline-exports Write all exports inline --inline-imports Write all imports inline --no-debug-names Ignore debug names in the binary file diff --git a/test/help/wast2json.txt b/test/help/wast2json.txt index f6833d904b..64b7883e60 100644 --- a/test/help/wast2json.txt +++ b/test/help/wast2json.txt @@ -25,6 +25,7 @@ options: --enable-tail-call Enable Tail-call support --enable-bulk-memory Enable Bulk-memory operations --enable-reference-types Enable Reference types (anyref) + --enable-annotations Enable Custom annotation syntax -o, --output=FILE output wasm binary file -r, --relocatable Create a relocatable wasm binary (suitable for linking with e.g. lld) --no-canonicalize-leb128s Write all LEB128 sizes as 5-bytes instead of their minimal size diff --git a/test/help/wat-desugar.txt b/test/help/wat-desugar.txt index f7d48d981a..a1d2561cfb 100644 --- a/test/help/wat-desugar.txt +++ b/test/help/wat-desugar.txt @@ -32,5 +32,6 @@ options: --enable-tail-call Enable Tail-call support --enable-bulk-memory Enable Bulk-memory operations --enable-reference-types Enable Reference types (anyref) + --enable-annotations Enable Custom annotation syntax --generate-names Give auto-generated names to non-named functions, types, etc. ;;; STDOUT ;;) diff --git a/test/help/wat2wasm.txt b/test/help/wat2wasm.txt index f052ebade2..8f3b5aa4f1 100644 --- a/test/help/wat2wasm.txt +++ b/test/help/wat2wasm.txt @@ -32,6 +32,7 @@ options: --enable-tail-call Enable Tail-call support --enable-bulk-memory Enable Bulk-memory operations --enable-reference-types Enable Reference types (anyref) + --enable-annotations Enable Custom annotation syntax -o, --output=FILE output wasm binary file -r, --relocatable Create a relocatable wasm binary (suitable for linking with e.g. lld) --no-canonicalize-leb128s Write all LEB128 sizes as 5-bytes instead of their minimal size diff --git a/test/parse/annotations.txt b/test/parse/annotations.txt new file mode 100644 index 0000000000..abac03b465 --- /dev/null +++ b/test/parse/annotations.txt @@ -0,0 +1,9 @@ +;;; TOOL: wat2wasm +;;; ARGS: --enable-annotations +(module + (func (@name "some func") (result i32) + i32.const 42 + return) + (@custom section) + (@custom (@nested section)) + (@custom (section) (@with "other") nested-subsections)) diff --git a/test/parse/bad-annotations.txt b/test/parse/bad-annotations.txt new file mode 100644 index 0000000000..501b6542fe --- /dev/null +++ b/test/parse/bad-annotations.txt @@ -0,0 +1,23 @@ +;;; TOOL: wat2wasm +;;; ERROR: 1 +(module + (func (@name "some func") (result i32) + i32.const 42 + return) + (@custom section) + (@custom (@nested section)) + (@custom (section) (@with "other") nested-subsections)) +(;; STDERR ;;; +out/test/parse/bad-annotations.txt:4:9: error: annotations not enabled: name + (func (@name "some func") (result i32) + ^^^^^^ +out/test/parse/bad-annotations.txt:4:16: error: unexpected token "some func", expected ). + (func (@name "some func") (result i32) + ^^^^^^^^^^^ +out/test/parse/bad-annotations.txt:7:3: error: annotations not enabled: custom + (@custom section) + ^^^^^^^^ +out/test/parse/bad-annotations.txt:7:12: error: unexpected token section. + (@custom section) + ^^^^^^^ +;;; STDERR ;;)