| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |