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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 | 183 |
184 struct DestructuringAssignment { | 184 struct DestructuringAssignment { |
185 public: | 185 public: |
186 DestructuringAssignment(ExpressionT expression, Scope* scope) | 186 DestructuringAssignment(ExpressionT expression, Scope* scope) |
187 : assignment(expression), scope(scope) {} | 187 : assignment(expression), scope(scope) {} |
188 | 188 |
189 ExpressionT assignment; | 189 ExpressionT assignment; |
190 Scope* scope; | 190 Scope* scope; |
191 }; | 191 }; |
192 | 192 |
193 struct TailCallExpression { | |
194 TailCallExpression(ExpressionT expression, int pos) | |
195 : expression(expression), pos(pos) {} | |
196 | |
197 ExpressionT expression; | |
198 int pos; | |
199 }; | |
200 | |
193 class FunctionState BASE_EMBEDDED { | 201 class FunctionState BASE_EMBEDDED { |
194 public: | 202 public: |
195 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, | 203 FunctionState(FunctionState** function_state_stack, Scope** scope_stack, |
196 Scope* scope, FunctionKind kind, | 204 Scope* scope, FunctionKind kind, |
197 typename Traits::Type::Factory* factory); | 205 typename Traits::Type::Factory* factory); |
198 ~FunctionState(); | 206 ~FunctionState(); |
199 | 207 |
200 int NextMaterializedLiteralIndex() { | 208 int NextMaterializedLiteralIndex() { |
201 return next_materialized_literal_index_++; | 209 return next_materialized_literal_index_++; |
202 } | 210 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 return generator_object_variable_; | 248 return generator_object_variable_; |
241 } | 249 } |
242 | 250 |
243 typename Traits::Type::Factory* factory() { return factory_; } | 251 typename Traits::Type::Factory* factory() { return factory_; } |
244 | 252 |
245 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() | 253 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() |
246 const { | 254 const { |
247 return destructuring_assignments_to_rewrite_; | 255 return destructuring_assignments_to_rewrite_; |
248 } | 256 } |
249 | 257 |
250 List<ExpressionT>& expressions_in_tail_position() { | 258 List<TailCallExpression>& expressions_in_tail_position() { |
251 return expressions_in_tail_position_; | 259 return expressions_in_tail_position_; |
252 } | 260 } |
253 void AddExpressionInTailPosition(ExpressionT expression) { | 261 void AddExpressionInTailPosition(ExpressionT expression, int pos) { |
254 if (collect_expressions_in_tail_position_) { | 262 if (collect_expressions_in_tail_position_) { |
255 expressions_in_tail_position_.Add(expression); | 263 expressions_in_tail_position_.Add(TailCallExpression(expression, pos)); |
256 } | 264 } |
257 } | 265 } |
258 | 266 |
259 bool collect_expressions_in_tail_position() const { | 267 bool collect_expressions_in_tail_position() const { |
260 return collect_expressions_in_tail_position_; | 268 return collect_expressions_in_tail_position_; |
261 } | 269 } |
262 void set_collect_expressions_in_tail_position(bool collect) { | 270 void set_collect_expressions_in_tail_position(bool collect) { |
263 collect_expressions_in_tail_position_ = collect; | 271 collect_expressions_in_tail_position_ = collect; |
264 } | 272 } |
265 | 273 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 // is used by yield expressions and return statements. It is not necessary | 316 // is used by yield expressions and return statements. It is not necessary |
309 // for generator functions to have this variable set. | 317 // for generator functions to have this variable set. |
310 Variable* generator_object_variable_; | 318 Variable* generator_object_variable_; |
311 | 319 |
312 FunctionState** function_state_stack_; | 320 FunctionState** function_state_stack_; |
313 FunctionState* outer_function_state_; | 321 FunctionState* outer_function_state_; |
314 Scope** scope_stack_; | 322 Scope** scope_stack_; |
315 Scope* outer_scope_; | 323 Scope* outer_scope_; |
316 | 324 |
317 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; | 325 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; |
318 List<ExpressionT> expressions_in_tail_position_; | 326 List<TailCallExpression> expressions_in_tail_position_; |
319 bool collect_expressions_in_tail_position_; | 327 bool collect_expressions_in_tail_position_; |
320 ZoneList<ExpressionT> non_patterns_to_rewrite_; | 328 ZoneList<ExpressionT> non_patterns_to_rewrite_; |
321 | 329 |
322 typename Traits::Type::Factory* factory_; | 330 typename Traits::Type::Factory* factory_; |
323 | 331 |
324 // If true, the next (and immediately following) function literal is | 332 // If true, the next (and immediately following) function literal is |
325 // preceded by a parenthesis. | 333 // preceded by a parenthesis. |
326 bool next_function_is_parenthesized_; | 334 bool next_function_is_parenthesized_; |
327 | 335 |
328 // The value of the parents' next_function_is_parenthesized_, as it applies | 336 // The value of the parents' next_function_is_parenthesized_, as it applies |
329 // to this function. Filled in by constructor. | 337 // to this function. Filled in by constructor. |
330 bool this_function_is_parenthesized_; | 338 bool this_function_is_parenthesized_; |
331 | 339 |
332 friend class ParserTraits; | 340 friend class ParserTraits; |
333 friend class PreParserTraits; | 341 friend class PreParserTraits; |
334 friend class Checkpoint; | 342 friend class Checkpoint; |
335 }; | 343 }; |
336 | 344 |
345 // This scope disables collecting of expressions at tail call position. | |
346 class DontCollectExpressionsInTailPositionScope { | |
347 public: | |
348 explicit DontCollectExpressionsInTailPositionScope( | |
349 FunctionState* function_state) | |
350 : function_state_(function_state), | |
351 old_value_(function_state->collect_expressions_in_tail_position()) { | |
352 function_state->set_collect_expressions_in_tail_position(false); | |
353 } | |
354 ~DontCollectExpressionsInTailPositionScope() { | |
355 function_state_->set_collect_expressions_in_tail_position(old_value_); | |
356 } | |
357 | |
358 private: | |
359 FunctionState* function_state_; | |
360 bool old_value_; | |
361 }; | |
362 | |
363 // Collects all return expressions at tail call position in this scope | |
364 // to a separate list. | |
365 class CollectExpressionsInTailPositionToListScope { | |
366 public: | |
367 CollectExpressionsInTailPositionToListScope(FunctionState* function_state, | |
368 List<TailCallExpression>* list) | |
369 : function_state_(function_state), list_(list) { | |
370 function_state->expressions_in_tail_position().Swap(list_); | |
371 } | |
372 ~CollectExpressionsInTailPositionToListScope() { | |
373 function_state_->expressions_in_tail_position().Swap(list_); | |
374 } | |
375 | |
376 private: | |
377 FunctionState* function_state_; | |
378 List<TailCallExpression>* list_; | |
379 }; | |
380 | |
337 // Annoyingly, arrow functions first parse as comma expressions, then when we | 381 // Annoyingly, arrow functions first parse as comma expressions, then when we |
338 // see the => we have to go back and reinterpret the arguments as being formal | 382 // see the => we have to go back and reinterpret the arguments as being formal |
339 // parameters. To do so we need to reset some of the parser state back to | 383 // parameters. To do so we need to reset some of the parser state back to |
340 // what it was before the arguments were first seen. | 384 // what it was before the arguments were first seen. |
341 class Checkpoint BASE_EMBEDDED { | 385 class Checkpoint BASE_EMBEDDED { |
342 public: | 386 public: |
343 explicit Checkpoint(ParserBase* parser) { | 387 explicit Checkpoint(ParserBase* parser) { |
344 function_state_ = parser->function_state_; | 388 function_state_ = parser->function_state_; |
345 next_materialized_literal_index_ = | 389 next_materialized_literal_index_ = |
346 function_state_->next_materialized_literal_index_; | 390 function_state_->next_materialized_literal_index_; |
(...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1885 template <class Traits> | 1929 template <class Traits> |
1886 typename ParserBase<Traits>::ExpressionT | 1930 typename ParserBase<Traits>::ExpressionT |
1887 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, | 1931 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
1888 ExpressionClassifier* classifier, | 1932 ExpressionClassifier* classifier, |
1889 bool* ok) { | 1933 bool* ok) { |
1890 // AssignmentExpression :: | 1934 // AssignmentExpression :: |
1891 // ConditionalExpression | 1935 // ConditionalExpression |
1892 // ArrowFunction | 1936 // ArrowFunction |
1893 // YieldExpression | 1937 // YieldExpression |
1894 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1938 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1939 // TailCallExpression | |
1895 bool is_destructuring_assignment = false; | 1940 bool is_destructuring_assignment = false; |
1896 int lhs_beg_pos = peek_position(); | 1941 int lhs_beg_pos = peek_position(); |
1897 | 1942 |
1898 if (peek() == Token::YIELD && is_generator()) { | 1943 if (peek() == Token::YIELD && is_generator()) { |
1899 return this->ParseYieldExpression(classifier, ok); | 1944 return this->ParseYieldExpression(classifier, ok); |
1900 } | 1945 } |
1901 | 1946 |
1902 FuncNameInferrer::State fni_state(fni_); | 1947 FuncNameInferrer::State fni_state(fni_); |
1903 ParserBase<Traits>::Checkpoint checkpoint(this); | 1948 ParserBase<Traits>::Checkpoint checkpoint(this); |
1904 ExpressionClassifier arrow_formals_classifier(this, | 1949 ExpressionClassifier arrow_formals_classifier(this, |
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2851 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, | 2896 this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
2852 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); | 2897 kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
2853 materialized_literal_count = | 2898 materialized_literal_count = |
2854 function_state.materialized_literal_count(); | 2899 function_state.materialized_literal_count(); |
2855 expected_property_count = function_state.expected_property_count(); | 2900 expected_property_count = function_state.expected_property_count(); |
2856 } | 2901 } |
2857 } else { | 2902 } else { |
2858 // Single-expression body | 2903 // Single-expression body |
2859 int pos = position(); | 2904 int pos = position(); |
2860 ExpressionClassifier classifier(this); | 2905 ExpressionClassifier classifier(this); |
2906 bool is_tail_call_expression; | |
2907 if (FLAG_harmony_explicit_tailcalls) { | |
2908 // TODO(ishell): update chapter number. | |
2909 // ES7 XX.YY.ZZ | |
2910 if (peek() == Token::CONTINUE) { | |
2911 Consume(Token::CONTINUE); | |
2912 pos = position(); | |
2913 is_tail_call_expression = true; | |
2914 } else { | |
2915 is_tail_call_expression = false; | |
2916 } | |
2917 } else { | |
2918 // ES6 14.6.1 Static Semantics: IsInTailPosition | |
2919 is_tail_call_expression = | |
2920 allow_tailcalls() && !is_sloppy(language_mode()); | |
2921 } | |
2861 ExpressionT expression = | 2922 ExpressionT expression = |
2862 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); | 2923 ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
2863 Traits::RewriteNonPattern(&classifier, CHECK_OK); | 2924 Traits::RewriteNonPattern(&classifier, CHECK_OK); |
2864 body = this->NewStatementList(1, zone()); | 2925 body = this->NewStatementList(1, zone()); |
2865 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); | 2926 this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); |
2866 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | 2927 body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
2867 materialized_literal_count = function_state.materialized_literal_count(); | 2928 materialized_literal_count = function_state.materialized_literal_count(); |
2868 expected_property_count = function_state.expected_property_count(); | 2929 expected_property_count = function_state.expected_property_count(); |
2869 // ES6 14.6.1 Static Semantics: IsInTailPosition | 2930 if (is_tail_call_expression) { |
rossberg
2016/04/26 14:56:57
Nit: why separate this from the rest of the logic?
Igor Sheludko
2016/04/26 16:48:17
I'll address this in a follow-up CL when I introdu
| |
2870 if (allow_tailcalls() && !is_sloppy(language_mode())) { | |
2871 this->MarkTailPosition(expression); | 2931 this->MarkTailPosition(expression); |
2872 } | 2932 } |
2873 } | 2933 } |
2874 super_loc = function_state.super_location(); | 2934 super_loc = function_state.super_location(); |
2875 | 2935 |
2876 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 2936 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
2877 | 2937 |
2878 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 2938 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
2879 // which is not the same as "parameters of a strict function"; it only means | 2939 // which is not the same as "parameters of a strict function"; it only means |
2880 // that duplicates are not allowed. Of course, the arrow function may | 2940 // that duplicates are not allowed. Of course, the arrow function may |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3119 has_seen_constructor_ = true; | 3179 has_seen_constructor_ = true; |
3120 return; | 3180 return; |
3121 } | 3181 } |
3122 } | 3182 } |
3123 | 3183 |
3124 | 3184 |
3125 } // namespace internal | 3185 } // namespace internal |
3126 } // namespace v8 | 3186 } // namespace v8 |
3127 | 3187 |
3128 #endif // V8_PARSING_PARSER_BASE_H | 3188 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |