Bug 1316554: wast parser: allow matching names at end of if/else/blocks; r=luke
authorBenjamin Bouvier <benj@benj.me>
Mon, 21 Nov 2016 16:36:16 +0100
changeset 324094 e588418674e17f60dbde2240e6eb1b70763f52f5
parent 324093 f978b398f89872881da40f1013f14ed6641add9a
child 324095 67ff8b138c460ae6d44a0e9f82f30ce9600729a1
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersluke
bugs1316554
milestone53.0a1
Bug 1316554: wast parser: allow matching names at end of if/else/blocks; r=luke MozReview-Commit-ID: KjMA6OPvxsZ
js/src/wasm/WasmTextToBinary.cpp
--- a/js/src/wasm/WasmTextToBinary.cpp
+++ b/js/src/wasm/WasmTextToBinary.cpp
@@ -368,17 +368,19 @@ static bool
 IsWasmLetter(char16_t c)
 {
     return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
 }
 
 static bool
 IsNameAfterDollar(char16_t c)
 {
-    return IsWasmLetter(c) || IsWasmDigit(c) || c == '_' || c == '$' || c == '-' || c == '.';
+    return IsWasmLetter(c) ||
+           IsWasmDigit(c) ||
+           c == '_' || c == '$' || c == '-' || c == '.' || c == '>';
 }
 
 static bool
 IsHexDigit(char c, uint8_t* value)
 {
     if (c >= '0' && c <= '9') {
         *value = c - '0';
         return true;
@@ -1557,16 +1559,38 @@ ParseBlockSignature(WasmParseContext& c,
     if (c.ts.getIf(WasmToken::ValueType, &token))
         *type = ToExprType(token.valueType());
     else
         *type = ExprType::Void;
 
     return true;
 }
 
+static bool
+MaybeMatchName(WasmParseContext& c, const AstName& name)
+{
+    WasmToken tok;
+    if (c.ts.getIf(WasmToken::Name, &tok)) {
+        AstName otherName = tok.name();
+        if (otherName.empty())
+            return true;
+
+        if (name.empty()) {
+            c.ts.generateError(tok, "end name without a start name", c.error);
+            return false;
+        }
+
+        if (otherName != name) {
+            c.ts.generateError(tok, "start/end names don't match", c.error);
+            return false;
+        }
+    }
+    return true;
+}
+
 static AstBlock*
 ParseBlock(WasmParseContext& c, Op op, bool inParens)
 {
     AstExprVector exprs(c.lifo);
 
     AstName name = c.ts.getIfName();
 
     // Compatibility syntax sugar: If a second label is present, we'll wrap
@@ -1585,16 +1609,18 @@ ParseBlock(WasmParseContext& c, Op op, b
         return nullptr;
 
     if (!ParseExprList(c, &exprs, inParens))
         return nullptr;
 
     if (!inParens) {
         if (!c.ts.match(WasmToken::End, c.error))
             return nullptr;
+        if (!MaybeMatchName(c, name))
+            return nullptr;
     }
 
     AstBlock* result = new(c.lifo) AstBlock(op, type, name, Move(exprs));
 
     if (op == Op::Loop && !otherName.empty()) {
         if (!exprs.append(result))
             return nullptr;
         result = new(c.lifo) AstBlock(Op::Block, type, otherName, Move(exprs));
@@ -2191,29 +2217,33 @@ ParseIf(WasmParseContext& c, bool inPare
     if (inParens) {
         if (!c.ts.match(WasmToken::CloseParen, c.error))
             return nullptr;
     }
 
     AstExprVector elseExprs(c.lifo);
     if (!inParens || c.ts.getIf(WasmToken::OpenParen)) {
         if (c.ts.getIf(WasmToken::Else)) {
+            if (!MaybeMatchName(c, name))
+                return nullptr;
             if (!ParseExprList(c, &elseExprs, inParens))
                 return nullptr;
         } else if (inParens) {
             AstExpr* elseBranch = ParseExprInsideParens(c);
             if (!elseBranch || !elseExprs.append(elseBranch))
                 return nullptr;
         }
         if (inParens) {
             if (!c.ts.match(WasmToken::CloseParen, c.error))
                 return nullptr;
         } else {
             if (!c.ts.match(WasmToken::End, c.error))
                 return nullptr;
+            if (!MaybeMatchName(c, name))
+                return nullptr;
         }
     }
 
     return new(c.lifo) AstIf(type, cond, name, Move(thenExprs), Move(elseExprs));
 }
 
 static bool
 ParseLoadStoreAddress(WasmParseContext& c, int32_t* offset, uint32_t* alignLog2, AstExpr** base,