--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -93,26 +93,29 @@ private:
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);
bool parseSwitchCaseList(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
bool parseBlockStatement(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
bool parseCatchClause(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
+ bool parseVariableDeclarator(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
// --- Parse the contents of a node whose kind has already been determined.
+ bool parseFunctionAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
bool parsePatternAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
bool parseBlockStatementAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
bool parseExpressionStatementAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
bool parseExpressionAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
bool parseVariableDeclarationAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
// --- Utilities.
+ bool readString(SimpleTokenReader* reader, std::string&);
bool readString(SimpleTokenReader* reader, MutableHandleString);
const ReadOnlyCompileOptions& options() const;
ParseNodeAllocator allocator;
ParseNode* allocParseNode(size_t size) {
MOZ_ASSERT(size == sizeof(ParseNode));
@@ -876,29 +879,117 @@ ASTReader::parseStatement(SimpleTokenRea
}
Unused << forHead.release();
Unused << body.release();
out = Move(result);
} else if (name == "FunctionDeclaration") {
- // FIXME: Implement
- } else if (name == "VariableDeclaration") {
+
// FIXME: Implement
- } else if (name == "SwitchStatement") {
- // FIXME: Implement
+
+ } else if (name == "VariableDeclaration") {
+
+ if (!this->parseVariableDeclarationAux(&sub, name, &fields, out)) {
+ return false;
+ }
+
} else {
return this->raiseError();
}
return true;
}
bool
+ASTReader::parseVariableDeclarationAux(SimpleTokenReader* reader, const std::string& name, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out) {
+ if (!out) {
+ return this->raiseError();
+ }
+
+ ParseNodeKind kind = PNK_LIMIT;
+ JSOp op = JSOP_NOP;
+ UniquePtr<ParseNode> result;
+
+ for (auto field: *fields) {
+ if (field == "kind") {
+ std::string kindName;
+ if (!this->readString(reader, kindName)) {
+ return false;
+ }
+
+ if (kindName == "let") {
+ kind = PNK_LET;
+ op = JSOP_DEFLET;
+ } else if (kindName == "var") {
+ kind = PNK_VAR;
+ op = JSOP_DEFVAR;
+ } else if (kindName == "const") {
+ kind = PNK_CONST;
+ op = JSOP_DEFCONST;
+ } else {
+ return this->raiseError();
+ }
+ } else if (field == "declarations") {
+ if (result) {
+ // Already parsed.
+ return this->raiseError();
+ }
+
+ uint32_t length;
+ SimpleTokenReader sub(this->cx);
+
+ if (!reader->readList(&length, &sub)) {
+ return false;
+ }
+
+ if (length == 0) {
+ return this->raiseError();
+ }
+
+ UniquePtr<ParseNode> root(new_<ListNode>(PNK_LIMIT /*Placeholder*/, JSOP_NOP/*Placeholder*/, TokenPos()));
+ if (!root) {
+ return false;
+ }
+
+ UniquePtr<ParseNode> first;
+ if (!this->parseVariableDeclarator(&sub, first)) {
+ return false;
+ }
+ root->initList(first.release());
+
+
+ for (uint32_t i = 1; i < length; ++i) {
+ UniquePtr<ParseNode> current;
+ if (!this->parseVariableDeclarator(&sub, current)) {
+ return false;
+ }
+ if (!current) {
+ return this->raiseError();
+ }
+ root->append(current.release());
+ }
+
+ result = Move(root);
+ }
+ }
+
+ if (!result || kind == PNK_LIMIT) {
+ return this->raiseError();
+ }
+
+ result->setKind(kind);
+ result->setOp(op);
+ out = Move(result);
+
+ return true;
+}
+
+bool
ASTReader::parseBool(SimpleTokenReader* reader, Maybe<bool>* result) {
if (result->isSome()) {
// Already parsed.
// FIXME: Can replace with an assert once we have
// implemented headers and header validation.
return this->raiseError();
}
return reader->readBool(result);