WIP: Proper handling if new_ fails draft
authorDavid Teller <dteller@mozilla.com>
Mon, 24 Jul 2017 20:59:15 +0200
changeset 641339 e62a6960920252cdeb167c35b5068f10b49f69e8
parent 641338 2d490e8c494e68db65fa2cf710cf03a549d7177c
child 641340 946967053af70fb85b245a4c3b286f43bf5844b0
push id72504
push userdteller@mozilla.com
push dateSun, 06 Aug 2017 22:28:40 +0000
milestone57.0a1
WIP: Proper handling if new_ fails MozReview-Commit-ID: 3pMG7nx6QYz
js/src/frontend/BinSource.cpp
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -10,17 +10,16 @@
 #include <frontend/BinTokenReader.h>
 
 
 using namespace mozilla;
 using NameBag = GCHashSet<JSString*>;
 using Names = GCVector<JSString*, 8>;
 
 // FIXME: Better error handling.
-// FIXME: Proper error handling if `new_` fails.
 // FIXME: Check that subnodes have the right type.
 // FIXME: Check scope information.
 
 namespace js {
 namespace frontend {
 
 
 // Copied from Parser.cpp
@@ -292,19 +291,22 @@ ASTReader::parseBlockStatementAux(Simple
         bool isCaptured = scope.capturedNames->has(name);
         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.
+    UniquePtr<ParseNode> result(new_<LexicalScopeNode>(bindings.get(), body.get()));
+    if (!result) {
+        return false;
+    }
+    Unused << bindings.release();
+    Unused << body.release();
     out = Move(result);
     // FIXME: Validate capturedNames, etc.
     return true;
 }
 
 bool
 ASTReader::parseStringList(SimpleTokenReader* reader, MutableHandle<Maybe<Names>> out) {
     if (out.get()) {
@@ -420,40 +422,45 @@ ASTReader::parseStatement(SimpleTokenRea
                 return this->raiseError();
             }
         }
         if (!body || !expr) {
             return false;
         }
 
         UniquePtr<ParseNode> result(new_<BinaryNode>(PNK_WITH, JSOP_NOP, TokenPos(),
-                                        expr.release(), body.release()));
+                                        expr.get(), body.get()));
         if (!result) {
             return this->raiseError();
         }
+        Unused << expr.release();
+        Unused << body.release();
+
         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()));
+        UniquePtr<ParseNode> result(new_<UnaryNode>(PNK_RETURN, JSOP_RETURN, TokenPos(), arg.get()));
         if (!result) {
             return this->raiseError();
         }
