--- 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") {