Bug 1577857 - Hoist FunctionTree into its own header r=tcampbell

Differential Revision: https://phabricator.services.mozilla.com/D45041

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matthew Gaudet 2019-09-10 15:53:03 +00:00
Родитель dfb71031ec
Коммит d08d8aa4a3
3 изменённых файлов: 129 добавлений и 104 удалений

Просмотреть файл

@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef frontend_FunctionTree_h
#define frontend_FunctionTree_h
#include "mozilla/Attributes.h"
#include "js/Vector.h"
namespace js {
namespace frontend {
class FunctionBox;
class ParserBase;
// A tree of function nodes pointing to a FunctionBox and all its
// nested inner functions.
class FunctionTree {
FunctionBox* funbox_;
Vector<FunctionTree> children_;
public:
explicit FunctionTree(JSContext* cx) : funbox_(nullptr), children_(cx) {}
// Note: If we're using vector type, the pointer returned here
// is only valid if the tree is only added to in DFS order
//
// Open to suggestions about how to do that better.
FunctionTree* add(JSContext* cx) {
if (!children_.emplaceBack(cx)) {
return nullptr;
}
return &children_.back();
}
void reset() {
funbox_ = nullptr;
children_.clear();
}
FunctionBox* funbox() { return funbox_; }
void setFunctionBox(FunctionBox* node) { funbox_ = node; }
typedef bool (*FunctionTreeVisitorFunction)(ParserBase*, FunctionTree*);
bool visitRecursively(JSContext* cx, ParserBase* parser,
FunctionTreeVisitorFunction func) {
if (!CheckRecursionLimit(cx)) {
return false;
}
for (auto& child : children_) {
if (!child.visitRecursively(cx, parser, func)) {
return false;
}
}
return func(parser, this);
}
void dump(JSContext* cx) { dump(cx, *this, 1); }
private:
static void dump(JSContext* cx, FunctionTree& node, int indent);
};
// Owner of a function tree
//
// The holder mode can be eager or deferred:
//
// - In Eager mode, deferred items happens right away and the tree is not
// constructed.
// - In Deferred mode, deferred items happens only when publishDeferredItems
// is called.
//
// Note: Function trees point to function boxes, which only have the lifetime of
// the BytecodeCompiler, so exercise caution when holding onto a
// holder.
class FunctionTreeHolder {
public:
enum Mode { Eager, Deferred };
private:
FunctionTree treeRoot_;
FunctionTree* currentParent_;
Mode mode_;
public:
explicit FunctionTreeHolder(JSContext* cx, Mode mode = Mode::Eager)
: treeRoot_(cx), currentParent_(&treeRoot_), mode_(mode) {}
FunctionTree* getFunctionTree() { return &treeRoot_; }
FunctionTree* getCurrentParent() { return currentParent_; }
void setCurrentParent(FunctionTree* parent) { currentParent_ = parent; }
bool isEager() { return mode_ == Mode::Eager; }
bool isDeferred() { return mode_ == Mode::Deferred; }
// When a parse has failed, we need to reset the root of the
// function tree as we don't want a reparse to have old entries.
void resetFunctionTree() {
treeRoot_.reset();
currentParent_ = &treeRoot_;
}
};
// A class used to maintain our function tree as ParseContexts are
// pushed and popped.
class MOZ_RAII AutoPushTree {
FunctionTreeHolder& holder_;
FunctionTree* oldParent_ = nullptr;
public:
explicit AutoPushTree(FunctionTreeHolder& holder);
~AutoPushTree();
bool init(JSContext* cx, FunctionBox* box);
};
} // namespace frontend
} // namespace js
#endif

Просмотреть файл

