--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -44,30 +44,30 @@ class ASTReader
{
public:
bool parse(char* start, char* stop, GlobalSharedContext* sc, UniquePtr<ParseNode>& out);
private:
bool raiseError();
// --- Parse full nodes.
- bool parseBool(SimpleTokenReader*, ParseContext* pc, Maybe<bool>*);
- bool parseProgram(SimpleTokenReader* reader, ParseContext* pc, UniquePtr<ParseNode>& out);
- bool parseStatement(SimpleTokenReader* reader, ParseContext* pc, UniquePtr<ParseNode>& out);
- bool parseStatementList(SimpleTokenReader* reader, ParseContext* pc, UniquePtr<ParseNode>& out);
- bool parseStringList(SimpleTokenReader* reader, ParseContext* pc, MutableHandle<Maybe<Names>> out);
- bool parseStringSet(SimpleTokenReader* reader, ParseContext* pc, MutableHandle<Maybe<NameBag>>);
+ bool parseBool(SimpleTokenReader*, Maybe<bool>*);
+ bool parseProgram(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
+ bool parseStatement(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
+ bool parseStatementList(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
+ bool parseStringList(SimpleTokenReader* reader, MutableHandle<Maybe<Names>> out);
+ bool parseStringSet(SimpleTokenReader* reader, MutableHandle<Maybe<NameBag>>);
// --- Parse the contents of a node whose kind has already been determined.
- bool parseBlockStatementAux(SimpleTokenReader* reader, ParseContext* pc, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
- bool parseExpressionStatementAux(SimpleTokenReader* reader, ParseContext* pc, const SimpleTokenReader::Fields* fields, UniquePtr<ParseNode>& out);
+ 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, ParseContext* pc, MutableHandleString);
+ bool readString(SimpleTokenReader* reader, MutableHandleString);
const ReadOnlyCompileOptions& options() const;
ParseNodeAllocator allocator;
ParseNode* allocParseNode(size_t size) {
MOZ_ASSERT(size == sizeof(ParseNode));
return static_cast<ParseNode*>(allocator.allocNode());
@@ -83,70 +83,77 @@ private:
JS_DECLARE_NEW_METHODS(new_, allocParseNode, inline)
private:
JSContext* cx;
LifoAlloc& alloc;
};
+class BinParseContext: public ParseContext {
+public:
+ BinParseContext(ASTReader*, GlobalSharedContext*, Directives*);
+};
bool
ASTReader::parse(char* start, char* stop, GlobalSharedContext* sc, UniquePtr<ParseNode>& out) {
SimpleTokenReader reader(this->cx);
reader.init(start, stop, nullptr);
Directives directives(options().strictOption);
GlobalSharedContext globalsc(this->cx, ScopeKind::Global,
directives, options().extraWarningsOption);
- ParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
+ BinParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
+ if (!globalpc.init()) {
+ return false;
+ }
if (!this->parseProgram(&reader, out) || !reader.uninit()) {
return false;
}
return true;
}
bool
-ASTReader::parseProgram(SimpleTokenReader* reader, ParseContext* pc, UniquePtr<ParseNode>& out) {
+ASTReader::parseProgram(SimpleTokenReader* reader, UniquePtr<ParseNode>& out) {
if (out) {
// Already parsed.
return this->raiseError();
}
SimpleTokenReader::Fields fields(this->cx);
SimpleTokenReader sub(this->cx);
std::string name;
if (!reader->taggedTuple(&name, &fields, &sub)) {
return false;
}
if (name != "Program") {
- return false;
+ return this->raiseError();
}
return this->parseBlockStatementAux(&sub, &fields, out);
}
bool
ASTReader::parseBlockStatementAux(SimpleTokenReader* reader,
- ParseContext* pc,
const SimpleTokenReader::Fields* fields,
UniquePtr<ParseNode>& out)
{
UniquePtr<ParseNode> body;
Maybe<bool> hasDirectEval;
Rooted<Maybe<Names>> letNames(this->cx);
Rooted<Maybe<Names>> constNames(this->cx);
Rooted<Maybe<Names>> varNames(this->cx);
Rooted<Maybe<NameBag>> capturedNames(this->cx);
for (auto field: *fields) {
+ // FIXME: We should make BINJS::Scope a field.
// Fields inherited from `BINJS::Scope`.
// FIXME: We could share this code.
if (field == BINJS_DIRECT_EVAL) {
if (!this->parseBool(reader, &hasDirectEval)) {
return false;
}
} else if (field == BINJS_LET_NAME) {
if (!this->parseStringList(reader, &letNames)) {
@@ -216,17 +223,17 @@ ASTReader::parseBlockStatementAux(Simple
UniquePtr<ParseNode> result(new_<LexicalScopeNode>(bindings.release(), body.release()));
out = Move(result);
// FIXME: Validate capturedNames, etc.
return true;
}
bool
-ASTReader::parseStringList(SimpleTokenReader* reader, ParseContext* pc, MutableHandle<Maybe<Names>> out) {
+ASTReader::parseStringList(SimpleTokenReader* reader, MutableHandle<Maybe<Names>> out) {
if (out.get()) {
return this->raiseError();
}
uint32_t length;
SimpleTokenReader sub(this->cx);
Names result(this->cx);
@@ -248,17 +255,17 @@ ASTReader::parseStringList(SimpleTokenRe
}
}
out.set(Move(Some(Move(result))));
return true;
}
bool
-ASTReader::parseStatementList(SimpleTokenReader* reader, ParseContext* pc, UniquePtr<ParseNode>& out) {
+ASTReader::parseStatementList(SimpleTokenReader* reader, UniquePtr<ParseNode>& out) {
if (out) {
return this->raiseError();
}
uint32_t length;
SimpleTokenReader sub(this->cx);
UniquePtr<ParseNode> result(new_<ListNode>(PNK_STATEMENTLIST, TokenPos()));
if (!result) {
@@ -278,17 +285,17 @@ ASTReader::parseStatementList(SimpleToke
result->append(statement.release()); // `result` knows how to deallocate `statement`.
}
result.swap(out);
return true;
}
bool
-ASTReader::parseStatement(SimpleTokenReader* reader, ParseContext* pc, UniquePtr<ParseNode>& out) {
+ASTReader::parseStatement(SimpleTokenReader* reader, UniquePtr<ParseNode>& out) {
if (out) {
return this->raiseError();
}
SimpleTokenReader::Fields fields(this->cx);
SimpleTokenReader sub(this->cx);
std::string name;
if (!reader->taggedTuple(&name, &fields, &sub)) {
@@ -356,17 +363,17 @@ ASTReader::parseStatement(SimpleTokenRea
} else {
return this->raiseError();
}
return true;
}
bool
-ASTReader::parseBool(SimpleTokenReader* reader, ParseContext* pc, Maybe<bool>* result) {
+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);
}