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

Side by Side Diff: src/parsing/parser-base.h

Issue 1917993004: [es8] Initial set of changes to support syntactic tail calls. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698