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 // ES8 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) { |
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 |