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 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 // not passing the ScopeInfo to the Scope constructor. | 943 // not passing the ScopeInfo to the Scope constructor. |
| 944 // TODO(adamk): Remove these calls once the above NewScope call | 944 // TODO(adamk): Remove these calls once the above NewScope call |
| 945 // passes the ScopeInfo. | 945 // passes the ScopeInfo. |
| 946 if (info->calls_eval()) { | 946 if (info->calls_eval()) { |
| 947 scope->RecordEvalCall(); | 947 scope->RecordEvalCall(); |
| 948 } | 948 } |
| 949 SetLanguageMode(scope, info->language_mode()); | 949 SetLanguageMode(scope, info->language_mode()); |
| 950 | 950 |
| 951 scope->set_start_position(info->start_position()); | 951 scope->set_start_position(info->start_position()); |
| 952 ExpressionClassifier formals_classifier(this); | 952 ExpressionClassifier formals_classifier(this); |
| 953 ParserFormalParameters formals(scope); | 953 ParserFormalParameters* formals = |
|
Toon Verwaest
2016/11/24 15:09:41
Are you sure you need formals to be zone allocated
marja
2016/11/25 10:08:23
Done.
| |
| 954 new (zone()) ParserFormalParameters(scope); | |
| 954 Checkpoint checkpoint(this); | 955 Checkpoint checkpoint(this); |
| 955 { | 956 { |
| 956 // Parsing patterns as variable reference expression creates | 957 // Parsing patterns as variable reference expression creates |
| 957 // NewUnresolved references in current scope. Entrer arrow function | 958 // NewUnresolved references in current scope. Entrer arrow function |
| 958 // scope for formal parameter parsing. | 959 // scope for formal parameter parsing. |
| 959 BlockState block_state(&scope_state_, scope); | 960 BlockState block_state(&scope_state_, scope); |
| 960 if (Check(Token::LPAREN)) { | 961 if (Check(Token::LPAREN)) { |
| 961 // '(' StrictFormalParameters ')' | 962 // '(' StrictFormalParameters ')' |
| 962 ParseFormalParameterList(&formals, &ok); | 963 ParseFormalParameterList(formals, &ok); |
| 963 if (ok) ok = Check(Token::RPAREN); | 964 if (ok) ok = Check(Token::RPAREN); |
| 964 } else { | 965 } else { |
| 965 // BindingIdentifier | 966 // BindingIdentifier |
| 966 ParseFormalParameter(&formals, &ok); | 967 ParseFormalParameter(formals, &ok); |
| 967 if (ok) DeclareFormalParameter(formals.scope, formals.at(0)); | 968 if (ok) DeclareFormalParameters(formals->scope, formals->params); |
| 968 } | 969 } |
| 969 } | 970 } |
| 970 | 971 |
| 971 if (ok) { | 972 if (ok) { |
| 972 checkpoint.Restore(&formals.materialized_literals_count); | 973 checkpoint.Restore(&formals->materialized_literals_count); |
| 973 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should | 974 // Pass `accept_IN=true` to ParseArrowFunctionLiteral --- This should |
| 974 // not be observable, or else the preparser would have failed. | 975 // not be observable, or else the preparser would have failed. |
| 975 Expression* expression = ParseArrowFunctionLiteral(true, formals, &ok); | 976 Expression* expression = ParseArrowFunctionLiteral(true, *formals, &ok); |
| 976 if (ok) { | 977 if (ok) { |
| 977 // Scanning must end at the same position that was recorded | 978 // Scanning must end at the same position that was recorded |
| 978 // previously. If not, parsing has been interrupted due to a stack | 979 // previously. If not, parsing has been interrupted due to a stack |
| 979 // overflow, at which point the partially parsed arrow function | 980 // overflow, at which point the partially parsed arrow function |
| 980 // concise body happens to be a valid expression. This is a problem | 981 // concise body happens to be a valid expression. This is a problem |
| 981 // only for arrow functions with single expression bodies, since there | 982 // only for arrow functions with single expression bodies, since there |
| 982 // is no end token such as "}" for normal functions. | 983 // is no end token such as "}" for normal functions. |
| 983 if (scanner()->location().end_pos == info->end_position()) { | 984 if (scanner()->location().end_pos == info->end_position()) { |
| 984 // The pre-parser saw an arrow function here, so the full parser | 985 // The pre-parser saw an arrow function here, so the full parser |
| 985 // must produce a FunctionLiteral. | 986 // must produce a FunctionLiteral. |
| (...skipping 1483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2469 if (parameters->arity > Code::kMaxArguments) { | 2470 if (parameters->arity > Code::kMaxArguments) { |
| 2470 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); | 2471 ReportMessageAt(params_loc, MessageTemplate::kMalformedArrowFunParamList); |
| 2471 *ok = false; | 2472 *ok = false; |
| 2472 return; | 2473 return; |
| 2473 } | 2474 } |
| 2474 | 2475 |
| 2475 ExpressionClassifier classifier(this); | 2476 ExpressionClassifier classifier(this); |
| 2476 if (!parameters->is_simple) { | 2477 if (!parameters->is_simple) { |
| 2477 this->classifier()->RecordNonSimpleParameter(); | 2478 this->classifier()->RecordNonSimpleParameter(); |
| 2478 } | 2479 } |
| 2479 for (int i = 0; i < parameters->arity; ++i) { | 2480 DeclareFormalParameters(parameters->scope, parameters->params); |
| 2480 auto parameter = parameters->at(i); | 2481 if (!this->classifier() |
| 2481 DeclareFormalParameter(parameters->scope, parameter); | 2482 ->is_valid_formal_parameter_list_without_duplicates()) { |
| 2482 if (!this->classifier() | 2483 *duplicate_loc = |
| 2483 ->is_valid_formal_parameter_list_without_duplicates() && | 2484 this->classifier()->duplicate_formal_parameter_error().location; |
| 2484 !duplicate_loc->IsValid()) { | |
| 2485 *duplicate_loc = | |
| 2486 this->classifier()->duplicate_formal_parameter_error().location; | |
| 2487 } | |
| 2488 } | 2485 } |
| 2489 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); | 2486 DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters()); |
| 2490 } | 2487 } |
| 2491 | 2488 |
| 2492 void Parser::ReindexLiterals(const ParserFormalParameters& parameters) { | 2489 void Parser::ReindexLiterals(const ParserFormalParameters& parameters) { |
| 2493 if (function_state_->materialized_literal_count() > 0) { | 2490 if (function_state_->materialized_literal_count() > 0) { |
| 2494 AstLiteralReindexer reindexer; | 2491 AstLiteralReindexer reindexer; |
| 2495 | 2492 |
| 2496 for (const auto p : parameters.params) { | 2493 for (auto p : parameters.params) { |
| 2497 if (p.pattern != nullptr) reindexer.Reindex(p.pattern); | 2494 if (p->pattern != nullptr) reindexer.Reindex(p->pattern); |
| 2498 if (p.initializer != nullptr) reindexer.Reindex(p.initializer); | 2495 if (p->initializer != nullptr) reindexer.Reindex(p->initializer); |
| 2499 } | 2496 } |
| 2500 | 2497 |
| 2501 DCHECK(reindexer.count() <= function_state_->materialized_literal_count()); | 2498 DCHECK(reindexer.count() <= function_state_->materialized_literal_count()); |
| 2502 } | 2499 } |
| 2503 } | 2500 } |
| 2504 | 2501 |
| 2505 void Parser::PrepareGeneratorVariables(FunctionState* function_state) { | 2502 void Parser::PrepareGeneratorVariables(FunctionState* function_state) { |
| 2506 // For generators, allocating variables in contexts is currently a win because | 2503 // For generators, allocating variables in contexts is currently a win because |
| 2507 // it minimizes the work needed to suspend and resume an activation. The | 2504 // it minimizes the work needed to suspend and resume an activation. The |
| 2508 // code produced for generators relies on this forced context allocation, but | 2505 // code produced for generators relies on this forced context allocation, but |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2917 InitializerRewriter rewriter(stack_limit_, expr, this, scope); | 2914 InitializerRewriter rewriter(stack_limit_, expr, this, scope); |
| 2918 rewriter.Run(); | 2915 rewriter.Run(); |
| 2919 } | 2916 } |
| 2920 | 2917 |
| 2921 | 2918 |
| 2922 Block* Parser::BuildParameterInitializationBlock( | 2919 Block* Parser::BuildParameterInitializationBlock( |
| 2923 const ParserFormalParameters& parameters, bool* ok) { | 2920 const ParserFormalParameters& parameters, bool* ok) { |
| 2924 DCHECK(!parameters.is_simple); | 2921 DCHECK(!parameters.is_simple); |
| 2925 DCHECK(scope()->is_function_scope()); | 2922 DCHECK(scope()->is_function_scope()); |
| 2926 Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition); | 2923 Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition); |
| 2927 for (int i = 0; i < parameters.params.length(); ++i) { | 2924 int index = 0; |
| 2928 auto parameter = parameters.params[i]; | 2925 for (auto parameter : parameters.params) { |
| 2929 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; | 2926 if (parameter->is_rest && parameter->pattern->IsVariableProxy()) break; |
| 2930 DeclarationDescriptor descriptor; | 2927 DeclarationDescriptor descriptor; |
| 2931 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; | 2928 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; |
| 2932 descriptor.scope = scope(); | 2929 descriptor.scope = scope(); |
| 2933 descriptor.hoist_scope = nullptr; | 2930 descriptor.hoist_scope = nullptr; |
| 2934 descriptor.mode = LET; | 2931 descriptor.mode = LET; |
| 2935 descriptor.declaration_pos = parameter.pattern->position(); | 2932 descriptor.declaration_pos = parameter->pattern->position(); |
| 2936 // The position that will be used by the AssignmentExpression | 2933 // The position that will be used by the AssignmentExpression |
| 2937 // which copies from the temp parameter to the pattern. | 2934 // which copies from the temp parameter to the pattern. |
| 2938 // | 2935 // |
| 2939 // TODO(adamk): Should this be kNoSourcePosition, since | 2936 // TODO(adamk): Should this be kNoSourcePosition, since |
| 2940 // it's just copying from a temp var to the real param var? | 2937 // it's just copying from a temp var to the real param var? |
| 2941 descriptor.initialization_pos = parameter.pattern->position(); | 2938 descriptor.initialization_pos = parameter->pattern->position(); |
| 2942 Expression* initial_value = | 2939 Expression* initial_value = |
| 2943 factory()->NewVariableProxy(parameters.scope->parameter(i)); | 2940 factory()->NewVariableProxy(parameters.scope->parameter(index)); |
| 2944 if (parameter.initializer != nullptr) { | 2941 if (parameter->initializer != nullptr) { |
| 2945 // IS_UNDEFINED($param) ? initializer : $param | 2942 // IS_UNDEFINED($param) ? initializer : $param |
| 2946 | 2943 |
| 2947 // Ensure initializer is rewritten | 2944 // Ensure initializer is rewritten |
| 2948 RewriteParameterInitializer(parameter.initializer, scope()); | 2945 RewriteParameterInitializer(parameter->initializer, scope()); |
| 2949 | 2946 |
| 2950 auto condition = factory()->NewCompareOperation( | 2947 auto condition = factory()->NewCompareOperation( |
| 2951 Token::EQ_STRICT, | 2948 Token::EQ_STRICT, |
| 2952 factory()->NewVariableProxy(parameters.scope->parameter(i)), | 2949 factory()->NewVariableProxy(parameters.scope->parameter(index)), |
| 2953 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); | 2950 factory()->NewUndefinedLiteral(kNoSourcePosition), kNoSourcePosition); |
| 2954 initial_value = factory()->NewConditional( | 2951 initial_value = factory()->NewConditional( |
| 2955 condition, parameter.initializer, initial_value, kNoSourcePosition); | 2952 condition, parameter->initializer, initial_value, kNoSourcePosition); |
| 2956 descriptor.initialization_pos = parameter.initializer->position(); | 2953 descriptor.initialization_pos = parameter->initializer->position(); |
| 2957 } | 2954 } |
| 2958 | 2955 |
| 2959 Scope* param_scope = scope(); | 2956 Scope* param_scope = scope(); |
| 2960 Block* param_block = init_block; | 2957 Block* param_block = init_block; |
| 2961 if (!parameter.is_simple() && scope()->calls_sloppy_eval()) { | 2958 if (!parameter->is_simple() && scope()->calls_sloppy_eval()) { |
| 2962 param_scope = NewVarblockScope(); | 2959 param_scope = NewVarblockScope(); |
| 2963 param_scope->set_start_position(descriptor.initialization_pos); | 2960 param_scope->set_start_position(descriptor.initialization_pos); |
| 2964 param_scope->set_end_position(parameter.initializer_end_position); | 2961 param_scope->set_end_position(parameter->initializer_end_position); |
| 2965 param_scope->RecordEvalCall(); | 2962 param_scope->RecordEvalCall(); |
| 2966 param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); | 2963 param_block = factory()->NewBlock(NULL, 8, true, kNoSourcePosition); |
| 2967 param_block->set_scope(param_scope); | 2964 param_block->set_scope(param_scope); |
| 2968 descriptor.hoist_scope = scope(); | 2965 descriptor.hoist_scope = scope(); |
| 2969 // Pass the appropriate scope in so that PatternRewriter can appropriately | 2966 // Pass the appropriate scope in so that PatternRewriter can appropriately |
| 2970 // rewrite inner initializers of the pattern to param_scope | 2967 // rewrite inner initializers of the pattern to param_scope |
| 2971 descriptor.scope = param_scope; | 2968 descriptor.scope = param_scope; |
| 2972 // Rewrite the outer initializer to point to param_scope | 2969 // Rewrite the outer initializer to point to param_scope |
| 2973 ReparentParameterExpressionScope(stack_limit(), initial_value, | 2970 ReparentParameterExpressionScope(stack_limit(), initial_value, |
| 2974 param_scope); | 2971 param_scope); |
| 2975 } | 2972 } |
| 2976 | 2973 |
| 2977 BlockState block_state(&scope_state_, param_scope); | 2974 BlockState block_state(&scope_state_, param_scope); |
| 2978 DeclarationParsingResult::Declaration decl( | 2975 DeclarationParsingResult::Declaration decl( |
| 2979 parameter.pattern, parameter.initializer_end_position, initial_value); | 2976 parameter->pattern, parameter->initializer_end_position, initial_value); |
| 2980 PatternRewriter::DeclareAndInitializeVariables( | 2977 PatternRewriter::DeclareAndInitializeVariables( |
| 2981 this, param_block, &descriptor, &decl, nullptr, CHECK_OK); | 2978 this, param_block, &descriptor, &decl, nullptr, CHECK_OK); |
| 2982 | 2979 |
| 2983 if (param_block != init_block) { | 2980 if (param_block != init_block) { |
| 2984 param_scope = block_state.FinalizedBlockScope(); | 2981 param_scope = block_state.FinalizedBlockScope(); |
| 2985 if (param_scope != nullptr) { | 2982 if (param_scope != nullptr) { |
| 2986 CheckConflictingVarDeclarations(param_scope, CHECK_OK); | 2983 CheckConflictingVarDeclarations(param_scope, CHECK_OK); |
| 2987 } | 2984 } |
| 2988 init_block->statements()->Add(param_block, zone()); | 2985 init_block->statements()->Add(param_block, zone()); |
| 2989 } | 2986 } |
| 2987 ++index; | |
| 2990 } | 2988 } |
| 2991 return init_block; | 2989 return init_block; |
| 2992 } | 2990 } |
| 2993 | 2991 |
| 2994 Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) { | 2992 Block* Parser::BuildRejectPromiseOnException(Block* inner_block, bool* ok) { |
| 2995 // .promise = %AsyncFunctionPromiseCreate(); | 2993 // .promise = %AsyncFunctionPromiseCreate(); |
| 2996 // try { | 2994 // try { |
| 2997 // <inner_block> | 2995 // <inner_block> |
| 2998 // } catch (.catch) { | 2996 // } catch (.catch) { |
| 2999 // %RejectPromise(.promise, .catch); | 2997 // %RejectPromise(.promise, .catch); |
| (...skipping 2460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5460 | 5458 |
| 5461 return final_loop; | 5459 return final_loop; |
| 5462 } | 5460 } |
| 5463 | 5461 |
| 5464 #undef CHECK_OK | 5462 #undef CHECK_OK |
| 5465 #undef CHECK_OK_VOID | 5463 #undef CHECK_OK_VOID |
| 5466 #undef CHECK_FAILED | 5464 #undef CHECK_FAILED |
| 5467 | 5465 |
| 5468 } // namespace internal | 5466 } // namespace internal |
| 5469 } // namespace v8 | 5467 } // namespace v8 |
| OLD | NEW |