| 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 // The PreParser checks that the syntax follows the grammar for JavaScript, | 115 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| 116 // and collects some information about the program along the way. | 116 // and collects some information about the program along the way. |
| 117 // The grammar check is only performed in order to understand the program | 117 // The grammar check is only performed in order to understand the program |
| 118 // sufficiently to deduce some information about it, that can be used | 118 // sufficiently to deduce some information about it, that can be used |
| 119 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 119 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 120 // rather it is to speed up properly written and correct programs. | 120 // rather it is to speed up properly written and correct programs. |
| 121 // That means that contextual checks (like a label being declared where | 121 // That means that contextual checks (like a label being declared where |
| 122 // it is used) are generally omitted. | 122 // it is used) are generally omitted. |
| 123 | 123 |
| 124 | 124 |
| 125 PreParser::Statement PreParser::ParseStatementListItem(bool* ok) { | |
| 126 // ECMA 262 6th Edition | |
| 127 // StatementListItem[Yield, Return] : | |
| 128 // Statement[?Yield, ?Return] | |
| 129 // Declaration[?Yield] | |
| 130 // | |
| 131 // Declaration[Yield] : | |
| 132 // HoistableDeclaration[?Yield] | |
| 133 // ClassDeclaration[?Yield] | |
| 134 // LexicalDeclaration[In, ?Yield] | |
| 135 // | |
| 136 // HoistableDeclaration[Yield, Default] : | |
| 137 // FunctionDeclaration[?Yield, ?Default] | |
| 138 // GeneratorDeclaration[?Yield, ?Default] | |
| 139 // | |
| 140 // LexicalDeclaration[In, Yield] : | |
| 141 // LetOrConst BindingList[?In, ?Yield] ; | |
| 142 | |
| 143 switch (peek()) { | |
| 144 case Token::FUNCTION: | |
| 145 return ParseHoistableDeclaration(ok); | |
| 146 case Token::CLASS: | |
| 147 return ParseClassDeclaration(ok); | |
| 148 case Token::CONST: | |
| 149 return ParseVariableStatement(kStatementListItem, ok); | |
| 150 case Token::LET: | |
| 151 if (IsNextLetKeyword()) { | |
| 152 return ParseVariableStatement(kStatementListItem, ok); | |
| 153 } | |
| 154 break; | |
| 155 case Token::ASYNC: | |
| 156 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION && | |
| 157 !scanner()->HasAnyLineTerminatorAfterNext()) { | |
| 158 Consume(Token::ASYNC); | |
| 159 return ParseAsyncFunctionDeclaration(ok); | |
| 160 } | |
| 161 /* falls through */ | |
| 162 default: | |
| 163 break; | |
| 164 } | |
| 165 return ParseStatement(kAllowLabelledFunctionStatement, ok); | |
| 166 } | |
| 167 | |
| 168 PreParser::LazyParsingResult PreParser::ParseStatementList(int end_token, | |
| 169 bool may_abort, | |
| 170 bool* ok) { | |
| 171 // SourceElements :: | |
| 172 // (Statement)* <end_token> | |
| 173 | |
| 174 int count_statements = 0; | |
| 175 | |
| 176 bool directive_prologue = true; | |
| 177 while (peek() != end_token) { | |
| 178 if (directive_prologue && peek() != Token::STRING) { | |
| 179 directive_prologue = false; | |
| 180 } | |
| 181 bool starts_with_identifier = peek() == Token::IDENTIFIER; | |
| 182 Scanner::Location token_loc = scanner()->peek_location(); | |
| 183 Statement statement = | |
| 184 ParseStatementListItem(CHECK_OK_VALUE(kLazyParsingComplete)); | |
| 185 | |
| 186 if (directive_prologue) { | |
| 187 bool use_strict_found = statement.IsUseStrictLiteral(); | |
| 188 | |
| 189 if (use_strict_found) { | |
| 190 scope()->SetLanguageMode( | |
| 191 static_cast<LanguageMode>(scope()->language_mode() | STRICT)); | |
| 192 } else if (!statement.IsStringLiteral()) { | |
| 193 directive_prologue = false; | |
| 194 } | |
| 195 | |
| 196 if (use_strict_found && !scope()->HasSimpleParameters()) { | |
| 197 // TC39 deemed "use strict" directives to be an error when occurring | |
| 198 // in the body of a function with non-simple parameter list, on | |
| 199 // 29/7/2015. https://goo.gl/ueA7Ln | |
| 200 ReportMessageAt(token_loc, | |
| 201 MessageTemplate::kIllegalLanguageModeDirective, | |
| 202 "use strict"); | |
| 203 *ok = false; | |
| 204 return kLazyParsingComplete; | |
| 205 } | |
| 206 } | |
| 207 | |
| 208 // If we're allowed to reset to a bookmark, we will do so when we see a long | |
| 209 // and trivial function. | |
| 210 // Our current definition of 'long and trivial' is: | |
| 211 // - over 200 statements | |
| 212 // - all starting with an identifier (i.e., no if, for, while, etc.) | |
| 213 if (may_abort) { | |
| 214 if (!starts_with_identifier) { | |
| 215 may_abort = false; | |
| 216 } else if (++count_statements > kLazyParseTrialLimit) { | |
| 217 return kLazyParsingAborted; | |
| 218 } | |
| 219 } | |
| 220 } | |
| 221 return kLazyParsingComplete; | |
| 222 } | |
| 223 | |
| 224 | |
| 225 PreParser::Statement PreParser::ParseStatement( | |
| 226 AllowLabelledFunctionStatement allow_function, bool* ok) { | |
| 227 // Statement :: | |
| 228 // EmptyStatement | |
| 229 // ... | |
| 230 | |
| 231 if (peek() == Token::SEMICOLON) { | |
| 232 Next(); | |
| 233 return Statement::Default(); | |
| 234 } | |
| 235 return ParseSubStatement(allow_function, ok); | |
| 236 } | |
| 237 | |
| 238 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { | 125 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { |
| 239 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | 126 if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
| 240 (legacy && allow_harmony_restrictive_declarations())) { | 127 (legacy && allow_harmony_restrictive_declarations())) { |
| 241 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); | 128 return ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok); |
| 242 } else { | 129 } else { |
| 243 BlockState block_state(&scope_state_); | 130 BlockState block_state(&scope_state_); |
| 244 return ParseFunctionDeclaration(ok); | 131 return ParseFunctionDeclaration(ok); |
| 245 } | 132 } |
| 246 } | 133 } |
| 247 | 134 |
| 248 PreParser::Statement PreParser::ParseSubStatement( | |
| 249 AllowLabelledFunctionStatement allow_function, bool* ok) { | |
| 250 // Statement :: | |
| 251 // Block | |
| 252 // VariableStatement | |
| 253 // EmptyStatement | |
| 254 // ExpressionStatement | |
| 255 // IfStatement | |
| 256 // IterationStatement | |
| 257 // ContinueStatement | |
| 258 // BreakStatement | |
| 259 // ReturnStatement | |
| 260 // WithStatement | |
| 261 // LabelledStatement | |
| 262 // SwitchStatement | |
| 263 // ThrowStatement | |
| 264 // TryStatement | |
| 265 // DebuggerStatement | |
| 266 | |
| 267 // Note: Since labels can only be used by 'break' and 'continue' | |
| 268 // statements, which themselves are only valid within blocks, | |
| 269 // iterations or 'switch' statements (i.e., BreakableStatements), | |
| 270 // labels can be simply ignored in all other cases; except for | |
| 271 // trivial labeled break statements 'label: break label' which is | |
| 272 // parsed into an empty statement. | |
| 273 | |
| 274 // Keep the source position of the statement | |
| 275 switch (peek()) { | |
| 276 case Token::LBRACE: | |
| 277 return ParseBlock(ok); | |
| 278 | |
| 279 case Token::SEMICOLON: | |
| 280 Next(); | |
| 281 return Statement::Default(); | |
| 282 | |
| 283 case Token::IF: | |
| 284 return ParseIfStatement(ok); | |
| 285 | |
| 286 case Token::DO: | |
| 287 return ParseDoWhileStatement(ok); | |
| 288 | |
| 289 case Token::WHILE: | |
| 290 return ParseWhileStatement(ok); | |
| 291 | |
| 292 case Token::FOR: | |
| 293 return ParseForStatement(ok); | |
| 294 | |
| 295 case Token::CONTINUE: | |
| 296 return ParseContinueStatement(ok); | |
| 297 | |
| 298 case Token::BREAK: | |
| 299 return ParseBreakStatement(ok); | |
| 300 | |
| 301 case Token::RETURN: | |
| 302 return ParseReturnStatement(ok); | |
| 303 | |
| 304 case Token::WITH: | |
| 305 return ParseWithStatement(ok); | |
| 306 | |
| 307 case Token::SWITCH: | |
| 308 return ParseSwitchStatement(ok); | |
| 309 | |
| 310 case Token::THROW: | |
| 311 return ParseThrowStatement(ok); | |
| 312 | |
| 313 case Token::TRY: | |
| 314 return ParseTryStatement(ok); | |
| 315 | |
| 316 case Token::FUNCTION: | |
| 317 // FunctionDeclaration only allowed as a StatementListItem, not in | |
| 318 // an arbitrary Statement position. Exceptions such as | |
| 319 // ES#sec-functiondeclarations-in-ifstatement-statement-clauses | |
| 320 // are handled by calling ParseScopedStatement rather than | |
| 321 // ParseSubStatement directly. | |
| 322 ReportMessageAt(scanner()->peek_location(), | |
| 323 is_strict(language_mode()) | |
| 324 ? MessageTemplate::kStrictFunction | |
| 325 : MessageTemplate::kSloppyFunction); | |
| 326 *ok = false; | |
| 327 return Statement::Default(); | |
| 328 | |
| 329 case Token::DEBUGGER: | |
| 330 return ParseDebuggerStatement(ok); | |
| 331 | |
| 332 case Token::VAR: | |
| 333 return ParseVariableStatement(kStatement, ok); | |
| 334 | |
| 335 default: | |
| 336 return ParseExpressionOrLabelledStatement(allow_function, ok); | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 PreParser::Statement PreParser::ParseHoistableDeclaration( | 135 PreParser::Statement PreParser::ParseHoistableDeclaration( |
| 341 int pos, ParseFunctionFlags flags, bool* ok) { | 136 int pos, ParseFunctionFlags flags, ZoneList<const AstRawString*>* names, |
| 137 bool default_export, bool* ok) { |
| 342 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; | 138 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator; |
| 343 const bool is_async = flags & ParseFunctionFlags::kIsAsync; | 139 const bool is_async = flags & ParseFunctionFlags::kIsAsync; |
| 344 DCHECK(!is_generator || !is_async); | 140 DCHECK(!is_generator || !is_async); |
| 345 | 141 |
| 346 bool is_strict_reserved = false; | 142 bool is_strict_reserved = false; |
| 347 Identifier name = ParseIdentifierOrStrictReservedWord( | 143 Identifier name = ParseIdentifierOrStrictReservedWord( |
| 348 &is_strict_reserved, CHECK_OK); | 144 &is_strict_reserved, CHECK_OK); |
| 349 | 145 |
| 350 ParseFunctionLiteral(name, scanner()->location(), | 146 ParseFunctionLiteral(name, scanner()->location(), |
| 351 is_strict_reserved ? kFunctionNameIsStrictReserved | 147 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 352 : kFunctionNameValidityUnknown, | 148 : kFunctionNameValidityUnknown, |
| 353 is_generator ? FunctionKind::kGeneratorFunction | 149 is_generator ? FunctionKind::kGeneratorFunction |
| 354 : is_async ? FunctionKind::kAsyncFunction | 150 : is_async ? FunctionKind::kAsyncFunction |
| 355 : FunctionKind::kNormalFunction, | 151 : FunctionKind::kNormalFunction, |
| 356 pos, FunctionLiteral::kDeclaration, language_mode(), | 152 pos, FunctionLiteral::kDeclaration, language_mode(), |
| 357 CHECK_OK); | 153 CHECK_OK); |
| 358 return Statement::FunctionDeclaration(); | 154 return Statement::FunctionDeclaration(); |
| 359 } | 155 } |
| 360 | 156 |
| 361 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) { | 157 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration( |
| 158 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { |
| 362 // AsyncFunctionDeclaration :: | 159 // AsyncFunctionDeclaration :: |
| 363 // async [no LineTerminator here] function BindingIdentifier[Await] | 160 // async [no LineTerminator here] function BindingIdentifier[Await] |
| 364 // ( FormalParameters[Await] ) { AsyncFunctionBody } | 161 // ( FormalParameters[Await] ) { AsyncFunctionBody } |
| 365 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); | 162 DCHECK_EQ(scanner()->current_token(), Token::ASYNC); |
| 366 int pos = position(); | 163 int pos = position(); |
| 367 Expect(Token::FUNCTION, CHECK_OK); | 164 Expect(Token::FUNCTION, CHECK_OK); |
| 368 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; | 165 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync; |
| 369 return ParseHoistableDeclaration(pos, flags, ok); | 166 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); |
| 370 } | 167 } |
| 371 | 168 |
| 372 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) { | 169 PreParser::Statement PreParser::ParseHoistableDeclaration( |
| 170 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { |
| 373 // FunctionDeclaration :: | 171 // FunctionDeclaration :: |
| 374 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 172 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 375 // GeneratorDeclaration :: | 173 // GeneratorDeclaration :: |
| 376 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 174 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 377 // '{' FunctionBody '}' | 175 // '{' FunctionBody '}' |
| 378 | 176 |
| 379 Expect(Token::FUNCTION, CHECK_OK); | 177 Expect(Token::FUNCTION, CHECK_OK); |
| 380 int pos = position(); | 178 int pos = position(); |
| 381 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; | 179 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 382 if (Check(Token::MUL)) { | 180 if (Check(Token::MUL)) { |
| 383 flags |= ParseFunctionFlags::kIsGenerator; | 181 flags |= ParseFunctionFlags::kIsGenerator; |
| 384 } | 182 } |
| 385 return ParseHoistableDeclaration(pos, flags, ok); | 183 return ParseHoistableDeclaration(pos, flags, names, default_export, ok); |
| 386 } | 184 } |
| 387 | 185 |
| 388 | 186 PreParser::Statement PreParser::ParseClassDeclaration( |
| 389 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { | 187 ZoneList<const AstRawString*>* names, bool default_export, bool* ok) { |
| 390 Expect(Token::CLASS, CHECK_OK); | |
| 391 | |
| 392 int pos = position(); | 188 int pos = position(); |
| 393 bool is_strict_reserved = false; | 189 bool is_strict_reserved = false; |
| 394 Identifier name = | 190 Identifier name = |
| 395 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 191 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 396 ExpressionClassifier no_classifier(this); | 192 ExpressionClassifier no_classifier(this); |
| 397 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, | 193 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, |
| 398 CHECK_OK); | 194 CHECK_OK); |
| 399 return Statement::Default(); | 195 return Statement::Default(); |
| 400 } | 196 } |
| 401 | 197 |
| 402 | 198 PreParser::Statement PreParser::ParseBlock( |
| 403 PreParser::Statement PreParser::ParseBlock(bool* ok) { | 199 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 404 // Block :: | 200 // Block :: |
| 405 // '{' StatementList '}' | 201 // '{' StatementList '}' |
| 406 | 202 |
| 407 Expect(Token::LBRACE, CHECK_OK); | 203 Expect(Token::LBRACE, CHECK_OK); |
| 408 Statement final = Statement::Default(); | 204 Statement final = Statement::Default(); |
| 409 { | 205 { |
| 410 BlockState block_state(&scope_state_); | 206 BlockState block_state(&scope_state_); |
| 411 while (peek() != Token::RBRACE) { | 207 while (peek() != Token::RBRACE) { |
| 412 final = ParseStatementListItem(CHECK_OK); | 208 final = ParseStatementListItem(CHECK_OK); |
| 413 } | 209 } |
| 414 } | 210 } |
| 415 Expect(Token::RBRACE, ok); | 211 Expect(Token::RBRACE, ok); |
| 416 return final; | 212 return final; |
| 417 } | 213 } |
| 418 | 214 |
| 419 | |
| 420 PreParser::Statement PreParser::ParseVariableStatement( | 215 PreParser::Statement PreParser::ParseVariableStatement( |
| 421 VariableDeclarationContext var_context, | 216 VariableDeclarationContext var_context, |
| 422 bool* ok) { | 217 ZoneList<const AstRawString*>* names, bool* ok) { |
| 423 // VariableStatement :: | 218 // VariableStatement :: |
| 424 // VariableDeclarations ';' | 219 // VariableDeclarations ';' |
| 425 | 220 |
| 426 Statement result = | 221 Statement result = |
| 427 ParseVariableDeclarations(var_context, nullptr, nullptr, CHECK_OK); | 222 ParseVariableDeclarations(var_context, nullptr, names, CHECK_OK); |
| 428 ExpectSemicolon(CHECK_OK); | 223 ExpectSemicolon(CHECK_OK); |
| 429 return result; | 224 return result; |
| 430 } | 225 } |
| 431 | 226 |
| 432 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 227 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
| 433 Consume(Token::FUNCTION); | 228 Consume(Token::FUNCTION); |
| 434 int pos = position(); | 229 int pos = position(); |
| 435 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; | 230 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal; |
| 436 if (Check(Token::MUL)) { | 231 if (Check(Token::MUL)) { |
| 437 flags |= ParseFunctionFlags::kIsGenerator; | 232 flags |= ParseFunctionFlags::kIsGenerator; |
| 438 if (allow_harmony_restrictive_declarations()) { | 233 if (allow_harmony_restrictive_declarations()) { |
| 439 ReportMessageAt(scanner()->location(), | 234 ReportMessageAt(scanner()->location(), |
| 440 MessageTemplate::kGeneratorInLegacyContext); | 235 MessageTemplate::kGeneratorInLegacyContext); |
| 441 *ok = false; | 236 *ok = false; |
| 442 return Statement::Default(); | 237 return Statement::Default(); |
| 443 } | 238 } |
| 444 } | 239 } |
| 445 return ParseHoistableDeclaration(pos, flags, ok); | 240 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok); |
| 446 } | 241 } |
| 447 | 242 |
| 448 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( | 243 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( |
| 244 ZoneList<const AstRawString*>* names, |
| 449 AllowLabelledFunctionStatement allow_function, bool* ok) { | 245 AllowLabelledFunctionStatement allow_function, bool* ok) { |
| 450 // ExpressionStatement | LabelledStatement :: | 246 // ExpressionStatement | LabelledStatement :: |
| 451 // Expression ';' | 247 // Expression ';' |
| 452 // Identifier ':' Statement | 248 // Identifier ':' Statement |
| 453 | 249 |
| 454 switch (peek()) { | 250 switch (peek()) { |
| 455 case Token::FUNCTION: | 251 case Token::FUNCTION: |
| 456 case Token::LBRACE: | 252 case Token::LBRACE: |
| 457 UNREACHABLE(); // Always handled by the callers. | 253 UNREACHABLE(); // Always handled by the callers. |
| 458 case Token::CLASS: | 254 case Token::CLASS: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 482 Consume(Token::COLON); | 278 Consume(Token::COLON); |
| 483 // ES#sec-labelled-function-declarations Labelled Function Declarations | 279 // ES#sec-labelled-function-declarations Labelled Function Declarations |
| 484 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { | 280 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { |
| 485 if (allow_function == kAllowLabelledFunctionStatement) { | 281 if (allow_function == kAllowLabelledFunctionStatement) { |
| 486 return ParseFunctionDeclaration(ok); | 282 return ParseFunctionDeclaration(ok); |
| 487 } else { | 283 } else { |
| 488 return ParseScopedStatement(true, ok); | 284 return ParseScopedStatement(true, ok); |
| 489 } | 285 } |
| 490 } | 286 } |
| 491 Statement statement = | 287 Statement statement = |
| 492 ParseStatement(kDisallowLabelledFunctionStatement, ok); | 288 ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok); |
| 493 return statement.IsJumpStatement() ? Statement::Default() : statement; | 289 return statement.IsJumpStatement() ? Statement::Default() : statement; |
| 494 // Preparsing is disabled for extensions (because the extension details | 290 // Preparsing is disabled for extensions (because the extension details |
| 495 // aren't passed to lazily compiled functions), so we don't | 291 // aren't passed to lazily compiled functions), so we don't |
| 496 // accept "native function" in the preparser. | 292 // accept "native function" in the preparser. |
| 497 } | 293 } |
| 498 // Parsed expression statement. | 294 // Parsed expression statement. |
| 499 ExpectSemicolon(CHECK_OK); | 295 ExpectSemicolon(CHECK_OK); |
| 500 return Statement::ExpressionStatement(expr); | 296 return Statement::ExpressionStatement(expr); |
| 501 } | 297 } |
| 502 | 298 |
| 503 | 299 PreParser::Statement PreParser::ParseIfStatement( |
| 504 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { | 300 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 505 // IfStatement :: | 301 // IfStatement :: |
| 506 // 'if' '(' Expression ')' Statement ('else' Statement)? | 302 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 507 | 303 |
| 508 Expect(Token::IF, CHECK_OK); | 304 Expect(Token::IF, CHECK_OK); |
| 509 Expect(Token::LPAREN, CHECK_OK); | 305 Expect(Token::LPAREN, CHECK_OK); |
| 510 ParseExpression(true, CHECK_OK); | 306 ParseExpression(true, CHECK_OK); |
| 511 Expect(Token::RPAREN, CHECK_OK); | 307 Expect(Token::RPAREN, CHECK_OK); |
| 512 Statement stat = ParseScopedStatement(false, CHECK_OK); | 308 Statement stat = ParseScopedStatement(false, CHECK_OK); |
| 513 if (peek() == Token::ELSE) { | 309 if (peek() == Token::ELSE) { |
| 514 Next(); | 310 Next(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 532 tok != Token::SEMICOLON && | 328 tok != Token::SEMICOLON && |
| 533 tok != Token::RBRACE && | 329 tok != Token::RBRACE && |
| 534 tok != Token::EOS) { | 330 tok != Token::EOS) { |
| 535 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 331 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 536 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 332 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
| 537 } | 333 } |
| 538 ExpectSemicolon(CHECK_OK); | 334 ExpectSemicolon(CHECK_OK); |
| 539 return Statement::Jump(); | 335 return Statement::Jump(); |
| 540 } | 336 } |
| 541 | 337 |
| 542 | 338 PreParser::Statement PreParser::ParseBreakStatement( |
| 543 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 339 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 544 // BreakStatement :: | 340 // BreakStatement :: |
| 545 // 'break' [no line terminator] Identifier? ';' | 341 // 'break' [no line terminator] Identifier? ';' |
| 546 | 342 |
| 547 Expect(Token::BREAK, CHECK_OK); | 343 Expect(Token::BREAK, CHECK_OK); |
| 548 Token::Value tok = peek(); | 344 Token::Value tok = peek(); |
| 549 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 345 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 550 tok != Token::SEMICOLON && | 346 tok != Token::SEMICOLON && |
| 551 tok != Token::RBRACE && | 347 tok != Token::RBRACE && |
| 552 tok != Token::EOS) { | 348 tok != Token::EOS) { |
| 553 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 349 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 : ReturnExprContext::kInsideValidReturnStatement; | 382 : ReturnExprContext::kInsideValidReturnStatement; |
| 587 | 383 |
| 588 ReturnExprScope maybe_allow_tail_calls(function_state_, | 384 ReturnExprScope maybe_allow_tail_calls(function_state_, |
| 589 return_expr_context); | 385 return_expr_context); |
| 590 ParseExpression(true, CHECK_OK); | 386 ParseExpression(true, CHECK_OK); |
| 591 } | 387 } |
| 592 ExpectSemicolon(CHECK_OK); | 388 ExpectSemicolon(CHECK_OK); |
| 593 return Statement::Jump(); | 389 return Statement::Jump(); |
| 594 } | 390 } |
| 595 | 391 |
| 596 | 392 PreParser::Statement PreParser::ParseWithStatement( |
| 597 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 393 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 598 // WithStatement :: | 394 // WithStatement :: |
| 599 // 'with' '(' Expression ')' Statement | 395 // 'with' '(' Expression ')' Statement |
| 600 Expect(Token::WITH, CHECK_OK); | 396 Expect(Token::WITH, CHECK_OK); |
| 601 if (is_strict(language_mode())) { | 397 if (is_strict(language_mode())) { |
| 602 ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith); | 398 ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith); |
| 603 *ok = false; | 399 *ok = false; |
| 604 return Statement::Default(); | 400 return Statement::Default(); |
| 605 } | 401 } |
| 606 Expect(Token::LPAREN, CHECK_OK); | 402 Expect(Token::LPAREN, CHECK_OK); |
| 607 ParseExpression(true, CHECK_OK); | 403 ParseExpression(true, CHECK_OK); |
| 608 Expect(Token::RPAREN, CHECK_OK); | 404 Expect(Token::RPAREN, CHECK_OK); |
| 609 | 405 |
| 610 Scope* with_scope = NewScope(WITH_SCOPE); | 406 Scope* with_scope = NewScope(WITH_SCOPE); |
| 611 BlockState block_state(&scope_state_, with_scope); | 407 BlockState block_state(&scope_state_, with_scope); |
| 612 ParseScopedStatement(true, CHECK_OK); | 408 ParseScopedStatement(true, CHECK_OK); |
| 613 return Statement::Default(); | 409 return Statement::Default(); |
| 614 } | 410 } |
| 615 | 411 |
| 616 | 412 PreParser::Statement PreParser::ParseSwitchStatement( |
| 617 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { | 413 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 618 // SwitchStatement :: | 414 // SwitchStatement :: |
| 619 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 415 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 620 | 416 |
| 621 Expect(Token::SWITCH, CHECK_OK); | 417 Expect(Token::SWITCH, CHECK_OK); |
| 622 Expect(Token::LPAREN, CHECK_OK); | 418 Expect(Token::LPAREN, CHECK_OK); |
| 623 ParseExpression(true, CHECK_OK); | 419 ParseExpression(true, CHECK_OK); |
| 624 Expect(Token::RPAREN, CHECK_OK); | 420 Expect(Token::RPAREN, CHECK_OK); |
| 625 | 421 |
| 626 { | 422 { |
| 627 BlockState cases_block_state(&scope_state_); | 423 BlockState cases_block_state(&scope_state_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 642 token != Token::RBRACE) { | 438 token != Token::RBRACE) { |
| 643 statement = ParseStatementListItem(CHECK_OK); | 439 statement = ParseStatementListItem(CHECK_OK); |
| 644 token = peek(); | 440 token = peek(); |
| 645 } | 441 } |
| 646 } | 442 } |
| 647 } | 443 } |
| 648 Expect(Token::RBRACE, ok); | 444 Expect(Token::RBRACE, ok); |
| 649 return Statement::Default(); | 445 return Statement::Default(); |
| 650 } | 446 } |
| 651 | 447 |
| 652 | 448 PreParser::Statement PreParser::ParseDoWhileStatement( |
| 653 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { | 449 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 654 // DoStatement :: | 450 // DoStatement :: |
| 655 // 'do' Statement 'while' '(' Expression ')' ';' | 451 // 'do' Statement 'while' '(' Expression ')' ';' |
| 656 | 452 |
| 657 Expect(Token::DO, CHECK_OK); | 453 Expect(Token::DO, CHECK_OK); |
| 658 ParseScopedStatement(true, CHECK_OK); | 454 ParseScopedStatement(true, CHECK_OK); |
| 659 Expect(Token::WHILE, CHECK_OK); | 455 Expect(Token::WHILE, CHECK_OK); |
| 660 Expect(Token::LPAREN, CHECK_OK); | 456 Expect(Token::LPAREN, CHECK_OK); |
| 661 ParseExpression(true, CHECK_OK); | 457 ParseExpression(true, CHECK_OK); |
| 662 Expect(Token::RPAREN, ok); | 458 Expect(Token::RPAREN, ok); |
| 663 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 459 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 664 return Statement::Default(); | 460 return Statement::Default(); |
| 665 } | 461 } |
| 666 | 462 |
| 667 | 463 PreParser::Statement PreParser::ParseWhileStatement( |
| 668 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { | 464 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 669 // WhileStatement :: | 465 // WhileStatement :: |
| 670 // 'while' '(' Expression ')' Statement | 466 // 'while' '(' Expression ')' Statement |
| 671 | 467 |
| 672 Expect(Token::WHILE, CHECK_OK); | 468 Expect(Token::WHILE, CHECK_OK); |
| 673 Expect(Token::LPAREN, CHECK_OK); | 469 Expect(Token::LPAREN, CHECK_OK); |
| 674 ParseExpression(true, CHECK_OK); | 470 ParseExpression(true, CHECK_OK); |
| 675 Expect(Token::RPAREN, CHECK_OK); | 471 Expect(Token::RPAREN, CHECK_OK); |
| 676 ParseScopedStatement(true, ok); | 472 ParseScopedStatement(true, ok); |
| 677 return Statement::Default(); | 473 return Statement::Default(); |
| 678 } | 474 } |
| 679 | 475 |
| 680 | 476 PreParser::Statement PreParser::ParseForStatement( |
| 681 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 477 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 682 // ForStatement :: | 478 // ForStatement :: |
| 683 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 479 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 684 | 480 |
| 685 // Create an in-between scope for let-bound iteration variables. | 481 // Create an in-between scope for let-bound iteration variables. |
| 686 bool has_lexical = false; | 482 bool has_lexical = false; |
| 687 | 483 |
| 688 BlockState block_state(&scope_state_); | 484 BlockState block_state(&scope_state_); |
| 689 Expect(Token::FOR, CHECK_OK); | 485 Expect(Token::FOR, CHECK_OK); |
| 690 Expect(Token::LPAREN, CHECK_OK); | 486 Expect(Token::LPAREN, CHECK_OK); |
| 691 if (peek() != Token::SEMICOLON) { | 487 if (peek() != Token::SEMICOLON) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 // 'catch' '(' Identifier ')' Block | 633 // 'catch' '(' Identifier ')' Block |
| 838 // | 634 // |
| 839 // Finally :: | 635 // Finally :: |
| 840 // 'finally' Block | 636 // 'finally' Block |
| 841 | 637 |
| 842 Expect(Token::TRY, CHECK_OK); | 638 Expect(Token::TRY, CHECK_OK); |
| 843 | 639 |
| 844 { | 640 { |
| 845 ReturnExprScope no_tail_calls(function_state_, | 641 ReturnExprScope no_tail_calls(function_state_, |
| 846 ReturnExprContext::kInsideTryBlock); | 642 ReturnExprContext::kInsideTryBlock); |
| 847 ParseBlock(CHECK_OK); | 643 ParseBlock(nullptr, CHECK_OK); |
| 848 } | 644 } |
| 849 | 645 |
| 850 Token::Value tok = peek(); | 646 Token::Value tok = peek(); |
| 851 if (tok != Token::CATCH && tok != Token::FINALLY) { | 647 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| 852 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); | 648 ReportMessageAt(scanner()->location(), MessageTemplate::kNoCatchOrFinally); |
| 853 *ok = false; | 649 *ok = false; |
| 854 return Statement::Default(); | 650 return Statement::Default(); |
| 855 } | 651 } |
| 856 TailCallExpressionList tail_call_expressions_in_catch_block(zone()); | 652 TailCallExpressionList tail_call_expressions_in_catch_block(zone()); |
| 857 bool catch_block_exists = false; | 653 bool catch_block_exists = false; |
| 858 if (tok == Token::CATCH) { | 654 if (tok == Token::CATCH) { |
| 859 Consume(Token::CATCH); | 655 Consume(Token::CATCH); |
| 860 Expect(Token::LPAREN, CHECK_OK); | 656 Expect(Token::LPAREN, CHECK_OK); |
| 861 Scope* catch_scope = NewScope(CATCH_SCOPE); | 657 Scope* catch_scope = NewScope(CATCH_SCOPE); |
| 862 ExpressionClassifier pattern_classifier(this); | 658 ExpressionClassifier pattern_classifier(this); |
| 863 ParsePrimaryExpression(CHECK_OK); | 659 ParsePrimaryExpression(CHECK_OK); |
| 864 ValidateBindingPattern(CHECK_OK); | 660 ValidateBindingPattern(CHECK_OK); |
| 865 Expect(Token::RPAREN, CHECK_OK); | 661 Expect(Token::RPAREN, CHECK_OK); |
| 866 { | 662 { |
| 867 CollectExpressionsInTailPositionToListScope | 663 CollectExpressionsInTailPositionToListScope |
| 868 collect_tail_call_expressions_scope( | 664 collect_tail_call_expressions_scope( |
| 869 function_state_, &tail_call_expressions_in_catch_block); | 665 function_state_, &tail_call_expressions_in_catch_block); |
| 870 BlockState block_state(&scope_state_, catch_scope); | 666 BlockState block_state(&scope_state_, catch_scope); |
| 871 { | 667 { |
| 872 BlockState block_state(&scope_state_); | 668 BlockState block_state(&scope_state_); |
| 873 ParseBlock(CHECK_OK); | 669 ParseBlock(nullptr, CHECK_OK); |
| 874 } | 670 } |
| 875 } | 671 } |
| 876 catch_block_exists = true; | 672 catch_block_exists = true; |
| 877 tok = peek(); | 673 tok = peek(); |
| 878 } | 674 } |
| 879 if (tok == Token::FINALLY) { | 675 if (tok == Token::FINALLY) { |
| 880 Consume(Token::FINALLY); | 676 Consume(Token::FINALLY); |
| 881 ParseBlock(CHECK_OK); | 677 ParseBlock(nullptr, CHECK_OK); |
| 882 if (FLAG_harmony_explicit_tailcalls && catch_block_exists && | 678 if (FLAG_harmony_explicit_tailcalls && catch_block_exists && |
| 883 tail_call_expressions_in_catch_block.has_explicit_tail_calls()) { | 679 tail_call_expressions_in_catch_block.has_explicit_tail_calls()) { |
| 884 // TODO(ishell): update chapter number. | 680 // TODO(ishell): update chapter number. |
| 885 // ES8 XX.YY.ZZ | 681 // ES8 XX.YY.ZZ |
| 886 ReportMessageAt(tail_call_expressions_in_catch_block.location(), | 682 ReportMessageAt(tail_call_expressions_in_catch_block.location(), |
| 887 MessageTemplate::kUnexpectedTailCallInCatchBlock); | 683 MessageTemplate::kUnexpectedTailCallInCatchBlock); |
| 888 *ok = false; | 684 *ok = false; |
| 889 return Statement::Default(); | 685 return Statement::Default(); |
| 890 } | 686 } |
| 891 } | 687 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 912 | 708 |
| 913 PreParser::Expression PreParser::ParseFunctionLiteral( | 709 PreParser::Expression PreParser::ParseFunctionLiteral( |
| 914 Identifier function_name, Scanner::Location function_name_location, | 710 Identifier function_name, Scanner::Location function_name_location, |
| 915 FunctionNameValidity function_name_validity, FunctionKind kind, | 711 FunctionNameValidity function_name_validity, FunctionKind kind, |
| 916 int function_token_pos, FunctionLiteral::FunctionType function_type, | 712 int function_token_pos, FunctionLiteral::FunctionType function_type, |
| 917 LanguageMode language_mode, bool* ok) { | 713 LanguageMode language_mode, bool* ok) { |
| 918 // Function :: | 714 // Function :: |
| 919 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 715 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 920 | 716 |
| 921 // Parse function body. | 717 // Parse function body. |
| 718 PreParserStatementList body; |
| 922 bool outer_is_script_scope = scope()->is_script_scope(); | 719 bool outer_is_script_scope = scope()->is_script_scope(); |
| 923 DeclarationScope* function_scope = NewFunctionScope(kind); | 720 DeclarationScope* function_scope = NewFunctionScope(kind); |
| 924 function_scope->SetLanguageMode(language_mode); | 721 function_scope->SetLanguageMode(language_mode); |
| 925 FunctionState function_state(&function_state_, &scope_state_, function_scope, | 722 FunctionState function_state(&function_state_, &scope_state_, function_scope, |
| 926 kind); | 723 kind); |
| 927 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 724 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 928 ExpressionClassifier formals_classifier(this, &duplicate_finder); | 725 ExpressionClassifier formals_classifier(this, &duplicate_finder); |
| 929 | 726 |
| 930 Expect(Token::LPAREN, CHECK_OK); | 727 Expect(Token::LPAREN, CHECK_OK); |
| 931 int start_position = scanner()->location().beg_pos; | 728 int start_position = scanner()->location().beg_pos; |
| 932 function_scope->set_start_position(start_position); | 729 function_scope->set_start_position(start_position); |
| 933 PreParserFormalParameters formals(function_scope); | 730 PreParserFormalParameters formals(function_scope); |
| 934 ParseFormalParameterList(&formals, CHECK_OK); | 731 ParseFormalParameterList(&formals, CHECK_OK); |
| 935 Expect(Token::RPAREN, CHECK_OK); | 732 Expect(Token::RPAREN, CHECK_OK); |
| 936 int formals_end_position = scanner()->location().end_pos; | 733 int formals_end_position = scanner()->location().end_pos; |
| 937 | 734 |
| 938 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, | 735 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, |
| 939 formals_end_position, CHECK_OK); | 736 formals_end_position, CHECK_OK); |
| 940 | 737 |
| 941 // See Parser::ParseFunctionLiteral for more information about lazy parsing | 738 // See Parser::ParseFunctionLiteral for more information about lazy parsing |
| 942 // and lazy compilation. | 739 // and lazy compilation. |
| 943 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() && | 740 bool is_lazily_parsed = (outer_is_script_scope && allow_lazy() && |
| 944 !function_state_->this_function_is_parenthesized()); | 741 !function_state_->this_function_is_parenthesized()); |
| 945 | 742 |
| 946 Expect(Token::LBRACE, CHECK_OK); | 743 Expect(Token::LBRACE, CHECK_OK); |
| 947 if (is_lazily_parsed) { | 744 if (is_lazily_parsed) { |
| 948 ParseLazyFunctionLiteralBody(false, CHECK_OK); | 745 ParseLazyFunctionLiteralBody(false, CHECK_OK); |
| 949 } else { | 746 } else { |
| 950 ParseStatementList(Token::RBRACE, CHECK_OK); | 747 ParseStatementList(body, Token::RBRACE, CHECK_OK); |
| 951 } | 748 } |
| 952 Expect(Token::RBRACE, CHECK_OK); | 749 Expect(Token::RBRACE, CHECK_OK); |
| 953 | 750 |
| 954 // Parsing the body may change the language mode in our scope. | 751 // Parsing the body may change the language mode in our scope. |
| 955 language_mode = function_scope->language_mode(); | 752 language_mode = function_scope->language_mode(); |
| 956 | 753 |
| 957 // Validate name and parameter names. We can do this only after parsing the | 754 // Validate name and parameter names. We can do this only after parsing the |
| 958 // function, since the function can declare itself strict. | 755 // function, since the function can declare itself strict. |
| 959 CheckFunctionName(language_mode, function_name, function_name_validity, | 756 CheckFunctionName(language_mode, function_name, function_name_validity, |
| 960 function_name_location, CHECK_OK); | 757 function_name_location, CHECK_OK); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 is_strict_reserved ? kFunctionNameIsStrictReserved | 792 is_strict_reserved ? kFunctionNameIsStrictReserved |
| 996 : kFunctionNameValidityUnknown, | 793 : kFunctionNameValidityUnknown, |
| 997 FunctionKind::kAsyncFunction, pos, type, language_mode(), | 794 FunctionKind::kAsyncFunction, pos, type, language_mode(), |
| 998 CHECK_OK); | 795 CHECK_OK); |
| 999 return Expression::Default(); | 796 return Expression::Default(); |
| 1000 } | 797 } |
| 1001 | 798 |
| 1002 PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody( | 799 PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody( |
| 1003 bool may_abort, bool* ok) { | 800 bool may_abort, bool* ok) { |
| 1004 int body_start = position(); | 801 int body_start = position(); |
| 802 PreParserStatementList body; |
| 1005 LazyParsingResult result = ParseStatementList( | 803 LazyParsingResult result = ParseStatementList( |
| 1006 Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); | 804 body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete)); |
| 1007 if (result == kLazyParsingAborted) return result; | 805 if (result == kLazyParsingAborted) return result; |
| 1008 | 806 |
| 1009 // Position right after terminal '}'. | 807 // Position right after terminal '}'. |
| 1010 DCHECK_EQ(Token::RBRACE, scanner()->peek()); | 808 DCHECK_EQ(Token::RBRACE, scanner()->peek()); |
| 1011 int body_end = scanner()->peek_location().end_pos; | 809 int body_end = scanner()->peek_location().end_pos; |
| 1012 DeclarationScope* scope = this->scope()->AsDeclarationScope(); | 810 DeclarationScope* scope = this->scope()->AsDeclarationScope(); |
| 1013 DCHECK(scope->is_function_scope()); | 811 DCHECK(scope->is_function_scope()); |
| 1014 log_->LogFunction(body_start, body_end, | 812 log_->LogFunction(body_start, body_end, |
| 1015 function_state_->materialized_literal_count(), | 813 function_state_->materialized_literal_count(), |
| 1016 function_state_->expected_property_count(), language_mode(), | 814 function_state_->expected_property_count(), language_mode(), |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 | 914 |
| 1117 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); | 915 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); |
| 1118 } | 916 } |
| 1119 | 917 |
| 1120 #undef CHECK_OK | 918 #undef CHECK_OK |
| 1121 #undef CHECK_OK_CUSTOM | 919 #undef CHECK_OK_CUSTOM |
| 1122 | 920 |
| 1123 | 921 |
| 1124 } // namespace internal | 922 } // namespace internal |
| 1125 } // namespace v8 | 923 } // namespace v8 |
| OLD | NEW |