[preparser] Adapted the PreParser to use ThreadedLists
PreParser types, e.g., PreParserExpression, PreParserList, PreParserFormalParameter. This also enhances ThreadedLists to be used on the same class more than once. Bug: v8:7926 Change-Id: Ied204120e5d12ab1f1c4192f6b3c05971a12683b Reviewed-on: https://chromium-review.googlesource.com/1199262 Commit-Queue: Florian Sattler <sattlerf@google.com> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#55584}
This commit is contained in:
parent
4e20a62a95
commit
00566ed460
@ -397,6 +397,7 @@ class Declaration : public AstNode {
|
||||
Declaration** next() { return &next_; }
|
||||
Declaration* next_;
|
||||
friend List;
|
||||
friend ThreadedListTraits<Declaration>;
|
||||
};
|
||||
|
||||
class VariableDeclaration : public Declaration {
|
||||
@ -1581,6 +1582,14 @@ class VariableProxy final : public Expression {
|
||||
void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; }
|
||||
VariableProxy* next_unresolved() { return next_unresolved_; }
|
||||
|
||||
// Provides an access type for the ThreadedList used by the PreParsers
|
||||
// expressions, lists, and formal parameters.
|
||||
struct PreParserNext {
|
||||
static VariableProxy** next(VariableProxy* t) {
|
||||
return t->pre_parser_expr_next();
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
friend class AstNodeFactory;
|
||||
|
||||
@ -1590,7 +1599,8 @@ class VariableProxy final : public Expression {
|
||||
int start_position)
|
||||
: Expression(start_position, kVariableProxy),
|
||||
raw_name_(name),
|
||||
next_unresolved_(nullptr) {
|
||||
next_unresolved_(nullptr),
|
||||
pre_parser_expr_next_(nullptr) {
|
||||
bit_field_ |= IsThisField::encode(variable_kind == THIS_VARIABLE) |
|
||||
IsAssignedField::encode(false) |
|
||||
IsResolvedField::encode(false) |
|
||||
@ -1614,8 +1624,10 @@ class VariableProxy final : public Expression {
|
||||
Variable* var_; // if is_resolved_
|
||||
};
|
||||
VariableProxy* next_unresolved_;
|
||||
};
|
||||
|
||||
VariableProxy** pre_parser_expr_next() { return &pre_parser_expr_next_; }
|
||||
VariableProxy* pre_parser_expr_next_;
|
||||
};
|
||||
|
||||
// Left-hand side can only be a property, a global or a (parameter or local)
|
||||
// slot.
|
||||
|
@ -215,6 +215,7 @@ class Variable final : public ZoneObject {
|
||||
ForceHoleInitializationField::kNext, 1> {};
|
||||
Variable** next() { return &next_; }
|
||||
friend List;
|
||||
friend ThreadedListTraits<Variable>;
|
||||
};
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -86,16 +86,18 @@ class PreParserIdentifier {
|
||||
friend class PreParserFactory;
|
||||
};
|
||||
|
||||
|
||||
class PreParserExpression {
|
||||
public:
|
||||
using VariableZoneThreadedListType =
|
||||
ZoneThreadedList<VariableProxy, VariableProxy::PreParserNext>;
|
||||
|
||||
PreParserExpression()
|
||||
: code_(TypeField::encode(kNull)), variables_(nullptr) {}
|
||||
|
||||
static PreParserExpression Null() { return PreParserExpression(); }
|
||||
|
||||
static PreParserExpression Default(
|
||||
ZonePtrList<VariableProxy>* variables = nullptr) {
|
||||
VariableZoneThreadedListType* variables = nullptr) {
|
||||
return PreParserExpression(TypeField::encode(kExpression), variables);
|
||||
}
|
||||
|
||||
@ -124,9 +126,7 @@ class PreParserExpression {
|
||||
right.variables_);
|
||||
}
|
||||
if (right.variables_ != nullptr) {
|
||||
for (auto variable : *right.variables_) {
|
||||
left.variables_->Add(variable, zone);
|
||||
}
|
||||
left.variables_->Append(right.variables_);
|
||||
}
|
||||
return PreParserExpression(TypeField::encode(kExpression),
|
||||
left.variables_);
|
||||
@ -134,7 +134,8 @@ class PreParserExpression {
|
||||
return PreParserExpression(TypeField::encode(kExpression));
|
||||
}
|
||||
|
||||
static PreParserExpression Assignment(ZonePtrList<VariableProxy>* variables) {
|
||||
static PreParserExpression Assignment(
|
||||
VariableZoneThreadedListType* variables) {
|
||||
return PreParserExpression(TypeField::encode(kExpression) |
|
||||
ExpressionTypeField::encode(kAssignment),
|
||||
variables);
|
||||
@ -145,13 +146,13 @@ class PreParserExpression {
|
||||
}
|
||||
|
||||
static PreParserExpression ObjectLiteral(
|
||||
ZonePtrList<VariableProxy>* variables) {
|
||||
VariableZoneThreadedListType* variables) {
|
||||
return PreParserExpression(TypeField::encode(kObjectLiteralExpression),
|
||||
variables);
|
||||
}
|
||||
|
||||
static PreParserExpression ArrayLiteral(
|
||||
ZonePtrList<VariableProxy>* variables) {
|
||||
VariableZoneThreadedListType* variables) {
|
||||
return PreParserExpression(TypeField::encode(kArrayLiteralExpression),
|
||||
variables);
|
||||
}
|
||||
@ -170,7 +171,7 @@ class PreParserExpression {
|
||||
IsUseAsmField::encode(true));
|
||||
}
|
||||
|
||||
static PreParserExpression This(ZonePtrList<VariableProxy>* variables) {
|
||||
static PreParserExpression This(VariableZoneThreadedListType* variables) {
|
||||
return PreParserExpression(TypeField::encode(kExpression) |
|
||||
ExpressionTypeField::encode(kThisExpression),
|
||||
variables);
|
||||
@ -335,7 +336,7 @@ class PreParserExpression {
|
||||
if (variables_ != nullptr) {
|
||||
DCHECK(IsIdentifier());
|
||||
DCHECK(AsIdentifier().IsPrivateName());
|
||||
DCHECK_EQ(1, variables_->length());
|
||||
DCHECK_EQ(1, variables_->LengthForTest());
|
||||
variables_->first()->set_is_private_field();
|
||||
}
|
||||
}
|
||||
@ -373,8 +374,9 @@ class PreParserExpression {
|
||||
kAssignment
|
||||
};
|
||||
|
||||
explicit PreParserExpression(uint32_t expression_code,
|
||||
ZonePtrList<VariableProxy>* variables = nullptr)
|
||||
explicit PreParserExpression(
|
||||
uint32_t expression_code,
|
||||
VariableZoneThreadedListType* variables = nullptr)
|
||||
: code_(expression_code), variables_(variables) {}
|
||||
|
||||
void AddVariable(VariableProxy* variable, Zone* zone) {
|
||||
@ -382,9 +384,9 @@ class PreParserExpression {
|
||||
return;
|
||||
}
|
||||
if (variables_ == nullptr) {
|
||||
variables_ = new (zone) ZonePtrList<VariableProxy>(1, zone);
|
||||
variables_ = new (zone) VariableZoneThreadedListType();
|
||||
}
|
||||
variables_->Add(variable, zone);
|
||||
variables_->Add(variable);
|
||||
}
|
||||
|
||||
// The first three bits are for the Type.
|
||||
@ -409,7 +411,7 @@ class PreParserExpression {
|
||||
uint32_t code_;
|
||||
// If the PreParser is used in the variable tracking mode, PreParserExpression
|
||||
// accumulates variables in that expression.
|
||||
ZonePtrList<VariableProxy>* variables_;
|
||||
VariableZoneThreadedListType* variables_;
|
||||
|
||||
friend class PreParser;
|
||||
friend class PreParserFactory;
|
||||
@ -423,6 +425,9 @@ class PreParserExpression {
|
||||
// build lists of variables though.
|
||||
template <typename T>
|
||||
class PreParserList {
|
||||
using VariableZoneThreadedListType =
|
||||
ZoneThreadedList<VariableProxy, VariableProxy::PreParserNext>;
|
||||
|
||||
public:
|
||||
// These functions make list->Add(some_expression) work (and do nothing).
|
||||
PreParserList() : length_(0), variables_(nullptr) {}
|
||||
@ -436,7 +441,8 @@ class PreParserList {
|
||||
private:
|
||||
explicit PreParserList(int n) : length_(n), variables_(nullptr) {}
|
||||
int length_;
|
||||
ZonePtrList<VariableProxy>* variables_;
|
||||
|
||||
VariableZoneThreadedListType* variables_;
|
||||
|
||||
friend class PreParser;
|
||||
friend class PreParserFactory;
|
||||
@ -449,11 +455,9 @@ inline void PreParserList<PreParserExpression>::Add(
|
||||
DCHECK(FLAG_lazy_inner_functions);
|
||||
DCHECK_NOT_NULL(zone);
|
||||
if (variables_ == nullptr) {
|
||||
variables_ = new (zone) ZonePtrList<VariableProxy>(1, zone);
|
||||
}
|
||||
for (auto identifier : (*expression.variables_)) {
|
||||
variables_->Add(identifier, zone);
|
||||
variables_ = new (zone) VariableZoneThreadedListType();
|
||||
}
|
||||
variables_->Append(expression.variables_);
|
||||
}
|
||||
++length_;
|
||||
}
|
||||
@ -851,12 +855,15 @@ class PreParserFactory {
|
||||
|
||||
struct PreParserFormalParameters : FormalParametersBase {
|
||||
struct Parameter : public ZoneObject {
|
||||
Parameter(ZonePtrList<VariableProxy>* variables, bool is_rest)
|
||||
using VariableZoneThreadedListType =
|
||||
ZoneThreadedList<VariableProxy, VariableProxy::PreParserNext>;
|
||||
|
||||
Parameter(VariableZoneThreadedListType* variables, bool is_rest)
|
||||
: variables_(variables), is_rest(is_rest) {}
|
||||
Parameter** next() { return &next_parameter; }
|
||||
Parameter* const* next() const { return &next_parameter; }
|
||||
|
||||
ZonePtrList<VariableProxy>* variables_;
|
||||
VariableZoneThreadedListType* variables_;
|
||||
Parameter* next_parameter = nullptr;
|
||||
bool is_rest : 1;
|
||||
};
|
||||
@ -1561,14 +1568,15 @@ class PreParser : public ParserBase<PreParser> {
|
||||
}
|
||||
|
||||
V8_INLINE PreParserExpression ThisExpression(int pos = kNoSourcePosition) {
|
||||
ZonePtrList<VariableProxy>* variables = nullptr;
|
||||
PreParserExpression::VariableZoneThreadedListType* variables = nullptr;
|
||||
if (track_unresolved_variables_) {
|
||||
VariableProxy* proxy = scope()->NewUnresolved(
|
||||
factory()->ast_node_factory(), ast_value_factory()->this_string(),
|
||||
pos, THIS_VARIABLE);
|
||||
|
||||
variables = new (zone()) ZonePtrList<VariableProxy>(1, zone());
|
||||
variables->Add(proxy, zone());
|
||||
variables =
|
||||
new (zone()) PreParserExpression::VariableZoneThreadedListType();
|
||||
variables->Add(proxy);
|
||||
}
|
||||
return PreParserExpression::This(variables);
|
||||
}
|
||||
@ -1681,7 +1689,7 @@ class PreParser : public ParserBase<PreParser> {
|
||||
DCHECK(FLAG_lazy_inner_functions);
|
||||
for (auto parameter : parameters) {
|
||||
DCHECK_IMPLIES(is_simple, parameter->variables_ != nullptr);
|
||||
DCHECK_IMPLIES(is_simple, parameter->variables_->length() == 1);
|
||||
DCHECK_IMPLIES(is_simple, parameter->variables_->LengthForTest() == 1);
|
||||
// Make sure each parameter is added only once even if it's a
|
||||
// destructuring parameter which contains multiple names.
|
||||
bool add_parameter = true;
|
||||
|
49
src/utils.h
49
src/utils.h
@ -1622,18 +1622,30 @@ static inline V ByteReverse(V value) {
|
||||
}
|
||||
}
|
||||
|
||||
// Represents a linked list that threads through the nodes in the linked list.
|
||||
// Entries in the list are pointers to nodes. The nodes need to have a T**
|
||||
// next() method that returns the location where the next value is stored.
|
||||
template <typename T>
|
||||
class ThreadedList final {
|
||||
struct ThreadedListTraits {
|
||||
static T** next(T* t) { return t->next(); }
|
||||
};
|
||||
|
||||
// Represents a linked list that threads through the nodes in the linked list.
|
||||
// Entries in the list are pointers to nodes. By default nodes need to have a
|
||||
// T** next() method that returns the location where the next value is stored.
|
||||
// The default can be overwritten by providing a ThreadedTraits class.
|
||||
template <typename T, typename BaseClass,
|
||||
typename TLTraits = ThreadedListTraits<T>>
|
||||
class ThreadedListBase final : public BaseClass {
|
||||
public:
|
||||
ThreadedList() : head_(nullptr), tail_(&head_) {}
|
||||
ThreadedListBase() : head_(nullptr), tail_(&head_) {}
|
||||
void Add(T* v) {
|
||||
DCHECK_NULL(*tail_);
|
||||
DCHECK_NULL(*v->next());
|
||||
DCHECK_NULL(*TLTraits::next(v));
|
||||
*tail_ = v;
|
||||
tail_ = v->next();
|
||||
tail_ = TLTraits::next(v);
|
||||
}
|
||||
|
||||
void Append(ThreadedListBase* list) {
|
||||
*tail_ = list->head_;
|
||||
tail_ = list->tail_;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
@ -1644,15 +1656,15 @@ class ThreadedList final {
|
||||
class Iterator final {
|
||||
public:
|
||||
Iterator& operator++() {
|
||||
entry_ = (*entry_)->next();
|
||||
entry_ = TLTraits::next(*entry_);
|
||||
return *this;
|
||||
}
|
||||
bool operator!=(const Iterator& other) { return entry_ != other.entry_; }
|
||||
T* operator*() { return *entry_; }
|
||||
T* operator->() { return *entry_; }
|
||||
Iterator& operator=(T* entry) {
|
||||
T* next = *(*entry_)->next();
|
||||
*entry->next() = next;
|
||||
T* next = *TLTraits::next(*entry_);
|
||||
*TLTraits::next(entry) = next;
|
||||
*entry_ = entry;
|
||||
return *this;
|
||||
}
|
||||
@ -1662,13 +1674,13 @@ class ThreadedList final {
|
||||
|
||||
T** entry_;
|
||||
|
||||
friend class ThreadedList;
|
||||
friend class ThreadedListBase;
|
||||
};
|
||||
|
||||
class ConstIterator final {
|
||||
public:
|
||||
ConstIterator& operator++() {
|
||||
entry_ = (*entry_)->next();
|
||||
entry_ = TLTraits::next(*entry_);
|
||||
return *this;
|
||||
}
|
||||
bool operator!=(const ConstIterator& other) {
|
||||
@ -1681,7 +1693,7 @@ class ThreadedList final {
|
||||
|
||||
T* const* entry_;
|
||||
|
||||
friend class ThreadedList;
|
||||
friend class ThreadedListBase;
|
||||
};
|
||||
|
||||
Iterator begin() { return Iterator(&head_); }
|
||||
@ -1695,7 +1707,7 @@ class ThreadedList final {
|
||||
*tail_ = nullptr;
|
||||
}
|
||||
|
||||
void MoveTail(ThreadedList<T>* parent, Iterator location) {
|
||||
void MoveTail(ThreadedListBase<T, BaseClass>* parent, Iterator location) {
|
||||
if (parent->end() != location) {
|
||||
DCHECK_NULL(*tail_);
|
||||
*tail_ = *location;
|
||||
@ -1706,6 +1718,8 @@ class ThreadedList final {
|
||||
|
||||
bool is_empty() const { return head_ == nullptr; }
|
||||
|
||||
T* first() { return head_; }
|
||||
|
||||
// Slow. For testing purposes.
|
||||
int LengthForTest() {
|
||||
int result = 0;
|
||||
@ -1721,9 +1735,14 @@ class ThreadedList final {
|
||||
private:
|
||||
T* head_;
|
||||
T** tail_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadedList);
|
||||
DISALLOW_COPY_AND_ASSIGN(ThreadedListBase);
|
||||
};
|
||||
|
||||
struct EmptyBase {};
|
||||
|
||||
template <typename T, typename TLTraits = ThreadedListTraits<T>>
|
||||
using ThreadedList = ThreadedListBase<T, EmptyBase, TLTraits>;
|
||||
|
||||
V8_EXPORT_PRIVATE bool PassesFilter(Vector<const char> name,
|
||||
Vector<const char> filter);
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/base/logging.h"
|
||||
#include "src/globals.h"
|
||||
#include "src/splay-tree.h"
|
||||
#include "src/utils.h"
|
||||
#include "src/zone/accounting-allocator.h"
|
||||
|
||||
#ifndef ZONE_NAME
|
||||
@ -295,6 +296,11 @@ class ZoneList final {
|
||||
template <typename T>
|
||||
using ZonePtrList = ZoneList<T*>;
|
||||
|
||||
// ZoneThreadedList is a special variant of the ThreadedList that can be put
|
||||
// into a Zone.
|
||||
template <typename T, typename TLTraits = ThreadedListTraits<T>>
|
||||
using ZoneThreadedList = ThreadedListBase<T, ZoneObject, TLTraits>;
|
||||
|
||||
// A zone splay tree. The config type parameter encapsulates the
|
||||
// different configurations of a concrete splay tree (see splay-tree.h).
|
||||
// The tree itself and all its elements are allocated in the Zone.
|
||||
|
Loading…
Reference in New Issue
Block a user