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

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: More fixes and space savings 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/parsing/parser.h » ('j') | no next file with comments »
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()),
88 reported_errors_(t->GetReportedErrorList()),
89 duplicate_finder_(nullptr),
66 invalid_productions_(0), 90 invalid_productions_(0),
67 function_properties_(0), 91 function_properties_(0) {
68 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()),
99 reported_errors_(t->GetReportedErrorList()),
100 duplicate_finder_(duplicate_finder),
75 invalid_productions_(0), 101 invalid_productions_(0),
76 function_properties_(0), 102 function_properties_(0) {
77 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;
210 formal_parameter_initializer_error_.arg = arg;
211 } 243 }
212 244
213 void RecordBindingPatternError(const Scanner::Location& loc, 245 void RecordBindingPatternError(const Scanner::Location& loc,
214 MessageTemplate::Template message, 246 MessageTemplate::Template message,
215 const char* arg = nullptr) { 247 const char* arg = nullptr) {
216 if (!is_valid_binding_pattern()) return; 248 if (!is_valid_binding_pattern()) return;
217 invalid_productions_ |= BindingPatternProduction; 249 invalid_productions_ |= BindingPatternProduction;
218 binding_pattern_error_.location = loc; 250 Add(Error(loc, message, kBindingPatternProduction, arg));
219 binding_pattern_error_.message = message;
220 binding_pattern_error_.arg = arg;
221 } 251 }
222 252
223 void RecordAssignmentPatternError(const Scanner::Location& loc, 253 void RecordAssignmentPatternError(const Scanner::Location& loc,
224 MessageTemplate::Template message, 254 MessageTemplate::Template message,
225 const char* arg = nullptr) { 255 const char* arg = nullptr) {
226 if (!is_valid_assignment_pattern()) return; 256 if (!is_valid_assignment_pattern()) return;
227 invalid_productions_ |= AssignmentPatternProduction; 257 invalid_productions_ |= AssignmentPatternProduction;
228 assignment_pattern_error_.location = loc; 258 Add(Error(loc, message, kAssignmentPatternProduction, arg));
229 assignment_pattern_error_.message = message;
230 assignment_pattern_error_.arg = arg;
231 } 259 }
232 260
233 void RecordPatternError(const Scanner::Location& loc, 261 void RecordPatternError(const Scanner::Location& loc,
234 MessageTemplate::Template message, 262 MessageTemplate::Template message,
235 const char* arg = nullptr) { 263 const char* arg = nullptr) {
236 RecordBindingPatternError(loc, message, arg); 264 RecordBindingPatternError(loc, message, arg);
237 RecordAssignmentPatternError(loc, message, arg); 265 RecordAssignmentPatternError(loc, message, arg);
238 } 266 }
239 267
240 void RecordArrowFormalParametersError(const Scanner::Location& loc, 268 void RecordArrowFormalParametersError(const Scanner::Location& loc,
241 MessageTemplate::Template message, 269 MessageTemplate::Template message,
242 const char* arg = nullptr) { 270 const char* arg = nullptr) {
243 if (!is_valid_arrow_formal_parameters()) return; 271 if (!is_valid_arrow_formal_parameters()) return;
244 invalid_productions_ |= ArrowFormalParametersProduction; 272 invalid_productions_ |= ArrowFormalParametersProduction;
245 arrow_formal_parameters_error_.location = loc; 273 Add(Error(loc, message, kArrowFormalParametersProduction, arg));
246 arrow_formal_parameters_error_.message = message;
247 arrow_formal_parameters_error_.arg = arg;
248 } 274 }
249 275
250 void RecordAsyncArrowFormalParametersError(const Scanner::Location& loc, 276 void RecordAsyncArrowFormalParametersError(const Scanner::Location& loc,
251 MessageTemplate::Template message, 277 MessageTemplate::Template message,
252 const char* arg = nullptr) { 278 const char* arg = nullptr) {
253 if (!is_valid_async_arrow_formal_parameters()) return; 279 if (!is_valid_async_arrow_formal_parameters()) return;
254 invalid_productions_ |= AsyncArrowFormalParametersProduction; 280 invalid_productions_ |= AsyncArrowFormalParametersProduction;
255 async_arrow_formal_parameters_error_.location = loc; 281 Add(Error(loc, message, kAsyncArrowFormalParametersProduction, arg));
256 async_arrow_formal_parameters_error_.message = message;
257 async_arrow_formal_parameters_error_.arg = arg;
258 } 282 }
259 283
260 void RecordAsyncBindingPatternError(const Scanner::Location& loc, 284 void RecordAsyncBindingPatternError(const Scanner::Location& loc,
261 MessageTemplate::Template message, 285 MessageTemplate::Template message,
262 const char* arg = nullptr) { 286 const char* arg = nullptr) {
263 if (!is_valid_async_binding_pattern()) return; 287 if (!is_valid_async_binding_pattern()) return;
264 invalid_productions_ |= AsyncBindingPatternProduction; 288 invalid_productions_ |= AsyncBindingPatternProduction;
265 async_binding_pattern_error_.location = loc; 289 Add(Error(loc, message, kAsyncBindingPatternProduction, arg));
266 async_binding_pattern_error_.message = message;
267 async_binding_pattern_error_.arg = arg;
268 } 290 }
269 291
270 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { 292 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
271 if (!is_valid_formal_parameter_list_without_duplicates()) return; 293 if (!is_valid_formal_parameter_list_without_duplicates()) return;
272 invalid_productions_ |= DistinctFormalParametersProduction; 294 invalid_productions_ |= DistinctFormalParametersProduction;
273 duplicate_formal_parameter_error_.location = loc; 295 Add(Error(loc, MessageTemplate::kParamDupe,
274 duplicate_formal_parameter_error_.message = MessageTemplate::kParamDupe; 296 kDistinctFormalParametersProduction));
275 duplicate_formal_parameter_error_.arg = nullptr;
276 } 297 }
277 298
278 // Record a binding that would be invalid in strict mode. Confusingly this 299 // Record a binding that would be invalid in strict mode. Confusingly this
279 // is not the same as StrictFormalParameterList, which simply forbids 300 // is not the same as StrictFormalParameterList, which simply forbids
280 // duplicate bindings. 301 // duplicate bindings.
281 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, 302 void RecordStrictModeFormalParameterError(const Scanner::Location& loc,
282 MessageTemplate::Template message, 303 MessageTemplate::Template message,
283 const char* arg = nullptr) { 304 const char* arg = nullptr) {
284 if (!is_valid_strict_mode_formal_parameters()) return; 305 if (!is_valid_strict_mode_formal_parameters()) return;
285 invalid_productions_ |= StrictModeFormalParametersProduction; 306 invalid_productions_ |= StrictModeFormalParametersProduction;
286 strict_mode_formal_parameter_error_.location = loc; 307 Add(Error(loc, message, kStrictModeFormalParametersProduction, arg));
287 strict_mode_formal_parameter_error_.message = message;
288 strict_mode_formal_parameter_error_.arg = arg;
289 } 308 }
290 309
291 void RecordLetPatternError(const Scanner::Location& loc, 310 void RecordLetPatternError(const Scanner::Location& loc,
292 MessageTemplate::Template message, 311 MessageTemplate::Template message,
293 const char* arg = nullptr) { 312 const char* arg = nullptr) {
294 if (!is_valid_let_pattern()) return; 313 if (!is_valid_let_pattern()) return;
295 invalid_productions_ |= LetPatternProduction; 314 invalid_productions_ |= LetPatternProduction;
296 let_pattern_error_.location = loc; 315 Add(Error(loc, message, kLetPatternProduction, arg));
297 let_pattern_error_.message = message;
298 let_pattern_error_.arg = arg;
299 } 316 }
300 317
301 void RecordCoverInitializedNameError(const Scanner::Location& loc, 318 void RecordCoverInitializedNameError(const Scanner::Location& loc,
302 MessageTemplate::Template message, 319 MessageTemplate::Template message,
303 const char* arg = nullptr) { 320 const char* arg = nullptr) {
304 if (has_cover_initialized_name()) return; 321 if (has_cover_initialized_name()) return;
305 invalid_productions_ |= CoverInitializedNameProduction; 322 invalid_productions_ |= CoverInitializedNameProduction;
306 cover_initialized_name_error_.location = loc; 323 Add(Error(loc, message, kCoverInitializedNameProduction, arg));
307 cover_initialized_name_error_.message = message;
308 cover_initialized_name_error_.arg = arg;
309 } 324 }
310 325
311 void RecordTailCallExpressionError(const Scanner::Location& loc, 326 void RecordTailCallExpressionError(const Scanner::Location& loc,
312 MessageTemplate::Template message, 327 MessageTemplate::Template message,
313 const char* arg = nullptr) { 328 const char* arg = nullptr) {
314 if (has_tail_call_expression()) return; 329 if (has_tail_call_expression()) return;
315 invalid_productions_ |= TailCallExpressionProduction; 330 invalid_productions_ |= TailCallExpressionProduction;
316 tail_call_expression_error_.location = loc; 331 Add(Error(loc, message, kTailCallExpressionProduction, arg));
317 tail_call_expression_error_.message = message;
318 tail_call_expression_error_.arg = arg;
319 } 332 }
320 333
321 void ForgiveCoverInitializedNameError() { 334 void ForgiveCoverInitializedNameError() {
335 if (!(invalid_productions_ & CoverInitializedNameProduction)) return;
336 Error& e = reported_error(kCoverInitializedNameProduction);
337 e.kind = kUnusedError;
322 invalid_productions_ &= ~CoverInitializedNameProduction; 338 invalid_productions_ &= ~CoverInitializedNameProduction;
323 cover_initialized_name_error_ = Error();
324 } 339 }
325 340
326 void ForgiveAssignmentPatternError() { 341 void ForgiveAssignmentPatternError() {
342 if (!(invalid_productions_ & AssignmentPatternProduction)) return;
343 Error& e = reported_error(kAssignmentPatternProduction);
344 e.kind = kUnusedError;
327 invalid_productions_ &= ~AssignmentPatternProduction; 345 invalid_productions_ &= ~AssignmentPatternProduction;
328 assignment_pattern_error_ = Error();
329 } 346 }
330 347
331 void Accumulate(ExpressionClassifier* inner, 348 void Accumulate(ExpressionClassifier* inner,
332 unsigned productions = StandardProductions, 349 unsigned productions = StandardProductions,
333 bool merge_non_patterns = true) { 350 bool merge_non_patterns = true) {
351 DCHECK_EQ(inner->reported_errors_, reported_errors_);
352 DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_);
353 DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length());
334 if (merge_non_patterns) MergeNonPatterns(inner); 354 if (merge_non_patterns) MergeNonPatterns(inner);
335 // Propagate errors from inner, but don't overwrite already recorded 355 // Propagate errors from inner, but don't overwrite already recorded
336 // errors. 356 // errors.
337 unsigned non_arrow_inner_invalid_productions = 357 unsigned non_arrow_inner_invalid_productions =
338 inner->invalid_productions_ & ~ArrowFormalParametersProduction; 358 inner->invalid_productions_ & ~ArrowFormalParametersProduction;
339 if (non_arrow_inner_invalid_productions == 0) return; 359 if (non_arrow_inner_invalid_productions) {
340 unsigned non_arrow_productions = 360 unsigned errors = non_arrow_inner_invalid_productions & productions &
341 productions & ~ArrowFormalParametersProduction; 361 ~invalid_productions_;
342 unsigned errors = 362 // The result will continue to be a valid arrow formal parameters if the
343 non_arrow_productions & non_arrow_inner_invalid_productions; 363 // inner expression is a valid binding pattern.
344 errors &= ~invalid_productions_; 364 bool copy_BP_to_AFP = false;
345 if (errors != 0) { 365 if (productions & ArrowFormalParametersProduction &&
346 invalid_productions_ |= errors; 366 is_valid_arrow_formal_parameters()) {
347 if (errors & ExpressionProduction) 367 // Also copy function properties if expecting an arrow function
348 expression_error_ = inner->expression_error_; 368 // parameter.
349 if (errors & FormalParameterInitializerProduction) 369 function_properties_ |= inner->function_properties_;
350 formal_parameter_initializer_error_ = 370 if (!inner->is_valid_binding_pattern()) {
351 inner->formal_parameter_initializer_error_; 371 copy_BP_to_AFP = true;
352 if (errors & BindingPatternProduction) 372 invalid_productions_ |= ArrowFormalParametersProduction;
353 binding_pattern_error_ = inner->binding_pattern_error_; 373 }
354 if (errors & AssignmentPatternProduction) 374 }
355 assignment_pattern_error_ = inner->assignment_pattern_error_; 375 // Traverse the list of errors reported by the inner classifier
356 if (errors & DistinctFormalParametersProduction) 376 // to copy what's necessary.
357 duplicate_formal_parameter_error_ = 377 if (errors != 0 || copy_BP_to_AFP) {
358 inner->duplicate_formal_parameter_error_; 378 invalid_productions_ |= errors;
359 if (errors & StrictModeFormalParametersProduction) 379 int binding_pattern_index = inner->reported_errors_end_;
360 strict_mode_formal_parameter_error_ = 380 for (int i = inner->reported_errors_begin_;
361 inner->strict_mode_formal_parameter_error_; 381 i < inner->reported_errors_end_; i++) {
362 if (errors & LetPatternProduction) 382 int k = reported_errors_->at(i).kind;
363 let_pattern_error_ = inner->let_pattern_error_; 383 if (errors & (1 << k)) Copy(i);
364 if (errors & CoverInitializedNameProduction) 384 // Check if it's a BP error that has to be copied to an AFP error.
365 cover_initialized_name_error_ = inner->cover_initialized_name_error_; 385 if (k == kBindingPatternProduction && copy_BP_to_AFP) {
366 if (errors & TailCallExpressionProduction) 386 if (reported_errors_end_ <= i) {
367 tail_call_expression_error_ = inner->tail_call_expression_error_; 387 // If the BP error itself has not already been copied,
368 if (errors & AsyncArrowFormalParametersProduction) 388 // copy it now and change it to an AFP error.
369 async_arrow_formal_parameters_error_ = 389 Copy(i);
370 inner->async_arrow_formal_parameters_error_; 390 reported_errors_->at(reported_errors_end_-1).kind =
371 if (errors & AsyncBindingPatternProduction) 391 kArrowFormalParametersProduction;
372 async_binding_pattern_error_ = inner->async_binding_pattern_error_; 392 } else {
373 } 393 // Otherwise, if the BP error was already copied, keep its
374 394 // position and wait until the end of the traversal.
375 // As an exception to the above, the result continues to be a valid arrow 395 DCHECK_EQ(reported_errors_end_, i+1);
376 // formal parameters if the inner expression is a valid binding pattern. 396 binding_pattern_index = i;
377 if (productions & ArrowFormalParametersProduction && 397 }
378 is_valid_arrow_formal_parameters()) { 398 }
379 // Also copy function properties if expecting an arrow function 399 }
380 // parameter. 400 // Do we still have to copy the BP error to an AFP error?
381 function_properties_ |= inner->function_properties_; 401 if (binding_pattern_index < inner->reported_errors_end_) {
382 402 // If there's still unused space in the list of the inner
383 if (!inner->is_valid_binding_pattern()) { 403 // classifier, copy it there, otherwise add it to the end
384 invalid_productions_ |= ArrowFormalParametersProduction; 404 // of the list.
385 arrow_formal_parameters_error_ = inner->binding_pattern_error_; 405 if (reported_errors_end_ < inner->reported_errors_end_)
406 Copy(binding_pattern_index);
407 else
408 Add(reported_errors_->at(binding_pattern_index));
409 reported_errors_->at(reported_errors_end_-1).kind =
410 kArrowFormalParametersProduction;
411 }
386 } 412 }
387 } 413 }
414 reported_errors_->Rewind(reported_errors_end_);
415 inner->reported_errors_begin_ = inner->reported_errors_end_ =
416 reported_errors_end_;
388 } 417 }
389 418
390 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } 419 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; }
391 420
392 V8_INLINE void Discard() { 421 V8_INLINE void Discard() {
422 if (reported_errors_end_ == reported_errors_->length()) {
423 reported_errors_->Rewind(reported_errors_begin_);
424 reported_errors_end_ = reported_errors_begin_;
425 }
426 DCHECK_EQ(reported_errors_begin_, reported_errors_end_);
393 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length()); 427 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length());
394 non_patterns_to_rewrite_->Rewind(non_pattern_begin_); 428 non_patterns_to_rewrite_->Rewind(non_pattern_begin_);
395 } 429 }
396 430
397 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) { 431 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) {
398 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_); 432 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_);
399 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length(); 433 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length();
400 } 434 }
401 435
402 private: 436 private:
437 V8_INLINE Error& reported_error(ErrorKind kind) const {
438 if (invalid_productions_ & (1 << kind)) {
439 for (int i = reported_errors_begin_; i < reported_errors_end_; i++) {
440 if (reported_errors_->at(i).kind == kind)
441 return reported_errors_->at(i);
442 }
443 UNREACHABLE();
444 }
445 // We should only be looking for an error when we know that one has
446 // been reported. But we're not... So this is to make sure we have
447 // the same behaviour.
448 static Error none;
449 return none;
450 }
451
452 // Adds e to the end of the list of reported errors for this classifier.
453 // It is expected that this classifier is the last one in the stack.
454 V8_INLINE void Add(const Error& e) {
455 DCHECK_EQ(reported_errors_end_, reported_errors_->length());
456 reported_errors_->Add(e, zone_);
457 reported_errors_end_++;
458 }
459
460 // Copies the error at position i of the list of reported errors, so that
461 // it becomes the last error reported for this classifier. Position i
462 // could be either after the existing errors of this classifier (i.e.,
463 // in an inner classifier) or it could be an existing error (in case a
464 // copy is needed).
465 V8_INLINE void Copy(int i) {
466 DCHECK_LE(reported_errors_end_, i);
467 DCHECK_LT(i, reported_errors_->length());
468 if (reported_errors_end_ != i)
469 reported_errors_->at(reported_errors_end_) = reported_errors_->at(i);
470 reported_errors_end_++;
471 }
472
403 Zone* zone_; 473 Zone* zone_;
404 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; 474 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_;
405 int non_pattern_begin_; 475 ZoneList<Error>* reported_errors_;
406 unsigned invalid_productions_;
407 unsigned function_properties_;
408 // TODO(ishell): consider using Zone[Hash]Map<TargetProduction, Error>
409 // here to consume less stack space during parsing.
410 Error expression_error_;
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_; 476 DuplicateFinder* duplicate_finder_;
477 uint16_t non_pattern_begin_;
478 unsigned invalid_productions_ : 14;
479 unsigned function_properties_ : 2;
480 uint16_t reported_errors_begin_;
adamk 2016/06/09 15:30:01 Can you add a comment here mentioning that these a
nickie 2016/06/10 13:19:39 Done.
481 uint16_t reported_errors_end_;
423 }; 482 };
424 483
425 484
485 #undef ERROR_CODES
486
487
426 } // namespace internal 488 } // namespace internal
427 } // namespace v8 489 } // namespace v8
428 490
429 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H 491 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H
OLDNEW
« no previous file with comments | « no previous file | src/parsing/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698