+
+        Unused << arg.release();
         out = Move(result);
 
     } else if (name == "LabeledStatement") {
 
         UniquePtr<PropertyName> label;
         UniquePtr<ParseNode> body;
 
         for (auto field: fields) {
@@ -469,21 +476,23 @@ ASTReader::parseStatement(SimpleTokenRea
                 return this->raiseError();
             }
         }
 
         if (!label || !body) {
             return this->raiseError();
         }
 
-        UniquePtr<ParseNode> result(new_<LabeledStatement>(label.release(), body.release(), 0));
+        UniquePtr<ParseNode> result(new_<LabeledStatement>(label.get(), body.get(), 0));
         if (!result) {
             return false;
         }
 
+        Unused << label.release();
+        Unused << body.release();
         out = Move(result);
 
     } else if (name == "BreakStatement" || name == "ContinueStatement") {
 
         UniquePtr<PropertyName> label;
 
         for (auto field: fields) {
             if (field == "label") {
@@ -495,29 +504,31 @@ ASTReader::parseStatement(SimpleTokenRea
             }
         }
 
         if (!label) {
             return this->raiseError();
         }
 
         if (name == "BreakStatement") {
-            UniquePtr<ParseNode> result(new_<BreakStatement>(label.release(), TokenPos()));
+            UniquePtr<ParseNode> result(new_<BreakStatement>(label.get(), TokenPos()));
             if (!result) {
                 return false;
             }
             out = Move(result);
         } else {
-            UniquePtr<ParseNode> result(new_<ContinueStatement>(label.release(), TokenPos()));
+            UniquePtr<ParseNode> result(new_<ContinueStatement>(label.get(), TokenPos()));
             if (!result) {
                 return false;
             }
             out = Move(result);
         }
 
+        Unused << label.release();
+
     } else if (name == "IfStatement") {
 
         UniquePtr<ParseNode> test;
         UniquePtr<ParseNode> consequent;
         UniquePtr<ParseNode> alternate; // Optional
 
         for (auto field: fields) {
             if (field == "test") {
@@ -537,20 +548,25 @@ ASTReader::parseStatement(SimpleTokenRea
             }
         }
 
         if (!test || !consequent) {
             // Do not test `alternate`, since that value is optional.
             return this->raiseError();
         }
 
-        UniquePtr<ParseNode> result(new_<TernaryNode>(PNK_IF, JSOP_NOP, test.release(), consequent.release(), alternate.release()));
+        UniquePtr<ParseNode> result(new_<TernaryNode>(PNK_IF, JSOP_NOP, test.get(), consequent.get(), alternate.get()));
         if (!result) {
             return false;
         }
+
+        Unused << test.release();
+        Unused << consequent.release();
+        Unused << alternate.release();
+
         out = Move(result);
 
     } else if (name == "SwitchStatement") {
 
         UniquePtr<ParseNode> discriminant;
         UniquePtr<ParseNode> cases;
 
         for (auto field: fields) {
@@ -566,21 +582,23 @@ ASTReader::parseStatement(SimpleTokenRea
                 return this->raiseError();
             }
         }
 
         if (!discriminant || !cases) {
             return this->raiseError();
         }
 
-        UniquePtr<ParseNode> result(new_<BinaryNode>(PNK_SWITCH, JSOP_NOP, TokenPos(), discriminant.release(), cases.release()));
+        UniquePtr<ParseNode> result(new_<BinaryNode>(PNK_SWITCH, JSOP_NOP, TokenPos(), discriminant.get(), cases.get()));
         if (!result) {
             return false;
         }
 
+        Unused << discriminant.release();
+        Unused << cases.release();
         out = Move(result);
 
     } else if (name == "SwitchCase") {
 
         UniquePtr<ParseNode> test;
         UniquePtr<ParseNode> consequent;
 
         for (auto field: fields) {
@@ -592,21 +610,23 @@ ASTReader::parseStatement(SimpleTokenRea
                 if (!this->parseStatementList(&sub, consequent)) {
                     return false;
                 }
             } else {
                 return this->raiseError();
             }
         }
 
-        UniquePtr<ParseNode> result(new_<CaseClause>(test.release(), consequent.release(), 0));
+        UniquePtr<ParseNode> result(new_<CaseClause>(test.get(), consequent.get(), 0));
         if (!result) {
             return false;
         }
 
+        Unused << test.release();
+        Unused << consequent.release();
         out = Move(result);
 
     } else if (name == "ThrowStatement") {
 
         UniquePtr<ParseNode> arg;
         for (auto field: fields) {
             if (field == "argument") {
                 if (!this->parseExpression(&sub, arg)) {
@@ -616,20 +636,22 @@ ASTReader::parseStatement(SimpleTokenRea
                 return this->raiseError();
             }
         }
 
         if (!arg) {
             return this->raiseError();
         }
 
-        UniquePtr<ParseNode> result(new_<UnaryNode>(PNK_THROW, JSOP_THROW, TokenPos(), arg.release()));
+        UniquePtr<ParseNode> result(new_<UnaryNode>(PNK_THROW, JSOP_THROW, TokenPos(), arg.get()));
         if (!result) {
             return this->raiseError();
         }
+
+        Unused << arg.release();
         out = Move(result);
 
     } else if (name == "TryStatement") {
 
         UniquePtr<ParseNode> block;
         UniquePtr<ParseNode> handler;
         UniquePtr<ParseNode> finalizer;
 
@@ -650,21 +672,25 @@ ASTReader::parseStatement(SimpleTokenRea
                 return this->raiseError();
             }
         }
 
         if (!block || !handler) { // `finalizer` is optional
             return this->raiseError();
         }
 
-        UniquePtr<ParseNode> result(new_<TernaryNode>(PNK_TRY, JSOP_NOP, block.release(), handler.release(), finalizer.release(), TokenPos()));
+        UniquePtr<ParseNode> result(new_<TernaryNode>(PNK_TRY, JSOP_NOP, block.get(), handler.get(), finalizer.get(), TokenPos()));
         if (!result) {
             return false;
         }
 
+        Unused << block.release();
+        Unused << handler.release();
+        Unused << finalizer.release();
+
         out = Move(result);
     } else if (name == "WhileStatement") {
         // FIXME: Implement
     } else if (name == "DoWhileStatement") {
         // FIXME: Implement
     } else if (name == "ForStatement") {
         // FIXME: Implement
     } else if (name == "ForInStatement") {