@ -11,6 +11,7 @@
#include "frontend/BytecodeCompiler.h"
#include "frontend/ErrorReporter.h"
#include "frontend/FunctionTree.h"
#include "frontend/NameCollections.h"
#include "frontend/SharedContext.h"
@ -178,19 +179,6 @@ class UsedNameTracker {
class FunctionTree;
class FunctionTreeHolder;
// A class used to maintain our function tree as ParseContexts are
// pushed and popped.
class MOZ_RAII AutoPushTree {
FunctionTreeHolder& holder_;
FunctionTree* oldParent_ = nullptr;
public:
explicit AutoPushTree(FunctionTreeHolder& holder);
~AutoPushTree();
bool init(JSContext* cx, FunctionBox* box);
};
/*
* The struct ParseContext stores information about the current parsing context,
* which is part of the parser state (see the field Parser::pc). The current

Просмотреть файл

@ -181,6 +181,7 @@
#include "frontend/BytecodeCompiler.h"
#include "frontend/ErrorReporter.h"
#include "frontend/FullParseHandler.h"
#include "frontend/FunctionTree.h"
#include "frontend/NameAnalysisTypes.h"
#include "frontend/NameCollections.h"
#include "frontend/ParseContext.h"
@ -291,97 +292,6 @@ class MOZ_STACK_CLASS ParserSharedBase : private JS::AutoGCRooter {
BigIntBox* newBigIntBox(BigInt* val);
};
// A tree of function nodes pointing to a FunctionBox and all its
// nested inner functions.
class FunctionTree {
FunctionBox* funbox_;
Vector<FunctionTree> children_;
public:
explicit FunctionTree(JSContext* cx) : funbox_(nullptr), children_(cx) {}
// Note: If we're using vector type, the pointer returned here
// is only valid if the tree is only added to in DFS order
//
// Open to suggestions about how to do that better.
FunctionTree* add(JSContext* cx) {
if (!children_.emplaceBack(cx)) {
return nullptr;
}
return &children_.back();
}
void reset() {
funbox_ = nullptr;
children_.clear();
}
FunctionBox* funbox() { return funbox_; }
void setFunctionBox(FunctionBox* node) { funbox_ = node; }
typedef bool (*FunctionTreeVisitorFunction)(ParserBase*, FunctionTree*);
bool visitRecursively(JSContext* cx, ParserBase* parser,
FunctionTreeVisitorFunction func) {
if (!CheckRecursionLimit(cx)) {
return false;
}
for (auto& child : children_) {
if (!child.visitRecursively(cx, parser, func)) {
return false;
}
}
return func(parser, this);
}
void dump(JSContext* cx) { dump(cx, *this, 1); }
private:
static void dump(JSContext* cx, FunctionTree& node, int indent);
};
// Owner of a function tree
//
// The holder mode can be eager or deferred:
//
// - In Eager mode, deferred items happens right away and the tree is not
// constructed.
// - In Deferred mode, deferred items happens only when publishDeferredItems
// is called.
//
// Note: Function trees point to function boxes, which only have the lifetime of
// the BytecodeCompiler, so exercise caution when holding onto a
// holder.
class FunctionTreeHolder {
public:
enum Mode { Eager, Deferred };
private:
FunctionTree treeRoot_;
FunctionTree* currentParent_;
Mode mode_;
public:
explicit FunctionTreeHolder(JSContext* cx, Mode mode = Mode::Eager)
: treeRoot_(cx), currentParent_(&treeRoot_), mode_(mode) {}
FunctionTree* getFunctionTree() { return &treeRoot_; }
FunctionTree* getCurrentParent() { return currentParent_; }
void setCurrentParent(FunctionTree* parent) { currentParent_ = parent; }
bool isEager() { return mode_ == Mode::Eager; }
bool isDeferred() { return mode_ == Mode::Deferred; }
// When a parse has failed, we need to reset the root of the
// function tree as we don't want a reparse to have old entries.
void resetFunctionTree() {
treeRoot_.reset();
currentParent_ = &treeRoot_;
}
};
class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
public ErrorReportMixin {
using Base = ErrorReportMixin;