Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(632)

Unified Diff: src/parsing/expression-classifier.h

Issue 1708193003: Reduce the memory footprint of expression classifiers (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Introduce implementation-limit error (too many non-pattern rewrites) Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/messages.h ('k') | src/parsing/parser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parsing/expression-classifier.h
diff --git a/src/parsing/expression-classifier.h b/src/parsing/expression-classifier.h
index 3f70ed82d060965cce15739cb5f3cada9f204354..a27dcb00ce4773026217c8b2d1cff67f77100758 100644
--- a/src/parsing/expression-classifier.h
+++ b/src/parsing/expression-classifier.h
@@ -13,35 +13,55 @@ namespace v8 {
namespace internal {
+#define ERROR_CODES(T) \
+ T(ExpressionProduction, 0) \
+ T(FormalParameterInitializerProduction, 1) \
+ T(BindingPatternProduction, 2) \
+ T(AssignmentPatternProduction, 3) \
+ T(DistinctFormalParametersProduction, 4) \
+ T(StrictModeFormalParametersProduction, 5) \
+ T(ArrowFormalParametersProduction, 6) \
+ T(LetPatternProduction, 7) \
+ T(CoverInitializedNameProduction, 8) \
+ T(TailCallExpressionProduction, 9) \
+ T(AsyncArrowFormalParametersProduction, 10) \
+ T(AsyncBindingPatternProduction, 11)
+
+
template <typename Traits>
class ExpressionClassifier {
public:
+ enum ErrorKind : unsigned {
+#define DEFINE_ERROR_KIND(NAME, CODE) k##NAME = CODE,
+ ERROR_CODES(DEFINE_ERROR_KIND)
+#undef DEFINE_ERROR_KIND
+ kUnusedError = 15 // Larger than error codes; should fit in 4 bits
+ };
+
struct Error {
- Error()
+ V8_INLINE Error()
: location(Scanner::Location::invalid()),
message(MessageTemplate::kNone),
+ kind(kUnusedError),
type(kSyntaxError),
arg(nullptr) {}
+ V8_INLINE explicit Error(Scanner::Location loc,
+ MessageTemplate::Template msg, ErrorKind k,
+ const char* a = nullptr,
+ ParseErrorType t = kSyntaxError)
+ : location(loc), message(msg), kind(k), type(t), arg(a) {}
Scanner::Location location;
- MessageTemplate::Template message : 30;
+ MessageTemplate::Template message : 26;
+ unsigned kind : 4;
ParseErrorType type : 2;
const char* arg;
};
- enum TargetProduction {
- ExpressionProduction = 1 << 0,
- FormalParameterInitializerProduction = 1 << 1,
- BindingPatternProduction = 1 << 2,
- AssignmentPatternProduction = 1 << 3,
- DistinctFormalParametersProduction = 1 << 4,
- StrictModeFormalParametersProduction = 1 << 5,
- ArrowFormalParametersProduction = 1 << 6,
- LetPatternProduction = 1 << 7,
- CoverInitializedNameProduction = 1 << 8,
- TailCallExpressionProduction = 1 << 9,
- AsyncArrowFormalParametersProduction = 1 << 10,
- AsyncBindingPatternProduction = 1 << 11,
+ enum TargetProduction : unsigned {
+#define DEFINE_PRODUCTION(NAME, CODE) NAME = 1 << CODE,
+ ERROR_CODES(DEFINE_PRODUCTION)
+#undef DEFINE_PRODUCTION
ExpressionProductions =
(ExpressionProduction | FormalParameterInitializerProduction |
@@ -58,63 +78,75 @@ class ExpressionClassifier {
AsyncArrowFormalParametersProduction | AsyncBindingPatternProduction)
};
- enum FunctionProperties { NonSimpleParameter = 1 << 0 };
+ enum FunctionProperties : unsigned {
+ NonSimpleParameter = 1 << 0
+ };
explicit ExpressionClassifier(const Traits* t)
: zone_(t->zone()),
non_patterns_to_rewrite_(t->GetNonPatternList()),
+ reported_errors_(t->GetReportedErrorList()),
+ duplicate_finder_(nullptr),
invalid_productions_(0),
- function_properties_(0),
- duplicate_finder_(nullptr) {
+ function_properties_(0) {
+ reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
non_pattern_begin_ = non_patterns_to_rewrite_->length();
}
ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder)
: zone_(t->zone()),
non_patterns_to_rewrite_(t->GetNonPatternList()),
+ reported_errors_(t->GetReportedErrorList()),
+ duplicate_finder_(duplicate_finder),
invalid_productions_(0),
- function_properties_(0),
- duplicate_finder_(duplicate_finder) {
+ function_properties_(0) {
+ reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
non_pattern_begin_ = non_patterns_to_rewrite_->length();
}
~ExpressionClassifier() { Discard(); }
- bool is_valid(unsigned productions) const {
+ V8_INLINE bool is_valid(unsigned productions) const {
return (invalid_productions_ & productions) == 0;
}
- DuplicateFinder* duplicate_finder() const { return duplicate_finder_; }
+ V8_INLINE DuplicateFinder* duplicate_finder() const {
+ return duplicate_finder_;
+ }
- bool is_valid_expression() const { return is_valid(ExpressionProduction); }
+ V8_INLINE bool is_valid_expression() const {
+ return is_valid(ExpressionProduction);
+ }
- bool is_valid_formal_parameter_initializer() const {
+ V8_INLINE bool is_valid_formal_parameter_initializer() const {
return is_valid(FormalParameterInitializerProduction);
}
- bool is_valid_binding_pattern() const {
+ V8_INLINE bool is_valid_binding_pattern() const {
return is_valid(BindingPatternProduction);
}
- bool is_valid_assignment_pattern() const {
+ V8_INLINE bool is_valid_assignment_pattern() const {
return is_valid(AssignmentPatternProduction);
}
- bool is_valid_arrow_formal_parameters() const {
+ V8_INLINE bool is_valid_arrow_formal_parameters() const {
return is_valid(ArrowFormalParametersProduction);
}
- bool is_valid_formal_parameter_list_without_duplicates() const {
+ V8_INLINE bool is_valid_formal_parameter_list_without_duplicates() const {
return is_valid(DistinctFormalParametersProduction);
}
// Note: callers should also check
// is_valid_formal_parameter_list_without_duplicates().
- bool is_valid_strict_mode_formal_parameters() const {
+ V8_INLINE bool is_valid_strict_mode_formal_parameters() const {
return is_valid(StrictModeFormalParametersProduction);
}
- bool is_valid_let_pattern() const { return is_valid(LetPatternProduction); }
+ V8_INLINE bool is_valid_let_pattern() const {
+ return is_valid(LetPatternProduction);
+ }
bool is_valid_async_arrow_formal_parameters() const {
return is_valid(AsyncArrowFormalParametersProduction);
@@ -124,58 +156,65 @@ class ExpressionClassifier {
return is_valid(AsyncBindingPatternProduction);
}
- const Error& expression_error() const { return expression_error_; }
+ V8_INLINE const Error& expression_error() const {
+ return reported_error(kExpressionProduction);
+ }
- const Error& formal_parameter_initializer_error() const {
- return formal_parameter_initializer_error_;
+ V8_INLINE const Error& formal_parameter_initializer_error() const {
+ return reported_error(kFormalParameterInitializerProduction);
}
- const Error& binding_pattern_error() const { return binding_pattern_error_; }
+ V8_INLINE const Error& binding_pattern_error() const {
+ return reported_error(kBindingPatternProduction);
+ }
- const Error& assignment_pattern_error() const {
- return assignment_pattern_error_;
+ V8_INLINE const Error& assignment_pattern_error() const {
+ return reported_error(kAssignmentPatternProduction);
}
- const Error& arrow_formal_parameters_error() const {
- return arrow_formal_parameters_error_;
+ V8_INLINE const Error& arrow_formal_parameters_error() const {
+ return reported_error(kArrowFormalParametersProduction);
}
- const Error& duplicate_formal_parameter_error() const {
- return duplicate_formal_parameter_error_;
+ V8_INLINE const Error& duplicate_formal_parameter_error() const {
+ return reported_error(kDistinctFormalParametersProduction);
}
- const Error& strict_mode_formal_parameter_error() const {
- return strict_mode_formal_parameter_error_;
+ V8_INLINE const Error& strict_mode_formal_parameter_error() const {
+ return reported_error(kStrictModeFormalParametersProduction);
}
- const Error& let_pattern_error() const { return let_pattern_error_; }
+ V8_INLINE const Error& let_pattern_error() const {
+ return reported_error(kLetPatternProduction);
+ }
- bool has_cover_initialized_name() const {
+ V8_INLINE bool has_cover_initialized_name() const {
return !is_valid(CoverInitializedNameProduction);
}
- const Error& cover_initialized_name_error() const {
- return cover_initialized_name_error_;
+
+ V8_INLINE const Error& cover_initialized_name_error() const {
+ return reported_error(kCoverInitializedNameProduction);
}
- bool has_tail_call_expression() const {
+ V8_INLINE bool has_tail_call_expression() const {
return !is_valid(TailCallExpressionProduction);
}
- const Error& tail_call_expression_error() const {
- return tail_call_expression_error_;
+ V8_INLINE const Error& tail_call_expression_error() const {
+ return reported_error(kTailCallExpressionProduction);
}
- const Error& async_arrow_formal_parameters_error() const {
- return async_arrow_formal_parameters_error_;
+ V8_INLINE const Error& async_arrow_formal_parameters_error() const {
+ return reported_error(kAsyncArrowFormalParametersProduction);
}
- const Error& async_binding_pattern_error() const {
- return async_binding_pattern_error_;
+ V8_INLINE const Error& async_binding_pattern_error() const {
+ return reported_error(kAsyncBindingPatternProduction);
}
- bool is_simple_parameter_list() const {
+ V8_INLINE bool is_simple_parameter_list() const {
return !(function_properties_ & NonSimpleParameter);
}
- void RecordNonSimpleParameter() {
+ V8_INLINE void RecordNonSimpleParameter() {
function_properties_ |= NonSimpleParameter;
}
@@ -184,9 +223,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_expression()) return;
invalid_productions_ |= ExpressionProduction;
- expression_error_.location = loc;
- expression_error_.message = message;
- expression_error_.arg = arg;
+ Add(Error(loc, message, kExpressionProduction, arg));
}
void RecordExpressionError(const Scanner::Location& loc,
@@ -194,10 +231,7 @@ class ExpressionClassifier {
ParseErrorType type, const char* arg = nullptr) {
if (!is_valid_expression()) return;
invalid_productions_ |= ExpressionProduction;
- expression_error_.location = loc;
- expression_error_.message = message;
- expression_error_.arg = arg;
- expression_error_.type = type;
+ Add(Error(loc, message, kExpressionProduction, arg, type));
}
void RecordFormalParameterInitializerError(const Scanner::Location& loc,
@@ -205,9 +239,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_formal_parameter_initializer()) return;
invalid_productions_ |= FormalParameterInitializerProduction;
- formal_parameter_initializer_error_.location = loc;
- formal_parameter_initializer_error_.message = message;
- formal_parameter_initializer_error_.arg = arg;
+ Add(Error(loc, message, kFormalParameterInitializerProduction, arg));
}
void RecordBindingPatternError(const Scanner::Location& loc,
@@ -215,9 +247,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_binding_pattern()) return;
invalid_productions_ |= BindingPatternProduction;
- binding_pattern_error_.location = loc;
- binding_pattern_error_.message = message;
- binding_pattern_error_.arg = arg;
+ Add(Error(loc, message, kBindingPatternProduction, arg));
}
void RecordAssignmentPatternError(const Scanner::Location& loc,
@@ -225,9 +255,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_assignment_pattern()) return;
invalid_productions_ |= AssignmentPatternProduction;
- assignment_pattern_error_.location = loc;
- assignment_pattern_error_.message = message;
- assignment_pattern_error_.arg = arg;
+ Add(Error(loc, message, kAssignmentPatternProduction, arg));
}
void RecordPatternError(const Scanner::Location& loc,
@@ -242,9 +270,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_arrow_formal_parameters()) return;
invalid_productions_ |= ArrowFormalParametersProduction;
- arrow_formal_parameters_error_.location = loc;
- arrow_formal_parameters_error_.message = message;
- arrow_formal_parameters_error_.arg = arg;
+ Add(Error(loc, message, kArrowFormalParametersProduction, arg));
}
void RecordAsyncArrowFormalParametersError(const Scanner::Location& loc,
@@ -252,9 +278,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_async_arrow_formal_parameters()) return;
invalid_productions_ |= AsyncArrowFormalParametersProduction;
- async_arrow_formal_parameters_error_.location = loc;
- async_arrow_formal_parameters_error_.message = message;
- async_arrow_formal_parameters_error_.arg = arg;
+ Add(Error(loc, message, kAsyncArrowFormalParametersProduction, arg));
}
void RecordAsyncBindingPatternError(const Scanner::Location& loc,
@@ -262,17 +286,14 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_async_binding_pattern()) return;
invalid_productions_ |= AsyncBindingPatternProduction;
- async_binding_pattern_error_.location = loc;
- async_binding_pattern_error_.message = message;
- async_binding_pattern_error_.arg = arg;
+ Add(Error(loc, message, kAsyncBindingPatternProduction, arg));
}
void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
if (!is_valid_formal_parameter_list_without_duplicates()) return;
invalid_productions_ |= DistinctFormalParametersProduction;
- duplicate_formal_parameter_error_.location = loc;
- duplicate_formal_parameter_error_.message = MessageTemplate::kParamDupe;
- duplicate_formal_parameter_error_.arg = nullptr;
+ Add(Error(loc, MessageTemplate::kParamDupe,
+ kDistinctFormalParametersProduction));
}
// Record a binding that would be invalid in strict mode. Confusingly this
@@ -283,9 +304,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_strict_mode_formal_parameters()) return;
invalid_productions_ |= StrictModeFormalParametersProduction;
- strict_mode_formal_parameter_error_.location = loc;
- strict_mode_formal_parameter_error_.message = message;
- strict_mode_formal_parameter_error_.arg = arg;
+ Add(Error(loc, message, kStrictModeFormalParametersProduction, arg));
}
void RecordLetPatternError(const Scanner::Location& loc,
@@ -293,9 +312,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (!is_valid_let_pattern()) return;
invalid_productions_ |= LetPatternProduction;
- let_pattern_error_.location = loc;
- let_pattern_error_.message = message;
- let_pattern_error_.arg = arg;
+ Add(Error(loc, message, kLetPatternProduction, arg));
}
void RecordCoverInitializedNameError(const Scanner::Location& loc,
@@ -303,9 +320,7 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (has_cover_initialized_name()) return;
invalid_productions_ |= CoverInitializedNameProduction;
- cover_initialized_name_error_.location = loc;
- cover_initialized_name_error_.message = message;
- cover_initialized_name_error_.arg = arg;
+ Add(Error(loc, message, kCoverInitializedNameProduction, arg));
}
void RecordTailCallExpressionError(const Scanner::Location& loc,
@@ -313,83 +328,102 @@ class ExpressionClassifier {
const char* arg = nullptr) {
if (has_tail_call_expression()) return;
invalid_productions_ |= TailCallExpressionProduction;
- tail_call_expression_error_.location = loc;
- tail_call_expression_error_.message = message;
- tail_call_expression_error_.arg = arg;
+ Add(Error(loc, message, kTailCallExpressionProduction, arg));
}
void ForgiveCoverInitializedNameError() {
+ if (!(invalid_productions_ & CoverInitializedNameProduction)) return;
+ Error& e = reported_error(kCoverInitializedNameProduction);
+ e.kind = kUnusedError;
invalid_productions_ &= ~CoverInitializedNameProduction;
- cover_initialized_name_error_ = Error();
}
void ForgiveAssignmentPatternError() {
+ if (!(invalid_productions_ & AssignmentPatternProduction)) return;
+ Error& e = reported_error(kAssignmentPatternProduction);
+ e.kind = kUnusedError;
invalid_productions_ &= ~AssignmentPatternProduction;
- assignment_pattern_error_ = Error();
}
void Accumulate(ExpressionClassifier* inner,
unsigned productions = StandardProductions,
bool merge_non_patterns = true) {
+ DCHECK_EQ(inner->reported_errors_, reported_errors_);
+ DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_);
+ DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length());
if (merge_non_patterns) MergeNonPatterns(inner);
// Propagate errors from inner, but don't overwrite already recorded
// errors.
unsigned non_arrow_inner_invalid_productions =
inner->invalid_productions_ & ~ArrowFormalParametersProduction;
- if (non_arrow_inner_invalid_productions == 0) return;
- unsigned non_arrow_productions =
- productions & ~ArrowFormalParametersProduction;
- unsigned errors =
- non_arrow_productions & non_arrow_inner_invalid_productions;
- errors &= ~invalid_productions_;
- if (errors != 0) {
- invalid_productions_ |= errors;
- if (errors & ExpressionProduction)
- expression_error_ = inner->expression_error_;
- if (errors & FormalParameterInitializerProduction)
- formal_parameter_initializer_error_ =
- inner->formal_parameter_initializer_error_;
- if (errors & BindingPatternProduction)
- binding_pattern_error_ = inner->binding_pattern_error_;
- if (errors & AssignmentPatternProduction)
- assignment_pattern_error_ = inner->assignment_pattern_error_;
- if (errors & DistinctFormalParametersProduction)
- duplicate_formal_parameter_error_ =
- inner->duplicate_formal_parameter_error_;
- if (errors & StrictModeFormalParametersProduction)
- strict_mode_formal_parameter_error_ =
- inner->strict_mode_formal_parameter_error_;
- if (errors & LetPatternProduction)
- let_pattern_error_ = inner->let_pattern_error_;
- if (errors & CoverInitializedNameProduction)
- cover_initialized_name_error_ = inner->cover_initialized_name_error_;
- if (errors & TailCallExpressionProduction)
- tail_call_expression_error_ = inner->tail_call_expression_error_;
- if (errors & AsyncArrowFormalParametersProduction)
- async_arrow_formal_parameters_error_ =
- inner->async_arrow_formal_parameters_error_;
- if (errors & AsyncBindingPatternProduction)
- async_binding_pattern_error_ = inner->async_binding_pattern_error_;
- }
-
- // As an exception to the above, the result continues to be a valid arrow
- // formal parameters if the inner expression is a valid binding pattern.
- if (productions & ArrowFormalParametersProduction &&
- is_valid_arrow_formal_parameters()) {
- // Also copy function properties if expecting an arrow function
- // parameter.
- function_properties_ |= inner->function_properties_;
-
- if (!inner->is_valid_binding_pattern()) {
- invalid_productions_ |= ArrowFormalParametersProduction;
- arrow_formal_parameters_error_ = inner->binding_pattern_error_;
+ if (non_arrow_inner_invalid_productions) {
+ unsigned errors = non_arrow_inner_invalid_productions & productions &
+ ~invalid_productions_;
+ // The result will continue to be a valid arrow formal parameters if the
+ // inner expression is a valid binding pattern.
+ bool copy_BP_to_AFP = false;
+ if (productions & ArrowFormalParametersProduction &&
+ is_valid_arrow_formal_parameters()) {
+ // Also copy function properties if expecting an arrow function
+ // parameter.
+ function_properties_ |= inner->function_properties_;
+ if (!inner->is_valid_binding_pattern()) {
+ copy_BP_to_AFP = true;
+ invalid_productions_ |= ArrowFormalParametersProduction;
+ }
+ }
+ // Traverse the list of errors reported by the inner classifier
+ // to copy what's necessary.
+ if (errors != 0 || copy_BP_to_AFP) {
+ invalid_productions_ |= errors;
+ int binding_pattern_index = inner->reported_errors_end_;
+ for (int i = inner->reported_errors_begin_;
+ i < inner->reported_errors_end_; i++) {
+ int k = reported_errors_->at(i).kind;
+ if (errors & (1 << k)) Copy(i);
+ // Check if it's a BP error that has to be copied to an AFP error.
+ if (k == kBindingPatternProduction && copy_BP_to_AFP) {
+ if (reported_errors_end_ <= i) {
+ // If the BP error itself has not already been copied,
+ // copy it now and change it to an AFP error.
+ Copy(i);
+ reported_errors_->at(reported_errors_end_-1).kind =
+ kArrowFormalParametersProduction;
+ } else {
+ // Otherwise, if the BP error was already copied, keep its
+ // position and wait until the end of the traversal.
+ DCHECK_EQ(reported_errors_end_, i+1);
+ binding_pattern_index = i;
+ }
+ }
+ }
+ // Do we still have to copy the BP error to an AFP error?
+ if (binding_pattern_index < inner->reported_errors_end_) {
+ // If there's still unused space in the list of the inner
+ // classifier, copy it there, otherwise add it to the end
+ // of the list.
+ if (reported_errors_end_ < inner->reported_errors_end_)
+ Copy(binding_pattern_index);
+ else
+ Add(reported_errors_->at(binding_pattern_index));
+ reported_errors_->at(reported_errors_end_-1).kind =
+ kArrowFormalParametersProduction;
+ }
}
}
+ reported_errors_->Rewind(reported_errors_end_);
+ inner->reported_errors_begin_ = inner->reported_errors_end_ =
+ reported_errors_end_;
}
V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; }
V8_INLINE void Discard() {
+ if (reported_errors_end_ == reported_errors_->length()) {
+ reported_errors_->Rewind(reported_errors_begin_);
+ reported_errors_end_ = reported_errors_begin_;
+ }
+ DCHECK_EQ(reported_errors_begin_, reported_errors_end_);
DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length());
non_patterns_to_rewrite_->Rewind(non_pattern_begin_);
}
@@ -400,29 +434,70 @@ class ExpressionClassifier {
}
private:
+ V8_INLINE Error& reported_error(ErrorKind kind) const {
+ if (invalid_productions_ & (1 << kind)) {
+ for (int i = reported_errors_begin_; i < reported_errors_end_; i++) {
+ if (reported_errors_->at(i).kind == kind)
+ return reported_errors_->at(i);
+ }
+ UNREACHABLE();
+ }
+ // We should only be looking for an error when we know that one has
+ // been reported. But we're not... So this is to make sure we have
+ // the same behaviour.
+ static Error none;
+ return none;
+ }
+
+ // Adds e to the end of the list of reported errors for this classifier.
+ // It is expected that this classifier is the last one in the stack.
+ V8_INLINE void Add(const Error& e) {
+ DCHECK_EQ(reported_errors_end_, reported_errors_->length());
+ reported_errors_->Add(e, zone_);
+ reported_errors_end_++;
+ }
+
+ // Copies the error at position i of the list of reported errors, so that
+ // it becomes the last error reported for this classifier. Position i
+ // could be either after the existing errors of this classifier (i.e.,
+ // in an inner classifier) or it could be an existing error (in case a
+ // copy is needed).
+ V8_INLINE void Copy(int i) {
+ DCHECK_LE(reported_errors_end_, i);
+ DCHECK_LT(i, reported_errors_->length());
+ if (reported_errors_end_ != i)
+ reported_errors_->at(reported_errors_end_) = reported_errors_->at(i);
+ reported_errors_end_++;
+ }
+
Zone* zone_;
ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_;
- int non_pattern_begin_;
- unsigned invalid_productions_;
- unsigned function_properties_;
- // TODO(ishell): consider using Zone[Hash]Map<TargetProduction, Error>
- // here to consume less stack space during parsing.
- Error expression_error_;
- Error formal_parameter_initializer_error_;
- Error binding_pattern_error_;
- Error assignment_pattern_error_;
- Error arrow_formal_parameters_error_;
- Error duplicate_formal_parameter_error_;
- Error strict_mode_formal_parameter_error_;
- Error let_pattern_error_;
- Error cover_initialized_name_error_;
- Error tail_call_expression_error_;
- Error async_arrow_formal_parameters_error_;
- Error async_binding_pattern_error_;
+ ZoneList<Error>* reported_errors_;
DuplicateFinder* duplicate_finder_;
+ // The uint16_t for non_pattern_begin_ will not be enough in the case,
+ // e.g., of an array literal containing more than 64K inner array
+ // literals with spreads, as in:
+ // var N=65536; eval("var x=[];" + "[" + "[...x],".repeat(N) + "].length");
+ // An implementation limit error in ParserBase::AddNonPatternForRewriting
+ // will be triggered in this case.
+ uint16_t non_pattern_begin_;
+ unsigned invalid_productions_ : 14;
+ unsigned function_properties_ : 2;
+ // The uint16_t for reported_errors_begin_ and reported_errors_end_ will
+ // not be enough in the case of a long series of expressions using nested
+ // classifiers, e.g., a long sequence of assignments, as in:
+ // literals with spreads, as in:
+ // var N=65536; eval("var x;" + "x=".repeat(N) + "42");
+ // This should not be a problem, as such things currently fail with a
+ // stack overflow while parsing.
+ uint16_t reported_errors_begin_;
+ uint16_t reported_errors_end_;
};
+#undef ERROR_CODES
+
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/messages.h ('k') | src/parsing/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698