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

Side by Side Diff: src/parser.cc

Issue 1053773006: [es6] implement default/optional parameters (WIP / comments) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Experimental not-quite-TDZ support Created 5 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
« no previous file with comments | « src/full-codegen.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper), 366 Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper),
367 args, pos); 367 args, pos);
368 body->Add(factory()->NewReturnStatement(call, pos), zone()); 368 body->Add(factory()->NewReturnStatement(call, pos), zone());
369 } 369 }
370 370
371 materialized_literal_count = function_state.materialized_literal_count(); 371 materialized_literal_count = function_state.materialized_literal_count();
372 expected_property_count = function_state.expected_property_count(); 372 expected_property_count = function_state.expected_property_count();
373 handler_count = function_state.handler_count(); 373 handler_count = function_state.handler_count();
374 } 374 }
375 375
376 ZoneList<Expression*>* default_values =
377 new (zone()) ZoneList<Expression*>(0, zone());
376 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 378 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
377 name, ast_value_factory(), function_scope, body, 379 name, ast_value_factory(), function_scope, body,
378 materialized_literal_count, expected_property_count, handler_count, 380 materialized_literal_count, expected_property_count, handler_count,
379 parameter_count, FunctionLiteral::kNoDuplicateParameters, 381 parameter_count, default_values, FunctionLiteral::kNoDuplicateParameters,
380 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction, 382 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
381 FunctionLiteral::kNotParenthesized, kind, pos); 383 FunctionLiteral::kNotParenthesized, kind, pos);
382 384
383 return function_literal; 385 return function_literal;
384 } 386 }
385 387
386 388
387 // ---------------------------------------------------------------------------- 389 // ----------------------------------------------------------------------------
388 // Target is a support class to facilitate manipulation of the 390 // Target is a support class to facilitate manipulation of the
389 // Parser's target_stack_ (the stack of potential 'break' and 391 // Parser's target_stack_ (the stack of potential 'break' and
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 if (body->length() != 1 || 1034 if (body->length() != 1 ||
1033 !body->at(0)->IsExpressionStatement() || 1035 !body->at(0)->IsExpressionStatement() ||
1034 !body->at(0)->AsExpressionStatement()-> 1036 !body->at(0)->AsExpressionStatement()->
1035 expression()->IsFunctionLiteral()) { 1037 expression()->IsFunctionLiteral()) {
1036 ReportMessage("single_function_literal"); 1038 ReportMessage("single_function_literal");
1037 ok = false; 1039 ok = false;
1038 } 1040 }
1039 } 1041 }
1040 1042
1041 if (ok) { 1043 if (ok) {
1044 ZoneList<Expression*>* default_values =
1045 new (zone()) ZoneList<Expression*>(0, zone());
1042 result = factory()->NewFunctionLiteral( 1046 result = factory()->NewFunctionLiteral(
1043 ast_value_factory()->empty_string(), ast_value_factory(), scope_, 1047 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1044 body, function_state.materialized_literal_count(), 1048 body, function_state.materialized_literal_count(),
1045 function_state.expected_property_count(), 1049 function_state.expected_property_count(),
1046 function_state.handler_count(), 0, 1050 function_state.handler_count(), 0, default_values,
1047 FunctionLiteral::kNoDuplicateParameters, 1051 FunctionLiteral::kNoDuplicateParameters,
1048 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, 1052 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
1049 FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0); 1053 FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
1050 } 1054 }
1051 } 1055 }
1052 1056
1053 // Make sure the target stack is empty. 1057 // Make sure the target stack is empty.
1054 DCHECK(target_stack_ == NULL); 1058 DCHECK(target_stack_ == NULL);
1055 1059
1056 return result; 1060 return result;
(...skipping 2773 matching lines...) Expand 10 before | Expand all | Expand 10 after
3830 // - (1) is the case iff the innermost scope of the deserialized scope chain 3834 // - (1) is the case iff the innermost scope of the deserialized scope chain
3831 // under which we compile is _not_ a declaration scope. This holds because 3835 // under which we compile is _not_ a declaration scope. This holds because
3832 // in all normal cases, function declarations are fully hoisted to a 3836 // in all normal cases, function declarations are fully hoisted to a
3833 // declaration scope and compiled relative to that. 3837 // declaration scope and compiled relative to that.
3834 // - (2) is the case iff the current declaration scope is still the original 3838 // - (2) is the case iff the current declaration scope is still the original
3835 // one relative to the deserialized scope chain. Otherwise we must be 3839 // one relative to the deserialized scope chain. Otherwise we must be
3836 // compiling a function in an inner declaration scope in the eval, e.g. a 3840 // compiling a function in an inner declaration scope in the eval, e.g. a
3837 // nested function, and hoisting works normally relative to that. 3841 // nested function, and hoisting works normally relative to that.
3838 Scope* declaration_scope = scope_->DeclarationScope(); 3842 Scope* declaration_scope = scope_->DeclarationScope();
3839 Scope* original_declaration_scope = original_scope_->DeclarationScope(); 3843 Scope* original_declaration_scope = original_scope_->DeclarationScope();
3840 Scope* scope = function_type == FunctionLiteral::DECLARATION && 3844 Scope* env_scope = function_type == FunctionLiteral::DECLARATION &&
3841 is_sloppy(language_mode()) && 3845 is_sloppy(language_mode()) &&
3842 (original_scope_ == original_declaration_scope || 3846 (original_scope_ == original_declaration_scope ||
3843 declaration_scope != original_declaration_scope) 3847 declaration_scope != original_declaration_scope)
3844 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind) 3848 ? declaration_scope
3845 : NewScope(scope_, FUNCTION_SCOPE, kind); 3849 : scope_;
3850 // A separate Environment Record is needed to ensure that closures created by
3851 // expressions in the formal parameter list do not have visibility of
3852 // declarations in the function body.
3853 Scope* param_expressions_scope = NewScope(env_scope, BLOCK_SCOPE);
3854
3855 Scope* scope = NewScope(env_scope, FUNCTION_SCOPE, kind);
3856
3846 ZoneList<Statement*>* body = NULL; 3857 ZoneList<Statement*>* body = NULL;
3847 int materialized_literal_count = -1; 3858 int materialized_literal_count = -1;
3848 int expected_property_count = -1; 3859 int expected_property_count = -1;
3849 int handler_count = 0; 3860 int handler_count = 0;
3850 FunctionLiteral::ParameterFlag duplicate_parameters = 3861 FunctionLiteral::ParameterFlag duplicate_parameters =
3851 FunctionLiteral::kNoDuplicateParameters; 3862 FunctionLiteral::kNoDuplicateParameters;
3852 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 3863 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3853 ? FunctionLiteral::kIsParenthesized 3864 ? FunctionLiteral::kIsParenthesized
3854 : FunctionLiteral::kNotParenthesized; 3865 : FunctionLiteral::kNotParenthesized;
3866
3867 ZoneList<Expression*>* param_initializers =
3868 new (zone()) ZoneList<Expression*>(0, zone());
3869
3855 // Parse function body. 3870 // Parse function body.
3856 { 3871 {
3857 AstNodeFactory function_factory(ast_value_factory()); 3872 AstNodeFactory function_factory(ast_value_factory());
3858 FunctionState function_state(&function_state_, &scope_, scope, kind, 3873 FunctionState function_state(&function_state_, &scope_, scope, kind,
3859 &function_factory); 3874 &function_factory);
3860 scope_->SetScopeName(function_name); 3875 scope_->SetScopeName(function_name);
3876 param_expressions_scope->SetParameterExpressionsScopeFor(scope_);
3861 3877
3862 if (is_generator) { 3878 if (is_generator) {
3863 // For generators, allocating variables in contexts is currently a win 3879 // For generators, allocating variables in contexts is currently a win
3864 // because it minimizes the work needed to suspend and resume an 3880 // because it minimizes the work needed to suspend and resume an
3865 // activation. 3881 // activation.
3866 scope_->ForceContextAllocation(); 3882 scope_->ForceContextAllocation();
3867 3883
3868 // Calling a generator returns a generator object. That object is stored 3884 // Calling a generator returns a generator object. That object is stored
3869 // in a temporary variable, a definition that is used by "yield" 3885 // in a temporary variable, a definition that is used by "yield"
3870 // expressions. This also marks the FunctionState as a generator. 3886 // expressions. This also marks the FunctionState as a generator.
(...skipping 16 matching lines...) Expand all
3887 3903
3888 // Similarly for strong mode. 3904 // Similarly for strong mode.
3889 Scanner::Location undefined_loc = Scanner::Location::invalid(); 3905 Scanner::Location undefined_loc = Scanner::Location::invalid();
3890 3906
3891 bool is_rest = false; 3907 bool is_rest = false;
3892 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || 3908 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3893 (peek() == Token::RPAREN && 3909 (peek() == Token::RPAREN &&
3894 arity_restriction != FunctionLiteral::SETTER_ARITY); 3910 arity_restriction != FunctionLiteral::SETTER_ARITY);
3895 while (!done) { 3911 while (!done) {
3896 bool is_strict_reserved = false; 3912 bool is_strict_reserved = false;
3897 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); 3913 int rest_pos;
3898 if (is_rest) { 3914
3915 ParameterKind kind = NormalParameter;
3916
3917 if (peek() == Token::ELLIPSIS && allow_harmony_rest_params()) {
3899 Consume(Token::ELLIPSIS); 3918 Consume(Token::ELLIPSIS);
3919 rest_pos = position();
3920 kind = RestParameter;
3900 } 3921 }
3901 3922
3902 const AstRawString* param_name = 3923 const AstRawString* param_name =
3903 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 3924 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3904 3925
3905 // Store locations for possible future error reports. 3926 // Store locations for possible future error reports.
3906 if (!eval_args_loc.IsValid() && IsEvalOrArguments(param_name)) { 3927 if (!eval_args_loc.IsValid() && IsEvalOrArguments(param_name)) {
3907 eval_args_loc = scanner()->location(); 3928 eval_args_loc = scanner()->location();
3908 } 3929 }
3909 if (!undefined_loc.IsValid() && IsUndefined(param_name)) { 3930 if (!undefined_loc.IsValid() && IsUndefined(param_name)) {
3910 undefined_loc = scanner()->location(); 3931 undefined_loc = scanner()->location();
3911 } 3932 }
3912 if (!reserved_loc.IsValid() && is_strict_reserved) { 3933 if (!reserved_loc.IsValid() && is_strict_reserved) {
3913 reserved_loc = scanner()->location(); 3934 reserved_loc = scanner()->location();
3914 } 3935 }
3915 if (!dupe_loc.IsValid() && 3936 if (!dupe_loc.IsValid() &&
3916 scope_->IsDeclaredParameter(param_name)) { 3937 scope_->IsDeclaredParameter(param_name)) {
3917 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; 3938 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3918 dupe_loc = scanner()->location(); 3939 dupe_loc = scanner()->location();
3919 } 3940 }
3920 3941
3921 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); 3942
3943 if (peek() == Token::ASSIGN) {
3944 // Default parameters:
3945 Consume(Token::ASSIGN);
3946 static const bool accept_IN = true;
3947 Expression* defaultValue = nullptr;
3948 {
3949 // Evaluate parameter initializations within context of separate scope
3950 BlockState state(&scope_, param_expressions_scope);
3951 defaultValue = ParseAssignmentExpression(accept_IN, CHECK_OK);
3952 }
3953 if (kind == RestParameter) {
3954 ReportMessageAt(
3955 Scanner::Location(rest_pos, scanner()->location().end_pos),
3956 "rest_param_default");
3957 *ok = false;
3958 return nullptr;
3959 }
3960 kind = OptionalParameter;
3961 param_initializers->Add(defaultValue, zone());
3962 }
3963
3964 Variable* var = scope_->DeclareParameter(param_name, VAR, kind);
3965
3922 if (is_sloppy(scope->language_mode())) { 3966 if (is_sloppy(scope->language_mode())) {
3923 // TODO(sigurds) Mark every parameter as maybe assigned. This is a 3967 // TODO(sigurds) Mark every parameter as maybe assigned. This is a
3924 // conservative approximation necessary to account for parameters 3968 // conservative approximation necessary to account for parameters
3925 // that are assigned via the arguments array. 3969 // that are assigned via the arguments array.
3926 var->set_maybe_assigned(); 3970 var->set_maybe_assigned();
3927 } 3971 }
3928 3972
3929 num_parameters++; 3973 num_parameters++;
3930 if (num_parameters > Code::kMaxArguments) { 3974 if (num_parameters > Code::kMaxArguments) {
3931 ReportMessage("too_many_parameters"); 3975 ReportMessage("too_many_parameters");
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
4043 kReferenceError); 4087 kReferenceError);
4044 *ok = false; 4088 *ok = false;
4045 return nullptr; 4089 return nullptr;
4046 } 4090 }
4047 } 4091 }
4048 } 4092 }
4049 4093
4050 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 4094 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4051 function_name, ast_value_factory(), scope, body, 4095 function_name, ast_value_factory(), scope, body,
4052 materialized_literal_count, expected_property_count, handler_count, 4096 materialized_literal_count, expected_property_count, handler_count,
4053 num_parameters, duplicate_parameters, function_type, 4097 num_parameters, param_initializers, duplicate_parameters, function_type,
4054 FunctionLiteral::kIsFunction, parenthesized, kind, pos); 4098 FunctionLiteral::kIsFunction, parenthesized, kind, pos);
4055 function_literal->set_function_token_position(function_token_pos); 4099 function_literal->set_function_token_position(function_token_pos);
4056 4100
4057 if (scope->has_rest_parameter()) { 4101 if (scope->has_rest_parameter()) {
4058 // TODO(caitp): enable optimization of functions with rest params 4102 // TODO(caitp): enable optimization of functions with rest params
4059 function_literal->set_dont_optimize_reason(kRestParameter); 4103 function_literal->set_dont_optimize_reason(kRestParameter);
4060 } 4104 }
4061 4105
4062 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 4106 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
4063 return function_literal; 4107 return function_literal;
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after
5759 5803
5760 Expression* Parser::SpreadCallNew(Expression* function, 5804 Expression* Parser::SpreadCallNew(Expression* function,
5761 ZoneList<v8::internal::Expression*>* args, 5805 ZoneList<v8::internal::Expression*>* args,
5762 int pos) { 5806 int pos) {
5763 args->InsertAt(0, function, zone()); 5807 args->InsertAt(0, function, zone());
5764 5808
5765 return factory()->NewCallRuntime( 5809 return factory()->NewCallRuntime(
5766 ast_value_factory()->reflect_construct_string(), NULL, args, pos); 5810 ast_value_factory()->reflect_construct_string(), NULL, args, pos);
5767 } 5811 }
5768 } } // namespace v8::internal 5812 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/full-codegen.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698