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

Side by Side 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: Created 4 years, 10 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/parsing/parser.h » ('j') | src/parsing/parser-base.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PARSING_EXPRESSION_CLASSIFIER_H 5 #ifndef V8_PARSING_EXPRESSION_CLASSIFIER_H
6 #define V8_PARSING_EXPRESSION_CLASSIFIER_H 6 #define V8_PARSING_EXPRESSION_CLASSIFIER_H
7 7
8 #include "src/messages.h" 8 #include "src/messages.h"
9 #include "src/parsing/scanner.h" 9 #include "src/parsing/scanner.h"
10 #include "src/parsing/token.h" 10 #include "src/parsing/token.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 #define ERROR_CODES(T) \
17 T(ExpressionProduction, 0) \
18 T(FormalParameterInitializerProduction, 1) \
19 T(BindingPatternProduction, 2) \
20 T(AssignmentPatternProduction, 3) \
21 T(DistinctFormalParametersProduction, 4) \
22 T(StrictModeFormalParametersProduction, 5) \
23 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
24 T(ArrowFormalParametersProduction, 7) \
25 T(LetPatternProduction, 8) \
26 T(CoverInitializedNameProduction, 9)
27
28
16 template <typename Traits> 29 template <typename Traits>
17 class ExpressionClassifier { 30 class ExpressionClassifier {
18 public: 31 public:
32 enum ErrorKind : unsigned {
33 #define DEFINE_ERROR_KIND(NAME, CODE) k##NAME = CODE,
34 ERROR_CODES(DEFINE_ERROR_KIND)
35 #undef DEFINE_ERROR_KIND
36 kUnusedError = 15 // Larger than error codes; should fit in 4 bits
37 };
38
19 struct Error { 39 struct Error {
20 Error() 40 V8_INLINE Error()
21 : location(Scanner::Location::invalid()), 41 : location(Scanner::Location::invalid()),
22 message(MessageTemplate::kNone), 42 message(MessageTemplate::kNone),
43 kind(kUnusedError),
23 type(kSyntaxError), 44 type(kSyntaxError),
24 arg(nullptr) {} 45 arg(nullptr) {}
46 V8_INLINE explicit Error(Scanner::Location loc,
47 MessageTemplate::Template msg, ErrorKind k,
48 const char* a = nullptr,
49 ParseErrorType t = kSyntaxError)
50 : location(loc), message(msg), kind(k), type(t), arg(a) {}
25 51
26 Scanner::Location location; 52 Scanner::Location location;
27 MessageTemplate::Template message : 30; 53 MessageTemplate::Template message : 26;
54 ErrorKind kind : 4;
28 ParseErrorType type : 2; 55 ParseErrorType type : 2;
29 const char* arg; 56 const char* arg;
30 }; 57 };
31 58
32 enum TargetProduction { 59 enum TargetProduction : unsigned {
33 ExpressionProduction = 1 << 0, 60 #define DEFINE_PRODUCTION(NAME, CODE) NAME = 1 << CODE,
34 FormalParameterInitializerProduction = 1 << 1, 61 ERROR_CODES(DEFINE_PRODUCTION)
35 BindingPatternProduction = 1 << 2, 62 #undef DEFINE_PRODUCTION
36 AssignmentPatternProduction = 1 << 3,
37 DistinctFormalParametersProduction = 1 << 4,
38 StrictModeFormalParametersProduction = 1 << 5,
39 StrongModeFormalParametersProduction = 1 << 6,
40 ArrowFormalParametersProduction = 1 << 7,
41 LetPatternProduction = 1 << 8,
42 CoverInitializedNameProduction = 1 << 9,
43 63
44 ExpressionProductions = 64 ExpressionProductions =
45 (ExpressionProduction | FormalParameterInitializerProduction), 65 (ExpressionProduction | FormalParameterInitializerProduction),
46 PatternProductions = (BindingPatternProduction | 66 PatternProductions = (BindingPatternProduction |
47 AssignmentPatternProduction | LetPatternProduction), 67 AssignmentPatternProduction | LetPatternProduction),
48 FormalParametersProductions = (DistinctFormalParametersProduction | 68 FormalParametersProductions = (DistinctFormalParametersProduction |
49 StrictModeFormalParametersProduction | 69 StrictModeFormalParametersProduction |
50 StrongModeFormalParametersProduction), 70 StrongModeFormalParametersProduction),
51 StandardProductions = ExpressionProductions | PatternProductions, 71 StandardProductions = ExpressionProductions | PatternProductions,
52 AllProductions = 72 AllProductions =
53 (StandardProductions | FormalParametersProductions | 73 (StandardProductions | FormalParametersProductions |
54 ArrowFormalParametersProduction | CoverInitializedNameProduction) 74 ArrowFormalParametersProduction | CoverInitializedNameProduction)
55 }; 75 };
56 76
57 enum FunctionProperties { NonSimpleParameter = 1 << 0 }; 77 enum FunctionProperties : unsigned {
78 NonSimpleParameter = 1 << 0
79 };
58 80
59 explicit ExpressionClassifier(const Traits* t) 81 explicit ExpressionClassifier(const Traits* t)
60 : zone_(t->zone()), 82 : zone_(t->zone()),
61 non_patterns_to_rewrite_(t->GetNonPatternList()), 83 non_patterns_to_rewrite_(t->GetNonPatternList()),
62 invalid_productions_(0), 84 invalid_productions_(0),
63 function_properties_(0), 85 function_properties_(0),
86 reported_errors_(t->GetReportedErrorList()),
64 duplicate_finder_(nullptr) { 87 duplicate_finder_(nullptr) {
88 reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
65 non_pattern_begin_ = non_patterns_to_rewrite_->length(); 89 non_pattern_begin_ = non_patterns_to_rewrite_->length();
66 } 90 }
67 91
68 ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder) 92 ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder)
69 : zone_(t->zone()), 93 : zone_(t->zone()),
70 non_patterns_to_rewrite_(t->GetNonPatternList()), 94 non_patterns_to_rewrite_(t->GetNonPatternList()),
71 invalid_productions_(0), 95 invalid_productions_(0),
72 function_properties_(0), 96 function_properties_(0),
97 reported_errors_(t->GetReportedErrorList()),
73 duplicate_finder_(duplicate_finder) { 98 duplicate_finder_(duplicate_finder) {
99 reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
74 non_pattern_begin_ = non_patterns_to_rewrite_->length(); 100 non_pattern_begin_ = non_patterns_to_rewrite_->length();
75 } 101 }
76 102
77 ~ExpressionClassifier() { Discard(); } 103 ~ExpressionClassifier() { Discard(); }
78 104
79 bool is_valid(unsigned productions) const { 105 V8_INLINE bool is_valid(unsigned productions) const {
80 return (invalid_productions_ & productions) == 0; 106 return (invalid_productions_ & productions) == 0;
81 } 107 }
82 108
83 DuplicateFinder* duplicate_finder() const { return duplicate_finder_; } 109 V8_INLINE DuplicateFinder* duplicate_finder() const {
110 return duplicate_finder_;
111 }
84 112
85 bool is_valid_expression() const { return is_valid(ExpressionProduction); } 113 V8_INLINE bool is_valid_expression() const {
114 return is_valid(ExpressionProduction);
115 }
86 116
87 bool is_valid_formal_parameter_initializer() const { 117 V8_INLINE bool is_valid_formal_parameter_initializer() const {
88 return is_valid(FormalParameterInitializerProduction); 118 return is_valid(FormalParameterInitializerProduction);
89 } 119 }
90 120
91 bool is_valid_binding_pattern() const { 121 V8_INLINE bool is_valid_binding_pattern() const {
92 return is_valid(BindingPatternProduction); 122 return is_valid(BindingPatternProduction);
93 } 123 }
94 124
95 bool is_valid_assignment_pattern() const { 125 V8_INLINE bool is_valid_assignment_pattern() const {
96 return is_valid(AssignmentPatternProduction); 126 return is_valid(AssignmentPatternProduction);
97 } 127 }
98 128
99 bool is_valid_arrow_formal_parameters() const { 129 V8_INLINE bool is_valid_arrow_formal_parameters() const {
100 return is_valid(ArrowFormalParametersProduction); 130 return is_valid(ArrowFormalParametersProduction);
101 } 131 }
102 132
103 bool is_valid_formal_parameter_list_without_duplicates() const { 133 V8_INLINE bool is_valid_formal_parameter_list_without_duplicates() const {
104 return is_valid(DistinctFormalParametersProduction); 134 return is_valid(DistinctFormalParametersProduction);
105 } 135 }
106 136
107 // Note: callers should also check 137 // Note: callers should also check
108 // is_valid_formal_parameter_list_without_duplicates(). 138 // is_valid_formal_parameter_list_without_duplicates().
109 bool is_valid_strict_mode_formal_parameters() const { 139 V8_INLINE bool is_valid_strict_mode_formal_parameters() const {
110 return is_valid(StrictModeFormalParametersProduction); 140 return is_valid(StrictModeFormalParametersProduction);
111 } 141 }
112 142
113 // Note: callers should also check is_valid_strict_mode_formal_parameters() 143 // Note: callers should also check is_valid_strict_mode_formal_parameters()
114 // and is_valid_formal_parameter_list_without_duplicates(). 144 // and is_valid_formal_parameter_list_without_duplicates().
115 bool is_valid_strong_mode_formal_parameters() const { 145 V8_INLINE bool is_valid_strong_mode_formal_parameters() const {
116 return is_valid(StrongModeFormalParametersProduction); 146 return is_valid(StrongModeFormalParametersProduction);
117 } 147 }
118 148
119 bool is_valid_let_pattern() const { return is_valid(LetPatternProduction); } 149 V8_INLINE bool is_valid_let_pattern() const {
120 150 return is_valid(LetPatternProduction);
121 const Error& expression_error() const { return expression_error_; }
122
123 const Error& formal_parameter_initializer_error() const {
124 return formal_parameter_initializer_error_;
125 } 151 }
126 152
127 const Error& binding_pattern_error() const { return binding_pattern_error_; } 153 V8_INLINE const Error& expression_error() const {
128 154 return reported_error(kExpressionProduction);
129 const Error& assignment_pattern_error() const {
130 return assignment_pattern_error_;
131 } 155 }
132 156
133 const Error& arrow_formal_parameters_error() const { 157 V8_INLINE const Error& formal_parameter_initializer_error() const {
134 return arrow_formal_parameters_error_; 158 return reported_error(kFormalParameterInitializerProduction);
135 } 159 }
136 160
137 const Error& duplicate_formal_parameter_error() const { 161 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
138 return duplicate_formal_parameter_error_; 162 return reported_error(kBindingPatternProduction);
139 } 163 }
140 164
141 const Error& strict_mode_formal_parameter_error() const { 165 V8_INLINE const Error& assignment_pattern_error() const {
142 return strict_mode_formal_parameter_error_; 166 return reported_error(kAssignmentPatternProduction);
143 } 167 }
144 168
145 const Error& strong_mode_formal_parameter_error() const { 169 V8_INLINE const Error& arrow_formal_parameters_error() const {
146 return strong_mode_formal_parameter_error_; 170 return reported_error(kArrowFormalParametersProduction);
147 } 171 }
148 172
149 const Error& let_pattern_error() const { return let_pattern_error_; } 173 V8_INLINE const Error& duplicate_formal_parameter_error() const {
174 return reported_error(kDistinctFormalParametersProduction);
175 }
150 176
151 bool has_cover_initialized_name() const { 177 V8_INLINE const Error& strict_mode_formal_parameter_error() const {
178 return reported_error(kStrictModeFormalParametersProduction);
179 }
180
181 V8_INLINE const Error& strong_mode_formal_parameter_error() const {
182 return reported_error(kStrongModeFormalParametersProduction);
183 }
184
185 V8_INLINE const Error& let_pattern_error() const {
186 return reported_error(kLetPatternProduction);
187 }
188
189 V8_INLINE bool has_cover_initialized_name() const {
152 return !is_valid(CoverInitializedNameProduction); 190 return !is_valid(CoverInitializedNameProduction);
153 } 191 }
154 const Error& cover_initialized_name_error() const { 192
155 return cover_initialized_name_error_; 193 V8_INLINE const Error& cover_initialized_name_error() const {
194 return reported_error(kCoverInitializedNameProduction);
156 } 195 }
157 196
158 bool is_simple_parameter_list() const { 197 V8_INLINE bool is_simple_parameter_list() const {
159 return !(function_properties_ & NonSimpleParameter); 198 return !(function_properties_ & NonSimpleParameter);
160 } 199 }
161 200
162 void RecordNonSimpleParameter() { 201 V8_INLINE void RecordNonSimpleParameter() {
163 function_properties_ |= NonSimpleParameter; 202 function_properties_ |= NonSimpleParameter;
164 } 203 }
165 204
166 void RecordExpressionError(const Scanner::Location& loc, 205 void RecordExpressionError(const Scanner::Location& loc,
167 MessageTemplate::Template message, 206 MessageTemplate::Template message,
168 const char* arg = nullptr) { 207 const char* arg = nullptr) {
169 if (!is_valid_expression()) return; 208 if (!is_valid_expression()) return;
170 invalid_productions_ |= ExpressionProduction; 209 invalid_productions_ |= ExpressionProduction;
171 expression_error_.location = loc; 210 Add(Error(loc, message, kExpressionProduction, arg));
172 expression_error_.message = message;
173 expression_error_.arg = arg;
174 } 211 }
175 212
176 void RecordExpressionError(const Scanner::Location& loc, 213 void RecordExpressionError(const Scanner::Location& loc,
177 MessageTemplate::Template message, 214 MessageTemplate::Template message,
178 ParseErrorType type, const char* arg = nullptr) { 215 ParseErrorType type, const char* arg = nullptr) {
179 if (!is_valid_expression()) return; 216 if (!is_valid_expression()) return;
180 invalid_productions_ |= ExpressionProduction; 217 invalid_productions_ |= ExpressionProduction;
181 expression_error_.location = loc; 218 Add(Error(loc, message, kExpressionProduction, arg, type));
182 expression_error_.message = message;
183 expression_error_.arg = arg;
184 expression_error_.type = type;
185 } 219 }
186 220
187 void RecordFormalParameterInitializerError(const Scanner::Location& loc, 221 void RecordFormalParameterInitializerError(const Scanner::Location& loc,
188 MessageTemplate::Template message, 222 MessageTemplate::Template message,
189 const char* arg = nullptr) { 223 const char* arg = nullptr) {
190 if (!is_valid_formal_parameter_initializer()) return; 224 if (!is_valid_formal_parameter_initializer()) return;
191 invalid_productions_ |= FormalParameterInitializerProduction; 225 invalid_productions_ |= FormalParameterInitializerProduction;
192 formal_parameter_initializer_error_.location = loc; 226 Add(Error(loc, message, kFormalParameterInitializerProduction, arg));
193 formal_parameter_initializer_error_.message = message; 227 }
194 formal_parameter_initializer_error_.arg = arg; 228
229 static Error BindingPatternError(const Scanner::Location& loc,
230 MessageTemplate::Template message,
231 const char* arg = nullptr) {
232 return Error(loc, message, kBindingPatternProduction, arg);
233 }
234
235 void RecordBindingPatternError(const Error& e) {
236 if (!is_valid_binding_pattern()) return;
237 invalid_productions_ |= BindingPatternProduction;
238 Add(e);
195 } 239 }
196 240
197 void RecordBindingPatternError(const Scanner::Location& loc, 241 void RecordBindingPatternError(const Scanner::Location& loc,
198 MessageTemplate::Template message, 242 MessageTemplate::Template message,
199 const char* arg = nullptr) { 243 const char* arg = nullptr) {
200 if (!is_valid_binding_pattern()) return; 244 RecordBindingPatternError(BindingPatternError(loc, message, arg));
201 invalid_productions_ |= BindingPatternProduction; 245 }
202 binding_pattern_error_.location = loc; 246
203 binding_pattern_error_.message = message; 247 static Error AssignmentPatternError(const Scanner::Location& loc,
204 binding_pattern_error_.arg = arg; 248 MessageTemplate::Template message,
249 const char* arg = nullptr) {
250 return Error(loc, message, kAssignmentPatternProduction, arg);
251 }
252
253 void RecordAssignmentPatternError(const Error& e) {
254 if (!is_valid_assignment_pattern()) return;
255 invalid_productions_ |= AssignmentPatternProduction;
256 Add(e);
205 } 257 }
206 258
207 void RecordAssignmentPatternError(const Scanner::Location& loc, 259 void RecordAssignmentPatternError(const Scanner::Location& loc,
208 MessageTemplate::Template message, 260 MessageTemplate::Template message,
209 const char* arg = nullptr) { 261 const char* arg = nullptr) {
210 if (!is_valid_assignment_pattern()) return; 262 RecordAssignmentPatternError(AssignmentPatternError(loc, message, arg));
211 invalid_productions_ |= AssignmentPatternProduction;
212 assignment_pattern_error_.location = loc;
213 assignment_pattern_error_.message = message;
214 assignment_pattern_error_.arg = arg;
215 } 263 }
216 264
217 void RecordPatternError(const Scanner::Location& loc, 265 void RecordPatternError(const Scanner::Location& loc,
218 MessageTemplate::Template message, 266 MessageTemplate::Template message,
219 const char* arg = nullptr) { 267 const char* arg = nullptr) {
220 RecordBindingPatternError(loc, message, arg); 268 RecordBindingPatternError(loc, message, arg);
221 RecordAssignmentPatternError(loc, message, arg); 269 RecordAssignmentPatternError(loc, message, arg);
222 } 270 }
223 271
224 void RecordArrowFormalParametersError(const Scanner::Location& loc, 272 void RecordArrowFormalParametersError(const Scanner::Location& loc,
225 MessageTemplate::Template message, 273 MessageTemplate::Template message,
226 const char* arg = nullptr) { 274 const char* arg = nullptr) {
227 if (!is_valid_arrow_formal_parameters()) return; 275 if (!is_valid_arrow_formal_parameters()) return;
228 invalid_productions_ |= ArrowFormalParametersProduction; 276 invalid_productions_ |= ArrowFormalParametersProduction;
229 arrow_formal_parameters_error_.location = loc; 277 Add(Error(loc, message, kArrowFormalParametersProduction, arg));
230 arrow_formal_parameters_error_.message = message;
231 arrow_formal_parameters_error_.arg = arg;
232 } 278 }
233 279
234 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { 280 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
235 if (!is_valid_formal_parameter_list_without_duplicates()) return; 281 if (!is_valid_formal_parameter_list_without_duplicates()) return;
236 invalid_productions_ |= DistinctFormalParametersProduction; 282 invalid_productions_ |= DistinctFormalParametersProduction;
237 duplicate_formal_parameter_error_.location = loc; 283 Add(Error(loc, MessageTemplate::kParamDupe,
238 duplicate_formal_parameter_error_.message = MessageTemplate::kParamDupe; 284 kDistinctFormalParametersProduction));
239 duplicate_formal_parameter_error_.arg = nullptr;
240 } 285 }
241 286
242 // Record a binding that would be invalid in strict mode. Confusingly this 287 // Record a binding that would be invalid in strict mode. Confusingly this
243 // is not the same as StrictFormalParameterList, which simply forbids 288 // is not the same as StrictFormalParameterList, which simply forbids
244 // duplicate bindings. 289 // duplicate bindings.
245 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, 290 void RecordStrictModeFormalParameterError(const Scanner::Location& loc,
246 MessageTemplate::Template message, 291 MessageTemplate::Template message,
247 const char* arg = nullptr) { 292 const char* arg = nullptr) {
248 if (!is_valid_strict_mode_formal_parameters()) return; 293 if (!is_valid_strict_mode_formal_parameters()) return;
249 invalid_productions_ |= StrictModeFormalParametersProduction; 294 invalid_productions_ |= StrictModeFormalParametersProduction;
250 strict_mode_formal_parameter_error_.location = loc; 295 Add(Error(loc, message, kStrictModeFormalParametersProduction, arg));
251 strict_mode_formal_parameter_error_.message = message;
252 strict_mode_formal_parameter_error_.arg = arg;
253 } 296 }
254 297
255 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, 298 void RecordStrongModeFormalParameterError(const Scanner::Location& loc,
256 MessageTemplate::Template message, 299 MessageTemplate::Template message,
257 const char* arg = nullptr) { 300 const char* arg = nullptr) {
258 if (!is_valid_strong_mode_formal_parameters()) return; 301 if (!is_valid_strong_mode_formal_parameters()) return;
259 invalid_productions_ |= StrongModeFormalParametersProduction; 302 invalid_productions_ |= StrongModeFormalParametersProduction;
260 strong_mode_formal_parameter_error_.location = loc; 303 Add(Error(loc, message, kStrongModeFormalParametersProduction, arg));
261 strong_mode_formal_parameter_error_.message = message;
262 strong_mode_formal_parameter_error_.arg = arg;
263 } 304 }
264 305
265 void RecordLetPatternError(const Scanner::Location& loc, 306 void RecordLetPatternError(const Scanner::Location& loc,
266 MessageTemplate::Template message, 307 MessageTemplate::Template message,
267 const char* arg = nullptr) { 308 const char* arg = nullptr) {
268 if (!is_valid_let_pattern()) return; 309 if (!is_valid_let_pattern()) return;
269 invalid_productions_ |= LetPatternProduction; 310 invalid_productions_ |= LetPatternProduction;
270 let_pattern_error_.location = loc; 311 Add(Error(loc, message, kLetPatternProduction, arg));
271 let_pattern_error_.message = message;
272 let_pattern_error_.arg = arg;
273 } 312 }
274 313
275 void RecordCoverInitializedNameError(const Scanner::Location& loc, 314 void RecordCoverInitializedNameError(const Scanner::Location& loc,
276 MessageTemplate::Template message, 315 MessageTemplate::Template message,
277 const char* arg = nullptr) { 316 const char* arg = nullptr) {
278 if (has_cover_initialized_name()) return; 317 if (has_cover_initialized_name()) return;
279 invalid_productions_ |= CoverInitializedNameProduction; 318 invalid_productions_ |= CoverInitializedNameProduction;
280 cover_initialized_name_error_.location = loc; 319 Add(Error(loc, message, kCoverInitializedNameProduction, arg));
281 cover_initialized_name_error_.message = message;
282 cover_initialized_name_error_.arg = arg;
283 } 320 }
284 321
285 void ForgiveCoverInitializedNameError() { 322 void ForgiveCoverInitializedNameError() {
323 if (!(invalid_productions_ & CoverInitializedNameProduction)) return;
286 invalid_productions_ &= ~CoverInitializedNameProduction; 324 invalid_productions_ &= ~CoverInitializedNameProduction;
287 cover_initialized_name_error_ = Error(); 325 Error& e = reported_error(kCoverInitializedNameProduction);
326 e.kind = kUnusedError;
288 } 327 }
289 328
290 void ForgiveAssignmentPatternError() { 329 void ForgiveAssignmentPatternError() {
330 if (!(invalid_productions_ & AssignmentPatternProduction)) return;
291 invalid_productions_ &= ~AssignmentPatternProduction; 331 invalid_productions_ &= ~AssignmentPatternProduction;
292 assignment_pattern_error_ = Error(); 332 Error& e = reported_error(kAssignmentPatternProduction);
333 e.kind = kUnusedError;
293 } 334 }
294 335
295 void Accumulate(ExpressionClassifier* inner, 336 void Accumulate(ExpressionClassifier* inner,
296 unsigned productions = StandardProductions, 337 unsigned productions = StandardProductions,
297 bool merge_non_patterns = true) { 338 bool merge_non_patterns = true) {
339 DCHECK_EQ(inner->reported_errors_, reported_errors_);
340 DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_);
341 DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length());
298 if (merge_non_patterns) MergeNonPatterns(inner); 342 if (merge_non_patterns) MergeNonPatterns(inner);
299 // Propagate errors from inner, but don't overwrite already recorded 343 // Propagate errors from inner, but don't overwrite already recorded
300 // errors. 344 // errors.
301 unsigned non_arrow_inner_invalid_productions = 345 unsigned non_arrow_inner_invalid_productions =
302 inner->invalid_productions_ & ~ArrowFormalParametersProduction; 346 inner->invalid_productions_ & ~ArrowFormalParametersProduction;
303 if (non_arrow_inner_invalid_productions == 0) return; 347 int next = inner->reported_errors_begin_;
304 unsigned non_arrow_productions = 348 if (non_arrow_inner_invalid_productions) {
305 productions & ~ArrowFormalParametersProduction; 349 unsigned non_arrow_productions =
306 unsigned errors = 350 productions & ~ArrowFormalParametersProduction;
307 non_arrow_productions & non_arrow_inner_invalid_productions; 351 unsigned errors =
308 errors &= ~invalid_productions_; 352 non_arrow_productions & non_arrow_inner_invalid_productions;
309 if (errors != 0) { 353 errors &= ~invalid_productions_;
310 invalid_productions_ |= errors;
311 if (errors & ExpressionProduction)
312 expression_error_ = inner->expression_error_;
313 if (errors & FormalParameterInitializerProduction)
314 formal_parameter_initializer_error_ =
315 inner->formal_parameter_initializer_error_;
316 if (errors & BindingPatternProduction)
317 binding_pattern_error_ = inner->binding_pattern_error_;
318 if (errors & AssignmentPatternProduction)
319 assignment_pattern_error_ = inner->assignment_pattern_error_;
320 if (errors & DistinctFormalParametersProduction)
321 duplicate_formal_parameter_error_ =
322 inner->duplicate_formal_parameter_error_;
323 if (errors & StrictModeFormalParametersProduction)
324 strict_mode_formal_parameter_error_ =
325 inner->strict_mode_formal_parameter_error_;
326 if (errors & StrongModeFormalParametersProduction)
327 strong_mode_formal_parameter_error_ =
328 inner->strong_mode_formal_parameter_error_;
329 if (errors & LetPatternProduction)
330 let_pattern_error_ = inner->let_pattern_error_;
331 if (errors & CoverInitializedNameProduction)
332 cover_initialized_name_error_ = inner->cover_initialized_name_error_;
333 }
334 354
335 // As an exception to the above, the result continues to be a valid arrow 355 // As an exception to the above, the result continues to be a valid arrow
336 // formal parameters if the inner expression is a valid binding pattern. 356 // formal parameters if the inner expression is a valid binding pattern.
337 if (productions & ArrowFormalParametersProduction && 357 if (productions & ArrowFormalParametersProduction &&
338 is_valid_arrow_formal_parameters()) { 358 is_valid_arrow_formal_parameters()) {
339 // Also copy function properties if expecting an arrow function 359 // Also copy function properties if expecting an arrow function
340 // parameter. 360 // parameter.
341 function_properties_ |= inner->function_properties_; 361 function_properties_ |= inner->function_properties_;
342 362
343 if (!inner->is_valid_binding_pattern()) { 363 if (!inner->is_valid_binding_pattern())
344 invalid_productions_ |= ArrowFormalParametersProduction; 364 errors |= ArrowFormalParametersProduction;
345 arrow_formal_parameters_error_ = inner->binding_pattern_error_; 365 }
366
367 if (errors != 0) {
368 invalid_productions_ |= errors;
369 int arrow_index = inner->reported_errors_end_;
370 for (int i = inner->reported_errors_begin_;
371 i < inner->reported_errors_end_; i++) {
372 if (reported_errors_->at(i).kind == kUnusedError ||
373 reported_errors_->at(i).kind == kArrowFormalParametersProduction)
374 continue;
375 if (errors & (1 << reported_errors_->at(i).kind))
376 Move(next++, i);
377 if (reported_errors_->at(i).kind == kBindingPatternProduction &&
378 errors & ArrowFormalParametersProduction) {
379 if (next <= i) {
380 Move(next, i);
381 reported_errors_->at(next++).kind =
382 kArrowFormalParametersProduction;
383 } else {
384 DCHECK_EQ(next, i+1);
385 arrow_index = i;
386 }
387 }
388 }
389 if (arrow_index < inner->reported_errors_end_) {
390 Add(reported_errors_->at(arrow_index));
391 reported_errors_->at(next++).kind = kArrowFormalParametersProduction;
392 }
346 } 393 }
347 } 394 }
395 DCHECK_EQ(reported_errors_end_, next);
396 reported_errors_->Rewind(next);
397 inner->reported_errors_begin_ = inner->reported_errors_end_ = next;
348 } 398 }
349 399
350 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } 400 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; }
351 401
352 V8_INLINE void Discard() { 402 V8_INLINE void Discard() {
403 if (reported_errors_end_ == reported_errors_->length()) {
404 reported_errors_->Rewind(reported_errors_begin_);
405 reported_errors_end_ = reported_errors_begin_;
406 }
407 DCHECK_EQ(reported_errors_begin_, reported_errors_end_);
353 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length()); 408 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length());
354 non_patterns_to_rewrite_->Rewind(non_pattern_begin_); 409 non_patterns_to_rewrite_->Rewind(non_pattern_begin_);
355 } 410 }
356 411
357 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) { 412 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) {
358 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_); 413 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_);
359 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length(); 414 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length();
360 } 415 }
361 416
362 private: 417 private:
418 V8_INLINE Error& reported_error(ErrorKind kind) const {
419 if (invalid_productions_ & (1 << kind)) {
420 for (int i = reported_errors_begin_; i < reported_errors_end_; i++) {
421 if (reported_errors_->at(i).kind == kind)
422 return reported_errors_->at(i);
423 }
424 }
425 // We should only be looking for an error when we know that one has
426 // been reported. But we're not... So this is to make sure we have
427 // the same behaviour.
428 static Error none;
429 return none;
430 }
431
432 V8_INLINE void Add(const Error& e) {
433 DCHECK_EQ(reported_errors_end_, reported_errors_->length());
434 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
435 reported_errors_end_++;
436 }
437
438 V8_INLINE void Move(int next, int i) {
439 DCHECK_EQ(reported_errors_end_, next);
440 DCHECK_LE(next, i);
441 DCHECK_LT(i, reported_errors_->length());
442 if (next < i) reported_errors_->at(next++) = reported_errors_->at(i);
443 reported_errors_end_++;
444 }
445
363 Zone* zone_; 446 Zone* zone_;
364 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; 447 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_;
365 int non_pattern_begin_; 448 int non_pattern_begin_;
366 unsigned invalid_productions_; 449 unsigned invalid_productions_ : 14;
367 unsigned function_properties_; 450 unsigned function_properties_ : 2;
368 Error expression_error_; 451 ZoneList<Error>* reported_errors_;
369 Error formal_parameter_initializer_error_; 452 int reported_errors_begin_;
370 Error binding_pattern_error_; 453 int reported_errors_end_;
371 Error assignment_pattern_error_;
372 Error arrow_formal_parameters_error_;
373 Error duplicate_formal_parameter_error_;
374 Error strict_mode_formal_parameter_error_;
375 Error strong_mode_formal_parameter_error_;
376 Error let_pattern_error_;
377 Error cover_initialized_name_error_;
378 DuplicateFinder* duplicate_finder_; 454 DuplicateFinder* duplicate_finder_;
379 }; 455 };
380 456
381 457
458 #undef ERROR_CODES
459
460
382 } // namespace internal 461 } // namespace internal
383 } // namespace v8 462 } // namespace v8
384 463
385 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H 464 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H
OLDNEW
« no previous file with comments | « no previous file | src/parsing/parser.h » ('j') | src/parsing/parser-base.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698