Chromium Code Reviews| 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 |