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/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/char-predicates-inl.h" | 10 #include "src/char-predicates-inl.h" |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 } | 745 } |
746 | 746 |
747 | 747 |
748 FunctionLiteral* ParserTraits::ParseFunctionLiteral( | 748 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
749 Handle<String> name, | 749 Handle<String> name, |
750 Scanner::Location function_name_location, | 750 Scanner::Location function_name_location, |
751 bool name_is_strict_reserved, | 751 bool name_is_strict_reserved, |
752 bool is_generator, | 752 bool is_generator, |
753 int function_token_position, | 753 int function_token_position, |
754 FunctionLiteral::FunctionType type, | 754 FunctionLiteral::FunctionType type, |
| 755 FunctionLiteral::ArityRestriction arity_restriction, |
755 bool* ok) { | 756 bool* ok) { |
756 return parser_->ParseFunctionLiteral(name, function_name_location, | 757 return parser_->ParseFunctionLiteral(name, function_name_location, |
757 name_is_strict_reserved, is_generator, | 758 name_is_strict_reserved, is_generator, |
758 function_token_position, type, ok); | 759 function_token_position, type, |
| 760 arity_restriction, ok); |
759 } | 761 } |
760 | 762 |
761 | 763 |
762 Parser::Parser(CompilationInfo* info) | 764 Parser::Parser(CompilationInfo* info) |
763 : ParserBase<ParserTraits>(&scanner_, | 765 : ParserBase<ParserTraits>(&scanner_, |
764 info->isolate()->stack_guard()->real_climit(), | 766 info->isolate()->stack_guard()->real_climit(), |
765 info->extension(), | 767 info->extension(), |
766 NULL, | 768 NULL, |
767 info->zone(), | 769 info->zone(), |
768 this), | 770 this), |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1011 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1010 : FunctionLiteral::NAMED_EXPRESSION) | 1012 : FunctionLiteral::NAMED_EXPRESSION) |
1011 : FunctionLiteral::DECLARATION; | 1013 : FunctionLiteral::DECLARATION; |
1012 bool ok = true; | 1014 bool ok = true; |
1013 result = ParseFunctionLiteral(name, | 1015 result = ParseFunctionLiteral(name, |
1014 Scanner::Location::invalid(), | 1016 Scanner::Location::invalid(), |
1015 false, // Strict mode name already checked. | 1017 false, // Strict mode name already checked. |
1016 shared_info->is_generator(), | 1018 shared_info->is_generator(), |
1017 RelocInfo::kNoPosition, | 1019 RelocInfo::kNoPosition, |
1018 function_type, | 1020 function_type, |
| 1021 FunctionLiteral::NORMAL_ARITY, |
1019 &ok); | 1022 &ok); |
1020 // Make sure the results agree. | 1023 // Make sure the results agree. |
1021 ASSERT(ok == (result != NULL)); | 1024 ASSERT(ok == (result != NULL)); |
1022 } | 1025 } |
1023 | 1026 |
1024 // Make sure the target stack is empty. | 1027 // Make sure the target stack is empty. |
1025 ASSERT(target_stack_ == NULL); | 1028 ASSERT(target_stack_ == NULL); |
1026 | 1029 |
1027 if (result == NULL) { | 1030 if (result == NULL) { |
1028 if (stack_overflow()) { | 1031 if (stack_overflow()) { |
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1858 bool is_generator = allow_generators() && Check(Token::MUL); | 1861 bool is_generator = allow_generators() && Check(Token::MUL); |
1859 bool is_strict_reserved = false; | 1862 bool is_strict_reserved = false; |
1860 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1863 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
1861 &is_strict_reserved, CHECK_OK); | 1864 &is_strict_reserved, CHECK_OK); |
1862 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1865 FunctionLiteral* fun = ParseFunctionLiteral(name, |
1863 scanner()->location(), | 1866 scanner()->location(), |
1864 is_strict_reserved, | 1867 is_strict_reserved, |
1865 is_generator, | 1868 is_generator, |
1866 pos, | 1869 pos, |
1867 FunctionLiteral::DECLARATION, | 1870 FunctionLiteral::DECLARATION, |
| 1871 FunctionLiteral::NORMAL_ARITY, |
1868 CHECK_OK); | 1872 CHECK_OK); |
1869 // Even if we're not at the top-level of the global or a function | 1873 // Even if we're not at the top-level of the global or a function |
1870 // scope, we treat it as such and introduce the function with its | 1874 // scope, we treat it as such and introduce the function with its |
1871 // initial value upon entering the corresponding scope. | 1875 // initial value upon entering the corresponding scope. |
1872 // In extended mode, a function behaves as a lexical binding, except in the | 1876 // In extended mode, a function behaves as a lexical binding, except in the |
1873 // global scope. | 1877 // global scope. |
1874 VariableMode mode = | 1878 VariableMode mode = |
1875 allow_harmony_scoping() && | 1879 allow_harmony_scoping() && |
1876 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; | 1880 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
1877 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1881 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3268 } | 3272 } |
3269 | 3273 |
3270 | 3274 |
3271 FunctionLiteral* Parser::ParseFunctionLiteral( | 3275 FunctionLiteral* Parser::ParseFunctionLiteral( |
3272 Handle<String> function_name, | 3276 Handle<String> function_name, |
3273 Scanner::Location function_name_location, | 3277 Scanner::Location function_name_location, |
3274 bool name_is_strict_reserved, | 3278 bool name_is_strict_reserved, |
3275 bool is_generator, | 3279 bool is_generator, |
3276 int function_token_pos, | 3280 int function_token_pos, |
3277 FunctionLiteral::FunctionType function_type, | 3281 FunctionLiteral::FunctionType function_type, |
| 3282 FunctionLiteral::ArityRestriction arity_restriction, |
3278 bool* ok) { | 3283 bool* ok) { |
3279 // Function :: | 3284 // Function :: |
3280 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3285 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 3286 // |
| 3287 // Getter :: |
| 3288 // '(' ')' '{' FunctionBody '}' |
| 3289 // |
| 3290 // Setter :: |
| 3291 // '(' PropertySetParameterList ')' '{' FunctionBody '}' |
3281 | 3292 |
3282 int pos = function_token_pos == RelocInfo::kNoPosition | 3293 int pos = function_token_pos == RelocInfo::kNoPosition |
3283 ? peek_position() : function_token_pos; | 3294 ? peek_position() : function_token_pos; |
3284 | 3295 |
3285 // Anonymous functions were passed either the empty symbol or a null | 3296 // Anonymous functions were passed either the empty symbol or a null |
3286 // handle as the function name. Remember if we were passed a non-empty | 3297 // handle as the function name. Remember if we were passed a non-empty |
3287 // handle to decide whether to invoke function name inference. | 3298 // handle to decide whether to invoke function name inference. |
3288 bool should_infer_name = function_name.is_null(); | 3299 bool should_infer_name = function_name.is_null(); |
3289 | 3300 |
3290 // We want a non-null handle as the function name. | 3301 // We want a non-null handle as the function name. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3363 Expect(Token::LPAREN, CHECK_OK); | 3374 Expect(Token::LPAREN, CHECK_OK); |
3364 scope->set_start_position(scanner()->location().beg_pos); | 3375 scope->set_start_position(scanner()->location().beg_pos); |
3365 | 3376 |
3366 // We don't yet know if the function will be strict, so we cannot yet | 3377 // We don't yet know if the function will be strict, so we cannot yet |
3367 // produce errors for parameter names or duplicates. However, we remember | 3378 // produce errors for parameter names or duplicates. However, we remember |
3368 // the locations of these errors if they occur and produce the errors later. | 3379 // the locations of these errors if they occur and produce the errors later. |
3369 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 3380 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
3370 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 3381 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
3371 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3382 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
3372 | 3383 |
3373 bool done = (peek() == Token::RPAREN); | 3384 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || |
| 3385 (peek() == Token::RPAREN && |
| 3386 arity_restriction != FunctionLiteral::SETTER_ARITY); |
3374 while (!done) { | 3387 while (!done) { |
3375 bool is_strict_reserved = false; | 3388 bool is_strict_reserved = false; |
3376 Handle<String> param_name = | 3389 Handle<String> param_name = |
3377 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 3390 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
3378 | 3391 |
3379 // Store locations for possible future error reports. | 3392 // Store locations for possible future error reports. |
3380 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 3393 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
3381 eval_args_error_log = scanner()->location(); | 3394 eval_args_error_log = scanner()->location(); |
3382 } | 3395 } |
3383 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3396 if (!reserved_loc.IsValid() && is_strict_reserved) { |
3384 reserved_loc = scanner()->location(); | 3397 reserved_loc = scanner()->location(); |
3385 } | 3398 } |
3386 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 3399 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { |
3387 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 3400 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
3388 dupe_error_loc = scanner()->location(); | 3401 dupe_error_loc = scanner()->location(); |
3389 } | 3402 } |
3390 | 3403 |
3391 scope_->DeclareParameter(param_name, VAR); | 3404 scope_->DeclareParameter(param_name, VAR); |
3392 num_parameters++; | 3405 num_parameters++; |
3393 if (num_parameters > Code::kMaxArguments) { | 3406 if (num_parameters > Code::kMaxArguments) { |
3394 ReportMessage("too_many_parameters"); | 3407 ReportMessage("too_many_parameters"); |
3395 *ok = false; | 3408 *ok = false; |
3396 return NULL; | 3409 return NULL; |
3397 } | 3410 } |
| 3411 if (arity_restriction == FunctionLiteral::SETTER_ARITY) break; |
3398 done = (peek() == Token::RPAREN); | 3412 done = (peek() == Token::RPAREN); |
3399 if (!done) Expect(Token::COMMA, CHECK_OK); | 3413 if (!done) Expect(Token::COMMA, CHECK_OK); |
3400 } | 3414 } |
3401 Expect(Token::RPAREN, CHECK_OK); | 3415 Expect(Token::RPAREN, CHECK_OK); |
3402 | 3416 |
3403 Expect(Token::LBRACE, CHECK_OK); | 3417 Expect(Token::LBRACE, CHECK_OK); |
3404 | 3418 |
3405 // If we have a named function expression, we add a local variable | 3419 // If we have a named function expression, we add a local variable |
3406 // declaration to the body of the function with the name of the | 3420 // declaration to the body of the function with the name of the |
3407 // function and let it refer to the function itself (closure). | 3421 // function and let it refer to the function itself (closure). |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4783 ASSERT(info()->isolate()->has_pending_exception()); | 4797 ASSERT(info()->isolate()->has_pending_exception()); |
4784 } else { | 4798 } else { |
4785 result = ParseProgram(); | 4799 result = ParseProgram(); |
4786 } | 4800 } |
4787 } | 4801 } |
4788 info()->SetFunction(result); | 4802 info()->SetFunction(result); |
4789 return (result != NULL); | 4803 return (result != NULL); |
4790 } | 4804 } |
4791 | 4805 |
4792 } } // namespace v8::internal | 4806 } } // namespace v8::internal |
OLD | NEW |