| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 // and collects some information about the program along the way. | 49 // and collects some information about the program along the way. |
| 50 // The grammar check is only performed in order to understand the program | 50 // The grammar check is only performed in order to understand the program |
| 51 // sufficiently to deduce some information about it, that can be used | 51 // sufficiently to deduce some information about it, that can be used |
| 52 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 52 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 53 // rather it is to speed up properly written and correct programs. | 53 // rather it is to speed up properly written and correct programs. |
| 54 // That means that contextual checks (like a label being declared where | 54 // That means that contextual checks (like a label being declared where |
| 55 // it is used) are generally omitted. | 55 // it is used) are generally omitted. |
| 56 | 56 |
| 57 namespace i = ::v8::internal; | 57 namespace i = ::v8::internal; |
| 58 | 58 |
| 59 #define CHECK_OK ok); \ | |
| 60 if (!*ok) return -1; \ | |
| 61 ((void)0 | |
| 62 #define DUMMY ) // to make indentation work | |
| 63 #undef DUMMY | |
| 64 | |
| 65 | |
| 66 void PreParser::ReportUnexpectedToken(i::Token::Value token) { | 59 void PreParser::ReportUnexpectedToken(i::Token::Value token) { |
| 67 // We don't report stack overflows here, to avoid increasing the | 60 // We don't report stack overflows here, to avoid increasing the |
| 68 // stack depth even further. Instead we report it after parsing is | 61 // stack depth even further. Instead we report it after parsing is |
| 69 // over, in ParseProgram. | 62 // over, in ParseProgram. |
| 70 if (token == i::Token::ILLEGAL && stack_overflow_) { | 63 if (token == i::Token::ILLEGAL && stack_overflow_) { |
| 71 return; | 64 return; |
| 72 } | 65 } |
| 73 i::JavaScriptScanner::Location source_location = scanner_->location(); | 66 i::JavaScriptScanner::Location source_location = scanner_->location(); |
| 74 | 67 |
| 75 // Four of the tokens are treated specially | 68 // Four of the tokens are treated specially |
| (...skipping 24 matching lines...) Expand all Loading... |
| 100 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 93 void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 101 i::Scanner::Location octal = scanner_->octal_position(); | 94 i::Scanner::Location octal = scanner_->octal_position(); |
| 102 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | 95 if (beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| 103 ReportMessageAt(octal.beg_pos, octal.end_pos, "strict_octal_literal", NULL); | 96 ReportMessageAt(octal.beg_pos, octal.end_pos, "strict_octal_literal", NULL); |
| 104 scanner_->clear_octal_position(); | 97 scanner_->clear_octal_position(); |
| 105 *ok = false; | 98 *ok = false; |
| 106 } | 99 } |
| 107 } | 100 } |
| 108 | 101 |
| 109 | 102 |
| 103 #define CHECK_OK ok); \ |
| 104 if (!*ok) return kUnknownSourceElements; \ |
| 105 ((void)0 |
| 106 #define DUMMY ) // to make indentation work |
| 107 #undef DUMMY |
| 108 |
| 109 |
| 110 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, | 110 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
| 111 bool* ok) { | 111 bool* ok) { |
| 112 // SourceElements :: | 112 // SourceElements :: |
| 113 // (Statement)* <end_token> | 113 // (Statement)* <end_token> |
| 114 | 114 |
| 115 bool allow_directive_prologue = true; | 115 bool allow_directive_prologue = true; |
| 116 while (peek() != end_token) { | 116 while (peek() != end_token) { |
| 117 Statement statement = ParseStatement(CHECK_OK); | 117 Statement statement = ParseStatement(CHECK_OK); |
| 118 if (allow_directive_prologue) { | 118 if (allow_directive_prologue) { |
| 119 if (statement == kUseStrictExpressionStatement) { | 119 if (statement.IsUseStrictLiteral()) { |
| 120 set_strict_mode(); | 120 set_strict_mode(); |
| 121 } else if (statement != kStringLiteralExpressionStatement) { | 121 } else if (!statement.IsStringLiteral()) { |
| 122 allow_directive_prologue = false; | 122 allow_directive_prologue = false; |
| 123 } | 123 } |
| 124 } | 124 } |
| 125 } | 125 } |
| 126 return kUnknownSourceElements; | 126 return kUnknownSourceElements; |
| 127 } | 127 } |
| 128 | 128 |
| 129 | 129 |
| 130 #undef CHECK_OK |
| 131 #define CHECK_OK ok); \ |
| 132 if (!*ok) return Statement::Default(); \ |
| 133 ((void)0 |
| 134 #define DUMMY ) // to make indentation work |
| 135 #undef DUMMY |
| 136 |
| 137 |
| 130 PreParser::Statement PreParser::ParseStatement(bool* ok) { | 138 PreParser::Statement PreParser::ParseStatement(bool* ok) { |
| 131 // Statement :: | 139 // Statement :: |
| 132 // Block | 140 // Block |
| 133 // VariableStatement | 141 // VariableStatement |
| 134 // EmptyStatement | 142 // EmptyStatement |
| 135 // ExpressionStatement | 143 // ExpressionStatement |
| 136 // IfStatement | 144 // IfStatement |
| 137 // IterationStatement | 145 // IterationStatement |
| 138 // ContinueStatement | 146 // ContinueStatement |
| 139 // BreakStatement | 147 // BreakStatement |
| (...skipping 16 matching lines...) Expand all Loading... |
| 156 switch (peek()) { | 164 switch (peek()) { |
| 157 case i::Token::LBRACE: | 165 case i::Token::LBRACE: |
| 158 return ParseBlock(ok); | 166 return ParseBlock(ok); |
| 159 | 167 |
| 160 case i::Token::CONST: | 168 case i::Token::CONST: |
| 161 case i::Token::VAR: | 169 case i::Token::VAR: |
| 162 return ParseVariableStatement(ok); | 170 return ParseVariableStatement(ok); |
| 163 | 171 |
| 164 case i::Token::SEMICOLON: | 172 case i::Token::SEMICOLON: |
| 165 Next(); | 173 Next(); |
| 166 return kUnknownStatement; | 174 return Statement::Default(); |
| 167 | 175 |
| 168 case i::Token::IF: | 176 case i::Token::IF: |
| 169 return ParseIfStatement(ok); | 177 return ParseIfStatement(ok); |
| 170 | 178 |
| 171 case i::Token::DO: | 179 case i::Token::DO: |
| 172 return ParseDoWhileStatement(ok); | 180 return ParseDoWhileStatement(ok); |
| 173 | 181 |
| 174 case i::Token::WHILE: | 182 case i::Token::WHILE: |
| 175 return ParseWhileStatement(ok); | 183 return ParseWhileStatement(ok); |
| 176 | 184 |
| 177 case i::Token::FOR: | 185 case i::Token::FOR: |
| 178 return ParseForStatement(ok); | 186 return ParseForStatement(ok); |
| 179 | 187 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 210 default: | 218 default: |
| 211 return ParseExpressionOrLabelledStatement(ok); | 219 return ParseExpressionOrLabelledStatement(ok); |
| 212 } | 220 } |
| 213 } | 221 } |
| 214 | 222 |
| 215 | 223 |
| 216 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 224 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
| 217 // FunctionDeclaration :: | 225 // FunctionDeclaration :: |
| 218 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 226 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 219 Expect(i::Token::FUNCTION, CHECK_OK); | 227 Expect(i::Token::FUNCTION, CHECK_OK); |
| 220 ParseIdentifier(CHECK_OK); | 228 |
| 221 ParseFunctionLiteral(CHECK_OK); | 229 Identifier identifier = ParseIdentifier(CHECK_OK); |
| 222 return kUnknownStatement; | 230 i::Scanner::Location location = scanner_->location(); |
| 231 |
| 232 Expression function_value = ParseFunctionLiteral(CHECK_OK); |
| 233 |
| 234 if (function_value.IsStrictFunction() && |
| 235 !identifier.IsValidStrictVariable()) { |
| 236 // Strict mode violation, using either reserved word or eval/arguments |
| 237 // as name of strict function. |
| 238 const char* type = "strict_function_name"; |
| 239 if (identifier.IsFutureReserved()) { |
| 240 type = "strict_reserved_word"; |
| 241 } |
| 242 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); |
| 243 *ok = false; |
| 244 } |
| 245 return Statement::Default(); |
| 223 } | 246 } |
| 224 | 247 |
| 225 | 248 |
| 226 // Language extension which is only enabled for source files loaded | 249 // Language extension which is only enabled for source files loaded |
| 227 // through the API's extension mechanism. A native function | 250 // through the API's extension mechanism. A native function |
| 228 // declaration is resolved by looking up the function through a | 251 // declaration is resolved by looking up the function through a |
| 229 // callback provided by the extension. | 252 // callback provided by the extension. |
| 230 PreParser::Statement PreParser::ParseNativeDeclaration(bool* ok) { | 253 PreParser::Statement PreParser::ParseNativeDeclaration(bool* ok) { |
| 231 Expect(i::Token::NATIVE, CHECK_OK); | 254 Expect(i::Token::NATIVE, CHECK_OK); |
| 232 Expect(i::Token::FUNCTION, CHECK_OK); | 255 Expect(i::Token::FUNCTION, CHECK_OK); |
| 233 ParseIdentifier(CHECK_OK); | 256 ParseIdentifier(CHECK_OK); |
| 234 Expect(i::Token::LPAREN, CHECK_OK); | 257 Expect(i::Token::LPAREN, CHECK_OK); |
| 235 bool done = (peek() == i::Token::RPAREN); | 258 bool done = (peek() == i::Token::RPAREN); |
| 236 while (!done) { | 259 while (!done) { |
| 237 ParseIdentifier(CHECK_OK); | 260 ParseIdentifier(CHECK_OK); |
| 238 done = (peek() == i::Token::RPAREN); | 261 done = (peek() == i::Token::RPAREN); |
| 239 if (!done) { | 262 if (!done) { |
| 240 Expect(i::Token::COMMA, CHECK_OK); | 263 Expect(i::Token::COMMA, CHECK_OK); |
| 241 } | 264 } |
| 242 } | 265 } |
| 243 Expect(i::Token::RPAREN, CHECK_OK); | 266 Expect(i::Token::RPAREN, CHECK_OK); |
| 244 Expect(i::Token::SEMICOLON, CHECK_OK); | 267 Expect(i::Token::SEMICOLON, CHECK_OK); |
| 245 return kUnknownStatement; | 268 return Statement::Default(); |
| 246 } | 269 } |
| 247 | 270 |
| 248 | 271 |
| 249 PreParser::Statement PreParser::ParseBlock(bool* ok) { | 272 PreParser::Statement PreParser::ParseBlock(bool* ok) { |
| 250 // Block :: | 273 // Block :: |
| 251 // '{' Statement* '}' | 274 // '{' Statement* '}' |
| 252 | 275 |
| 253 // Note that a Block does not introduce a new execution scope! | 276 // Note that a Block does not introduce a new execution scope! |
| 254 // (ECMA-262, 3rd, 12.2) | 277 // (ECMA-262, 3rd, 12.2) |
| 255 // | 278 // |
| 256 Expect(i::Token::LBRACE, CHECK_OK); | 279 Expect(i::Token::LBRACE, CHECK_OK); |
| 257 while (peek() != i::Token::RBRACE) { | 280 while (peek() != i::Token::RBRACE) { |
| 258 ParseStatement(CHECK_OK); | 281 ParseStatement(CHECK_OK); |
| 259 } | 282 } |
| 260 Expect(i::Token::RBRACE, CHECK_OK); | 283 Expect(i::Token::RBRACE, ok); |
| 261 return kUnknownStatement; | 284 return Statement::Default(); |
| 262 } | 285 } |
| 263 | 286 |
| 264 | 287 |
| 265 PreParser::Statement PreParser::ParseVariableStatement(bool* ok) { | 288 PreParser::Statement PreParser::ParseVariableStatement(bool* ok) { |
| 266 // VariableStatement :: | 289 // VariableStatement :: |
| 267 // VariableDeclarations ';' | 290 // VariableDeclarations ';' |
| 268 | 291 |
| 269 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); | 292 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); |
| 270 ExpectSemicolon(CHECK_OK); | 293 ExpectSemicolon(CHECK_OK); |
| 271 return result; | 294 return result; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 282 bool* ok) { | 305 bool* ok) { |
| 283 // VariableDeclarations :: | 306 // VariableDeclarations :: |
| 284 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 307 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
| 285 | 308 |
| 286 if (peek() == i::Token::VAR) { | 309 if (peek() == i::Token::VAR) { |
| 287 Consume(i::Token::VAR); | 310 Consume(i::Token::VAR); |
| 288 } else if (peek() == i::Token::CONST) { | 311 } else if (peek() == i::Token::CONST) { |
| 289 Consume(i::Token::CONST); | 312 Consume(i::Token::CONST); |
| 290 } else { | 313 } else { |
| 291 *ok = false; | 314 *ok = false; |
| 292 return 0; | 315 return Statement::Default(); |
| 293 } | 316 } |
| 294 | 317 |
| 295 // The scope of a variable/const declared anywhere inside a function | 318 // The scope of a variable/const declared anywhere inside a function |
| 296 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). . | 319 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). . |
| 297 int nvars = 0; // the number of variables declared | 320 int nvars = 0; // the number of variables declared |
| 298 do { | 321 do { |
| 299 // Parse variable name. | 322 // Parse variable name. |
| 300 if (nvars > 0) Consume(i::Token::COMMA); | 323 if (nvars > 0) Consume(i::Token::COMMA); |
| 301 ParseIdentifier(CHECK_OK); | 324 Identifier identifier = ParseIdentifier(CHECK_OK); |
| 325 if (strict_mode() && !identifier.IsValidStrictVariable()) { |
| 326 StrictModeIdentifierViolation(scanner_->location(), |
| 327 "strict_var_name", |
| 328 identifier, |
| 329 ok); |
| 330 return Statement::Default(); |
| 331 } |
| 302 nvars++; | 332 nvars++; |
| 303 if (peek() == i::Token::ASSIGN) { | 333 if (peek() == i::Token::ASSIGN) { |
| 304 Expect(i::Token::ASSIGN, CHECK_OK); | 334 Expect(i::Token::ASSIGN, CHECK_OK); |
| 305 ParseAssignmentExpression(accept_IN, CHECK_OK); | 335 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 306 } | 336 } |
| 307 } while (peek() == i::Token::COMMA); | 337 } while (peek() == i::Token::COMMA); |
| 308 | 338 |
| 309 if (num_decl != NULL) *num_decl = nvars; | 339 if (num_decl != NULL) *num_decl = nvars; |
| 310 return kUnknownStatement; | 340 return Statement::Default(); |
| 311 } | 341 } |
| 312 | 342 |
| 313 | 343 |
| 314 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( | 344 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
| 315 bool* ok) { | |
| 316 // ExpressionStatement | LabelledStatement :: | 345 // ExpressionStatement | LabelledStatement :: |
| 317 // Expression ';' | 346 // Expression ';' |
| 318 // Identifier ':' Statement | 347 // Identifier ':' Statement |
| 319 | 348 |
| 320 Expression expr = ParseExpression(true, CHECK_OK); | 349 Expression expr = ParseExpression(true, CHECK_OK); |
| 321 if (peek() == i::Token::COLON && expr == kIdentifierExpression) { | 350 if (peek() == i::Token::COLON && expr.IsRawIdentifier()) { |
| 322 Consume(i::Token::COLON); | 351 Consume(i::Token::COLON); |
| 323 ParseStatement(ok); | 352 ParseStatement(ok); |
| 324 return kUnknownStatement; | 353 return Statement::Default(); |
| 325 } | 354 } |
| 326 // Parsed expression statement. | 355 // Parsed expression statement. |
| 327 ExpectSemicolon(CHECK_OK); | 356 ExpectSemicolon(CHECK_OK); |
| 328 if (expr == kStringLiteralExpression) { | 357 return Statement::ExpressionStatement(expr); |
| 329 return kStringLiteralExpressionStatement; | |
| 330 } | |
| 331 if (expr == kUseStrictString) { | |
| 332 return kUseStrictExpressionStatement; | |
| 333 } | |
| 334 return kUnknownStatement; | |
| 335 } | 358 } |
| 336 | 359 |
| 337 | 360 |
| 338 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { | 361 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { |
| 339 // IfStatement :: | 362 // IfStatement :: |
| 340 // 'if' '(' Expression ')' Statement ('else' Statement)? | 363 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 341 | 364 |
| 342 Expect(i::Token::IF, CHECK_OK); | 365 Expect(i::Token::IF, CHECK_OK); |
| 343 Expect(i::Token::LPAREN, CHECK_OK); | 366 Expect(i::Token::LPAREN, CHECK_OK); |
| 344 ParseExpression(true, CHECK_OK); | 367 ParseExpression(true, CHECK_OK); |
| 345 Expect(i::Token::RPAREN, CHECK_OK); | 368 Expect(i::Token::RPAREN, CHECK_OK); |
| 346 ParseStatement(CHECK_OK); | 369 ParseStatement(CHECK_OK); |
| 347 if (peek() == i::Token::ELSE) { | 370 if (peek() == i::Token::ELSE) { |
| 348 Next(); | 371 Next(); |
| 349 ParseStatement(CHECK_OK); | 372 ParseStatement(CHECK_OK); |
| 350 } | 373 } |
| 351 return kUnknownStatement; | 374 return Statement::Default(); |
| 352 } | 375 } |
| 353 | 376 |
| 354 | 377 |
| 355 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { | 378 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
| 356 // ContinueStatement :: | 379 // ContinueStatement :: |
| 357 // 'continue' [no line terminator] Identifier? ';' | 380 // 'continue' [no line terminator] Identifier? ';' |
| 358 | 381 |
| 359 Expect(i::Token::CONTINUE, CHECK_OK); | 382 Expect(i::Token::CONTINUE, CHECK_OK); |
| 360 i::Token::Value tok = peek(); | 383 i::Token::Value tok = peek(); |
| 361 if (!scanner_->has_line_terminator_before_next() && | 384 if (!scanner_->has_line_terminator_before_next() && |
| 362 tok != i::Token::SEMICOLON && | 385 tok != i::Token::SEMICOLON && |
| 363 tok != i::Token::RBRACE && | 386 tok != i::Token::RBRACE && |
| 364 tok != i::Token::EOS) { | 387 tok != i::Token::EOS) { |
| 365 ParseIdentifier(CHECK_OK); | 388 ParseIdentifier(CHECK_OK); |
| 366 } | 389 } |
| 367 ExpectSemicolon(CHECK_OK); | 390 ExpectSemicolon(CHECK_OK); |
| 368 return kUnknownStatement; | 391 return Statement::Default(); |
| 369 } | 392 } |
| 370 | 393 |
| 371 | 394 |
| 372 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 395 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
| 373 // BreakStatement :: | 396 // BreakStatement :: |
| 374 // 'break' [no line terminator] Identifier? ';' | 397 // 'break' [no line terminator] Identifier? ';' |
| 375 | 398 |
| 376 Expect(i::Token::BREAK, CHECK_OK); | 399 Expect(i::Token::BREAK, CHECK_OK); |
| 377 i::Token::Value tok = peek(); | 400 i::Token::Value tok = peek(); |
| 378 if (!scanner_->has_line_terminator_before_next() && | 401 if (!scanner_->has_line_terminator_before_next() && |
| 379 tok != i::Token::SEMICOLON && | 402 tok != i::Token::SEMICOLON && |
| 380 tok != i::Token::RBRACE && | 403 tok != i::Token::RBRACE && |
| 381 tok != i::Token::EOS) { | 404 tok != i::Token::EOS) { |
| 382 ParseIdentifier(CHECK_OK); | 405 ParseIdentifier(CHECK_OK); |
| 383 } | 406 } |
| 384 ExpectSemicolon(CHECK_OK); | 407 ExpectSemicolon(CHECK_OK); |
| 385 return kUnknownStatement; | 408 return Statement::Default(); |
| 386 } | 409 } |
| 387 | 410 |
| 388 | 411 |
| 389 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 412 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
| 390 // ReturnStatement :: | 413 // ReturnStatement :: |
| 391 // 'return' [no line terminator] Expression? ';' | 414 // 'return' [no line terminator] Expression? ';' |
| 392 | 415 |
| 393 // Consume the return token. It is necessary to do the before | 416 // Consume the return token. It is necessary to do the before |
| 394 // reporting any errors on it, because of the way errors are | 417 // reporting any errors on it, because of the way errors are |
| 395 // reported (underlining). | 418 // reported (underlining). |
| 396 Expect(i::Token::RETURN, CHECK_OK); | 419 Expect(i::Token::RETURN, CHECK_OK); |
| 397 | 420 |
| 398 // An ECMAScript program is considered syntactically incorrect if it | 421 // An ECMAScript program is considered syntactically incorrect if it |
| 399 // contains a return statement that is not within the body of a | 422 // contains a return statement that is not within the body of a |
| 400 // function. See ECMA-262, section 12.9, page 67. | 423 // function. See ECMA-262, section 12.9, page 67. |
| 401 // This is not handled during preparsing. | 424 // This is not handled during preparsing. |
| 402 | 425 |
| 403 i::Token::Value tok = peek(); | 426 i::Token::Value tok = peek(); |
| 404 if (!scanner_->has_line_terminator_before_next() && | 427 if (!scanner_->has_line_terminator_before_next() && |
| 405 tok != i::Token::SEMICOLON && | 428 tok != i::Token::SEMICOLON && |
| 406 tok != i::Token::RBRACE && | 429 tok != i::Token::RBRACE && |
| 407 tok != i::Token::EOS) { | 430 tok != i::Token::EOS) { |
| 408 ParseExpression(true, CHECK_OK); | 431 ParseExpression(true, CHECK_OK); |
| 409 } | 432 } |
| 410 ExpectSemicolon(CHECK_OK); | 433 ExpectSemicolon(CHECK_OK); |
| 411 return kUnknownStatement; | 434 return Statement::Default(); |
| 412 } | 435 } |
| 413 | 436 |
| 414 | 437 |
| 415 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { | 438 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { |
| 416 // WithStatement :: | 439 // WithStatement :: |
| 417 // 'with' '(' Expression ')' Statement | 440 // 'with' '(' Expression ')' Statement |
| 418 Expect(i::Token::WITH, CHECK_OK); | 441 Expect(i::Token::WITH, CHECK_OK); |
| 442 if (strict_mode()) { |
| 443 i::Scanner::Location location = scanner_->location(); |
| 444 ReportMessageAt(location.beg_pos, location.end_pos, |
| 445 "strict_mode_with", NULL); |
| 446 *ok = false; |
| 447 return Statement::Default(); |
| 448 } |
| 419 Expect(i::Token::LPAREN, CHECK_OK); | 449 Expect(i::Token::LPAREN, CHECK_OK); |
| 420 ParseExpression(true, CHECK_OK); | 450 ParseExpression(true, CHECK_OK); |
| 421 Expect(i::Token::RPAREN, CHECK_OK); | 451 Expect(i::Token::RPAREN, CHECK_OK); |
| 422 | 452 |
| 423 scope_->EnterWith(); | 453 scope_->EnterWith(); |
| 424 ParseStatement(CHECK_OK); | 454 ParseStatement(CHECK_OK); |
| 425 scope_->LeaveWith(); | 455 scope_->LeaveWith(); |
| 426 return kUnknownStatement; | 456 return Statement::Default(); |
| 427 } | 457 } |
| 428 | 458 |
| 429 | 459 |
| 430 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { | 460 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { |
| 431 // SwitchStatement :: | 461 // SwitchStatement :: |
| 432 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 462 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 433 | 463 |
| 434 Expect(i::Token::SWITCH, CHECK_OK); | 464 Expect(i::Token::SWITCH, CHECK_OK); |
| 435 Expect(i::Token::LPAREN, CHECK_OK); | 465 Expect(i::Token::LPAREN, CHECK_OK); |
| 436 ParseExpression(true, CHECK_OK); | 466 ParseExpression(true, CHECK_OK); |
| 437 Expect(i::Token::RPAREN, CHECK_OK); | 467 Expect(i::Token::RPAREN, CHECK_OK); |
| 438 | 468 |
| 439 Expect(i::Token::LBRACE, CHECK_OK); | 469 Expect(i::Token::LBRACE, CHECK_OK); |
| 440 i::Token::Value token = peek(); | 470 i::Token::Value token = peek(); |
| 441 while (token != i::Token::RBRACE) { | 471 while (token != i::Token::RBRACE) { |
| 442 if (token == i::Token::CASE) { | 472 if (token == i::Token::CASE) { |
| 443 Expect(i::Token::CASE, CHECK_OK); | 473 Expect(i::Token::CASE, CHECK_OK); |
| 444 ParseExpression(true, CHECK_OK); | 474 ParseExpression(true, CHECK_OK); |
| 445 Expect(i::Token::COLON, CHECK_OK); | 475 Expect(i::Token::COLON, CHECK_OK); |
| 446 } else if (token == i::Token::DEFAULT) { | 476 } else if (token == i::Token::DEFAULT) { |
| 447 Expect(i::Token::DEFAULT, CHECK_OK); | 477 Expect(i::Token::DEFAULT, CHECK_OK); |
| 448 Expect(i::Token::COLON, CHECK_OK); | 478 Expect(i::Token::COLON, CHECK_OK); |
| 449 } else { | 479 } else { |
| 450 ParseStatement(CHECK_OK); | 480 ParseStatement(CHECK_OK); |
| 451 } | 481 } |
| 452 token = peek(); | 482 token = peek(); |
| 453 } | 483 } |
| 454 Expect(i::Token::RBRACE, CHECK_OK); | 484 Expect(i::Token::RBRACE, ok); |
| 455 | 485 return Statement::Default(); |
| 456 return kUnknownStatement; | |
| 457 } | 486 } |
| 458 | 487 |
| 459 | 488 |
| 460 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { | 489 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { |
| 461 // DoStatement :: | 490 // DoStatement :: |
| 462 // 'do' Statement 'while' '(' Expression ')' ';' | 491 // 'do' Statement 'while' '(' Expression ')' ';' |
| 463 | 492 |
| 464 Expect(i::Token::DO, CHECK_OK); | 493 Expect(i::Token::DO, CHECK_OK); |
| 465 ParseStatement(CHECK_OK); | 494 ParseStatement(CHECK_OK); |
| 466 Expect(i::Token::WHILE, CHECK_OK); | 495 Expect(i::Token::WHILE, CHECK_OK); |
| 467 Expect(i::Token::LPAREN, CHECK_OK); | 496 Expect(i::Token::LPAREN, CHECK_OK); |
| 468 ParseExpression(true, CHECK_OK); | 497 ParseExpression(true, CHECK_OK); |
| 469 Expect(i::Token::RPAREN, CHECK_OK); | 498 Expect(i::Token::RPAREN, ok); |
| 470 return kUnknownStatement; | 499 return Statement::Default(); |
| 471 } | 500 } |
| 472 | 501 |
| 473 | 502 |
| 474 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { | 503 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { |
| 475 // WhileStatement :: | 504 // WhileStatement :: |
| 476 // 'while' '(' Expression ')' Statement | 505 // 'while' '(' Expression ')' Statement |
| 477 | 506 |
| 478 Expect(i::Token::WHILE, CHECK_OK); | 507 Expect(i::Token::WHILE, CHECK_OK); |
| 479 Expect(i::Token::LPAREN, CHECK_OK); | 508 Expect(i::Token::LPAREN, CHECK_OK); |
| 480 ParseExpression(true, CHECK_OK); | 509 ParseExpression(true, CHECK_OK); |
| 481 Expect(i::Token::RPAREN, CHECK_OK); | 510 Expect(i::Token::RPAREN, CHECK_OK); |
| 482 ParseStatement(CHECK_OK); | 511 ParseStatement(ok); |
| 483 return kUnknownStatement; | 512 return Statement::Default(); |
| 484 } | 513 } |
| 485 | 514 |
| 486 | 515 |
| 487 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 516 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
| 488 // ForStatement :: | 517 // ForStatement :: |
| 489 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 518 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 490 | 519 |
| 491 Expect(i::Token::FOR, CHECK_OK); | 520 Expect(i::Token::FOR, CHECK_OK); |
| 492 Expect(i::Token::LPAREN, CHECK_OK); | 521 Expect(i::Token::LPAREN, CHECK_OK); |
| 493 if (peek() != i::Token::SEMICOLON) { | 522 if (peek() != i::Token::SEMICOLON) { |
| 494 if (peek() == i::Token::VAR || peek() == i::Token::CONST) { | 523 if (peek() == i::Token::VAR || peek() == i::Token::CONST) { |
| 495 int decl_count; | 524 int decl_count; |
| 496 ParseVariableDeclarations(false, &decl_count, CHECK_OK); | 525 ParseVariableDeclarations(false, &decl_count, CHECK_OK); |
| 497 if (peek() == i::Token::IN && decl_count == 1) { | 526 if (peek() == i::Token::IN && decl_count == 1) { |
| 498 Expect(i::Token::IN, CHECK_OK); | 527 Expect(i::Token::IN, CHECK_OK); |
| 499 ParseExpression(true, CHECK_OK); | 528 ParseExpression(true, CHECK_OK); |
| 500 Expect(i::Token::RPAREN, CHECK_OK); | 529 Expect(i::Token::RPAREN, CHECK_OK); |
| 501 | 530 |
| 502 ParseStatement(CHECK_OK); | 531 ParseStatement(CHECK_OK); |
| 503 return kUnknownStatement; | 532 return Statement::Default(); |
| 504 } | 533 } |
| 505 } else { | 534 } else { |
| 506 ParseExpression(false, CHECK_OK); | 535 ParseExpression(false, CHECK_OK); |
| 507 if (peek() == i::Token::IN) { | 536 if (peek() == i::Token::IN) { |
| 508 Expect(i::Token::IN, CHECK_OK); | 537 Expect(i::Token::IN, CHECK_OK); |
| 509 ParseExpression(true, CHECK_OK); | 538 ParseExpression(true, CHECK_OK); |
| 510 Expect(i::Token::RPAREN, CHECK_OK); | 539 Expect(i::Token::RPAREN, CHECK_OK); |
| 511 | 540 |
| 512 ParseStatement(CHECK_OK); | 541 ParseStatement(CHECK_OK); |
| 513 return kUnknownStatement; | 542 return Statement::Default(); |
| 514 } | 543 } |
| 515 } | 544 } |
| 516 } | 545 } |
| 517 | 546 |
| 518 // Parsed initializer at this point. | 547 // Parsed initializer at this point. |
| 519 Expect(i::Token::SEMICOLON, CHECK_OK); | 548 Expect(i::Token::SEMICOLON, CHECK_OK); |
| 520 | 549 |
| 521 if (peek() != i::Token::SEMICOLON) { | 550 if (peek() != i::Token::SEMICOLON) { |
| 522 ParseExpression(true, CHECK_OK); | 551 ParseExpression(true, CHECK_OK); |
| 523 } | 552 } |
| 524 Expect(i::Token::SEMICOLON, CHECK_OK); | 553 Expect(i::Token::SEMICOLON, CHECK_OK); |
| 525 | 554 |
| 526 if (peek() != i::Token::RPAREN) { | 555 if (peek() != i::Token::RPAREN) { |
| 527 ParseExpression(true, CHECK_OK); | 556 ParseExpression(true, CHECK_OK); |
| 528 } | 557 } |
| 529 Expect(i::Token::RPAREN, CHECK_OK); | 558 Expect(i::Token::RPAREN, CHECK_OK); |
| 530 | 559 |
| 531 ParseStatement(CHECK_OK); | 560 ParseStatement(ok); |
| 532 return kUnknownStatement; | 561 return Statement::Default(); |
| 533 } | 562 } |
| 534 | 563 |
| 535 | 564 |
| 536 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { | 565 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { |
| 537 // ThrowStatement :: | 566 // ThrowStatement :: |
| 538 // 'throw' [no line terminator] Expression ';' | 567 // 'throw' [no line terminator] Expression ';' |
| 539 | 568 |
| 540 Expect(i::Token::THROW, CHECK_OK); | 569 Expect(i::Token::THROW, CHECK_OK); |
| 541 if (scanner_->has_line_terminator_before_next()) { | 570 if (scanner_->has_line_terminator_before_next()) { |
| 542 i::JavaScriptScanner::Location pos = scanner_->location(); | 571 i::JavaScriptScanner::Location pos = scanner_->location(); |
| 543 ReportMessageAt(pos.beg_pos, pos.end_pos, | 572 ReportMessageAt(pos.beg_pos, pos.end_pos, |
| 544 "newline_after_throw", NULL); | 573 "newline_after_throw", NULL); |
| 545 *ok = false; | 574 *ok = false; |
| 546 return kUnknownStatement; | 575 return Statement::Default(); |
| 547 } | 576 } |
| 548 ParseExpression(true, CHECK_OK); | 577 ParseExpression(true, CHECK_OK); |
| 549 ExpectSemicolon(CHECK_OK); | 578 ExpectSemicolon(ok); |
| 550 | 579 return Statement::Default(); |
| 551 return kUnknownStatement; | |
| 552 } | 580 } |
| 553 | 581 |
| 554 | 582 |
| 555 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { | 583 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { |
| 556 // TryStatement :: | 584 // TryStatement :: |
| 557 // 'try' Block Catch | 585 // 'try' Block Catch |
| 558 // 'try' Block Finally | 586 // 'try' Block Finally |
| 559 // 'try' Block Catch Finally | 587 // 'try' Block Catch Finally |
| 560 // | 588 // |
| 561 // Catch :: | 589 // Catch :: |
| 562 // 'catch' '(' Identifier ')' Block | 590 // 'catch' '(' Identifier ')' Block |
| 563 // | 591 // |
| 564 // Finally :: | 592 // Finally :: |
| 565 // 'finally' Block | 593 // 'finally' Block |
| 566 | 594 |
| 567 // In preparsing, allow any number of catch/finally blocks, including zero | 595 // In preparsing, allow any number of catch/finally blocks, including zero |
| 568 // of both. | 596 // of both. |
| 569 | 597 |
| 570 Expect(i::Token::TRY, CHECK_OK); | 598 Expect(i::Token::TRY, CHECK_OK); |
| 571 | 599 |
| 572 ParseBlock(CHECK_OK); | 600 ParseBlock(CHECK_OK); |
| 573 | 601 |
| 574 bool catch_or_finally_seen = false; | 602 bool catch_or_finally_seen = false; |
| 575 if (peek() == i::Token::CATCH) { | 603 if (peek() == i::Token::CATCH) { |
| 576 Consume(i::Token::CATCH); | 604 Consume(i::Token::CATCH); |
| 577 Expect(i::Token::LPAREN, CHECK_OK); | 605 Expect(i::Token::LPAREN, CHECK_OK); |
| 578 ParseIdentifier(CHECK_OK); | 606 Identifier id = ParseIdentifier(CHECK_OK); |
| 607 if (strict_mode() && !id.IsValidStrictVariable()) { |
| 608 StrictModeIdentifierViolation(scanner_->location(), |
| 609 "strict_catch_variable", |
| 610 id, |
| 611 ok); |
| 612 return Statement::Default(); |
| 613 } |
| 579 Expect(i::Token::RPAREN, CHECK_OK); | 614 Expect(i::Token::RPAREN, CHECK_OK); |
| 580 scope_->EnterWith(); | 615 scope_->EnterWith(); |
| 581 ParseBlock(ok); | 616 ParseBlock(ok); |
| 582 scope_->LeaveWith(); | 617 scope_->LeaveWith(); |
| 583 if (!*ok) return kUnknownStatement; | 618 if (!*ok) Statement::Default(); |
| 584 catch_or_finally_seen = true; | 619 catch_or_finally_seen = true; |
| 585 } | 620 } |
| 586 if (peek() == i::Token::FINALLY) { | 621 if (peek() == i::Token::FINALLY) { |
| 587 Consume(i::Token::FINALLY); | 622 Consume(i::Token::FINALLY); |
| 588 ParseBlock(CHECK_OK); | 623 ParseBlock(CHECK_OK); |
| 589 catch_or_finally_seen = true; | 624 catch_or_finally_seen = true; |
| 590 } | 625 } |
| 591 if (!catch_or_finally_seen) { | 626 if (!catch_or_finally_seen) { |
| 592 *ok = false; | 627 *ok = false; |
| 593 } | 628 } |
| 594 return kUnknownStatement; | 629 return Statement::Default(); |
| 595 } | 630 } |
| 596 | 631 |
| 597 | 632 |
| 598 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { | 633 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { |
| 599 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 634 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 600 // contexts this is used as a statement which invokes the debugger as if a | 635 // contexts this is used as a statement which invokes the debugger as if a |
| 601 // break point is present. | 636 // break point is present. |
| 602 // DebuggerStatement :: | 637 // DebuggerStatement :: |
| 603 // 'debugger' ';' | 638 // 'debugger' ';' |
| 604 | 639 |
| 605 Expect(i::Token::DEBUGGER, CHECK_OK); | 640 Expect(i::Token::DEBUGGER, CHECK_OK); |
| 606 ExpectSemicolon(CHECK_OK); | 641 ExpectSemicolon(ok); |
| 607 return kUnknownStatement; | 642 return Statement::Default(); |
| 608 } | 643 } |
| 609 | 644 |
| 610 | 645 |
| 646 #undef CHECK_OK |
| 647 #define CHECK_OK ok); \ |
| 648 if (!*ok) return Expression::Default(); \ |
| 649 ((void)0 |
| 650 #define DUMMY ) // to make indentation work |
| 651 #undef DUMMY |
| 652 |
| 653 |
| 611 // Precedence = 1 | 654 // Precedence = 1 |
| 612 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { | 655 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { |
| 613 // Expression :: | 656 // Expression :: |
| 614 // AssignmentExpression | 657 // AssignmentExpression |
| 615 // Expression ',' AssignmentExpression | 658 // Expression ',' AssignmentExpression |
| 616 | 659 |
| 617 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 660 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 618 while (peek() == i::Token::COMMA) { | 661 while (peek() == i::Token::COMMA) { |
| 619 Expect(i::Token::COMMA, CHECK_OK); | 662 Expect(i::Token::COMMA, CHECK_OK); |
| 620 ParseAssignmentExpression(accept_IN, CHECK_OK); | 663 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 621 result = kUnknownExpression; | 664 result = Expression::Default(); |
| 622 } | 665 } |
| 623 return result; | 666 return result; |
| 624 } | 667 } |
| 625 | 668 |
| 626 | 669 |
| 627 // Precedence = 2 | 670 // Precedence = 2 |
| 628 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, | 671 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, |
| 629 bool* ok) { | 672 bool* ok) { |
| 630 // AssignmentExpression :: | 673 // AssignmentExpression :: |
| 631 // ConditionalExpression | 674 // ConditionalExpression |
| 632 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 675 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 633 | 676 |
| 677 i::Scanner::Location before = scanner_->peek_location(); |
| 634 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 678 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
| 635 | 679 |
| 636 if (!i::Token::IsAssignmentOp(peek())) { | 680 if (!i::Token::IsAssignmentOp(peek())) { |
| 637 // Parsed conditional expression only (no assignment). | 681 // Parsed conditional expression only (no assignment). |
| 638 return expression; | 682 return expression; |
| 639 } | 683 } |
| 640 | 684 |
| 685 if (strict_mode() && expression.IsIdentifier() && |
| 686 expression.AsIdentifier().IsEvalOrArguments()) { |
| 687 i::Scanner::Location after = scanner_->location(); |
| 688 ReportMessageAt(before.beg_pos, after.end_pos, |
| 689 "strict_lhs_assignment", NULL); |
| 690 *ok = false; |
| 691 return Expression::Default(); |
| 692 } |
| 693 |
| 641 i::Token::Value op = Next(); // Get assignment operator. | 694 i::Token::Value op = Next(); // Get assignment operator. |
| 642 ParseAssignmentExpression(accept_IN, CHECK_OK); | 695 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 643 | 696 |
| 644 if ((op == i::Token::ASSIGN) && (expression == kThisPropertyExpression)) { | 697 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { |
| 645 scope_->AddProperty(); | 698 scope_->AddProperty(); |
| 646 } | 699 } |
| 647 | 700 |
| 648 return kUnknownExpression; | 701 return Expression::Default(); |
| 649 } | 702 } |
| 650 | 703 |
| 651 | 704 |
| 652 // Precedence = 3 | 705 // Precedence = 3 |
| 653 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, | 706 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, |
| 654 bool* ok) { | 707 bool* ok) { |
| 655 // ConditionalExpression :: | 708 // ConditionalExpression :: |
| 656 // LogicalOrExpression | 709 // LogicalOrExpression |
| 657 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 710 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 658 | 711 |
| 659 // We start using the binary expression parser for prec >= 4 only! | 712 // We start using the binary expression parser for prec >= 4 only! |
| 660 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 713 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 661 if (peek() != i::Token::CONDITIONAL) return expression; | 714 if (peek() != i::Token::CONDITIONAL) return expression; |
| 662 Consume(i::Token::CONDITIONAL); | 715 Consume(i::Token::CONDITIONAL); |
| 663 // In parsing the first assignment expression in conditional | 716 // In parsing the first assignment expression in conditional |
| 664 // expressions we always accept the 'in' keyword; see ECMA-262, | 717 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 665 // section 11.12, page 58. | 718 // section 11.12, page 58. |
| 666 ParseAssignmentExpression(true, CHECK_OK); | 719 ParseAssignmentExpression(true, CHECK_OK); |
| 667 Expect(i::Token::COLON, CHECK_OK); | 720 Expect(i::Token::COLON, CHECK_OK); |
| 668 ParseAssignmentExpression(accept_IN, CHECK_OK); | 721 ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 669 return kUnknownExpression; | 722 return Expression::Default(); |
| 670 } | 723 } |
| 671 | 724 |
| 672 | 725 |
| 673 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) { | 726 int PreParser::Precedence(i::Token::Value tok, bool accept_IN) { |
| 674 if (tok == i::Token::IN && !accept_IN) | 727 if (tok == i::Token::IN && !accept_IN) |
| 675 return 0; // 0 precedence will terminate binary expression parsing | 728 return 0; // 0 precedence will terminate binary expression parsing |
| 676 | 729 |
| 677 return i::Token::Precedence(tok); | 730 return i::Token::Precedence(tok); |
| 678 } | 731 } |
| 679 | 732 |
| 680 | 733 |
| 681 // Precedence >= 4 | 734 // Precedence >= 4 |
| 682 PreParser::Expression PreParser::ParseBinaryExpression(int prec, | 735 PreParser::Expression PreParser::ParseBinaryExpression(int prec, |
| 683 bool accept_IN, | 736 bool accept_IN, |
| 684 bool* ok) { | 737 bool* ok) { |
| 685 Expression result = ParseUnaryExpression(CHECK_OK); | 738 Expression result = ParseUnaryExpression(CHECK_OK); |
| 686 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 739 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 687 // prec1 >= 4 | 740 // prec1 >= 4 |
| 688 while (Precedence(peek(), accept_IN) == prec1) { | 741 while (Precedence(peek(), accept_IN) == prec1) { |
| 689 Next(); | 742 Next(); |
| 690 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 743 ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| 691 result = kUnknownExpression; | 744 result = Expression::Default(); |
| 692 } | 745 } |
| 693 } | 746 } |
| 694 return result; | 747 return result; |
| 695 } | 748 } |
| 696 | 749 |
| 697 | 750 |
| 698 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) { | 751 PreParser::Expression PreParser::ParseUnaryExpression(bool* ok) { |
| 699 // UnaryExpression :: | 752 // UnaryExpression :: |
| 700 // PostfixExpression | 753 // PostfixExpression |
| 701 // 'delete' UnaryExpression | 754 // 'delete' UnaryExpression |
| 702 // 'void' UnaryExpression | 755 // 'void' UnaryExpression |
| 703 // 'typeof' UnaryExpression | 756 // 'typeof' UnaryExpression |
| 704 // '++' UnaryExpression | 757 // '++' UnaryExpression |
| 705 // '--' UnaryExpression | 758 // '--' UnaryExpression |
| 706 // '+' UnaryExpression | 759 // '+' UnaryExpression |
| 707 // '-' UnaryExpression | 760 // '-' UnaryExpression |
| 708 // '~' UnaryExpression | 761 // '~' UnaryExpression |
| 709 // '!' UnaryExpression | 762 // '!' UnaryExpression |
| 710 | 763 |
| 711 i::Token::Value op = peek(); | 764 i::Token::Value op = peek(); |
| 712 if (i::Token::IsUnaryOp(op) || i::Token::IsCountOp(op)) { | 765 if (i::Token::IsUnaryOp(op)) { |
| 713 op = Next(); | 766 op = Next(); |
| 714 ParseUnaryExpression(ok); | 767 ParseUnaryExpression(ok); |
| 715 return kUnknownExpression; | 768 return Expression::Default(); |
| 769 } else if (i::Token::IsCountOp(op)) { |
| 770 op = Next(); |
| 771 i::Scanner::Location before = scanner_->peek_location(); |
| 772 Expression expression = ParseUnaryExpression(CHECK_OK); |
| 773 if (strict_mode() && expression.IsIdentifier() && |
| 774 expression.AsIdentifier().IsEvalOrArguments()) { |
| 775 i::Scanner::Location after = scanner_->location(); |
| 776 ReportMessageAt(before.beg_pos, after.end_pos, |
| 777 "strict_lhs_prefix", NULL); |
| 778 *ok = false; |
| 779 } |
| 780 return Expression::Default(); |
| 716 } else { | 781 } else { |
| 717 return ParsePostfixExpression(ok); | 782 return ParsePostfixExpression(ok); |
| 718 } | 783 } |
| 719 } | 784 } |
| 720 | 785 |
| 721 | 786 |
| 722 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { | 787 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { |
| 723 // PostfixExpression :: | 788 // PostfixExpression :: |
| 724 // LeftHandSideExpression ('++' | '--')? | 789 // LeftHandSideExpression ('++' | '--')? |
| 725 | 790 |
| 791 i::Scanner::Location before = scanner_->peek_location(); |
| 726 Expression expression = ParseLeftHandSideExpression(CHECK_OK); | 792 Expression expression = ParseLeftHandSideExpression(CHECK_OK); |
| 727 if (!scanner_->has_line_terminator_before_next() && | 793 if (!scanner_->has_line_terminator_before_next() && |
| 728 i::Token::IsCountOp(peek())) { | 794 i::Token::IsCountOp(peek())) { |
| 795 if (strict_mode() && expression.IsIdentifier() && |
| 796 expression.AsIdentifier().IsEvalOrArguments()) { |
| 797 i::Scanner::Location after = scanner_->location(); |
| 798 ReportMessageAt(before.beg_pos, after.end_pos, |
| 799 "strict_lhs_postfix", NULL); |
| 800 *ok = false; |
| 801 return Expression::Default(); |
| 802 } |
| 729 Next(); | 803 Next(); |
| 730 return kUnknownExpression; | 804 return Expression::Default(); |
| 731 } | 805 } |
| 732 return expression; | 806 return expression; |
| 733 } | 807 } |
| 734 | 808 |
| 735 | 809 |
| 736 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { | 810 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { |
| 737 // LeftHandSideExpression :: | 811 // LeftHandSideExpression :: |
| 738 // (NewExpression | MemberExpression) ... | 812 // (NewExpression | MemberExpression) ... |
| 739 | 813 |
| 740 Expression result; | 814 Expression result = Expression::Default(); |
| 741 if (peek() == i::Token::NEW) { | 815 if (peek() == i::Token::NEW) { |
| 742 result = ParseNewExpression(CHECK_OK); | 816 result = ParseNewExpression(CHECK_OK); |
| 743 } else { | 817 } else { |
| 744 result = ParseMemberExpression(CHECK_OK); | 818 result = ParseMemberExpression(CHECK_OK); |
| 745 } | 819 } |
| 746 | 820 |
| 747 while (true) { | 821 while (true) { |
| 748 switch (peek()) { | 822 switch (peek()) { |
| 749 case i::Token::LBRACK: { | 823 case i::Token::LBRACK: { |
| 750 Consume(i::Token::LBRACK); | 824 Consume(i::Token::LBRACK); |
| 751 ParseExpression(true, CHECK_OK); | 825 ParseExpression(true, CHECK_OK); |
| 752 Expect(i::Token::RBRACK, CHECK_OK); | 826 Expect(i::Token::RBRACK, CHECK_OK); |
| 753 if (result == kThisExpression) { | 827 if (result.IsThis()) { |
| 754 result = kThisPropertyExpression; | 828 result = Expression::ThisProperty(); |
| 755 } else { | 829 } else { |
| 756 result = kUnknownExpression; | 830 result = Expression::Default(); |
| 757 } | 831 } |
| 758 break; | 832 break; |
| 759 } | 833 } |
| 760 | 834 |
| 761 case i::Token::LPAREN: { | 835 case i::Token::LPAREN: { |
| 762 ParseArguments(CHECK_OK); | 836 ParseArguments(CHECK_OK); |
| 763 result = kUnknownExpression; | 837 result = Expression::Default(); |
| 764 break; | 838 break; |
| 765 } | 839 } |
| 766 | 840 |
| 767 case i::Token::PERIOD: { | 841 case i::Token::PERIOD: { |
| 768 Consume(i::Token::PERIOD); | 842 Consume(i::Token::PERIOD); |
| 769 ParseIdentifierName(CHECK_OK); | 843 ParseIdentifierName(CHECK_OK); |
| 770 if (result == kThisExpression) { | 844 if (result.IsThis()) { |
| 771 result = kThisPropertyExpression; | 845 result = Expression::ThisProperty(); |
| 772 } else { | 846 } else { |
| 773 result = kUnknownExpression; | 847 result = Expression::Default(); |
| 774 } | 848 } |
| 775 break; | 849 break; |
| 776 } | 850 } |
| 777 | 851 |
| 778 default: | 852 default: |
| 779 return result; | 853 return result; |
| 780 } | 854 } |
| 781 } | 855 } |
| 782 } | 856 } |
| 783 | 857 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 809 } | 883 } |
| 810 | 884 |
| 811 | 885 |
| 812 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( | 886 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( |
| 813 unsigned new_count, bool* ok) { | 887 unsigned new_count, bool* ok) { |
| 814 // MemberExpression :: | 888 // MemberExpression :: |
| 815 // (PrimaryExpression | FunctionLiteral) | 889 // (PrimaryExpression | FunctionLiteral) |
| 816 // ('[' Expression ']' | '.' Identifier | Arguments)* | 890 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 817 | 891 |
| 818 // Parse the initial primary or function expression. | 892 // Parse the initial primary or function expression. |
| 819 Expression result = kUnknownExpression; | 893 Expression result = Expression::Default(); |
| 820 if (peek() == i::Token::FUNCTION) { | 894 if (peek() == i::Token::FUNCTION) { |
| 821 Consume(i::Token::FUNCTION); | 895 Consume(i::Token::FUNCTION); |
| 896 Identifier identifier = Identifier::Default(); |
| 822 if (peek_any_identifier()) { | 897 if (peek_any_identifier()) { |
| 823 ParseIdentifier(CHECK_OK); | 898 identifier = ParseIdentifier(CHECK_OK); |
| 824 } | 899 } |
| 825 result = ParseFunctionLiteral(CHECK_OK); | 900 result = ParseFunctionLiteral(CHECK_OK); |
| 901 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { |
| 902 StrictModeIdentifierViolation(scanner_->location(), |
| 903 "strict_function_name", |
| 904 identifier, |
| 905 ok); |
| 906 return Expression::Default(); |
| 907 } |
| 826 } else { | 908 } else { |
| 827 result = ParsePrimaryExpression(CHECK_OK); | 909 result = ParsePrimaryExpression(CHECK_OK); |
| 828 } | 910 } |
| 829 | 911 |
| 830 while (true) { | 912 while (true) { |
| 831 switch (peek()) { | 913 switch (peek()) { |
| 832 case i::Token::LBRACK: { | 914 case i::Token::LBRACK: { |
| 833 Consume(i::Token::LBRACK); | 915 Consume(i::Token::LBRACK); |
| 834 ParseExpression(true, CHECK_OK); | 916 ParseExpression(true, CHECK_OK); |
| 835 Expect(i::Token::RBRACK, CHECK_OK); | 917 Expect(i::Token::RBRACK, CHECK_OK); |
| 836 if (result == kThisExpression) { | 918 if (result.IsThis()) { |
| 837 result = kThisPropertyExpression; | 919 result = Expression::ThisProperty(); |
| 838 } else { | 920 } else { |
| 839 result = kUnknownExpression; | 921 result = Expression::Default(); |
| 840 } | 922 } |
| 841 break; | 923 break; |
| 842 } | 924 } |
| 843 case i::Token::PERIOD: { | 925 case i::Token::PERIOD: { |
| 844 Consume(i::Token::PERIOD); | 926 Consume(i::Token::PERIOD); |
| 845 ParseIdentifierName(CHECK_OK); | 927 ParseIdentifierName(CHECK_OK); |
| 846 if (result == kThisExpression) { | 928 if (result.IsThis()) { |
| 847 result = kThisPropertyExpression; | 929 result = Expression::ThisProperty(); |
| 848 } else { | 930 } else { |
| 849 result = kUnknownExpression; | 931 result = Expression::Default(); |
| 850 } | 932 } |
| 851 break; | 933 break; |
| 852 } | 934 } |
| 853 case i::Token::LPAREN: { | 935 case i::Token::LPAREN: { |
| 854 if (new_count == 0) return result; | 936 if (new_count == 0) return result; |
| 855 // Consume one of the new prefixes (already parsed). | 937 // Consume one of the new prefixes (already parsed). |
| 856 ParseArguments(CHECK_OK); | 938 ParseArguments(CHECK_OK); |
| 857 new_count--; | 939 new_count--; |
| 858 result = kUnknownExpression; | 940 result = Expression::Default(); |
| 859 break; | 941 break; |
| 860 } | 942 } |
| 861 default: | 943 default: |
| 862 return result; | 944 return result; |
| 863 } | 945 } |
| 864 } | 946 } |
| 865 } | 947 } |
| 866 | 948 |
| 867 | 949 |
| 868 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) { | 950 PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) { |
| 869 // PrimaryExpression :: | 951 // PrimaryExpression :: |
| 870 // 'this' | 952 // 'this' |
| 871 // 'null' | 953 // 'null' |
| 872 // 'true' | 954 // 'true' |
| 873 // 'false' | 955 // 'false' |
| 874 // Identifier | 956 // Identifier |
| 875 // Number | 957 // Number |
| 876 // String | 958 // String |
| 877 // ArrayLiteral | 959 // ArrayLiteral |
| 878 // ObjectLiteral | 960 // ObjectLiteral |
| 879 // RegExpLiteral | 961 // RegExpLiteral |
| 880 // '(' Expression ')' | 962 // '(' Expression ')' |
| 881 | 963 |
| 882 Expression result = kUnknownExpression; | 964 Expression result = Expression::Default(); |
| 883 switch (peek()) { | 965 switch (peek()) { |
| 884 case i::Token::THIS: { | 966 case i::Token::THIS: { |
| 885 Next(); | 967 Next(); |
| 886 result = kThisExpression; | 968 result = Expression::This(); |
| 887 break; | 969 break; |
| 888 } | 970 } |
| 889 | 971 |
| 890 case i::Token::IDENTIFIER: | 972 case i::Token::FUTURE_RESERVED_WORD: |
| 891 case i::Token::FUTURE_RESERVED_WORD: { | 973 if (strict_mode()) { |
| 892 ParseIdentifier(CHECK_OK); | 974 Next(); |
| 893 result = kIdentifierExpression; | 975 i::Scanner::Location location = scanner_->location(); |
| 976 ReportMessageAt(location.beg_pos, location.end_pos, |
| 977 "strict_reserved_word", NULL); |
| 978 *ok = false; |
| 979 return Expression::Default(); |
| 980 } |
| 981 // FALLTHROUGH |
| 982 case i::Token::IDENTIFIER: { |
| 983 Identifier id = ParseIdentifier(CHECK_OK); |
| 984 result = Expression::Identifier(id); |
| 894 break; | 985 break; |
| 895 } | 986 } |
| 896 | 987 |
| 897 case i::Token::NULL_LITERAL: | 988 case i::Token::NULL_LITERAL: |
| 898 case i::Token::TRUE_LITERAL: | 989 case i::Token::TRUE_LITERAL: |
| 899 case i::Token::FALSE_LITERAL: | 990 case i::Token::FALSE_LITERAL: |
| 900 case i::Token::NUMBER: { | 991 case i::Token::NUMBER: { |
| 901 Next(); | 992 Next(); |
| 902 break; | 993 break; |
| 903 } | 994 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 921 | 1012 |
| 922 case i::Token::LBRACE: | 1013 case i::Token::LBRACE: |
| 923 result = ParseObjectLiteral(CHECK_OK); | 1014 result = ParseObjectLiteral(CHECK_OK); |
| 924 break; | 1015 break; |
| 925 | 1016 |
| 926 case i::Token::LPAREN: | 1017 case i::Token::LPAREN: |
| 927 Consume(i::Token::LPAREN); | 1018 Consume(i::Token::LPAREN); |
| 928 parenthesized_function_ = (peek() == i::Token::FUNCTION); | 1019 parenthesized_function_ = (peek() == i::Token::FUNCTION); |
| 929 result = ParseExpression(true, CHECK_OK); | 1020 result = ParseExpression(true, CHECK_OK); |
| 930 Expect(i::Token::RPAREN, CHECK_OK); | 1021 Expect(i::Token::RPAREN, CHECK_OK); |
| 931 if (result == kIdentifierExpression) result = kUnknownExpression; | 1022 result = result.Parenthesize(); |
| 932 break; | 1023 break; |
| 933 | 1024 |
| 934 case i::Token::MOD: | 1025 case i::Token::MOD: |
| 935 result = ParseV8Intrinsic(CHECK_OK); | 1026 result = ParseV8Intrinsic(CHECK_OK); |
| 936 break; | 1027 break; |
| 937 | 1028 |
| 938 default: { | 1029 default: { |
| 939 Next(); | 1030 Next(); |
| 940 *ok = false; | 1031 *ok = false; |
| 941 return kUnknownExpression; | 1032 return Expression::Default(); |
| 942 } | 1033 } |
| 943 } | 1034 } |
| 944 | 1035 |
| 945 return result; | 1036 return result; |
| 946 } | 1037 } |
| 947 | 1038 |
| 948 | 1039 |
| 949 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) { | 1040 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) { |
| 950 // ArrayLiteral :: | 1041 // ArrayLiteral :: |
| 951 // '[' Expression? (',' Expression?)* ']' | 1042 // '[' Expression? (',' Expression?)* ']' |
| 952 Expect(i::Token::LBRACK, CHECK_OK); | 1043 Expect(i::Token::LBRACK, CHECK_OK); |
| 953 while (peek() != i::Token::RBRACK) { | 1044 while (peek() != i::Token::RBRACK) { |
| 954 if (peek() != i::Token::COMMA) { | 1045 if (peek() != i::Token::COMMA) { |
| 955 ParseAssignmentExpression(true, CHECK_OK); | 1046 ParseAssignmentExpression(true, CHECK_OK); |
| 956 } | 1047 } |
| 957 if (peek() != i::Token::RBRACK) { | 1048 if (peek() != i::Token::RBRACK) { |
| 958 Expect(i::Token::COMMA, CHECK_OK); | 1049 Expect(i::Token::COMMA, CHECK_OK); |
| 959 } | 1050 } |
| 960 } | 1051 } |
| 961 Expect(i::Token::RBRACK, CHECK_OK); | 1052 Expect(i::Token::RBRACK, CHECK_OK); |
| 962 | 1053 |
| 963 scope_->NextMaterializedLiteralIndex(); | 1054 scope_->NextMaterializedLiteralIndex(); |
| 964 return kUnknownExpression; | 1055 return Expression::Default(); |
| 965 } | 1056 } |
| 966 | 1057 |
| 967 | 1058 |
| 968 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { | 1059 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { |
| 969 // ObjectLiteral :: | 1060 // ObjectLiteral :: |
| 970 // '{' ( | 1061 // '{' ( |
| 971 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 1062 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 972 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 1063 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 973 // )*[','] '}' | 1064 // )*[','] '}' |
| 974 | 1065 |
| 975 Expect(i::Token::LBRACE, CHECK_OK); | 1066 Expect(i::Token::LBRACE, CHECK_OK); |
| 976 while (peek() != i::Token::RBRACE) { | 1067 while (peek() != i::Token::RBRACE) { |
| 977 i::Token::Value next = peek(); | 1068 i::Token::Value next = peek(); |
| 978 switch (next) { | 1069 switch (next) { |
| 979 case i::Token::IDENTIFIER: | 1070 case i::Token::IDENTIFIER: |
| 980 case i::Token::FUTURE_RESERVED_WORD: { | 1071 case i::Token::FUTURE_RESERVED_WORD: { |
| 981 bool is_getter = false; | 1072 bool is_getter = false; |
| 982 bool is_setter = false; | 1073 bool is_setter = false; |
| 983 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 1074 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 984 if ((is_getter || is_setter) && peek() != i::Token::COLON) { | 1075 if ((is_getter || is_setter) && peek() != i::Token::COLON) { |
| 985 i::Token::Value name = Next(); | 1076 i::Token::Value name = Next(); |
| 986 bool is_keyword = i::Token::IsKeyword(name); | 1077 bool is_keyword = i::Token::IsKeyword(name); |
| 987 if (name != i::Token::IDENTIFIER && | 1078 if (name != i::Token::IDENTIFIER && |
| 988 name != i::Token::FUTURE_RESERVED_WORD && | 1079 name != i::Token::FUTURE_RESERVED_WORD && |
| 989 name != i::Token::NUMBER && | 1080 name != i::Token::NUMBER && |
| 990 name != i::Token::STRING && | 1081 name != i::Token::STRING && |
| 991 !is_keyword) { | 1082 !is_keyword) { |
| 992 *ok = false; | 1083 *ok = false; |
| 993 return kUnknownExpression; | 1084 return Expression::Default(); |
| 994 } | 1085 } |
| 995 if (!is_keyword) { | 1086 if (!is_keyword) { |
| 996 LogSymbol(); | 1087 LogSymbol(); |
| 997 } | 1088 } |
| 998 ParseFunctionLiteral(CHECK_OK); | 1089 ParseFunctionLiteral(CHECK_OK); |
| 999 if (peek() != i::Token::RBRACE) { | 1090 if (peek() != i::Token::RBRACE) { |
| 1000 Expect(i::Token::COMMA, CHECK_OK); | 1091 Expect(i::Token::COMMA, CHECK_OK); |
| 1001 } | 1092 } |
| 1002 continue; // restart the while | 1093 continue; // restart the while |
| 1003 } | 1094 } |
| 1004 break; | 1095 break; |
| 1005 } | 1096 } |
| 1006 case i::Token::STRING: | 1097 case i::Token::STRING: |
| 1007 Consume(next); | 1098 Consume(next); |
| 1008 GetStringSymbol(); | 1099 GetStringSymbol(); |
| 1009 break; | 1100 break; |
| 1010 case i::Token::NUMBER: | 1101 case i::Token::NUMBER: |
| 1011 Consume(next); | 1102 Consume(next); |
| 1012 break; | 1103 break; |
| 1013 default: | 1104 default: |
| 1014 if (i::Token::IsKeyword(next)) { | 1105 if (i::Token::IsKeyword(next)) { |
| 1015 Consume(next); | 1106 Consume(next); |
| 1016 } else { | 1107 } else { |
| 1017 // Unexpected token. | 1108 // Unexpected token. |
| 1018 *ok = false; | 1109 *ok = false; |
| 1019 return kUnknownExpression; | 1110 return Expression::Default(); |
| 1020 } | 1111 } |
| 1021 } | 1112 } |
| 1022 | 1113 |
| 1023 Expect(i::Token::COLON, CHECK_OK); | 1114 Expect(i::Token::COLON, CHECK_OK); |
| 1024 ParseAssignmentExpression(true, CHECK_OK); | 1115 ParseAssignmentExpression(true, CHECK_OK); |
| 1025 | 1116 |
| 1026 // TODO(1240767): Consider allowing trailing comma. | 1117 // TODO(1240767): Consider allowing trailing comma. |
| 1027 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK); | 1118 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK); |
| 1028 } | 1119 } |
| 1029 Expect(i::Token::RBRACE, CHECK_OK); | 1120 Expect(i::Token::RBRACE, CHECK_OK); |
| 1030 | 1121 |
| 1031 scope_->NextMaterializedLiteralIndex(); | 1122 scope_->NextMaterializedLiteralIndex(); |
| 1032 return kUnknownExpression; | 1123 return Expression::Default(); |
| 1033 } | 1124 } |
| 1034 | 1125 |
| 1035 | 1126 |
| 1036 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, | 1127 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, |
| 1037 bool* ok) { | 1128 bool* ok) { |
| 1038 if (!scanner_->ScanRegExpPattern(seen_equal)) { | 1129 if (!scanner_->ScanRegExpPattern(seen_equal)) { |
| 1039 Next(); | 1130 Next(); |
| 1040 i::JavaScriptScanner::Location location = scanner_->location(); | 1131 i::JavaScriptScanner::Location location = scanner_->location(); |
| 1041 ReportMessageAt(location.beg_pos, location.end_pos, | 1132 ReportMessageAt(location.beg_pos, location.end_pos, |
| 1042 "unterminated_regexp", NULL); | 1133 "unterminated_regexp", NULL); |
| 1043 *ok = false; | 1134 *ok = false; |
| 1044 return kUnknownExpression; | 1135 return Expression::Default(); |
| 1045 } | 1136 } |
| 1046 | 1137 |
| 1047 scope_->NextMaterializedLiteralIndex(); | 1138 scope_->NextMaterializedLiteralIndex(); |
| 1048 | 1139 |
| 1049 if (!scanner_->ScanRegExpFlags()) { | 1140 if (!scanner_->ScanRegExpFlags()) { |
| 1050 Next(); | 1141 Next(); |
| 1051 i::JavaScriptScanner::Location location = scanner_->location(); | 1142 i::JavaScriptScanner::Location location = scanner_->location(); |
| 1052 ReportMessageAt(location.beg_pos, location.end_pos, | 1143 ReportMessageAt(location.beg_pos, location.end_pos, |
| 1053 "invalid_regexp_flags", NULL); | 1144 "invalid_regexp_flags", NULL); |
| 1054 *ok = false; | 1145 *ok = false; |
| 1055 return kUnknownExpression; | 1146 return Expression::Default(); |
| 1056 } | 1147 } |
| 1057 Next(); | 1148 Next(); |
| 1058 return kUnknownExpression; | 1149 return Expression::Default(); |
| 1059 } | 1150 } |
| 1060 | 1151 |
| 1061 | 1152 |
| 1062 PreParser::Arguments PreParser::ParseArguments(bool* ok) { | 1153 PreParser::Arguments PreParser::ParseArguments(bool* ok) { |
| 1063 // Arguments :: | 1154 // Arguments :: |
| 1064 // '(' (AssignmentExpression)*[','] ')' | 1155 // '(' (AssignmentExpression)*[','] ')' |
| 1065 | 1156 |
| 1066 Expect(i::Token::LPAREN, CHECK_OK); | 1157 Expect(i::Token::LPAREN, ok); |
| 1158 if (!*ok) return -1; |
| 1067 bool done = (peek() == i::Token::RPAREN); | 1159 bool done = (peek() == i::Token::RPAREN); |
| 1068 int argc = 0; | 1160 int argc = 0; |
| 1069 while (!done) { | 1161 while (!done) { |
| 1070 ParseAssignmentExpression(true, CHECK_OK); | 1162 ParseAssignmentExpression(true, ok); |
| 1163 if (!*ok) return -1; |
| 1071 argc++; | 1164 argc++; |
| 1072 done = (peek() == i::Token::RPAREN); | 1165 done = (peek() == i::Token::RPAREN); |
| 1073 if (!done) Expect(i::Token::COMMA, CHECK_OK); | 1166 if (!done) { |
| 1167 Expect(i::Token::COMMA, ok); |
| 1168 if (!*ok) return -1; |
| 1169 } |
| 1074 } | 1170 } |
| 1075 Expect(i::Token::RPAREN, CHECK_OK); | 1171 Expect(i::Token::RPAREN, ok); |
| 1076 return argc; | 1172 return argc; |
| 1077 } | 1173 } |
| 1078 | 1174 |
| 1079 | 1175 |
| 1080 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { | 1176 PreParser::Expression PreParser::ParseFunctionLiteral(bool* ok) { |
| 1081 // Function :: | 1177 // Function :: |
| 1082 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 1178 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 1083 | 1179 |
| 1084 // Parse function body. | 1180 // Parse function body. |
| 1085 ScopeType outer_scope_type = scope_->type(); | 1181 ScopeType outer_scope_type = scope_->type(); |
| 1086 bool inside_with = scope_->IsInsideWith(); | 1182 bool inside_with = scope_->IsInsideWith(); |
| 1087 Scope function_scope(&scope_, kFunctionScope); | 1183 Scope function_scope(&scope_, kFunctionScope); |
| 1088 // FormalParameterList :: | 1184 // FormalParameterList :: |
| 1089 // '(' (Identifier)*[','] ')' | 1185 // '(' (Identifier)*[','] ')' |
| 1090 Expect(i::Token::LPAREN, CHECK_OK); | 1186 Expect(i::Token::LPAREN, CHECK_OK); |
| 1091 int start_position = scanner_->location().beg_pos; | 1187 int start_position = scanner_->location().beg_pos; |
| 1092 bool done = (peek() == i::Token::RPAREN); | 1188 bool done = (peek() == i::Token::RPAREN); |
| 1093 while (!done) { | 1189 while (!done) { |
| 1094 ParseIdentifier(CHECK_OK); | 1190 Identifier id = ParseIdentifier(CHECK_OK); |
| 1191 if (!id.IsValidStrictVariable()) { |
| 1192 StrictModeIdentifierViolation(scanner_->location(), |
| 1193 "strict_param_name", |
| 1194 id, |
| 1195 CHECK_OK); |
| 1196 } |
| 1095 done = (peek() == i::Token::RPAREN); | 1197 done = (peek() == i::Token::RPAREN); |
| 1096 if (!done) { | 1198 if (!done) { |
| 1097 Expect(i::Token::COMMA, CHECK_OK); | 1199 Expect(i::Token::COMMA, CHECK_OK); |
| 1098 } | 1200 } |
| 1099 } | 1201 } |
| 1100 Expect(i::Token::RPAREN, CHECK_OK); | 1202 Expect(i::Token::RPAREN, CHECK_OK); |
| 1101 | 1203 |
| 1102 Expect(i::Token::LBRACE, CHECK_OK); | 1204 Expect(i::Token::LBRACE, CHECK_OK); |
| 1103 int function_block_pos = scanner_->location().beg_pos; | 1205 int function_block_pos = scanner_->location().beg_pos; |
| 1104 | 1206 |
| 1105 // Determine if the function will be lazily compiled. | 1207 // Determine if the function will be lazily compiled. |
| 1106 // Currently only happens to top-level functions. | 1208 // Currently only happens to top-level functions. |
| 1107 // Optimistically assume that all top-level functions are lazily compiled. | 1209 // Optimistically assume that all top-level functions are lazily compiled. |
| 1108 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && | 1210 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && |
| 1109 !inside_with && allow_lazy_ && | 1211 !inside_with && allow_lazy_ && |
| 1110 !parenthesized_function_); | 1212 !parenthesized_function_); |
| 1111 parenthesized_function_ = false; | 1213 parenthesized_function_ = false; |
| 1112 | 1214 |
| 1113 if (is_lazily_compiled) { | 1215 if (is_lazily_compiled) { |
| 1114 log_->PauseRecording(); | 1216 log_->PauseRecording(); |
| 1115 ParseSourceElements(i::Token::RBRACE, ok); | 1217 ParseSourceElements(i::Token::RBRACE, ok); |
| 1116 log_->ResumeRecording(); | 1218 log_->ResumeRecording(); |
| 1117 if (!*ok) return kUnknownExpression; | 1219 if (!*ok) Expression::Default(); |
| 1118 | 1220 |
| 1119 Expect(i::Token::RBRACE, CHECK_OK); | 1221 Expect(i::Token::RBRACE, CHECK_OK); |
| 1120 | 1222 |
| 1121 // Position right after terminal '}'. | 1223 // Position right after terminal '}'. |
| 1122 int end_pos = scanner_->location().end_pos; | 1224 int end_pos = scanner_->location().end_pos; |
| 1123 log_->LogFunction(function_block_pos, end_pos, | 1225 log_->LogFunction(function_block_pos, end_pos, |
| 1124 function_scope.materialized_literal_count(), | 1226 function_scope.materialized_literal_count(), |
| 1125 function_scope.expected_properties()); | 1227 function_scope.expected_properties()); |
| 1126 } else { | 1228 } else { |
| 1127 ParseSourceElements(i::Token::RBRACE, CHECK_OK); | 1229 ParseSourceElements(i::Token::RBRACE, CHECK_OK); |
| 1128 Expect(i::Token::RBRACE, CHECK_OK); | 1230 Expect(i::Token::RBRACE, CHECK_OK); |
| 1129 } | 1231 } |
| 1130 | 1232 |
| 1131 if (scope_->is_strict()) { | 1233 if (strict_mode()) { |
| 1132 int end_position = scanner_->location().end_pos; | 1234 int end_position = scanner_->location().end_pos; |
| 1133 CheckOctalLiteral(start_position, end_position, CHECK_OK); | 1235 CheckOctalLiteral(start_position, end_position, CHECK_OK); |
| 1236 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); |
| 1237 return Expression::StrictFunction(); |
| 1134 } | 1238 } |
| 1135 | 1239 |
| 1136 return kUnknownExpression; | 1240 return Expression::Default(); |
| 1137 } | 1241 } |
| 1138 | 1242 |
| 1139 | 1243 |
| 1140 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1244 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
| 1141 // CallRuntime :: | 1245 // CallRuntime :: |
| 1142 // '%' Identifier Arguments | 1246 // '%' Identifier Arguments |
| 1143 | 1247 |
| 1144 Expect(i::Token::MOD, CHECK_OK); | 1248 Expect(i::Token::MOD, CHECK_OK); |
| 1145 ParseIdentifier(CHECK_OK); | 1249 ParseIdentifier(CHECK_OK); |
| 1146 ParseArguments(CHECK_OK); | 1250 ParseArguments(ok); |
| 1147 | 1251 |
| 1148 return kUnknownExpression; | 1252 return Expression::Default(); |
| 1149 } | 1253 } |
| 1150 | 1254 |
| 1255 #undef CHECK_OK |
| 1256 |
| 1151 | 1257 |
| 1152 void PreParser::ExpectSemicolon(bool* ok) { | 1258 void PreParser::ExpectSemicolon(bool* ok) { |
| 1153 // Check for automatic semicolon insertion according to | 1259 // Check for automatic semicolon insertion according to |
| 1154 // the rules given in ECMA-262, section 7.9, page 21. | 1260 // the rules given in ECMA-262, section 7.9, page 21. |
| 1155 i::Token::Value tok = peek(); | 1261 i::Token::Value tok = peek(); |
| 1156 if (tok == i::Token::SEMICOLON) { | 1262 if (tok == i::Token::SEMICOLON) { |
| 1157 Next(); | 1263 Next(); |
| 1158 return; | 1264 return; |
| 1159 } | 1265 } |
| 1160 if (scanner_->has_line_terminator_before_next() || | 1266 if (scanner_->has_line_terminator_before_next() || |
| 1161 tok == i::Token::RBRACE || | 1267 tok == i::Token::RBRACE || |
| 1162 tok == i::Token::EOS) { | 1268 tok == i::Token::EOS) { |
| 1163 return; | 1269 return; |
| 1164 } | 1270 } |
| 1165 Expect(i::Token::SEMICOLON, ok); | 1271 Expect(i::Token::SEMICOLON, ok); |
| 1166 } | 1272 } |
| 1167 | 1273 |
| 1168 | 1274 |
| 1169 void PreParser::LogSymbol() { | 1275 void PreParser::LogSymbol() { |
| 1170 int identifier_pos = scanner_->location().beg_pos; | 1276 int identifier_pos = scanner_->location().beg_pos; |
| 1171 if (scanner_->is_literal_ascii()) { | 1277 if (scanner_->is_literal_ascii()) { |
| 1172 log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string()); | 1278 log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string()); |
| 1173 } else { | 1279 } else { |
| 1174 log_->LogUC16Symbol(identifier_pos, scanner_->literal_uc16_string()); | 1280 log_->LogUC16Symbol(identifier_pos, scanner_->literal_uc16_string()); |
| 1175 } | 1281 } |
| 1176 } | 1282 } |
| 1177 | 1283 |
| 1178 | 1284 |
| 1179 PreParser::Identifier PreParser::GetIdentifierSymbol() { | |
| 1180 LogSymbol(); | |
| 1181 return kUnknownIdentifier; | |
| 1182 } | |
| 1183 | |
| 1184 | |
| 1185 PreParser::Expression PreParser::GetStringSymbol() { | 1285 PreParser::Expression PreParser::GetStringSymbol() { |
| 1186 const int kUseStrictLength = 10; | 1286 const int kUseStrictLength = 10; |
| 1187 const char* kUseStrictChars = "use strict"; | 1287 const char* kUseStrictChars = "use strict"; |
| 1188 LogSymbol(); | 1288 LogSymbol(); |
| 1189 if (scanner_->is_literal_ascii() && | 1289 if (scanner_->is_literal_ascii() && |
| 1190 scanner_->literal_length() == kUseStrictLength && | 1290 scanner_->literal_length() == kUseStrictLength && |
| 1191 !scanner_->literal_contains_escapes() && | 1291 !scanner_->literal_contains_escapes() && |
| 1192 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, | 1292 !strncmp(scanner_->literal_ascii_string().start(), kUseStrictChars, |
| 1193 kUseStrictLength)) { | 1293 kUseStrictLength)) { |
| 1194 return kUseStrictString; | 1294 return Expression::UseStrictStringLiteral(); |
| 1195 } | 1295 } |
| 1196 return kStringLiteralExpression; | 1296 return Expression::StringLiteral(); |
| 1297 } |
| 1298 |
| 1299 |
| 1300 PreParser::Identifier PreParser::GetIdentifierSymbol() { |
| 1301 LogSymbol(); |
| 1302 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) { |
| 1303 return Identifier::FutureReserved(); |
| 1304 } |
| 1305 if (scanner_->is_literal_ascii()) { |
| 1306 // Detect strict-mode poison words. |
| 1307 if (scanner_->literal_length() == 4 && |
| 1308 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) { |
| 1309 return Identifier::Eval(); |
| 1310 } |
| 1311 if (scanner_->literal_length() == 9 && |
| 1312 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) { |
| 1313 return Identifier::Arguments(); |
| 1314 } |
| 1315 } |
| 1316 return Identifier::Default(); |
| 1197 } | 1317 } |
| 1198 | 1318 |
| 1199 | 1319 |
| 1200 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { | 1320 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { |
| 1201 if (!Check(i::Token::FUTURE_RESERVED_WORD)) { | 1321 if (!Check(i::Token::FUTURE_RESERVED_WORD)) { |
| 1202 Expect(i::Token::IDENTIFIER, ok); | 1322 Expect(i::Token::IDENTIFIER, ok); |
| 1323 if (!*ok) return Identifier::Default(); |
| 1203 } | 1324 } |
| 1204 if (!*ok) return kUnknownIdentifier; | |
| 1205 return GetIdentifierSymbol(); | 1325 return GetIdentifierSymbol(); |
| 1206 } | 1326 } |
| 1207 | 1327 |
| 1208 | 1328 |
| 1329 void PreParser::SetStrictModeViolation(i::Scanner::Location location, |
| 1330 const char* type, |
| 1331 bool* ok) { |
| 1332 if (strict_mode()) { |
| 1333 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); |
| 1334 *ok = false; |
| 1335 return; |
| 1336 } |
| 1337 // Delay report in case this later turns out to be strict code |
| 1338 // (i.e., for function names and parameters prior to a "use strict" |
| 1339 // directive). |
| 1340 strict_mode_violation_location_ = location; |
| 1341 strict_mode_violation_type_ = type; |
| 1342 } |
| 1343 |
| 1344 |
| 1345 void PreParser::CheckDelayedStrictModeViolation(int beg_pos, |
| 1346 int end_pos, |
| 1347 bool* ok) { |
| 1348 i::Scanner::Location location = strict_mode_violation_location_; |
| 1349 if (location.IsValid() && |
| 1350 location.beg_pos > beg_pos && location.end_pos < end_pos) { |
| 1351 ReportMessageAt(location.beg_pos, location.end_pos, |
| 1352 strict_mode_violation_type_, NULL); |
| 1353 *ok = false; |
| 1354 } |
| 1355 strict_mode_violation_location_ = i::Scanner::Location::invalid(); |
| 1356 } |
| 1357 |
| 1358 |
| 1359 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location, |
| 1360 const char* eval_args_type, |
| 1361 Identifier identifier, |
| 1362 bool* ok) { |
| 1363 const char* type = eval_args_type; |
| 1364 if (identifier.IsFutureReserved()) { |
| 1365 type = "strict_reserved_word"; |
| 1366 } |
| 1367 if (strict_mode()) { |
| 1368 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); |
| 1369 *ok = false; |
| 1370 return; |
| 1371 } |
| 1372 strict_mode_violation_location_ = location; |
| 1373 strict_mode_violation_type_ = type; |
| 1374 } |
| 1375 |
| 1376 |
| 1209 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { | 1377 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { |
| 1210 i::Token::Value next = Next(); | 1378 i::Token::Value next = Next(); |
| 1211 if (i::Token::IsKeyword(next)) { | 1379 if (i::Token::IsKeyword(next)) { |
| 1212 int pos = scanner_->location().beg_pos; | 1380 int pos = scanner_->location().beg_pos; |
| 1213 const char* keyword = i::Token::String(next); | 1381 const char* keyword = i::Token::String(next); |
| 1214 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, | 1382 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, |
| 1215 i::StrLength(keyword))); | 1383 i::StrLength(keyword))); |
| 1216 return kUnknownExpression; | 1384 return Identifier::Default(); |
| 1217 } | 1385 } |
| 1218 if (next == i::Token::IDENTIFIER || | 1386 if (next == i::Token::IDENTIFIER || |
| 1219 next == i::Token::FUTURE_RESERVED_WORD) { | 1387 next == i::Token::FUTURE_RESERVED_WORD) { |
| 1220 return GetIdentifierSymbol(); | 1388 return GetIdentifierSymbol(); |
| 1221 } | 1389 } |
| 1222 *ok = false; | 1390 *ok = false; |
| 1223 return kUnknownIdentifier; | 1391 return Identifier::Default(); |
| 1224 } | 1392 } |
| 1225 | 1393 |
| 1394 #undef CHECK_OK |
| 1395 |
| 1226 | 1396 |
| 1227 // This function reads an identifier and determines whether or not it | 1397 // This function reads an identifier and determines whether or not it |
| 1228 // is 'get' or 'set'. | 1398 // is 'get' or 'set'. |
| 1229 PreParser::Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get, | 1399 PreParser::Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get, |
| 1230 bool* is_set, | 1400 bool* is_set, |
| 1231 bool* ok) { | 1401 bool* ok) { |
| 1232 PreParser::Identifier result = ParseIdentifier(CHECK_OK); | 1402 Identifier result = ParseIdentifier(ok); |
| 1233 if (scanner_->is_literal_ascii() && scanner_->literal_length() == 3) { | 1403 if (!*ok) return Identifier::Default(); |
| 1404 if (scanner_->is_literal_ascii() && |
| 1405 scanner_->literal_length() == 3) { |
| 1234 const char* token = scanner_->literal_ascii_string().start(); | 1406 const char* token = scanner_->literal_ascii_string().start(); |
| 1235 *is_get = strncmp(token, "get", 3) == 0; | 1407 *is_get = strncmp(token, "get", 3) == 0; |
| 1236 *is_set = !*is_get && strncmp(token, "set", 3) == 0; | 1408 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
| 1237 } | 1409 } |
| 1238 return result; | 1410 return result; |
| 1239 } | 1411 } |
| 1240 | 1412 |
| 1241 bool PreParser::peek_any_identifier() { | 1413 bool PreParser::peek_any_identifier() { |
| 1242 i::Token::Value next = peek(); | 1414 i::Token::Value next = peek(); |
| 1243 return next == i::Token::IDENTIFIER || | 1415 return next == i::Token::IDENTIFIER || |
| 1244 next == i::Token::FUTURE_RESERVED_WORD; | 1416 next == i::Token::FUTURE_RESERVED_WORD; |
| 1245 } | 1417 } |
| 1246 | |
| 1247 #undef CHECK_OK | |
| 1248 } } // v8::preparser | 1418 } } // v8::preparser |
| OLD | NEW |