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

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: Improve expression classifier accumulate Created 4 years, 7 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(ArrowFormalParametersProduction, 6) \
24 T(LetPatternProduction, 7) \
25 T(CoverInitializedNameProduction, 8) \
26 T(TailCallExpressionProduction, 9) \
27 T(AsyncArrowFormalParametersProduction, 10) \
28 T(AsyncBindingPatternProduction, 11)
29
30
16 template <typename Traits> 31 template <typename Traits>
17 class ExpressionClassifier { 32 class ExpressionClassifier {
18 public: 33 public:
34 enum ErrorKind : unsigned {
35 #define DEFINE_ERROR_KIND(NAME, CODE) k##NAME = CODE,
36 ERROR_CODES(DEFINE_ERROR_KIND)
37 #undef DEFINE_ERROR_KIND
38 kUnusedError = 15 // Larger than error codes; should fit in 4 bits
39 };
40
19 struct Error { 41 struct Error {
20 Error() 42 V8_INLINE Error()
21 : location(Scanner::Location::invalid()), 43 : location(Scanner::Location::invalid()),
22 message(MessageTemplate::kNone), 44 message(MessageTemplate::kNone),
45 kind(kUnusedError),
23 type(kSyntaxError), 46 type(kSyntaxError),
24 arg(nullptr) {} 47 arg(nullptr) {}
48 V8_INLINE explicit Error(Scanner::Location loc,
49 MessageTemplate::Template msg, ErrorKind k,
50 const char* a = nullptr,
51 ParseErrorType t = kSyntaxError)
52 : location(loc), message(msg), kind(k), type(t), arg(a) {}
25 53
26 Scanner::Location location; 54 Scanner::Location location;
27 MessageTemplate::Template message : 30; 55 MessageTemplate::Template message : 26;
56 unsigned kind : 4;
28 ParseErrorType type : 2; 57 ParseErrorType type : 2;
29 const char* arg; 58 const char* arg;
30 }; 59 };
31 60
32 enum TargetProduction { 61 enum TargetProduction : unsigned {
33 ExpressionProduction = 1 << 0, 62 #define DEFINE_PRODUCTION(NAME, CODE) NAME = 1 << CODE,
34 FormalParameterInitializerProduction = 1 << 1, 63 ERROR_CODES(DEFINE_PRODUCTION)
35 BindingPatternProduction = 1 << 2, 64 #undef DEFINE_PRODUCTION
36 AssignmentPatternProduction = 1 << 3,
37 DistinctFormalParametersProduction = 1 << 4,
38 StrictModeFormalParametersProduction = 1 << 5,
39 ArrowFormalParametersProduction = 1 << 6,
40 LetPatternProduction = 1 << 7,
41 CoverInitializedNameProduction = 1 << 8,
42 TailCallExpressionProduction = 1 << 9,
43 AsyncArrowFormalParametersProduction = 1 << 10,
44 AsyncBindingPatternProduction = 1 << 11,
45 65
46 ExpressionProductions = 66 ExpressionProductions =
47 (ExpressionProduction | FormalParameterInitializerProduction | 67 (ExpressionProduction | FormalParameterInitializerProduction |
48 TailCallExpressionProduction), 68 TailCallExpressionProduction),
49 PatternProductions = 69 PatternProductions =
50 (BindingPatternProduction | AssignmentPatternProduction | 70 (BindingPatternProduction | AssignmentPatternProduction |
51 LetPatternProduction | AsyncBindingPatternProduction), 71 LetPatternProduction | AsyncBindingPatternProduction),
52 FormalParametersProductions = (DistinctFormalParametersProduction | 72 FormalParametersProductions = (DistinctFormalParametersProduction |
53 StrictModeFormalParametersProduction), 73 StrictModeFormalParametersProduction),
54 StandardProductions = ExpressionProductions | PatternProductions, 74 StandardProductions = ExpressionProductions | PatternProductions,
55 AllProductions = 75 AllProductions =
56 (StandardProductions | FormalParametersProductions | 76 (StandardProductions | FormalParametersProductions |
57 ArrowFormalParametersProduction | CoverInitializedNameProduction | 77 ArrowFormalParametersProduction | CoverInitializedNameProduction |
58 AsyncArrowFormalParametersProduction | AsyncBindingPatternProduction) 78 AsyncArrowFormalParametersProduction | AsyncBindingPatternProduction)
59 }; 79 };
60 80
61 enum FunctionProperties { NonSimpleParameter = 1 << 0 }; 81 enum FunctionProperties : unsigned {
82 NonSimpleParameter = 1 << 0
83 };
62 84
63 explicit ExpressionClassifier(const Traits* t) 85 explicit ExpressionClassifier(const Traits* t)
64 : zone_(t->zone()), 86 : zone_(t->zone()),
65 non_patterns_to_rewrite_(t->GetNonPatternList()), 87 non_patterns_to_rewrite_(t->GetNonPatternList()),
66 invalid_productions_(0), 88 invalid_productions_(0),
67 function_properties_(0), 89 function_properties_(0),
90 reported_errors_(t->GetReportedErrorList()),
68 duplicate_finder_(nullptr) { 91 duplicate_finder_(nullptr) {
92 reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
69 non_pattern_begin_ = non_patterns_to_rewrite_->length(); 93 non_pattern_begin_ = non_patterns_to_rewrite_->length();
70 } 94 }
71 95
72 ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder) 96 ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder)
73 : zone_(t->zone()), 97 : zone_(t->zone()),
74 non_patterns_to_rewrite_(t->GetNonPatternList()), 98 non_patterns_to_rewrite_(t->GetNonPatternList()),
75 invalid_productions_(0), 99 invalid_productions_(0),
76 function_properties_(0), 100 function_properties_(0),
101 reported_errors_(t->GetReportedErrorList()),
77 duplicate_finder_(duplicate_finder) { 102 duplicate_finder_(duplicate_finder) {
103 reported_errors_begin_ = reported_errors_end_ = reported_errors_->length();
78 non_pattern_begin_ = non_patterns_to_rewrite_->length(); 104 non_pattern_begin_ = non_patterns_to_rewrite_->length();
79 } 105 }
80 106
81 ~ExpressionClassifier() { Discard(); } 107 ~ExpressionClassifier() { Discard(); }
82 108
83 bool is_valid(unsigned productions) const { 109 V8_INLINE bool is_valid(unsigned productions) const {
84 return (invalid_productions_ & productions) == 0; 110 return (invalid_productions_ & productions) == 0;
85 } 111 }
86 112
87 DuplicateFinder* duplicate_finder() const { return duplicate_finder_; } 113 V8_INLINE DuplicateFinder* duplicate_finder() const {
114 return duplicate_finder_;
115 }
88 116
89 bool is_valid_expression() const { return is_valid(ExpressionProduction); } 117 V8_INLINE bool is_valid_expression() const {
118 return is_valid(ExpressionProduction);
119 }
90 120
91 bool is_valid_formal_parameter_initializer() const { 121 V8_INLINE bool is_valid_formal_parameter_initializer() const {
92 return is_valid(FormalParameterInitializerProduction); 122 return is_valid(FormalParameterInitializerProduction);
93 } 123 }
94 124
95 bool is_valid_binding_pattern() const { 125 V8_INLINE bool is_valid_binding_pattern() const {
96 return is_valid(BindingPatternProduction); 126 return is_valid(BindingPatternProduction);
97 } 127 }
98 128
99 bool is_valid_assignment_pattern() const { 129 V8_INLINE bool is_valid_assignment_pattern() const {
100 return is_valid(AssignmentPatternProduction); 130 return is_valid(AssignmentPatternProduction);
101 } 131 }
102 132
103 bool is_valid_arrow_formal_parameters() const { 133 V8_INLINE bool is_valid_arrow_formal_parameters() const {
104 return is_valid(ArrowFormalParametersProduction); 134 return is_valid(ArrowFormalParametersProduction);
105 } 135 }
106 136
107 bool is_valid_formal_parameter_list_without_duplicates() const { 137 V8_INLINE bool is_valid_formal_parameter_list_without_duplicates() const {
108 return is_valid(DistinctFormalParametersProduction); 138 return is_valid(DistinctFormalParametersProduction);
109 } 139 }
110 140
111 // Note: callers should also check 141 // Note: callers should also check
112 // is_valid_formal_parameter_list_without_duplicates(). 142 // is_valid_formal_parameter_list_without_duplicates().
113 bool is_valid_strict_mode_formal_parameters() const { 143 V8_INLINE bool is_valid_strict_mode_formal_parameters() const {
114 return is_valid(StrictModeFormalParametersProduction); 144 return is_valid(StrictModeFormalParametersProduction);
115 } 145 }
116 146
117 bool is_valid_let_pattern() const { return is_valid(LetPatternProduction); } 147 V8_INLINE bool is_valid_let_pattern() const {
148 return is_valid(LetPatternProduction);
149 }
118 150
119 bool is_valid_async_arrow_formal_parameters() const { 151 bool is_valid_async_arrow_formal_parameters() const {
120 return is_valid(AsyncArrowFormalParametersProduction); 152 return is_valid(AsyncArrowFormalParametersProduction);
121 } 153 }
122 154
123 bool is_valid_async_binding_pattern() const { 155 bool is_valid_async_binding_pattern() const {
124 return is_valid(AsyncBindingPatternProduction); 156 return is_valid(AsyncBindingPatternProduction);
125 } 157 }
126 158
127 const Error& expression_error() const { return expression_error_; } 159 V8_INLINE const Error& expression_error() const {
128 160 return reported_error(kExpressionProduction);
129 const Error& formal_parameter_initializer_error() const {
130 return formal_parameter_initializer_error_;
131 } 161 }
132 162
133 const Error& binding_pattern_error() const { return binding_pattern_error_; } 163 V8_INLINE const Error& formal_parameter_initializer_error() const {
134 164 return reported_error(kFormalParameterInitializerProduction);
135 const Error& assignment_pattern_error() const {
136 return assignment_pattern_error_;
137 } 165 }
138 166
139 const Error& arrow_formal_parameters_error() const { 167 V8_INLINE const Error& binding_pattern_error() const {
140 return arrow_formal_parameters_error_; 168 return reported_error(kBindingPatternProduction);
141 } 169 }
142 170
143 const Error& duplicate_formal_parameter_error() const { 171 V8_INLINE const Error& assignment_pattern_error() const {
144 return duplicate_formal_parameter_error_; 172 return reported_error(kAssignmentPatternProduction);
145 } 173 }
146 174
147 const Error& strict_mode_formal_parameter_error() const { 175 V8_INLINE const Error& arrow_formal_parameters_error() const {
148 return strict_mode_formal_parameter_error_; 176 return reported_error(kArrowFormalParametersProduction);
149 } 177 }
150 178
151 const Error& let_pattern_error() const { return let_pattern_error_; } 179 V8_INLINE const Error& duplicate_formal_parameter_error() const {
180 return reported_error(kDistinctFormalParametersProduction);
181 }
152 182
153 bool has_cover_initialized_name() const { 183 V8_INLINE const Error& strict_mode_formal_parameter_error() const {
184 return reported_error(kStrictModeFormalParametersProduction);
185 }
186
187 V8_INLINE const Error& let_pattern_error() const {
188 return reported_error(kLetPatternProduction);
189 }
190
191 V8_INLINE bool has_cover_initialized_name() const {
154 return !is_valid(CoverInitializedNameProduction); 192 return !is_valid(CoverInitializedNameProduction);
155 } 193 }
156 const Error& cover_initialized_name_error() const { 194
157 return cover_initialized_name_error_; 195 V8_INLINE const Error& cover_initialized_name_error() const {
196 return reported_error(kCoverInitializedNameProduction);
158 } 197 }
159 198
160 bool has_tail_call_expression() const { 199 V8_INLINE bool has_tail_call_expression() const {
161 return !is_valid(TailCallExpressionProduction); 200 return !is_valid(TailCallExpressionProduction);
162 } 201 }
163 const Error& tail_call_expression_error() const { 202 V8_INLINE const Error& tail_call_expression_error() const {
164 return tail_call_expression_error_; 203 return reported_error(kTailCallExpressionProduction);
165 } 204 }
166 const Error& async_arrow_formal_parameters_error() const { 205 V8_INLINE const Error& async_arrow_formal_parameters_error() const {
167 return async_arrow_formal_parameters_error_; 206 return reported_error(kAsyncArrowFormalParametersProduction);
168 } 207 }
169 208
170 const Error& async_binding_pattern_error() const { 209 V8_INLINE const Error& async_binding_pattern_error() const {
171 return async_binding_pattern_error_; 210 return reported_error(kAsyncBindingPatternProduction);
172 } 211 }
173 212
174 bool is_simple_parameter_list() const { 213 V8_INLINE bool is_simple_parameter_list() const {
175 return !(function_properties_ & NonSimpleParameter); 214 return !(function_properties_ & NonSimpleParameter);
176 } 215 }
177 216
178 void RecordNonSimpleParameter() { 217 V8_INLINE void RecordNonSimpleParameter() {
179 function_properties_ |= NonSimpleParameter; 218 function_properties_ |= NonSimpleParameter;
180 } 219 }
181 220
182 void RecordExpressionError(const Scanner::Location& loc, 221 void RecordExpressionError(const Scanner::Location& loc,
183 MessageTemplate::Template message, 222 MessageTemplate::Template message,
184 const char* arg = nullptr) { 223 const char* arg = nullptr) {
185 if (!is_valid_expression()) return; 224 if (!is_valid_expression()) return;
186 invalid_productions_ |= ExpressionProduction; 225 invalid_productions_ |= ExpressionProduction;
187 expression_error_.location = loc; 226 Add(Error(loc, message, kExpressionProduction, arg));
188 expression_error_.message = message;
189 expression_error_.arg = arg;
190 } 227 }
191 228
192 void RecordExpressionError(const Scanner::Location& loc, 229 void RecordExpressionError(const Scanner::Location& loc,
193 MessageTemplate::Template message, 230 MessageTemplate::Template message,
194 ParseErrorType type, const char* arg = nullptr) { 231 ParseErrorType type, const char* arg = nullptr) {
195 if (!is_valid_expression()) return; 232 if (!is_valid_expression()) return;
196 invalid_productions_ |= ExpressionProduction; 233 invalid_productions_ |= ExpressionProduction;
197 expression_error_.location = loc; 234 Add(Error(loc, message, kExpressionProduction, arg, type));
198 expression_error_.message = message;
199 expression_error_.arg = arg;
200 expression_error_.type = type;
201 } 235 }
202 236
203 void RecordFormalParameterInitializerError(const Scanner::Location& loc, 237 void RecordFormalParameterInitializerError(const Scanner::Location& loc,
204 MessageTemplate::Template message, 238 MessageTemplate::Template message,
205 const char* arg = nullptr) { 239 const char* arg = nullptr) {
206 if (!is_valid_formal_parameter_initializer()) return; 240 if (!is_valid_formal_parameter_initializer()) return;
207 invalid_productions_ |= FormalParameterInitializerProduction; 241 invalid_productions_ |= FormalParameterInitializerProduction;
208 formal_parameter_initializer_error_.location = loc; 242 Add(Error(loc, message, kFormalParameterInitializerProduction, arg));
209 formal_parameter_initializer_error_.message = message; 243 }
210 formal_parameter_initializer_error_.arg = arg; 244
245 static Error BindingPatternError(const Scanner::Location& loc,
246 MessageTemplate::Template message,
247 const char* arg = nullptr) {
248 return Error(loc, message, kBindingPatternProduction, arg);
249 }
250
251 void RecordBindingPatternError(const Error& e) {
252 if (!is_valid_binding_pattern()) return;
253 invalid_productions_ |= BindingPatternProduction;
254 Add(e);
211 } 255 }
212 256
213 void RecordBindingPatternError(const Scanner::Location& loc, 257 void RecordBindingPatternError(const Scanner::Location& loc,
214 MessageTemplate::Template message, 258 MessageTemplate::Template message,
215 const char* arg = nullptr) { 259 const char* arg = nullptr) {
216 if (!is_valid_binding_pattern()) return; 260 RecordBindingPatternError(BindingPatternError(loc, message, arg));
217 invalid_productions_ |= BindingPatternProduction; 261 }
218 binding_pattern_error_.location = loc; 262
219 binding_pattern_error_.message = message; 263 static Error AssignmentPatternError(const Scanner::Location& loc,
220 binding_pattern_error_.arg = arg; 264 MessageTemplate::Template message,
265 const char* arg = nullptr) {
266 return Error(loc, message, kAssignmentPatternProduction, arg);
267 }
268
269 void RecordAssignmentPatternError(const Error& e) {
270 if (!is_valid_assignment_pattern()) return;
271 invalid_productions_ |= AssignmentPatternProduction;
272 Add(e);
221 } 273 }
222 274
223 void RecordAssignmentPatternError(const Scanner::Location& loc, 275 void RecordAssignmentPatternError(const Scanner::Location& loc,
224 MessageTemplate::Template message, 276 MessageTemplate::Template message,
225 const char* arg = nullptr) { 277 const char* arg = nullptr) {
226 if (!is_valid_assignment_pattern()) return; 278 RecordAssignmentPatternError(AssignmentPatternError(loc, message, arg));
227 invalid_productions_ |= AssignmentPatternProduction;
228 assignment_pattern_error_.location = loc;
229 assignment_pattern_error_.message = message;
230 assignment_pattern_error_.arg = arg;
231 } 279 }
232 280
233 void RecordPatternError(const Scanner::Location& loc, 281 void RecordPatternError(const Scanner::Location& loc,
234 MessageTemplate::Template message, 282 MessageTemplate::Template message,
235 const char* arg = nullptr) { 283 const char* arg = nullptr) {
236 RecordBindingPatternError(loc, message, arg); 284 RecordBindingPatternError(loc, message, arg);
237 RecordAssignmentPatternError(loc, message, arg); 285 RecordAssignmentPatternError(loc, message, arg);
238 } 286 }
239 287
240 void RecordArrowFormalParametersError(const Scanner::Location& loc, 288 void RecordArrowFormalParametersError(const Scanner::Location& loc,
241 MessageTemplate::Template message, 289 MessageTemplate::Template message,
242 const char* arg = nullptr) { 290 const char* arg = nullptr) {
243 if (!is_valid_arrow_formal_parameters()) return; 291 if (!is_valid_arrow_formal_parameters()) return;
244 invalid_productions_ |= ArrowFormalParametersProduction; 292 invalid_productions_ |= ArrowFormalParametersProduction;
245 arrow_formal_parameters_error_.location = loc; 293 Add(Error(loc, message, kArrowFormalParametersProduction, arg));
246 arrow_formal_parameters_error_.message = message;
247 arrow_formal_parameters_error_.arg = arg;
248 } 294 }
249 295
250 void RecordAsyncArrowFormalParametersError(const Scanner::Location& loc, 296 void RecordAsyncArrowFormalParametersError(const Scanner::Location& loc,
251 MessageTemplate::Template message, 297 MessageTemplate::Template message,
252 const char* arg = nullptr) { 298 const char* arg = nullptr) {
253 if (!is_valid_async_arrow_formal_parameters()) return; 299 if (!is_valid_async_arrow_formal_parameters()) return;
254 invalid_productions_ |= AsyncArrowFormalParametersProduction; 300 invalid_productions_ |= AsyncArrowFormalParametersProduction;
255 async_arrow_formal_parameters_error_.location = loc; 301 Add(Error(loc, message, kAsyncArrowFormalParametersProduction, arg));
256 async_arrow_formal_parameters_error_.message = message;
257 async_arrow_formal_parameters_error_.arg = arg;
258 } 302 }
259 303
260 void RecordAsyncBindingPatternError(const Scanner::Location& loc, 304 void RecordAsyncBindingPatternError(const Scanner::Location& loc,
261 MessageTemplate::Template message, 305 MessageTemplate::Template message,
262 const char* arg = nullptr) { 306 const char* arg = nullptr) {
263 if (!is_valid_async_binding_pattern()) return; 307 if (!is_valid_async_binding_pattern()) return;
264 invalid_productions_ |= AsyncBindingPatternProduction; 308 invalid_productions_ |= AsyncBindingPatternProduction;
265 async_binding_pattern_error_.location = loc; 309 Add(Error(loc, message, kAsyncBindingPatternProduction, arg));
266 async_binding_pattern_error_.message = message;
267 async_binding_pattern_error_.arg = arg;
268 } 310 }
269 311
270 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { 312 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
271 if (!is_valid_formal_parameter_list_without_duplicates()) return; 313 if (!is_valid_formal_parameter_list_without_duplicates()) return;
272 invalid_productions_ |= DistinctFormalParametersProduction; 314 invalid_productions_ |= DistinctFormalParametersProduction;
273 duplicate_formal_parameter_error_.location = loc; 315 Add(Error(loc, MessageTemplate::kParamDupe,
274 duplicate_formal_parameter_error_.message = MessageTemplate::kParamDupe; 316 kDistinctFormalParametersProduction));
275 duplicate_formal_parameter_error_.arg = nullptr;
276 } 317 }
277 318
278 // Record a binding that would be invalid in strict mode. Confusingly this 319 // Record a binding that would be invalid in strict mode. Confusingly this
279 // is not the same as StrictFormalParameterList, which simply forbids 320 // is not the same as StrictFormalParameterList, which simply forbids
280 // duplicate bindings. 321 // duplicate bindings.
281 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, 322 void RecordStrictModeFormalParameterError(const Scanner::Location& loc,
282 MessageTemplate::Template message, 323 MessageTemplate::Template message,
283 const char* arg = nullptr) { 324 const char* arg = nullptr) {
284 if (!is_valid_strict_mode_formal_parameters()) return; 325 if (!is_valid_strict_mode_formal_parameters()) return;
285 invalid_productions_ |= StrictModeFormalParametersProduction; 326 invalid_productions_ |= StrictModeFormalParametersProduction;
286 strict_mode_formal_parameter_error_.location = loc; 327 Add(Error(loc, message, kStrictModeFormalParametersProduction, arg));
287 strict_mode_formal_parameter_error_.message = message;
288 strict_mode_formal_parameter_error_.arg = arg;
289 } 328 }
290 329
291 void RecordLetPatternError(const Scanner::Location& loc, 330 void RecordLetPatternError(const Scanner::Location& loc,
292 MessageTemplate::Template message, 331 MessageTemplate::Template message,
293 const char* arg = nullptr) { 332 const char* arg = nullptr) {
294 if (!is_valid_let_pattern()) return; 333 if (!is_valid_let_pattern()) return;
295 invalid_productions_ |= LetPatternProduction; 334 invalid_productions_ |= LetPatternProduction;
296 let_pattern_error_.location = loc; 335 Add(Error(loc, message, kLetPatternProduction, arg));
297 let_pattern_error_.message = message;
298 let_pattern_error_.arg = arg;
299 } 336 }
300 337
301 void RecordCoverInitializedNameError(const Scanner::Location& loc, 338 void RecordCoverInitializedNameError(const Scanner::Location& loc,
302 MessageTemplate::Template message, 339 MessageTemplate::Template message,
303 const char* arg = nullptr) { 340 const char* arg = nullptr) {
304 if (has_cover_initialized_name()) return; 341 if (has_cover_initialized_name()) return;
305 invalid_productions_ |= CoverInitializedNameProduction; 342 invalid_productions_ |= CoverInitializedNameProduction;
306 cover_initialized_name_error_.location = loc; 343 Add(Error(loc, message, kCoverInitializedNameProduction, arg));
307 cover_initialized_name_error_.message = message;
308 cover_initialized_name_error_.arg = arg;
309 } 344 }
310 345
311 void RecordTailCallExpressionError(const Scanner::Location& loc, 346 void RecordTailCallExpressionError(const Scanner::Location& loc,
312 MessageTemplate::Template message, 347 MessageTemplate::Template message,
313 const char* arg = nullptr) { 348 const char* arg = nullptr) {
314 if (has_tail_call_expression()) return; 349 if (has_tail_call_expression()) return;
315 invalid_productions_ |= TailCallExpressionProduction; 350 invalid_productions_ |= TailCallExpressionProduction;
316 tail_call_expression_error_.location = loc; 351 Add(Error(loc, message, kTailCallExpressionProduction, arg));
317 tail_call_expression_error_.message = message;
318 tail_call_expression_error_.arg = arg;
319 } 352 }
320 353
321 void ForgiveCoverInitializedNameError() { 354 void ForgiveCoverInitializedNameError() {
355 if (!(invalid_productions_ & CoverInitializedNameProduction)) return;
322 invalid_productions_ &= ~CoverInitializedNameProduction; 356 invalid_productions_ &= ~CoverInitializedNameProduction;
nickie 2016/06/08 11:38:46 This was a bug, and fixed. Line 356 was moved aft
323 cover_initialized_name_error_ = Error(); 357 Error& e = reported_error(kCoverInitializedNameProduction);
358 e.kind = kUnusedError;
324 } 359 }
325 360
326 void ForgiveAssignmentPatternError() { 361 void ForgiveAssignmentPatternError() {
362 if (!(invalid_productions_ & AssignmentPatternProduction)) return;
327 invalid_productions_ &= ~AssignmentPatternProduction; 363 invalid_productions_ &= ~AssignmentPatternProduction;
nickie 2016/06/08 11:38:45 Same thing.
328 assignment_pattern_error_ = Error(); 364 Error& e = reported_error(kAssignmentPatternProduction);
365 e.kind = kUnusedError;
329 } 366 }
330 367
331 void Accumulate(ExpressionClassifier* inner, 368 void Accumulate(ExpressionClassifier* inner,
332 unsigned productions = StandardProductions, 369 unsigned productions = StandardProductions,
333 bool merge_non_patterns = true) { 370 bool merge_non_patterns = true) {
371 DCHECK_EQ(inner->reported_errors_, reported_errors_);
372 DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_);
373 DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length());
334 if (merge_non_patterns) MergeNonPatterns(inner); 374 if (merge_non_patterns) MergeNonPatterns(inner);
335 // Propagate errors from inner, but don't overwrite already recorded 375 // Propagate errors from inner, but don't overwrite already recorded
336 // errors. 376 // errors.
337 unsigned non_arrow_inner_invalid_productions = 377 unsigned non_arrow_inner_invalid_productions =
338 inner->invalid_productions_ & ~ArrowFormalParametersProduction; 378 inner->invalid_productions_ & ~ArrowFormalParametersProduction;
339 if (non_arrow_inner_invalid_productions == 0) return; 379 if (non_arrow_inner_invalid_productions) {
340 unsigned non_arrow_productions = 380 unsigned errors = non_arrow_inner_invalid_productions & productions &
341 productions & ~ArrowFormalParametersProduction; 381 ~invalid_productions_;
342 unsigned errors = 382 // As an exception to the above, the result continues to be a valid arrow
adamk 2016/06/06 20:51:02 This comment is now out-of-order (it refers to "ab
nickie 2016/06/08 11:38:45 I removed the beginning of the sentence.
343 non_arrow_productions & non_arrow_inner_invalid_productions; 383 // formal parameters if the inner expression is a valid binding pattern.
344 errors &= ~invalid_productions_; 384 if (productions & ArrowFormalParametersProduction &&
345 if (errors != 0) { 385 is_valid_arrow_formal_parameters()) {
346 invalid_productions_ |= errors; 386 // Also copy function properties if expecting an arrow function
347 if (errors & ExpressionProduction) 387 // parameter.
348 expression_error_ = inner->expression_error_; 388 function_properties_ |= inner->function_properties_;
349 if (errors & FormalParameterInitializerProduction)
350 formal_parameter_initializer_error_ =
351 inner->formal_parameter_initializer_error_;
352 if (errors & BindingPatternProduction)
353 binding_pattern_error_ = inner->binding_pattern_error_;
354 if (errors & AssignmentPatternProduction)
355 assignment_pattern_error_ = inner->assignment_pattern_error_;
356 if (errors & DistinctFormalParametersProduction)
357 duplicate_formal_parameter_error_ =
358 inner->duplicate_formal_parameter_error_;
359 if (errors & StrictModeFormalParametersProduction)
360 strict_mode_formal_parameter_error_ =
361 inner->strict_mode_formal_parameter_error_;
362 if (errors & LetPatternProduction)
363 let_pattern_error_ = inner->let_pattern_error_;
364 if (errors & CoverInitializedNameProduction)
365 cover_initialized_name_error_ = inner->cover_initialized_name_error_;
366 if (errors & TailCallExpressionProduction)
367 tail_call_expression_error_ = inner->tail_call_expression_error_;
368 if (errors & AsyncArrowFormalParametersProduction)
369 async_arrow_formal_parameters_error_ =
370 inner->async_arrow_formal_parameters_error_;
371 if (errors & AsyncBindingPatternProduction)
372 async_binding_pattern_error_ = inner->async_binding_pattern_error_;
373 }
374 389
375 // As an exception to the above, the result continues to be a valid arrow 390 if (!inner->is_valid_binding_pattern())
376 // formal parameters if the inner expression is a valid binding pattern. 391 errors |= ArrowFormalParametersProduction;
377 if (productions & ArrowFormalParametersProduction && 392 }
378 is_valid_arrow_formal_parameters()) {
379 // Also copy function properties if expecting an arrow function
380 // parameter.
381 function_properties_ |= inner->function_properties_;
382 393
383 if (!inner->is_valid_binding_pattern()) { 394 if (errors != 0) {
384 invalid_productions_ |= ArrowFormalParametersProduction; 395 invalid_productions_ |= errors;
385 arrow_formal_parameters_error_ = inner->binding_pattern_error_; 396 int arrow_index = inner->reported_errors_end_;
397 for (int i = inner->reported_errors_begin_;
398 i < inner->reported_errors_end_; i++) {
399 if (reported_errors_->at(i).kind == kUnusedError ||
400 reported_errors_->at(i).kind == kArrowFormalParametersProduction)
401 continue;
402 if (errors & (1 << reported_errors_->at(i).kind))
403 Move(i);
404 if (reported_errors_->at(i).kind == kBindingPatternProduction &&
405 errors & ArrowFormalParametersProduction) {
406 if (reported_errors_end_ <= i) {
407 Move(i);
408 reported_errors_->at(reported_errors_end_-1).kind =
409 kArrowFormalParametersProduction;
410 } else {
411 DCHECK_EQ(reported_errors_end_, i+1);
412 arrow_index = i;
413 }
414 }
415 }
416 if (arrow_index < inner->reported_errors_end_) {
417 if (reported_errors_end_ < inner->reported_errors_end_) {
418 Replace(reported_errors_end_, arrow_index);
419 reported_errors_->at(reported_errors_end_++).kind =
420 kArrowFormalParametersProduction;
421 } else {
422 Add(reported_errors_->at(arrow_index));
423 reported_errors_->at(reported_errors_end_-1).kind =
424 kArrowFormalParametersProduction;
425 }
426 }
386 } 427 }
387 } 428 }
429 reported_errors_->Rewind(reported_errors_end_);
430 inner->reported_errors_begin_ = inner->reported_errors_end_ =
431 reported_errors_end_;
388 } 432 }
389 433
390 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } 434 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; }
391 435
392 V8_INLINE void Discard() { 436 V8_INLINE void Discard() {
437 if (reported_errors_end_ == reported_errors_->length()) {
438 reported_errors_->Rewind(reported_errors_begin_);
439 reported_errors_end_ = reported_errors_begin_;
440 }
441 DCHECK_EQ(reported_errors_begin_, reported_errors_end_);
393 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length()); 442 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length());
394 non_patterns_to_rewrite_->Rewind(non_pattern_begin_); 443 non_patterns_to_rewrite_->Rewind(non_pattern_begin_);
395 } 444 }
396 445
397 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) { 446 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) {
398 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_); 447 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_);
399 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length(); 448 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length();
400 } 449 }
401 450
402 private: 451 private:
452 V8_INLINE Error& reported_error(ErrorKind kind) const {
453 if (invalid_productions_ & (1 << kind)) {
454 for (int i = reported_errors_begin_; i < reported_errors_end_; i++) {
455 if (reported_errors_->at(i).kind == kind)
456 return reported_errors_->at(i);
457 }
nickie 2016/06/08 11:38:46 I'm introducing an UNREACHABLE() here, partly to a
458 }
459 // We should only be looking for an error when we know that one has
460 // been reported. But we're not... So this is to make sure we have
adamk 2016/06/06 20:51:02 This sounds odd, where does this show up?
nickie 2016/06/08 11:38:46 If you replace these lines with UNREACHABLE(), you
461 // the same behaviour.
462 static Error none;
463 return none;
464 }
465
466 V8_INLINE void Add(const Error& e) {
adamk 2016/06/06 20:51:02 Can you give each of Add, Move, and Replace a comm
nickie 2016/06/08 11:38:46 Done. I simplified this by merging Move and Repla
467 DCHECK_EQ(reported_errors_end_, reported_errors_->length());
468 reported_errors_->Add(e, zone_);
469 reported_errors_end_++;
470 }
471
472 V8_INLINE void Move(int i) {
473 DCHECK_LE(reported_errors_end_, i);
474 DCHECK_LT(i, reported_errors_->length());
475 if (reported_errors_end_ < i)
476 reported_errors_->at(reported_errors_end_) = reported_errors_->at(i);
477 reported_errors_end_++;
478 }
479
480 V8_INLINE void Replace(int j, int i) {
481 DCHECK_LT(i, reported_errors_->length());
482 DCHECK_LE(j, reported_errors_end_);
483 DCHECK(j == reported_errors_end_ ||
484 reported_errors_->at(j).kind == kUnusedError);
485 if (i != j) reported_errors_->at(j) = reported_errors_->at(i);
486 }
487
403 Zone* zone_; 488 Zone* zone_;
404 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; 489 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_;
405 int non_pattern_begin_; 490 int non_pattern_begin_;
406 unsigned invalid_productions_; 491 unsigned invalid_productions_ : 14;
407 unsigned function_properties_; 492 unsigned function_properties_ : 2;
408 // TODO(ishell): consider using Zone[Hash]Map<TargetProduction, Error> 493 ZoneList<Error>* reported_errors_;
409 // here to consume less stack space during parsing. 494 int reported_errors_begin_;
410 Error expression_error_; 495 int reported_errors_end_;
411 Error formal_parameter_initializer_error_;
412 Error binding_pattern_error_;
413 Error assignment_pattern_error_;
414 Error arrow_formal_parameters_error_;
415 Error duplicate_formal_parameter_error_;
416 Error strict_mode_formal_parameter_error_;
417 Error let_pattern_error_;
418 Error cover_initialized_name_error_;
419 Error tail_call_expression_error_;
420 Error async_arrow_formal_parameters_error_;
421 Error async_binding_pattern_error_;
422 DuplicateFinder* duplicate_finder_; 496 DuplicateFinder* duplicate_finder_;
423 }; 497 };
424 498
425 499
500 #undef ERROR_CODES
501
502
426 } // namespace internal 503 } // namespace internal
427 } // namespace v8 504 } // namespace v8
428 505
429 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H 506 #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