| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <cmath> | 5 #include <cmath> |
| 6 | 6 |
| 7 #include "src/allocation.h" | 7 #include "src/allocation.h" |
| 8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
| 9 #include "src/conversions-inl.h" | 9 #include "src/conversions-inl.h" |
| 10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 PreParserIdentifier symbol = GetSymbolHelper(scanner()); | 77 PreParserIdentifier symbol = GetSymbolHelper(scanner()); |
| 78 if (track_unresolved_variables_) { | 78 if (track_unresolved_variables_) { |
| 79 const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory()); | 79 const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory()); |
| 80 DCHECK_NOT_NULL(result); | 80 DCHECK_NOT_NULL(result); |
| 81 symbol.string_ = result; | 81 symbol.string_ = result; |
| 82 } | 82 } |
| 83 return symbol; | 83 return symbol; |
| 84 } | 84 } |
| 85 | 85 |
| 86 PreParser::PreParseResult PreParser::PreParseLazyFunction( | 86 PreParser::PreParseResult PreParser::PreParseLazyFunction( |
| 87 DeclarationScope* function_scope, bool parsing_module, ParserRecorder* log, | 87 DeclarationScope* function_scope, bool parsing_module, SingletonLogger* log, |
| 88 bool is_inner_function, bool may_abort, int* use_counts) { | 88 bool is_inner_function, bool may_abort, int* use_counts) { |
| 89 DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type()); | 89 DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type()); |
| 90 parsing_module_ = parsing_module; | 90 parsing_module_ = parsing_module; |
| 91 log_ = log; | 91 log_ = log; |
| 92 use_counts_ = use_counts; | 92 use_counts_ = use_counts; |
| 93 DCHECK(!track_unresolved_variables_); | 93 DCHECK(!track_unresolved_variables_); |
| 94 track_unresolved_variables_ = is_inner_function; | 94 track_unresolved_variables_ = is_inner_function; |
| 95 | 95 |
| 96 // The caller passes the function_scope which is not yet inserted into the | 96 // The caller passes the function_scope which is not yet inserted into the |
| 97 // scope_state_. All scopes above the function_scope are ignored by the | 97 // scope_state_. All scopes above the function_scope are ignored by the |
| 98 // PreParser. | 98 // PreParser. |
| 99 DCHECK_NULL(scope_state_); | 99 DCHECK_NULL(scope_state_); |
| 100 FunctionState function_state(&function_state_, &scope_state_, function_scope); | 100 FunctionState function_state(&function_state_, &scope_state_, function_scope); |
| 101 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 101 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| 102 bool ok = true; | 102 bool ok = true; |
| 103 int start_position = peek_position(); | 103 int start_position = peek_position(); |
| 104 LazyParsingResult result = ParseLazyFunctionLiteralBody(may_abort, &ok); | 104 LazyParsingResult result = ParseStatementListAndLogFunction(may_abort, &ok); |
| 105 use_counts_ = nullptr; | 105 use_counts_ = nullptr; |
| 106 track_unresolved_variables_ = false; | 106 track_unresolved_variables_ = false; |
| 107 if (result == kLazyParsingAborted) { | 107 if (result == kLazyParsingAborted) { |
| 108 return kPreParseAbort; | 108 return kPreParseAbort; |
| 109 } else if (stack_overflow()) { | 109 } else if (stack_overflow()) { |
| 110 return kPreParseStackOverflow; | 110 return kPreParseStackOverflow; |
| 111 } else if (!ok) { | 111 } else if (!ok) { |
| 112 ReportUnexpectedToken(scanner()->current_token()); | 112 DCHECK(log->has_error()); |
| 113 } else { | 113 } else { |
| 114 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 114 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
| 115 if (is_strict(function_scope->language_mode())) { | 115 if (is_strict(function_scope->language_mode())) { |
| 116 int end_pos = scanner()->location().end_pos; | 116 int end_pos = scanner()->location().end_pos; |
| 117 CheckStrictOctalLiteral(start_position, end_pos, &ok); | 117 CheckStrictOctalLiteral(start_position, end_pos, &ok); |
| 118 CheckDecimalLiteralWithLeadingZero(start_position, end_pos); | 118 CheckDecimalLiteralWithLeadingZero(start_position, end_pos); |
| 119 } | 119 } |
| 120 } | 120 } |
| 121 return kPreParseSuccess; | 121 return kPreParseSuccess; |
| 122 } | 122 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 138 PreParser::Expression PreParser::ParseFunctionLiteral( | 138 PreParser::Expression PreParser::ParseFunctionLiteral( |
| 139 Identifier function_name, Scanner::Location function_name_location, | 139 Identifier function_name, Scanner::Location function_name_location, |
| 140 FunctionNameValidity function_name_validity, FunctionKind kind, | 140 FunctionNameValidity function_name_validity, FunctionKind kind, |
| 141 int function_token_pos, FunctionLiteral::FunctionType function_type, | 141 int function_token_pos, FunctionLiteral::FunctionType function_type, |
| 142 LanguageMode language_mode, bool* ok) { | 142 LanguageMode language_mode, bool* ok) { |
| 143 // Function :: | 143 // Function :: |
| 144 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 144 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 145 | 145 |
| 146 // Parse function body. | 146 // Parse function body. |
| 147 PreParserStatementList body; | 147 PreParserStatementList body; |
| 148 bool outer_is_script_scope = scope()->is_script_scope(); | |
| 149 DeclarationScope* function_scope = NewFunctionScope(kind); | 148 DeclarationScope* function_scope = NewFunctionScope(kind); |
| 150 function_scope->SetLanguageMode(language_mode); | 149 function_scope->SetLanguageMode(language_mode); |
| 151 FunctionState function_state(&function_state_, &scope_state_, function_scope); | 150 FunctionState function_state(&function_state_, &scope_state_, function_scope); |
| 152 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 151 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 153 ExpressionClassifier formals_classifier(this, &duplicate_finder); | 152 ExpressionClassifier formals_classifier(this, &duplicate_finder); |
| 154 | 153 |
| 155 Expect(Token::LPAREN, CHECK_OK); | 154 Expect(Token::LPAREN, CHECK_OK); |
| 156 int start_position = scanner()->location().beg_pos; | 155 int start_position = scanner()->location().beg_pos; |
| 157 function_scope->set_start_position(start_position); | 156 function_scope->set_start_position(start_position); |
| 158 PreParserFormalParameters formals(function_scope); | 157 PreParserFormalParameters formals(function_scope); |
| 159 ParseFormalParameterList(&formals, CHECK_OK); | 158 ParseFormalParameterList(&formals, CHECK_OK); |
| 160 Expect(Token::RPAREN, CHECK_OK); | 159 Expect(Token::RPAREN, CHECK_OK); |
| 161 int formals_end_position = scanner()->location().end_pos; | 160 int formals_end_position = scanner()->location().end_pos; |
| 162 | 161 |
| 163 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, | 162 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, |
| 164 formals_end_position, CHECK_OK); | 163 formals_end_position, CHECK_OK); |
| 165 | 164 |
| 166 // See Parser::ParseFunctionLiteral for more information about lazy parsing | |
| 167 // and lazy compilation. | |
| 168 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() && | |
| 169 !function_state_->this_function_is_parenthesized()); | |
| 170 | |
| 171 Expect(Token::LBRACE, CHECK_OK); | 165 Expect(Token::LBRACE, CHECK_OK); |
| 172 if (is_lazily_parsed) { | 166 ParseStatementList(body, Token::RBRACE, CHECK_OK); |
| 173 ParseLazyFunctionLiteralBody(false, CHECK_OK); | |
| 174 } else { | |
| 175 ParseStatementList(body, Token::RBRACE, CHECK_OK); | |
| 176 } | |
| 177 Expect(Token::RBRACE, CHECK_OK); | 167 Expect(Token::RBRACE, CHECK_OK); |
| 178 | 168 |
| 179 // Parsing the body may change the language mode in our scope. | 169 // Parsing the body may change the language mode in our scope. |
| 180 language_mode = function_scope->language_mode(); | 170 language_mode = function_scope->language_mode(); |
| 181 | 171 |
| 182 // Validate name and parameter names. We can do this only after parsing the | 172 // Validate name and parameter names. We can do this only after parsing the |
| 183 // function, since the function can declare itself strict. | 173 // function, since the function can declare itself strict. |
| 184 CheckFunctionName(language_mode, function_name, function_name_validity, | 174 CheckFunctionName(language_mode, function_name, function_name_validity, |
| 185 function_name_location, CHECK_OK); | 175 function_name_location, CHECK_OK); |
| 186 const bool allow_duplicate_parameters = | 176 const bool allow_duplicate_parameters = |
| 187 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); | 177 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); |
| 188 ValidateFormalParameters(language_mode, allow_duplicate_parameters, CHECK_OK); | 178 ValidateFormalParameters(language_mode, allow_duplicate_parameters, CHECK_OK); |
| 189 | 179 |
| 190 if (is_strict(language_mode)) { | 180 if (is_strict(language_mode)) { |
| 191 int end_position = scanner()->location().end_pos; | 181 int end_position = scanner()->location().end_pos; |
| 192 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); | 182 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); |
| 193 CheckDecimalLiteralWithLeadingZero(start_position, end_position); | 183 CheckDecimalLiteralWithLeadingZero(start_position, end_position); |
| 194 } | 184 } |
| 195 | 185 |
| 196 return Expression::Default(); | 186 return Expression::Default(); |
| 197 } | 187 } |
| 198 | 188 |
| 199 PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody( | 189 PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction( |
| 200 bool may_abort, bool* ok) { | 190 bool may_abort, bool* ok) { |
| 201 int body_start = position(); | 191 int body_start = position(); |
| 202 PreParserStatementList body; | 192 PreParserStatementList body; |
| 203 LazyParsingResult result = ParseStatementList( | 193 LazyParsingResult result = ParseStatementList( |
| 204 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); | 194 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); |
| 205 if (result == kLazyParsingAborted) return result; | 195 if (result == kLazyParsingAborted) return result; |
| 206 | 196 |
| 207 // Position right after terminal '}'. | 197 // Position right after terminal '}'. |
| 208 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 198 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
| 209 int body_end = scanner()->peek_location().end_pos; | 199 int body_end = scanner()->peek_location().end_pos; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 } | 246 } |
| 257 } | 247 } |
| 258 } | 248 } |
| 259 | 249 |
| 260 #undef CHECK_OK | 250 #undef CHECK_OK |
| 261 #undef CHECK_OK_CUSTOM | 251 #undef CHECK_OK_CUSTOM |
| 262 | 252 |
| 263 | 253 |
| 264 } // namespace internal | 254 } // namespace internal |
| 265 } // namespace v8 | 255 } // namespace v8 |
| OLD | NEW |