OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/hashmap.h" | 10 #include "src/hashmap.h" |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 DestructuringAssignment(ExpressionT expression, Scope* scope) | 187 DestructuringAssignment(ExpressionT expression, Scope* scope) |
188 : assignment(expression), scope(scope) {} | 188 : assignment(expression), scope(scope) {} |
189 | 189 |
190 ExpressionT assignment; | 190 ExpressionT assignment; |
191 Scope* scope; | 191 Scope* scope; |
192 }; | 192 }; |
193 | 193 |
194 class TailCallExpressionList { | 194 class TailCallExpressionList { |
195 public: | 195 public: |
196 explicit TailCallExpressionList(Zone* zone) | 196 explicit TailCallExpressionList(Zone* zone) |
197 : zone_(zone), expressions_(0, zone) {} | 197 : zone_(zone), expressions_(0, zone), has_explicit_tail_calls_(false) {} |
198 | 198 |
199 const ZoneList<ExpressionT>& expressions() const { return expressions_; } | 199 const ZoneList<ExpressionT>& expressions() const { return expressions_; } |
200 const Scanner::Location& location() const { return loc_; } | 200 const Scanner::Location& location() const { return loc_; } |
201 | 201 |
202 bool is_empty() const { return expressions_.is_empty(); } | 202 bool has_explicit_tail_calls() const { return has_explicit_tail_calls_; } |
203 | 203 |
204 void Swap(TailCallExpressionList& other) { | 204 void Swap(TailCallExpressionList& other) { |
205 expressions_.Swap(&other.expressions_); | 205 expressions_.Swap(&other.expressions_); |
206 std::swap(loc_, other.loc_); | 206 std::swap(loc_, other.loc_); |
| 207 std::swap(has_explicit_tail_calls_, other.has_explicit_tail_calls_); |
207 } | 208 } |
208 | 209 |
209 void Add(ExpressionT expr, const Scanner::Location& loc) { | 210 void AddImplicitTailCall(ExpressionT expr) { |
210 if (expressions_.is_empty()) loc_ = loc; | 211 expressions_.Add(expr, zone_); |
| 212 } |
| 213 |
| 214 void AddExplicitTailCall(ExpressionT expr, const Scanner::Location& loc) { |
| 215 if (!has_explicit_tail_calls()) { |
| 216 loc_ = loc; |
| 217 has_explicit_tail_calls_ = true; |
| 218 } |
211 expressions_.Add(expr, zone_); | 219 expressions_.Add(expr, zone_); |
212 } | 220 } |
213 | 221 |
214 void Append(const TailCallExpressionList& other) { | 222 void Append(const TailCallExpressionList& other) { |
215 if (expressions_.is_empty()) loc_ = other.loc_; | 223 if (!has_explicit_tail_calls()) { |
| 224 loc_ = other.loc_; |
| 225 has_explicit_tail_calls_ = other.has_explicit_tail_calls_; |
| 226 } |
216 expressions_.AddAll(other.expressions_, zone_); | 227 expressions_.AddAll(other.expressions_, zone_); |
217 } | 228 } |
218 | 229 |
219 private: | 230 private: |
220 Zone* zone_; | 231 Zone* zone_; |
221 ZoneList<ExpressionT> expressions_; | 232 ZoneList<ExpressionT> expressions_; |
222 Scanner::Location loc_; | 233 Scanner::Location loc_; |
| 234 bool has_explicit_tail_calls_; |
223 }; | 235 }; |
224 | 236 |
225 // Defines whether tail call expressions are allowed or not. | 237 // Defines whether tail call expressions are allowed or not. |
226 enum class ReturnExprContext { | 238 enum class ReturnExprContext { |
227 // We are inside return statement which is allowed to contain tail call | 239 // We are inside return statement which is allowed to contain tail call |
228 // expressions. Tail call expressions are allowed. | 240 // expressions. Tail call expressions are allowed. |
229 kInsideValidReturnStatement, | 241 kInsideValidReturnStatement, |
230 | 242 |
231 // We are inside a block in which tail call expressions are allowed but | 243 // We are inside a block in which tail call expressions are allowed but |
232 // not yet inside a return statement. | 244 // not yet inside a return statement. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 typename Traits::Type::Factory* factory() { return factory_; } | 302 typename Traits::Type::Factory* factory() { return factory_; } |
291 | 303 |
292 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 304 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
293 const { | 305 const { |
294 return destructuring_assignments_to_rewrite_; | 306 return destructuring_assignments_to_rewrite_; |
295 } | 307 } |
296 | 308 |
297 TailCallExpressionList& tail_call_expressions() { | 309 TailCallExpressionList& tail_call_expressions() { |
298 return tail_call_expressions_; | 310 return tail_call_expressions_; |
299 } | 311 } |
300 void AddExpressionInTailPosition(ExpressionT expression, | 312 void AddImplicitTailCallExpression(ExpressionT expression) { |
301 const Scanner::Location& loc) { | |
302 // If only FLAG_harmony_explicit_tailcalls is enabled then expression | |
303 // must be a Call expression. | |
304 DCHECK(FLAG_harmony_tailcalls || !FLAG_harmony_explicit_tailcalls || | |
305 expression->IsCall()); | |
306 if (return_expr_context() == | 313 if (return_expr_context() == |
307 ReturnExprContext::kInsideValidReturnStatement) { | 314 ReturnExprContext::kInsideValidReturnStatement) { |
308 tail_call_expressions_.Add(expression, loc); | 315 tail_call_expressions_.AddImplicitTailCall(expression); |
| 316 } |
| 317 } |
| 318 void AddExplicitTailCallExpression(ExpressionT expression, |
| 319 const Scanner::Location& loc) { |
| 320 DCHECK(expression->IsCall()); |
| 321 if (return_expr_context() == |
| 322 ReturnExprContext::kInsideValidReturnStatement) { |
| 323 tail_call_expressions_.AddExplicitTailCall(expression, loc); |
309 } | 324 } |
310 } | 325 } |
311 | 326 |
312 ReturnExprContext return_expr_context() const { | 327 ReturnExprContext return_expr_context() const { |
313 return return_expr_context_; | 328 return return_expr_context_; |
314 } | 329 } |
315 void set_return_expr_context(ReturnExprContext context) { | 330 void set_return_expr_context(ReturnExprContext context) { |
316 return_expr_context_ = context; | 331 return_expr_context_ = context; |
317 } | 332 } |
318 | 333 |
(...skipping 1943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2262 case ReturnExprContext::kInsideForInOfBody: | 2277 case ReturnExprContext::kInsideForInOfBody: |
2263 msg = MessageTemplate::kUnexpectedTailCallInForInOf; | 2278 msg = MessageTemplate::kUnexpectedTailCallInForInOf; |
2264 break; | 2279 break; |
2265 } | 2280 } |
2266 ReportMessageAt(loc, msg); | 2281 ReportMessageAt(loc, msg); |
2267 *ok = false; | 2282 *ok = false; |
2268 return Traits::EmptyExpression(); | 2283 return Traits::EmptyExpression(); |
2269 } | 2284 } |
2270 classifier->RecordTailCallExpressionError( | 2285 classifier->RecordTailCallExpressionError( |
2271 loc, MessageTemplate::kUnexpectedTailCall); | 2286 loc, MessageTemplate::kUnexpectedTailCall); |
2272 function_state_->AddExpressionInTailPosition(expression, loc); | 2287 function_state_->AddExplicitTailCallExpression(expression, loc); |
2273 return expression; | 2288 return expression; |
2274 } | 2289 } |
2275 | 2290 |
2276 // Precedence = 3 | 2291 // Precedence = 3 |
2277 template <class Traits> | 2292 template <class Traits> |
2278 typename ParserBase<Traits>::ExpressionT | 2293 typename ParserBase<Traits>::ExpressionT |
2279 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, | 2294 ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, |
2280 ExpressionClassifier* classifier, | 2295 ExpressionClassifier* classifier, |
2281 bool* ok) { | 2296 bool* ok) { |
2282 // ConditionalExpression :: | 2297 // ConditionalExpression :: |
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3322 has_seen_constructor_ = true; | 3337 has_seen_constructor_ = true; |
3323 return; | 3338 return; |
3324 } | 3339 } |
3325 } | 3340 } |
3326 | 3341 |
3327 | 3342 |
3328 } // namespace internal | 3343 } // namespace internal |
3329 } // namespace v8 | 3344 } // namespace v8 |
3330 | 3345 |
3331 #endif // V8_PARSING_PARSER_BASE_H | 3346 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |