WIP: Implemented LabeledStatement draft
authorDavid Teller <dteller@mozilla.com>
Mon, 24 Jul 2017 18:56:56 +0200
changeset 641333 29801100444078abc8091304c25b98a4837bc3b8
parent 641332 4a4cdba6501a7e0cf738ca8c9e1dd4ee0d1a746d
child 641334 0f3d922122bfce624ea495cb352b5f420ce95a6e
push id72504
push userdteller@mozilla.com
push dateSun, 06 Aug 2017 22:28:40 +0000
milestone57.0a1
WIP: Implemented LabeledStatement MozReview-Commit-ID: JjzkhJjfCwp
js/src/frontend/BinSource.cpp
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -85,16 +85,17 @@ private:
     bool parseStatement(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parseStatementList(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parseStringList(SimpleTokenReader* reader, MutableHandle<Maybe<Names>> out);
     bool parseStringList(SimpleTokenReader* reader, MutableHandle<Names> out);
     bool parseStringSet(SimpleTokenReader* reader, MutableHandle<Maybe<NameBag>>);
     bool parseStringSet(SimpleTokenReader* reader, MutableHandle<NameBag>);
     bool parseScope(SimpleTokenReader* reader, ScopeData& out);
     bool parseExpression(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
+    bool parsePropertyName(SimpleTokenReader* reader, UniquePtr<PropertyName>& out);
 
     // --- Parse the contents of a node whose kind has already been determined.
 
     bool parseBlockStatementAux(SimpleTokenReader* reader, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
     bool parseExpressionStatementAux(SimpleTokenReader* reader, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
 
     // --- Utilities.
     bool readString(SimpleTokenReader* reader, MutableHandleString);
@@ -284,16 +285,18 @@ ASTReader::parseBlockStatementAux(Simple
         BindingName binding(atom, isCaptured);
         PodCopy(cursor, &binding, 1); // FIXME: Why does this work?
         cursor++;
         bindings->length++;
     }
     bindings->constStart = scope.letNames->length();
 
     UniquePtr<ParseNode> result(new_<LexicalScopeNode>(bindings.release(), body.release()));
+    // FIXME: Handle case in which `new_` fails. This complicates `release()`.
+    // FIXME: Also for other nodes.
     out = Move(result);
     // FIXME: Validate capturedNames, etc.
     return true;
 }
 
 bool
 ASTReader::parseStringList(SimpleTokenReader* reader, MutableHandle<Maybe<Names>> out) {
     if (out.get()) {
@@ -414,36 +417,67 @@ ASTReader::parseStatement(SimpleTokenRea
         }
 
         UniquePtr<ParseNode> result(new_<BinaryNode>(PNK_WITH, JSOP_NOP, TokenPos(),
                                         expr.release(), body.release()));
         if (!result) {
             return false;
         }
         out = Move(result);
+
     } else if (name == "ReturnStatement") {
 
         UniquePtr<ParseNode> arg;
         for (auto field: fields) {
             if (field == "argument") {
                 if (!this->parseExpression(&sub, arg)) { // FIXME: Make sure that it works with no expression.
                     return false;
                 }
             } else {
                 return this->raiseError();
             }
         }
+
+        // `arg` is optional, so we don't check whether it's `nullptr`.
         UniquePtr<ParseNode> result(new_<UnaryNode>(PNK_RETURN, JSOP_RETURN, TokenPos(), arg.release()));
         if (!result) {
             return false;
         }
         out = Move(result);
 
     } else if (name == "LabeledStatement") {
-        // FIXME: Implement
+
+        UniquePtr<PropertyName> label;
+        UniquePtr<ParseNode> body;
+
+        for (auto field: fields) {
+            if (field == "label") {
+                if (!this->parsePropertyName(&sub, label)) {
+                    return false;
+                }
+            } else if (field == "body") {
+                if (!this->parseStatement(&sub, body)) {
+                    return false;
+                }
+            } else {
+                return this->raiseError();
+            }
+        }
+
+        if (!label || !body) {
+            return false;
+        }
+
+        UniquePtr<ParseNode> result(new_<LabeledStatement>(label.release(), body.release(), 0));
+        if (!result) {
+            return false;
+        }
+
+        out = Move(result);
+
     } else if (name == "BreakStatement") {
         // FIXME: Implement
     } else if (name == "ContinueStatement") {
         // FIXME: Implement
     } else if (name == "IfStatement") {
         // FIXME: Implement
     } else if (name == "SwitchStatement") {
         // FIXME: Implement