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

Side by Side Diff: src/parser.cc

Issue 160073006: Implement handling of arrow functions in the parser (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Implement handling of arrow functions in the parser Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.h » ('J')
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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 744
745 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { 745 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
746 return parser_->ParseV8Intrinsic(ok); 746 return parser_->ParseV8Intrinsic(ok);
747 } 747 }
748 748
749 749
750 FunctionLiteral* ParserTraits::ParseFunctionLiteral( 750 FunctionLiteral* ParserTraits::ParseFunctionLiteral(
751 Handle<String> name, 751 Handle<String> name,
752 Scanner::Location function_name_location, 752 Scanner::Location function_name_location,
753 bool name_is_strict_reserved, 753 bool name_is_strict_reserved,
754 bool is_generator, 754 FunctionParsingMode parsing_mode,
755 Expression* params_ast,
755 int function_token_position, 756 int function_token_position,
756 FunctionLiteral::FunctionType type, 757 FunctionLiteral::FunctionType type,
757 bool* ok) { 758 bool* ok) {
758 return parser_->ParseFunctionLiteral(name, function_name_location, 759 return parser_->ParseFunctionLiteral(name, function_name_location,
759 name_is_strict_reserved, is_generator, 760 name_is_strict_reserved, parsing_mode,
760 function_token_position, type, ok); 761 params_ast, function_token_position,
762 type, ok);
761 } 763 }
762 764
763 765
764 Parser::Parser(CompilationInfo* info) 766 Parser::Parser(CompilationInfo* info)
765 : ParserBase<ParserTraits>(&scanner_, 767 : ParserBase<ParserTraits>(&scanner_,
766 info->isolate()->stack_guard()->real_climit(), 768 info->isolate()->stack_guard()->real_climit(),
767 info->extension(), 769 info->extension(),
768 NULL, 770 NULL,
769 info->zone(), 771 info->zone(),
770 this), 772 this),
771 isolate_(info->isolate()), 773 isolate_(info->isolate()),
772 symbol_cache_(0, info->zone()), 774 symbol_cache_(0, info->zone()),
773 script_(info->script()), 775 script_(info->script()),
774 scanner_(isolate_->unicode_cache()), 776 scanner_(isolate_->unicode_cache()),
775 reusable_preparser_(NULL), 777 reusable_preparser_(NULL),
776 original_scope_(NULL), 778 original_scope_(NULL),
777 target_stack_(NULL), 779 target_stack_(NULL),
778 cached_data_(NULL), 780 cached_data_(NULL),
779 cached_data_mode_(NO_CACHED_DATA), 781 cached_data_mode_(NO_CACHED_DATA),
780 info_(info) { 782 info_(info) {
781 ASSERT(!script_.is_null()); 783 ASSERT(!script_.is_null());
782 isolate_->set_ast_node_id(0); 784 isolate_->set_ast_node_id(0);
783 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); 785 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
784 set_allow_modules(!info->is_native() && FLAG_harmony_modules); 786 set_allow_modules(!info->is_native() && FLAG_harmony_modules);
785 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); 787 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
786 set_allow_lazy(false); // Must be explicitly enabled. 788 set_allow_lazy(false); // Must be explicitly enabled.
787 set_allow_generators(FLAG_harmony_generators); 789 set_allow_generators(FLAG_harmony_generators);
788 set_allow_for_of(FLAG_harmony_iteration); 790 set_allow_for_of(FLAG_harmony_iteration);
791 set_allow_arrow_functions(FLAG_harmony_arrow_functions);
789 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 792 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
790 } 793 }
791 794
792 795
793 FunctionLiteral* Parser::ParseProgram() { 796 FunctionLiteral* Parser::ParseProgram() {
794 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, 797 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here,
795 // see comment for HistogramTimerScope class. 798 // see comment for HistogramTimerScope class.
796 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); 799 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true);
797 Handle<String> source(String::cast(script_->source())); 800 Handle<String> source(String::cast(script_->source()));
798 isolate()->counters()->total_parse_size()->Increment(source->length()); 801 isolate()->counters()->total_parse_size()->Increment(source->length());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 body, 917 body,
915 function_state.materialized_literal_count(), 918 function_state.materialized_literal_count(),
916 function_state.expected_property_count(), 919 function_state.expected_property_count(),
917 function_state.handler_count(), 920 function_state.handler_count(),
918 0, 921 0,
919 FunctionLiteral::kNoDuplicateParameters, 922 FunctionLiteral::kNoDuplicateParameters,
920 FunctionLiteral::ANONYMOUS_EXPRESSION, 923 FunctionLiteral::ANONYMOUS_EXPRESSION,
921 FunctionLiteral::kGlobalOrEval, 924 FunctionLiteral::kGlobalOrEval,
922 FunctionLiteral::kNotParenthesized, 925 FunctionLiteral::kNotParenthesized,
923 FunctionLiteral::kNotGenerator, 926 FunctionLiteral::kNotGenerator,
927 FunctionLiteral::kNotArrow,
924 0); 928 0);
925 result->set_ast_properties(factory()->visitor()->ast_properties()); 929 result->set_ast_properties(factory()->visitor()->ast_properties());
926 result->set_slot_processor(factory()->visitor()->slot_processor()); 930 result->set_slot_processor(factory()->visitor()->slot_processor());
927 result->set_dont_optimize_reason( 931 result->set_dont_optimize_reason(
928 factory()->visitor()->dont_optimize_reason()); 932 factory()->visitor()->dont_optimize_reason());
929 } else if (stack_overflow()) { 933 } else if (stack_overflow()) {
930 isolate()->StackOverflow(); 934 isolate()->StackOverflow();
931 } 935 }
932 } 936 }
933 937
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 original_scope_ = scope; 1003 original_scope_ = scope;
1000 FunctionState function_state(&function_state_, &scope_, scope, zone()); 1004 FunctionState function_state(&function_state_, &scope_, scope, zone());
1001 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); 1005 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
1002 ASSERT(info()->strict_mode() == shared_info->strict_mode()); 1006 ASSERT(info()->strict_mode() == shared_info->strict_mode());
1003 scope->SetStrictMode(shared_info->strict_mode()); 1007 scope->SetStrictMode(shared_info->strict_mode());
1004 FunctionLiteral::FunctionType function_type = shared_info->is_expression() 1008 FunctionLiteral::FunctionType function_type = shared_info->is_expression()
1005 ? (shared_info->is_anonymous() 1009 ? (shared_info->is_anonymous()
1006 ? FunctionLiteral::ANONYMOUS_EXPRESSION 1010 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1007 : FunctionLiteral::NAMED_EXPRESSION) 1011 : FunctionLiteral::NAMED_EXPRESSION)
1008 : FunctionLiteral::DECLARATION; 1012 : FunctionLiteral::DECLARATION;
1013 FunctionParsingMode parsing_mode = shared_info->is_generator()
rossberg 2014/03/25 12:35:34 Nit: I'd prefer formatting this like FunctionPars
1014 ? kGeneratorFunction
1015 : (shared_info->is_arrow() ? kArrowFunction : kNormalFunction);
1009 bool ok = true; 1016 bool ok = true;
1010 result = ParseFunctionLiteral(name, 1017 result = ParseFunctionLiteral(name,
1011 Scanner::Location::invalid(), 1018 Scanner::Location::invalid(),
1012 false, // Strict mode name already checked. 1019 false, // Strict mode name already checked.
1013 shared_info->is_generator(), 1020 parsing_mode,
1021 EmptyExpression(),
1014 RelocInfo::kNoPosition, 1022 RelocInfo::kNoPosition,
1015 function_type, 1023 function_type,
1016 &ok); 1024 &ok);
1017 // Make sure the results agree. 1025 // Make sure the results agree.
1018 ASSERT(ok == (result != NULL)); 1026 ASSERT(ok == (result != NULL));
1019 } 1027 }
1020 1028
1021 // Make sure the target stack is empty. 1029 // Make sure the target stack is empty.
1022 ASSERT(target_stack_ == NULL); 1030 ASSERT(target_stack_ == NULL);
1023 1031
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 1860
1853 1861
1854 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { 1862 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
1855 // FunctionDeclaration :: 1863 // FunctionDeclaration ::
1856 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1864 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1857 // GeneratorDeclaration :: 1865 // GeneratorDeclaration ::
1858 // 'function' '*' Identifier '(' FormalParameterListopt ')' 1866 // 'function' '*' Identifier '(' FormalParameterListopt ')'
1859 // '{' FunctionBody '}' 1867 // '{' FunctionBody '}'
1860 Expect(Token::FUNCTION, CHECK_OK); 1868 Expect(Token::FUNCTION, CHECK_OK);
1861 int pos = position(); 1869 int pos = position();
1862 bool is_generator = allow_generators() && Check(Token::MUL); 1870 FunctionParsingMode parsing_mode = (allow_generators() && Check(Token::MUL))
1871 ? kGeneratorFunction
1872 : kNormalFunction;
1863 bool is_strict_reserved = false; 1873 bool is_strict_reserved = false;
1864 Handle<String> name = ParseIdentifierOrStrictReservedWord( 1874 Handle<String> name = ParseIdentifierOrStrictReservedWord(
1865 &is_strict_reserved, CHECK_OK); 1875 &is_strict_reserved, CHECK_OK);
1866 FunctionLiteral* fun = ParseFunctionLiteral(name, 1876 FunctionLiteral* fun = ParseFunctionLiteral(name,
1867 scanner()->location(), 1877 scanner()->location(),
1868 is_strict_reserved, 1878 is_strict_reserved,
1869 is_generator, 1879 parsing_mode,
1880 EmptyExpression(),
1870 pos, 1881 pos,
1871 FunctionLiteral::DECLARATION, 1882 FunctionLiteral::DECLARATION,
1872 CHECK_OK); 1883 CHECK_OK);
1873 // Even if we're not at the top-level of the global or a function 1884 // Even if we're not at the top-level of the global or a function
1874 // scope, we treat it as such and introduce the function with its 1885 // scope, we treat it as such and introduce the function with its
1875 // initial value upon entering the corresponding scope. 1886 // initial value upon entering the corresponding scope.
1876 // In extended mode, a function behaves as a lexical binding, except in the 1887 // In extended mode, a function behaves as a lexical binding, except in the
1877 // global scope. 1888 // global scope.
1878 VariableMode mode = 1889 VariableMode mode =
1879 FLAG_harmony_scoping && 1890 FLAG_harmony_scoping &&
(...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after
3118 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); 3129 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot));
3119 return static_cast<LiteralType>(literal_type->value()); 3130 return static_cast<LiteralType>(literal_type->value());
3120 } 3131 }
3121 3132
3122 3133
3123 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3134 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
3124 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3135 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
3125 } 3136 }
3126 3137
3127 3138
3139 Vector<VariableProxy*> Parser::ParameterListFromExpression(
rossberg 2014/03/25 12:35:34 How does this rule out illegal parenthesis? For ex
aperez 2014/04/09 08:47:16 True, this case is tricky to implement when re-int
3140 Expression* expression, bool* ok) {
3141 if (expression == NULL)
marja 2014/03/24 09:04:06 Normally having expression == NULL would be an err
aperez 2014/04/09 08:47:16 Yes, when the argument list is empty, “expression”
3142 return Vector<VariableProxy*>::empty();
3143
3144 Collector<VariableProxy*> collector;
3145 while (expression->IsBinaryOperation()) {
3146 BinaryOperation* binop = expression->AsBinaryOperation();
3147
3148 if (binop->op() != Token::COMMA) {
3149 const char* token_name = Token::String(binop->op());
3150 int pos = binop->position();
3151 ParserTraits::ReportMessageAt(Scanner::Location(pos, pos),
rossberg 2014/03/25 12:35:34 Can we refactor this a little to avoid all the err
aperez 2014/04/09 08:47:16 Sure.
3152 "unexpected_token",
3153 Vector<const char*>(&token_name, 1));
3154 *ok = false;
3155 return Vector<VariableProxy*>::empty();
3156 }
3157
3158 if (!binop->right()->IsVariableProxy()) {
3159 const char* token_name = Token::String(binop->op());
3160 int pos = binop->position();
3161 ParserTraits::ReportMessageAt(Scanner::Location(pos, pos),
3162 "unexpected_token",
3163 Vector<const char*>(&token_name, 1));
3164 *ok = false;
3165 return Vector<VariableProxy*>::empty();
3166 }
3167
3168 if (binop->right()->AsVariableProxy()->is_this()) {
3169 const char* token_name = Token::String(Token::THIS);
3170 int pos = binop->right()->position();
3171 ParserTraits::ReportMessageAt(Scanner::Location(pos, pos + 4),
3172 "unexpected_token",
3173 Vector<const char*>(&token_name, 1));
3174 *ok = false;
3175 return Vector<VariableProxy*>::empty();
3176 }
3177
3178 collector.Add(binop->right()->AsVariableProxy());
3179 expression = binop->left();
3180 }
3181
3182 if (!expression->IsVariableProxy()) {
3183 int pos = expression->position();
3184 ParserTraits::ReportMessageAt(Scanner::Location(pos, pos),
3185 "unexpected_token",
3186 Vector<const char*>());
3187 *ok = false;
3188 return Vector<VariableProxy*>::empty();
3189 }
3190
3191 if (expression->AsVariableProxy()->is_this()) {
3192 const char* token_name = Token::String(Token::THIS);
3193 int pos = expression->position();
3194 ParserTraits::ReportMessageAt(Scanner::Location(pos, pos + 4),
3195 "unexpected_token",
3196 Vector<const char*>(&token_name, 1));
3197 *ok = false;
3198 return Vector<VariableProxy*>::empty();
3199 }
3200
3201 collector.Add(expression->AsVariableProxy());
3202
3203 return collector.ToVector();
3204 }
3205
3128 FunctionLiteral* Parser::ParseFunctionLiteral( 3206 FunctionLiteral* Parser::ParseFunctionLiteral(
3129 Handle<String> function_name, 3207 Handle<String> function_name,
3130 Scanner::Location function_name_location, 3208 Scanner::Location function_name_location,
3131 bool name_is_strict_reserved, 3209 bool name_is_strict_reserved,
3132 bool is_generator, 3210 FunctionParsingMode func_parsing_mode,
3211 Expression* params_ast,
3133 int function_token_pos, 3212 int function_token_pos,
3134 FunctionLiteral::FunctionType function_type, 3213 FunctionLiteral::FunctionType function_type,
3135 bool* ok) { 3214 bool* ok) {
3136 // Function :: 3215 // Function ::
3137 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3216 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3138 3217
3139 int pos = function_token_pos == RelocInfo::kNoPosition 3218 int pos = function_token_pos == RelocInfo::kNoPosition
3140 ? peek_position() : function_token_pos; 3219 ? peek_position() : function_token_pos;
3141 3220
3142 // Anonymous functions were passed either the empty symbol or a null 3221 // Anonymous functions were passed either the empty symbol or a null
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3188 : NewScope(scope_, FUNCTION_SCOPE); 3267 : NewScope(scope_, FUNCTION_SCOPE);
3189 ZoneList<Statement*>* body = NULL; 3268 ZoneList<Statement*>* body = NULL;
3190 int materialized_literal_count = -1; 3269 int materialized_literal_count = -1;
3191 int expected_property_count = -1; 3270 int expected_property_count = -1;
3192 int handler_count = 0; 3271 int handler_count = 0;
3193 FunctionLiteral::ParameterFlag duplicate_parameters = 3272 FunctionLiteral::ParameterFlag duplicate_parameters =
3194 FunctionLiteral::kNoDuplicateParameters; 3273 FunctionLiteral::kNoDuplicateParameters;
3195 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ 3274 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
3196 ? FunctionLiteral::kIsParenthesized 3275 ? FunctionLiteral::kIsParenthesized
3197 : FunctionLiteral::kNotParenthesized; 3276 : FunctionLiteral::kNotParenthesized;
3198 FunctionLiteral::IsGeneratorFlag generator = is_generator 3277 FunctionLiteral::IsGeneratorFlag generator =
3199 ? FunctionLiteral::kIsGenerator 3278 (func_parsing_mode == kGeneratorFunction)
3200 : FunctionLiteral::kNotGenerator; 3279 ? FunctionLiteral::kIsGenerator
3280 : FunctionLiteral::kNotGenerator;
3281 FunctionLiteral::IsArrowFlag arrow = (func_parsing_mode == kArrowFunction)
3282 ? FunctionLiteral::kIsArrow
3283 : FunctionLiteral::kNotArrow;
3201 DeferredFeedbackSlotProcessor* slot_processor; 3284 DeferredFeedbackSlotProcessor* slot_processor;
3202 AstProperties ast_properties; 3285 AstProperties ast_properties;
3203 BailoutReason dont_optimize_reason = kNoReason; 3286 BailoutReason dont_optimize_reason = kNoReason;
3204 // Parse function body. 3287 // Parse function body.
3205 { FunctionState function_state(&function_state_, &scope_, scope, zone()); 3288 { FunctionState function_state(&function_state_, &scope_, scope, zone());
3206 scope_->SetScopeName(function_name); 3289 scope_->SetScopeName(function_name);
3207 3290
3208 if (is_generator) { 3291 if (func_parsing_mode == kGeneratorFunction) {
3209 // For generators, allocating variables in contexts is currently a win 3292 // For generators, allocating variables in contexts is currently a win
3210 // because it minimizes the work needed to suspend and resume an 3293 // because it minimizes the work needed to suspend and resume an
3211 // activation. 3294 // activation.
3212 scope_->ForceContextAllocation(); 3295 scope_->ForceContextAllocation();
3213 3296
3214 // Calling a generator returns a generator object. That object is stored 3297 // Calling a generator returns a generator object. That object is stored
3215 // in a temporary variable, a definition that is used by "yield" 3298 // in a temporary variable, a definition that is used by "yield"
3216 // expressions. This also marks the FunctionState as a generator. 3299 // expressions. This also marks the FunctionState as a generator.
3217 Variable* temp = scope_->DeclarationScope()->NewTemporary( 3300 Variable* temp = scope_->DeclarationScope()->NewTemporary(
3218 isolate()->factory()->dot_generator_object_string()); 3301 isolate()->factory()->dot_generator_object_string());
3219 function_state.set_generator_object_variable(temp); 3302 function_state.set_generator_object_variable(temp);
3220 } 3303 }
3221 3304
3222 // FormalParameterList ::
3223 // '(' (Identifier)*[','] ')'
3224 Expect(Token::LPAREN, CHECK_OK);
3225 scope->set_start_position(scanner()->location().beg_pos);
3226
3227 // We don't yet know if the function will be strict, so we cannot yet 3305 // We don't yet know if the function will be strict, so we cannot yet
3228 // produce errors for parameter names or duplicates. However, we remember 3306 // produce errors for parameter names or duplicates. However, we remember
3229 // the locations of these errors if they occur and produce the errors later. 3307 // the locations of these errors if they occur and produce the errors later.
3230 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); 3308 Scanner::Location eval_args_error_log = Scanner::Location::invalid();
3231 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); 3309 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3232 Scanner::Location reserved_loc = Scanner::Location::invalid(); 3310 Scanner::Location reserved_loc = Scanner::Location::invalid();
3233 3311
3234 bool done = (peek() == Token::RPAREN); 3312 // FormalParameterList ::
marja 2014/03/24 09:04:06 This ParseFunctionLiteral is pretty monstrous as i
rossberg 2014/03/25 12:35:34 +1. The arrow function case is parsing quite diffe
aperez 2014/04/09 08:47:16 I am in the process of moving parsing of arrow fun
3235 while (!done) { 3313 // '(' (Identifier)*[','] ')'
3236 bool is_strict_reserved = false; 3314
3237 Handle<String> param_name = 3315 if (func_parsing_mode == kArrowFunction && peek() == Token::ARROW) {
rossberg 2014/03/25 12:35:34 Can it ever happen that the first condition is tru
aperez 2014/04/09 08:47:16 It could happen when the function is parsed lazily
3238 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 3316 // The parameter list has already been scanned and turned into an AST
3239 3317 // and it is passed as "params_ast". Re-interpreting the AST avoids
3240 // Store locations for possible future error reports. 3318 // needing to rewind and re-parse the parameter list. The starting
3241 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { 3319 // position of the parameter list is passed as "function_token_pos".
3242 eval_args_error_log = scanner()->location(); 3320 scope->set_start_position(function_token_pos);
3243 } 3321 Vector<VariableProxy*> params = ParameterListFromExpression(params_ast,
3244 if (!reserved_loc.IsValid() && is_strict_reserved) { 3322 CHECK_OK);
3245 reserved_loc = scanner()->location(); 3323
3246 } 3324 if ((num_parameters = params.length()) > Code::kMaxArguments) {
3247 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { 3325 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
3248 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; 3326 "too_many_parameters");
3249 dupe_error_loc = scanner()->location();
3250 }
3251
3252 scope_->DeclareParameter(param_name, VAR);
3253 num_parameters++;
3254 if (num_parameters > Code::kMaxArguments) {
3255 ReportMessageAt(scanner()->location(), "too_many_parameters");
3256 *ok = false; 3327 *ok = false;
3257 return NULL; 3328 return NULL;
3258 } 3329 }
3259 done = (peek() == Token::RPAREN); 3330
3260 if (!done) Expect(Token::COMMA, CHECK_OK); 3331 // The vector has the items in reverse order
3332 for (int i = params.length() - 1; i >= 0; --i) {
3333 Handle<String> param_name = params.at(i)->name();
3334 int param_pos = params.at(i)->position();
3335
3336 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3337 eval_args_error_log =
3338 Scanner::Location(param_pos, param_pos + param_name->length());
3339 }
3340 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3341 dupe_error_loc =
3342 Scanner::Location(param_pos, param_pos + param_name->length());
3343 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3344 }
3345
3346 scope_->DeclareParameter(param_name, VAR);
3347 }
3348 } else {
3349 bool arrow_single_param =
3350 (func_parsing_mode == kArrowFunction && peek() != Token::LPAREN);
3351
3352 if (!arrow_single_param) {
3353 Expect(Token::LPAREN, CHECK_OK);
3354 }
3355
3356 scope->set_start_position(scanner()->location().beg_pos);
3357
3358 bool done = (peek() == Token::RPAREN);
3359 while (!done) {
3360 bool is_strict_reserved = false;
3361 Handle<String> param_name =
3362 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3363
3364 // Store locations for possible future error reports.
3365 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) {
3366 eval_args_error_log = scanner()->location();
3367 }
3368 if (!reserved_loc.IsValid() && is_strict_reserved) {
3369 reserved_loc = scanner()->location();
3370 }
3371 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
3372 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3373 dupe_error_loc = scanner()->location();
3374 }
3375
3376 scope_->DeclareParameter(param_name, VAR);
3377 num_parameters++;
3378 if (num_parameters > Code::kMaxArguments) {
3379 ReportMessageAt(scanner()->location(), "too_many_parameters");
3380 *ok = false;
3381 return NULL;
3382 }
3383
3384 done = (peek() == Token::RPAREN);
3385 if (arrow_single_param) break;
3386 if (!done) Expect(Token::COMMA, CHECK_OK);
3387 }
3388
3389 if (!arrow_single_param) {
3390 Expect(Token::RPAREN, CHECK_OK);
3391 }
3261 } 3392 }
3262 Expect(Token::RPAREN, CHECK_OK); 3393
3263 3394 if (func_parsing_mode == kArrowFunction) {
3264 Expect(Token::LBRACE, CHECK_OK); 3395 Expect(Token::ARROW, CHECK_OK);
3265 3396
3266 // If we have a named function expression, we add a local variable 3397 // The arrow function has a single-expression body
3267 // declaration to the body of the function with the name of the 3398 if (peek() != Token::LBRACE) {
3268 // function and let it refer to the function itself (closure). 3399 int pos = position();
3269 // NOTE: We create a proxy and resolve it here so that in the 3400 Expression* expression = ParseExpression(true, CHECK_OK);
rossberg 2014/03/25 12:35:34 Shouldn't this be ParseAssignmentExpression?
aperez 2014/04/09 08:47:16 Indeed.
3270 // future we can change the AST to only refer to VariableProxies 3401 body = new(zone()) ZoneList<Statement*>(1, zone());
3271 // instead of Variables and Proxis as is the case now. 3402 body->Add(factory()->NewReturnStatement(expression, pos), zone());
3272 Variable* fvar = NULL; 3403
3273 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; 3404 materialized_literal_count =
3274 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { 3405 function_state.materialized_literal_count();
3275 if (FLAG_harmony_scoping && strict_mode() == STRICT) { 3406 expected_property_count = function_state.expected_property_count();
3276 fvar_init_op = Token::INIT_CONST; 3407 handler_count = function_state.handler_count();
3277 } 3408
3278 VariableMode fvar_mode = FLAG_harmony_scoping && strict_mode() == STRICT 3409 scope->set_end_position(scanner()->location().end_pos);
3279 ? CONST : CONST_LEGACY; 3410 }
3280 fvar = new(zone()) Variable(scope_,
3281 function_name, fvar_mode, true /* is valid LHS */,
3282 Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
3283 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3284 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration(
3285 proxy, fvar_mode, scope_, RelocInfo::kNoPosition);
3286 scope_->DeclareFunctionVar(fvar_declaration);
3287 } 3411 }
3288 3412
3289 // Determine if the function can be parsed lazily. Lazy parsing is different 3413 // If an arrow function has a single-expression body,
3290 // from lazy compilation; we need to parse more eagerly than we compile. 3414 // it was already parsed above and "body" is non-NULL.
3291 3415 if (body == NULL) {
3292 // We can only parse lazily if we also compile lazily. The heuristics for 3416 Expect(Token::LBRACE, CHECK_OK);
3293 // lazy compilation are: 3417
3294 // - It must not have been prohibited by the caller to Parse (some callers 3418 // If we have a named function expression, we add a local variable
3295 // need a full AST). 3419 // declaration to the body of the function with the name of the
3296 // - The outer scope must allow lazy compilation of inner functions. 3420 // function and let it refer to the function itself (closure).
3297 // - The function mustn't be a function expression with an open parenthesis 3421 // NOTE: We create a proxy and resolve it here so that in the
3298 // before; we consider that a hint that the function will be called 3422 // future we can change the AST to only refer to VariableProxies
3299 // immediately, and it would be a waste of time to make it lazily 3423 // instead of Variables and Proxis as is the case now.
3300 // compiled. 3424 Variable* fvar = NULL;
3301 // These are all things we can know at this point, without looking at the 3425 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
3302 // function itself. 3426 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
3303 3427 if (FLAG_harmony_scoping && strict_mode() == STRICT) {
3304 // In addition, we need to distinguish between these cases: 3428 fvar_init_op = Token::INIT_CONST;
3305 // (function foo() { 3429 }
3306 // bar = function() { return 1; } 3430 VariableMode fvar_mode = FLAG_harmony_scoping && strict_mode() == STRICT
3307 // })(); 3431 ? CONST : CONST_LEGACY;
3308 // and 3432 fvar = new(zone()) Variable(scope_,
3309 // (function foo() { 3433 function_name, fvar_mode, true /* is valid LHS */,
3310 // var a = 1; 3434 Variable::NORMAL, kCreatedInitialized, Interface::NewConst());
3311 // bar = function() { return a; } 3435 VariableProxy* proxy = factory()->NewVariableProxy(fvar);
3312 // })(); 3436 VariableDeclaration* fvar_declaration =
3313 3437 factory()->NewVariableDeclaration(proxy, fvar_mode, scope_,
3314 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume 3438 RelocInfo::kNoPosition);
3315 // parenthesis before the function means that it will be called 3439 scope_->DeclareFunctionVar(fvar_declaration);
3316 // immediately). The inner function *must* be parsed eagerly to resolve the 3440 }
3317 // possible reference to the variable in foo's scope. However, it's possible 3441
3318 // that it will be compiled lazily. 3442 // Determine if the function can be parsed lazily. Lazy parsing is
3319 3443 // different from lazy compilation; we need to parse more eagerly than
3320 // To make this additional case work, both Parser and PreParser implement a 3444 // we compile.
3321 // logic where only top-level functions will be parsed lazily. 3445
3322 bool is_lazily_parsed = (mode() == PARSE_LAZILY && 3446 // We can only parse lazily if we also compile lazily. The heuristics for
3323 scope_->AllowsLazyCompilation() && 3447 // lazy compilation are:
3324 !parenthesized_function_); 3448 // - It must not have been prohibited by the caller to Parse (some
3325 parenthesized_function_ = false; // The bit was set for this function only. 3449 // callers need a full AST).
3326 3450 // - The outer scope must allow lazy compilation of inner functions.
3327 if (is_lazily_parsed) { 3451 // - The function mustn't be a function expression with an open
3328 int function_block_pos = position(); 3452 // parenthesis before; we consider that a hint that the function will
3329 FunctionEntry entry; 3453 // be called immediately, and it would be a waste of time to make it
3330 if (cached_data_mode_ == CONSUME_CACHED_DATA) { 3454 // lazily compiled.
3331 // If we have cached data, we use it to skip parsing the function body. 3455 // These are all things we can know at this point, without looking at
3332 // The data contains the information we need to construct the lazy 3456 // the function itself.
3333 // function. 3457
3334 entry = (*cached_data())->GetFunctionEntry(function_block_pos); 3458 // In addition, we need to distinguish between these cases:
3335 if (entry.is_valid()) { 3459 // (function foo() {
3336 if (entry.end_pos() <= function_block_pos) { 3460 // bar = function() { return 1; }
3337 // End position greater than end of stream is safe, and hard 3461 // })();
3338 // to check. 3462 // and
3339 ReportInvalidPreparseData(function_name, CHECK_OK); 3463 // (function foo() {
3464 // var a = 1;
3465 // bar = function() { return a; }
3466 // })();
3467
3468 // Now foo will be parsed eagerly and compiled eagerly (optimization:
3469 // assume parenthesis before the function means that it will be called
3470 // immediately). The inner function *must* be parsed eagerly to resolve
3471 // the possible reference to the variable in foo's scope. However, it's
3472 // possible that it will be compiled lazily.
3473
3474 // To make this additional case work, both Parser and PreParser implement
3475 // a logic where only top-level functions will be parsed lazily.
3476 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
3477 scope_->AllowsLazyCompilation() &&
3478 !parenthesized_function_ &&
3479 (func_parsing_mode != kArrowFunction));
3480
3481 // The bit was set for this function only.
3482 parenthesized_function_ = false;
3483
3484 if (is_lazily_parsed) {
3485 int function_block_pos = position();
3486 FunctionEntry entry;
3487 if (cached_data_mode_ == CONSUME_CACHED_DATA) {
3488 // If we have cached data, we use it to skip parsing the function
3489 // body. The data contains the information we need to construct the
3490 // lazy function.
3491 entry = (*cached_data())->GetFunctionEntry(function_block_pos);
3492 if (entry.is_valid()) {
3493 if (entry.end_pos() <= function_block_pos) {
3494 // End position greater than end of stream is safe, and hard
3495 // to check.
3496 ReportInvalidPreparseData(function_name, CHECK_OK);
3497 }
3498 scanner()->SeekForward(entry.end_pos() - 1);
3499
3500 scope->set_end_position(entry.end_pos());
3501 Expect(Token::RBRACE, CHECK_OK);
3502 isolate()->counters()->total_preparse_skipped()->Increment(
3503 scope->end_position() - function_block_pos);
3504 materialized_literal_count = entry.literal_count();
3505 expected_property_count = entry.property_count();
3506 scope_->SetStrictMode(entry.strict_mode());
3507 } else {
3508 // This case happens when we have preparse data but it doesn't
3509 // contain an entry for the function. As a safety net, fall back
3510 // to eager parsing. It is unclear whether PreParser's laziness
3511 // analysis can produce different results than the Parser's
3512 // laziness analysis (see https://codereview.chromium.org/7565003).
3513 // In this case, we must discard all the preparse data, since the
3514 // symbol data will be wrong.
3515 is_lazily_parsed = false;
3516 cached_data_mode_ = NO_CACHED_DATA;
3340 } 3517 }
3341 scanner()->SeekForward(entry.end_pos() - 1); 3518 } else {
3342 3519 // With no cached data, we partially parse the function, without
3343 scope->set_end_position(entry.end_pos()); 3520 // building an AST. This gathers the data needed to build a lazy
3521 // function.
3522 // FIXME(marja): Now the PreParser doesn't need to log functions /
3523 // symbols; only errors -> clean that up.
3524 SingletonLogger logger;
3525 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger);
3526 if (result == PreParser::kPreParseStackOverflow) {
3527 // Propagate stack overflow.
3528 set_stack_overflow();
3529 *ok = false;
3530 return NULL;
3531 }
3532 if (logger.has_error()) {
3533 const char* arg = logger.argument_opt();
3534 Vector<const char*> args;
3535 if (arg != NULL) {
3536 args = Vector<const char*>(&arg, 1);
3537 }
3538 ParserTraits::ReportMessageAt(
3539 Scanner::Location(logger.start(), logger.end()),
3540 logger.message(),
3541 args);
3542 *ok = false;
3543 return NULL;
3544 }
3545 scope->set_end_position(logger.end());
3344 Expect(Token::RBRACE, CHECK_OK); 3546 Expect(Token::RBRACE, CHECK_OK);
3345 isolate()->counters()->total_preparse_skipped()->Increment( 3547 isolate()->counters()->total_preparse_skipped()->Increment(
3346 scope->end_position() - function_block_pos); 3548 scope->end_position() - function_block_pos);
3347 materialized_literal_count = entry.literal_count(); 3549 materialized_literal_count = logger.literals();
3348 expected_property_count = entry.property_count(); 3550 expected_property_count = logger.properties();
3349 scope_->SetStrictMode(entry.strict_mode()); 3551 scope_->SetStrictMode(logger.strict_mode());
3350 } else { 3552 if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
3351 // This case happens when we have preparse data but it doesn't contain 3553 ASSERT(log_);
3352 // an entry for the function. As a safety net, fall back to eager 3554 // Position right after terminal '}'.
3353 // parsing. It is unclear whether PreParser's laziness analysis can 3555 int body_end = scanner()->location().end_pos;
3354 // produce different results than the Parser's laziness analysis (see 3556 log_->LogFunction(function_block_pos, body_end,
3355 // https://codereview.chromium.org/7565003 ). In this case, we must 3557 materialized_literal_count,
3356 // discard all the preparse data, since the symbol data will be wrong. 3558 expected_property_count,
3357 is_lazily_parsed = false; 3559 scope_->strict_mode());
3358 cached_data_mode_ = NO_CACHED_DATA;
3359 }
3360 } else {
3361 // With no cached data, we partially parse the function, without
3362 // building an AST. This gathers the data needed to build a lazy
3363 // function.
3364 // FIXME(marja): Now the PreParser doesn't need to log functions /
3365 // symbols; only errors -> clean that up.
3366 SingletonLogger logger;
3367 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger);
3368 if (result == PreParser::kPreParseStackOverflow) {
3369 // Propagate stack overflow.
3370 set_stack_overflow();
3371 *ok = false;
3372 return NULL;
3373 }
3374 if (logger.has_error()) {
3375 const char* arg = logger.argument_opt();
3376 Vector<const char*> args;
3377 if (arg != NULL) {
3378 args = Vector<const char*>(&arg, 1);
3379 } 3560 }
3380 ParserTraits::ReportMessageAt( 3561 }
3381 Scanner::Location(logger.start(), logger.end()), 3562 }
3382 logger.message(), 3563
3383 args); 3564 if (!is_lazily_parsed) {
3384 *ok = false; 3565 // Everything inside an eagerly parsed function will be parsed eagerly
3385 return NULL; 3566 // (see comment above).
3386 } 3567 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3387 scope->set_end_position(logger.end()); 3568 body = new(zone()) ZoneList<Statement*>(8, zone());
3569 if (fvar != NULL) {
3570 VariableProxy* fproxy = scope_->NewUnresolved(
3571 factory(), function_name, Interface::NewConst());
3572 fproxy->BindTo(fvar);
3573 body->Add(factory()->NewExpressionStatement(
3574 factory()->NewAssignment(fvar_init_op,
3575 fproxy,
3576 factory()->NewThisFunction(pos),
3577 RelocInfo::kNoPosition),
3578 RelocInfo::kNoPosition), zone());
3579 }
3580
3581 // For generators, allocate and yield an iterator on function entry.
3582 if (func_parsing_mode == kGeneratorFunction) {
3583 ZoneList<Expression*>* arguments =
3584 new(zone()) ZoneList<Expression*>(0, zone());
3585 CallRuntime* allocation = factory()->NewCallRuntime(
3586 isolate()->factory()->empty_string(),
3587 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
3588 arguments, pos);
3589 VariableProxy* init_proxy = factory()->NewVariableProxy(
3590 function_state_->generator_object_variable());
3591 Assignment* assignment = factory()->NewAssignment(
3592 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3593 VariableProxy* get_proxy = factory()->NewVariableProxy(
3594 function_state_->generator_object_variable());
3595 Yield* yield = factory()->NewYield(
3596 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
3597 body->Add(factory()->NewExpressionStatement(
3598 yield, RelocInfo::kNoPosition), zone());
3599 }
3600
3601 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
3602
3603 if (func_parsing_mode == kGeneratorFunction) {
3604 VariableProxy* get_proxy = factory()->NewVariableProxy(
3605 function_state_->generator_object_variable());
3606 Expression *undefined = factory()->NewLiteral(
3607 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition);
3608 Yield* yield = factory()->NewYield(
3609 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
3610 body->Add(factory()->NewExpressionStatement(
3611 yield, RelocInfo::kNoPosition), zone());
3612 }
3613
3614 materialized_literal_count =
3615 function_state.materialized_literal_count();
3616 expected_property_count = function_state.expected_property_count();
3617 handler_count = function_state.handler_count();
3618
3388 Expect(Token::RBRACE, CHECK_OK); 3619 Expect(Token::RBRACE, CHECK_OK);
3389 isolate()->counters()->total_preparse_skipped()->Increment( 3620 scope->set_end_position(scanner()->location().end_pos);
3390 scope->end_position() - function_block_pos); 3621 }
3391 materialized_literal_count = logger.literals();
3392 expected_property_count = logger.properties();
3393 scope_->SetStrictMode(logger.strict_mode());
3394 if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
3395 ASSERT(log_);
3396 // Position right after terminal '}'.
3397 int body_end = scanner()->location().end_pos;
3398 log_->LogFunction(function_block_pos, body_end,
3399 materialized_literal_count,
3400 expected_property_count,
3401 scope_->strict_mode());
3402 }
3403 }
3404 }
3405
3406 if (!is_lazily_parsed) {
3407 // Everything inside an eagerly parsed function will be parsed eagerly
3408 // (see comment above).
3409 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3410 body = new(zone()) ZoneList<Statement*>(8, zone());
3411 if (fvar != NULL) {
3412 VariableProxy* fproxy = scope_->NewUnresolved(
3413 factory(), function_name, Interface::NewConst());
3414 fproxy->BindTo(fvar);
3415 body->Add(factory()->NewExpressionStatement(
3416 factory()->NewAssignment(fvar_init_op,
3417 fproxy,
3418 factory()->NewThisFunction(pos),
3419 RelocInfo::kNoPosition),
3420 RelocInfo::kNoPosition), zone());
3421 }
3422
3423 // For generators, allocate and yield an iterator on function entry.
3424 if (is_generator) {
3425 ZoneList<Expression*>* arguments =
3426 new(zone()) ZoneList<Expression*>(0, zone());
3427 CallRuntime* allocation = factory()->NewCallRuntime(
3428 isolate()->factory()->empty_string(),
3429 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject),
3430 arguments, pos);
3431 VariableProxy* init_proxy = factory()->NewVariableProxy(
3432 function_state_->generator_object_variable());
3433 Assignment* assignment = factory()->NewAssignment(
3434 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition);
3435 VariableProxy* get_proxy = factory()->NewVariableProxy(
3436 function_state_->generator_object_variable());
3437 Yield* yield = factory()->NewYield(
3438 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition);
3439 body->Add(factory()->NewExpressionStatement(
3440 yield, RelocInfo::kNoPosition), zone());
3441 }
3442
3443 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK);
3444
3445 if (is_generator) {
3446 VariableProxy* get_proxy = factory()->NewVariableProxy(
3447 function_state_->generator_object_variable());
3448 Expression *undefined = factory()->NewLiteral(
3449 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition);
3450 Yield* yield = factory()->NewYield(
3451 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition);
3452 body->Add(factory()->NewExpressionStatement(
3453 yield, RelocInfo::kNoPosition), zone());
3454 }
3455
3456 materialized_literal_count = function_state.materialized_literal_count();
3457 expected_property_count = function_state.expected_property_count();
3458 handler_count = function_state.handler_count();
3459
3460 Expect(Token::RBRACE, CHECK_OK);
3461 scope->set_end_position(scanner()->location().end_pos);
3462 } 3622 }
3463 3623
3464 // Validate strict mode. We can do this only after parsing the function, 3624 // Validate strict mode. We can do this only after parsing the function,
3465 // since the function can declare itself strict. 3625 // since the function can declare itself strict.
3466 if (strict_mode() == STRICT) { 3626 if (strict_mode() == STRICT) {
3467 if (IsEvalOrArguments(function_name)) { 3627 if (IsEvalOrArguments(function_name)) {
3468 ReportMessageAt(function_name_location, "strict_eval_arguments"); 3628 ReportMessageAt(function_name_location, "strict_eval_arguments");
3469 *ok = false; 3629 *ok = false;
3470 return NULL; 3630 return NULL;
3471 } 3631 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3508 body, 3668 body,
3509 materialized_literal_count, 3669 materialized_literal_count,
3510 expected_property_count, 3670 expected_property_count,
3511 handler_count, 3671 handler_count,
3512 num_parameters, 3672 num_parameters,
3513 duplicate_parameters, 3673 duplicate_parameters,
3514 function_type, 3674 function_type,
3515 FunctionLiteral::kIsFunction, 3675 FunctionLiteral::kIsFunction,
3516 parenthesized, 3676 parenthesized,
3517 generator, 3677 generator,
3678 arrow,
3518 pos); 3679 pos);
3519 function_literal->set_function_token_position(function_token_pos); 3680 function_literal->set_function_token_position(function_token_pos);
3520 function_literal->set_ast_properties(&ast_properties); 3681 function_literal->set_ast_properties(&ast_properties);
3521 function_literal->set_slot_processor(slot_processor); 3682 function_literal->set_slot_processor(slot_processor);
3522 function_literal->set_dont_optimize_reason(dont_optimize_reason); 3683 function_literal->set_dont_optimize_reason(dont_optimize_reason);
3523 3684
3524 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); 3685 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
3525 return function_literal; 3686 return function_literal;
3526 } 3687 }
3527 3688
3528 3689
3529 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( 3690 PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
3530 SingletonLogger* logger) { 3691 SingletonLogger* logger) {
3531 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); 3692 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse());
3532 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); 3693 ASSERT_EQ(Token::LBRACE, scanner()->current_token());
3533 3694
3534 if (reusable_preparser_ == NULL) { 3695 if (reusable_preparser_ == NULL) {
3535 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); 3696 intptr_t stack_limit = isolate()->stack_guard()->real_climit();
3536 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); 3697 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit);
3537 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); 3698 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
3538 reusable_preparser_->set_allow_modules(allow_modules()); 3699 reusable_preparser_->set_allow_modules(allow_modules());
3539 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); 3700 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
3540 reusable_preparser_->set_allow_lazy(true); 3701 reusable_preparser_->set_allow_lazy(true);
3541 reusable_preparser_->set_allow_generators(allow_generators()); 3702 reusable_preparser_->set_allow_generators(allow_generators());
3542 reusable_preparser_->set_allow_for_of(allow_for_of()); 3703 reusable_preparser_->set_allow_for_of(allow_for_of());
3704 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions());
3543 reusable_preparser_->set_allow_harmony_numeric_literals( 3705 reusable_preparser_->set_allow_harmony_numeric_literals(
3544 allow_harmony_numeric_literals()); 3706 allow_harmony_numeric_literals());
3545 } 3707 }
3546 PreParser::PreParseResult result = 3708 PreParser::PreParseResult result =
3547 reusable_preparser_->PreParseLazyFunction(strict_mode(), 3709 reusable_preparser_->PreParseLazyFunction(strict_mode(),
3548 is_generator(), 3710 is_generator(),
3549 logger); 3711 logger);
3550 return result; 3712 return result;
3551 } 3713 }
3552 3714
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after
4617 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate, 4779 ScriptDataImpl* PreParserApi::PreParse(Isolate* isolate,
4618 Utf16CharacterStream* source) { 4780 Utf16CharacterStream* source) {
4619 CompleteParserRecorder recorder; 4781 CompleteParserRecorder recorder;
4620 HistogramTimerScope timer(isolate->counters()->pre_parse()); 4782 HistogramTimerScope timer(isolate->counters()->pre_parse());
4621 Scanner scanner(isolate->unicode_cache()); 4783 Scanner scanner(isolate->unicode_cache());
4622 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 4784 intptr_t stack_limit = isolate->stack_guard()->real_climit();
4623 PreParser preparser(&scanner, &recorder, stack_limit); 4785 PreParser preparser(&scanner, &recorder, stack_limit);
4624 preparser.set_allow_lazy(true); 4786 preparser.set_allow_lazy(true);
4625 preparser.set_allow_generators(FLAG_harmony_generators); 4787 preparser.set_allow_generators(FLAG_harmony_generators);
4626 preparser.set_allow_for_of(FLAG_harmony_iteration); 4788 preparser.set_allow_for_of(FLAG_harmony_iteration);
4789 preparser.set_allow_arrow_functions(FLAG_harmony_arrow_functions);
4627 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); 4790 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping);
4628 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); 4791 preparser.set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
4629 scanner.Initialize(source); 4792 scanner.Initialize(source);
4630 PreParser::PreParseResult result = preparser.PreParseProgram(); 4793 PreParser::PreParseResult result = preparser.PreParseProgram();
4631 if (result == PreParser::kPreParseStackOverflow) { 4794 if (result == PreParser::kPreParseStackOverflow) {
4632 isolate->StackOverflow(); 4795 isolate->StackOverflow();
4633 return NULL; 4796 return NULL;
4634 } 4797 }
4635 4798
4636 // Extract the accumulated data from the recorder as a single 4799 // Extract the accumulated data from the recorder as a single
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4690 ASSERT(info()->isolate()->has_pending_exception()); 4853 ASSERT(info()->isolate()->has_pending_exception());
4691 } else { 4854 } else {
4692 result = ParseProgram(); 4855 result = ParseProgram();
4693 } 4856 }
4694 } 4857 }
4695 info()->SetFunction(result); 4858 info()->SetFunction(result);
4696 return (result != NULL); 4859 return (result != NULL);
4697 } 4860 }
4698 4861
4699 } } // namespace v8::internal 4862 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698