Index: src/parsing/expression-classifier.h |
diff --git a/src/parsing/expression-classifier.h b/src/parsing/expression-classifier.h |
index fa1a2f97a486895482bcc6e88b851f8331347131..5640d689fbfa09ccc49c6c5a1e23a9b32029446a 100644 |
--- a/src/parsing/expression-classifier.h |
+++ b/src/parsing/expression-classifier.h |
@@ -13,33 +13,53 @@ 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(StrongModeFormalParametersProduction, 6) \ |
caitp (gmail)
2016/02/18 16:50:22
I feel like we could probably just take this oppor
nickie
2016/02/19 08:56:31
I assumed strong mode removal would be an independ
|
+ T(ArrowFormalParametersProduction, 7) \ |
+ T(LetPatternProduction, 8) \ |
+ T(CoverInitializedNameProduction, 9) |
+ |
+ |
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; |
+ ErrorKind 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, |
- StrongModeFormalParametersProduction = 1 << 6, |
- ArrowFormalParametersProduction = 1 << 7, |
- LetPatternProduction = 1 << 8, |
- CoverInitializedNameProduction = 1 << 9, |
+ enum TargetProduction : unsigned { |
+#define DEFINE_PRODUCTION(NAME, CODE) NAME = 1 << CODE, |
+ ERROR_CODES(DEFINE_PRODUCTION) |
+#undef DEFINE_PRODUCTION |
ExpressionProductions = |
(ExpressionProduction | FormalParameterInitializerProduction), |
@@ -54,14 +74,18 @@ class ExpressionClassifier { |
ArrowFormalParametersProduction | CoverInitializedNameProduction) |
}; |
- 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()), |
invalid_productions_(0), |
function_properties_(0), |
+ reported_errors_(t->GetReportedErrorList()), |
duplicate_finder_(nullptr) { |
+ reported_errors_begin_ = reported_errors_end_ = reported_errors_->length(); |
non_pattern_begin_ = non_patterns_to_rewrite_->length(); |
} |
@@ -70,96 +94,111 @@ class ExpressionClassifier { |
non_patterns_to_rewrite_(t->GetNonPatternList()), |
invalid_productions_(0), |
function_properties_(0), |
+ reported_errors_(t->GetReportedErrorList()), |
duplicate_finder_(duplicate_finder) { |
+ 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); |
} |
// Note: callers should also check is_valid_strict_mode_formal_parameters() |
// and is_valid_formal_parameter_list_without_duplicates(). |
- bool is_valid_strong_mode_formal_parameters() const { |
+ V8_INLINE bool is_valid_strong_mode_formal_parameters() const { |
return is_valid(StrongModeFormalParametersProduction); |
} |
- bool is_valid_let_pattern() const { return is_valid(LetPatternProduction); } |
+ V8_INLINE bool is_valid_let_pattern() const { |
+ return is_valid(LetPatternProduction); |
+ } |
- 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 { |
caitp (gmail)
2016/02/18 16:57:47
maybe if you added like a `accessor_name` paramete
nickie
2016/02/19 08:56:31
While the error codes and the bit flags are named
|
+ 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& strong_mode_formal_parameter_error() const { |
- return strong_mode_formal_parameter_error_; |
+ V8_INLINE const Error& strong_mode_formal_parameter_error() const { |
+ return reported_error(kStrongModeFormalParametersProduction); |
} |
- 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 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; |
} |
@@ -168,9 +207,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, |
@@ -178,10 +215,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, |
@@ -189,29 +223,43 @@ 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)); |
+ } |
+ |
+ static Error BindingPatternError(const Scanner::Location& loc, |
+ MessageTemplate::Template message, |
+ const char* arg = nullptr) { |
+ return Error(loc, message, kBindingPatternProduction, arg); |
+ } |
+ |
+ void RecordBindingPatternError(const Error& e) { |
+ if (!is_valid_binding_pattern()) return; |
+ invalid_productions_ |= BindingPatternProduction; |
+ Add(e); |
} |
void RecordBindingPatternError(const Scanner::Location& loc, |
MessageTemplate::Template message, |
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; |
+ RecordBindingPatternError(BindingPatternError(loc, message, arg)); |
+ } |
+ |
+ static Error AssignmentPatternError(const Scanner::Location& loc, |
+ MessageTemplate::Template message, |
+ const char* arg = nullptr) { |
+ return Error(loc, message, kAssignmentPatternProduction, arg); |
+ } |
+ |
+ void RecordAssignmentPatternError(const Error& e) { |
+ if (!is_valid_assignment_pattern()) return; |
+ invalid_productions_ |= AssignmentPatternProduction; |
+ Add(e); |
} |
void RecordAssignmentPatternError(const Scanner::Location& loc, |
MessageTemplate::Template message, |
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; |
+ RecordAssignmentPatternError(AssignmentPatternError(loc, message, arg)); |
} |
void RecordPatternError(const Scanner::Location& loc, |
@@ -226,17 +274,14 @@ 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 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 |
@@ -247,9 +292,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 RecordStrongModeFormalParameterError(const Scanner::Location& loc, |
@@ -257,9 +300,7 @@ class ExpressionClassifier { |
const char* arg = nullptr) { |
if (!is_valid_strong_mode_formal_parameters()) return; |
invalid_productions_ |= StrongModeFormalParametersProduction; |
- strong_mode_formal_parameter_error_.location = loc; |
- strong_mode_formal_parameter_error_.message = message; |
- strong_mode_formal_parameter_error_.arg = arg; |
+ Add(Error(loc, message, kStrongModeFormalParametersProduction, arg)); |
} |
void RecordLetPatternError(const Scanner::Location& loc, |
@@ -267,9 +308,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, |
@@ -277,79 +316,95 @@ 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 ForgiveCoverInitializedNameError() { |
+ if (!(invalid_productions_ & CoverInitializedNameProduction)) return; |
invalid_productions_ &= ~CoverInitializedNameProduction; |
- cover_initialized_name_error_ = Error(); |
+ Error& e = reported_error(kCoverInitializedNameProduction); |
+ e.kind = kUnusedError; |
} |
void ForgiveAssignmentPatternError() { |
+ if (!(invalid_productions_ & AssignmentPatternProduction)) return; |
invalid_productions_ &= ~AssignmentPatternProduction; |
- assignment_pattern_error_ = Error(); |
+ Error& e = reported_error(kAssignmentPatternProduction); |
+ e.kind = kUnusedError; |
} |
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 & StrongModeFormalParametersProduction) |
- strong_mode_formal_parameter_error_ = |
- inner->strong_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_; |
- } |
+ int next = inner->reported_errors_begin_; |
+ if (non_arrow_inner_invalid_productions) { |
+ unsigned non_arrow_productions = |
+ productions & ~ArrowFormalParametersProduction; |
+ unsigned errors = |
+ non_arrow_productions & non_arrow_inner_invalid_productions; |
+ errors &= ~invalid_productions_; |
+ |
+ // 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()) |
+ errors |= ArrowFormalParametersProduction; |
+ } |
- // 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 (errors != 0) { |
+ invalid_productions_ |= errors; |
+ int arrow_index = inner->reported_errors_end_; |
+ for (int i = inner->reported_errors_begin_; |
+ i < inner->reported_errors_end_; i++) { |
+ if (reported_errors_->at(i).kind == kUnusedError || |
+ reported_errors_->at(i).kind == kArrowFormalParametersProduction) |
+ continue; |
+ if (errors & (1 << reported_errors_->at(i).kind)) |
+ Move(next++, i); |
+ if (reported_errors_->at(i).kind == kBindingPatternProduction && |
+ errors & ArrowFormalParametersProduction) { |
+ if (next <= i) { |
+ Move(next, i); |
+ reported_errors_->at(next++).kind = |
+ kArrowFormalParametersProduction; |
+ } else { |
+ DCHECK_EQ(next, i+1); |
+ arrow_index = i; |
+ } |
+ } |
+ } |
+ if (arrow_index < inner->reported_errors_end_) { |
+ Add(reported_errors_->at(arrow_index)); |
+ reported_errors_->at(next++).kind = kArrowFormalParametersProduction; |
+ } |
} |
} |
+ DCHECK_EQ(reported_errors_end_, next); |
+ reported_errors_->Rewind(next); |
+ inner->reported_errors_begin_ = inner->reported_errors_end_ = next; |
} |
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_); |
} |
@@ -360,25 +415,49 @@ 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); |
+ } |
+ } |
+ // 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; |
+ } |
+ |
+ V8_INLINE void Add(const Error& e) { |
+ DCHECK_EQ(reported_errors_end_, reported_errors_->length()); |
+ reported_errors_->Add(e, zone_); |
caitp (gmail)
2016/02/18 16:57:47
It might be worth having the very commonly used on
nickie
2016/02/19 08:56:31
If you could suggest a subset, I could try to benc
caitp (gmail)
2016/02/19 09:07:28
the main one is Object/Array Literals vs Assignmen
nickie
2016/02/19 09:25:50
One way to go then is to always store BindingPatte
|
+ reported_errors_end_++; |
+ } |
+ |
+ V8_INLINE void Move(int next, int i) { |
+ DCHECK_EQ(reported_errors_end_, next); |
+ DCHECK_LE(next, i); |
+ DCHECK_LT(i, reported_errors_->length()); |
+ if (next < i) reported_errors_->at(next++) = 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_; |
- 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 strong_mode_formal_parameter_error_; |
- Error let_pattern_error_; |
- Error cover_initialized_name_error_; |
+ unsigned invalid_productions_ : 14; |
+ unsigned function_properties_ : 2; |
+ ZoneList<Error>* reported_errors_; |
+ int reported_errors_begin_; |
+ int reported_errors_end_; |
DuplicateFinder* duplicate_finder_; |
}; |
+#undef ERROR_CODES |
+ |
+ |
} // namespace internal |
} // namespace v8 |