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

Side by Side Diff: src/preparser.cc

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/preparser.h ('k') | src/preparser-api.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 20 matching lines...) Expand all
31 #include "checks.h" 31 #include "checks.h"
32 #include "allocation.h" 32 #include "allocation.h"
33 #include "utils.h" 33 #include "utils.h"
34 #include "list.h" 34 #include "list.h"
35 35
36 #include "scanner-base.h" 36 #include "scanner-base.h"
37 #include "preparse-data-format.h" 37 #include "preparse-data-format.h"
38 #include "preparse-data.h" 38 #include "preparse-data.h"
39 #include "preparser.h" 39 #include "preparser.h"
40 40
41 #include "conversions-inl.h"
42
41 namespace v8 { 43 namespace v8 {
42 namespace preparser { 44 namespace preparser {
43 45
44 // Preparsing checks a JavaScript program and emits preparse-data that helps 46 // Preparsing checks a JavaScript program and emits preparse-data that helps
45 // a later parsing to be faster. 47 // a later parsing to be faster.
46 // See preparser-data.h for the data. 48 // See preparser-data.h for the data.
47 49
48 // The PreParser checks that the syntax follows the grammar for JavaScript, 50 // The PreParser checks that the syntax follows the grammar for JavaScript,
49 // and collects some information about the program along the way. 51 // and collects some information about the program along the way.
50 // The grammar check is only performed in order to understand the program 52 // The grammar check is only performed in order to understand the program
(...skipping 19 matching lines...) Expand all
70 case i::Token::EOS: 72 case i::Token::EOS:
71 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 73 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
72 "unexpected_eos", NULL); 74 "unexpected_eos", NULL);
73 case i::Token::NUMBER: 75 case i::Token::NUMBER:
74 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 76 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
75 "unexpected_token_number", NULL); 77 "unexpected_token_number", NULL);
76 case i::Token::STRING: 78 case i::Token::STRING:
77 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 79 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
78 "unexpected_token_string", NULL); 80 "unexpected_token_string", NULL);
79 case i::Token::IDENTIFIER: 81 case i::Token::IDENTIFIER:
82 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
83 "unexpected_token_identifier", NULL);
80 case i::Token::FUTURE_RESERVED_WORD: 84 case i::Token::FUTURE_RESERVED_WORD:
81 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 85 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
82 "unexpected_token_identifier", NULL); 86 "unexpected_reserved", NULL);
87 case i::Token::FUTURE_STRICT_RESERVED_WORD:
88 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
89 "unexpected_strict_reserved", NULL);
83 default: 90 default:
84 const char* name = i::Token::String(token); 91 const char* name = i::Token::String(token);
85 ReportMessageAt(source_location.beg_pos, source_location.end_pos, 92 ReportMessageAt(source_location.beg_pos, source_location.end_pos,
86 "unexpected_token", name); 93 "unexpected_token", name);
87 } 94 }
88 } 95 }
89 96
90 97
91 // Checks whether octal literal last seen is between beg_pos and end_pos. 98 // Checks whether octal literal last seen is between beg_pos and end_pos.
92 // If so, reports an error. 99 // If so, reports an error.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 209
203 case i::Token::THROW: 210 case i::Token::THROW:
204 return ParseThrowStatement(ok); 211 return ParseThrowStatement(ok);
205 212
206 case i::Token::TRY: 213 case i::Token::TRY:
207 return ParseTryStatement(ok); 214 return ParseTryStatement(ok);
208 215
209 case i::Token::FUNCTION: 216 case i::Token::FUNCTION:
210 return ParseFunctionDeclaration(ok); 217 return ParseFunctionDeclaration(ok);
211 218
212 case i::Token::NATIVE:
213 return ParseNativeDeclaration(ok);
214
215 case i::Token::DEBUGGER: 219 case i::Token::DEBUGGER:
216 return ParseDebuggerStatement(ok); 220 return ParseDebuggerStatement(ok);
217 221
218 default: 222 default:
219 return ParseExpressionOrLabelledStatement(ok); 223 return ParseExpressionOrLabelledStatement(ok);
220 } 224 }
221 } 225 }
222 226
223 227
224 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 228 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
225 // FunctionDeclaration :: 229 // FunctionDeclaration ::
226 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 230 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
227 Expect(i::Token::FUNCTION, CHECK_OK); 231 Expect(i::Token::FUNCTION, CHECK_OK);
228 232
229 Identifier identifier = ParseIdentifier(CHECK_OK); 233 Identifier identifier = ParseIdentifier(CHECK_OK);
230 i::Scanner::Location location = scanner_->location(); 234 i::Scanner::Location location = scanner_->location();
231 235
232 Expression function_value = ParseFunctionLiteral(CHECK_OK); 236 Expression function_value = ParseFunctionLiteral(CHECK_OK);
233 237
234 if (function_value.IsStrictFunction() && 238 if (function_value.IsStrictFunction() &&
235 !identifier.IsValidStrictVariable()) { 239 !identifier.IsValidStrictVariable()) {
236 // Strict mode violation, using either reserved word or eval/arguments 240 // Strict mode violation, using either reserved word or eval/arguments
237 // as name of strict function. 241 // as name of strict function.
238 const char* type = "strict_function_name"; 242 const char* type = "strict_function_name";
239 if (identifier.IsFutureReserved()) { 243 if (identifier.IsFutureStrictReserved()) {
240 type = "strict_reserved_word"; 244 type = "strict_reserved_word";
241 } 245 }
242 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); 246 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
243 *ok = false; 247 *ok = false;
244 } 248 }
245 return Statement::FunctionDeclaration(); 249 return Statement::FunctionDeclaration();
246 } 250 }
247 251
248 252
249 // Language extension which is only enabled for source files loaded
250 // through the API's extension mechanism. A native function
251 // declaration is resolved by looking up the function through a
252 // callback provided by the extension.
253 PreParser::Statement PreParser::ParseNativeDeclaration(bool* ok) {
254 Expect(i::Token::NATIVE, CHECK_OK);
255 Expect(i::Token::FUNCTION, CHECK_OK);
256 ParseIdentifier(CHECK_OK);
257 Expect(i::Token::LPAREN, CHECK_OK);
258 bool done = (peek() == i::Token::RPAREN);
259 while (!done) {
260 ParseIdentifier(CHECK_OK);
261 done = (peek() == i::Token::RPAREN);
262 if (!done) {
263 Expect(i::Token::COMMA, CHECK_OK);
264 }
265 }
266 Expect(i::Token::RPAREN, CHECK_OK);
267 Expect(i::Token::SEMICOLON, CHECK_OK);
268 return Statement::Default();
269 }
270
271
272 PreParser::Statement PreParser::ParseBlock(bool* ok) { 253 PreParser::Statement PreParser::ParseBlock(bool* ok) {
273 // Block :: 254 // Block ::
274 // '{' Statement* '}' 255 // '{' Statement* '}'
275 256
276 // Note that a Block does not introduce a new execution scope! 257 // Note that a Block does not introduce a new execution scope!
277 // (ECMA-262, 3rd, 12.2) 258 // (ECMA-262, 3rd, 12.2)
278 // 259 //
279 Expect(i::Token::LBRACE, CHECK_OK); 260 Expect(i::Token::LBRACE, CHECK_OK);
280 while (peek() != i::Token::RBRACE) { 261 while (peek() != i::Token::RBRACE) {
281 i::Scanner::Location start_location = scanner_->peek_location(); 262 i::Scanner::Location start_location = scanner_->peek_location();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 return Statement::Default(); 336 return Statement::Default();
356 } 337 }
357 338
358 339
359 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 340 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
360 // ExpressionStatement | LabelledStatement :: 341 // ExpressionStatement | LabelledStatement ::
361 // Expression ';' 342 // Expression ';'
362 // Identifier ':' Statement 343 // Identifier ':' Statement
363 344
364 Expression expr = ParseExpression(true, CHECK_OK); 345 Expression expr = ParseExpression(true, CHECK_OK);
365 if (peek() == i::Token::COLON && expr.IsRawIdentifier()) { 346 if (expr.IsRawIdentifier()) {
366 if (!strict_mode() || !expr.AsIdentifier().IsFutureReserved()) { 347 if (peek() == i::Token::COLON &&
348 (!strict_mode() || !expr.AsIdentifier().IsFutureReserved())) {
367 Consume(i::Token::COLON); 349 Consume(i::Token::COLON);
368 i::Scanner::Location start_location = scanner_->peek_location(); 350 i::Scanner::Location start_location = scanner_->peek_location();
369 Statement statement = ParseStatement(CHECK_OK); 351 Statement statement = ParseStatement(CHECK_OK);
370 if (strict_mode() && statement.IsFunctionDeclaration()) { 352 if (strict_mode() && statement.IsFunctionDeclaration()) {
371 i::Scanner::Location end_location = scanner_->location(); 353 i::Scanner::Location end_location = scanner_->location();
372 ReportMessageAt(start_location.beg_pos, end_location.end_pos, 354 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
373 "strict_function", NULL); 355 "strict_function", NULL);
374 *ok = false; 356 *ok = false;
375 } 357 }
376 return Statement::Default(); 358 return Statement::Default();
377 } 359 }
360 // Preparsing is disabled for extensions (because the extension details
361 // aren't passed to lazily compiled functions), so we don't
362 // accept "native function" in the preparser.
378 } 363 }
379 // Parsed expression statement. 364 // Parsed expression statement.
380 ExpectSemicolon(CHECK_OK); 365 ExpectSemicolon(CHECK_OK);
381 return Statement::ExpressionStatement(expr); 366 return Statement::ExpressionStatement(expr);
382 } 367 }
383 368
384 369
385 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { 370 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
386 // IfStatement :: 371 // IfStatement ::
387 // 'if' '(' Expression ')' Statement ('else' Statement)? 372 // 'if' '(' Expression ')' Statement ('else' Statement)?
(...skipping 10 matching lines...) Expand all
398 return Statement::Default(); 383 return Statement::Default();
399 } 384 }
400 385
401 386
402 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 387 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
403 // ContinueStatement :: 388 // ContinueStatement ::
404 // 'continue' [no line terminator] Identifier? ';' 389 // 'continue' [no line terminator] Identifier? ';'
405 390
406 Expect(i::Token::CONTINUE, CHECK_OK); 391 Expect(i::Token::CONTINUE, CHECK_OK);
407 i::Token::Value tok = peek(); 392 i::Token::Value tok = peek();
408 if (!scanner_->has_line_terminator_before_next() && 393 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
409 tok != i::Token::SEMICOLON && 394 tok != i::Token::SEMICOLON &&
410 tok != i::Token::RBRACE && 395 tok != i::Token::RBRACE &&
411 tok != i::Token::EOS) { 396 tok != i::Token::EOS) {
412 ParseIdentifier(CHECK_OK); 397 ParseIdentifier(CHECK_OK);
413 } 398 }
414 ExpectSemicolon(CHECK_OK); 399 ExpectSemicolon(CHECK_OK);
415 return Statement::Default(); 400 return Statement::Default();
416 } 401 }
417 402
418 403
419 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 404 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
420 // BreakStatement :: 405 // BreakStatement ::
421 // 'break' [no line terminator] Identifier? ';' 406 // 'break' [no line terminator] Identifier? ';'
422 407
423 Expect(i::Token::BREAK, CHECK_OK); 408 Expect(i::Token::BREAK, CHECK_OK);
424 i::Token::Value tok = peek(); 409 i::Token::Value tok = peek();
425 if (!scanner_->has_line_terminator_before_next() && 410 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
426 tok != i::Token::SEMICOLON && 411 tok != i::Token::SEMICOLON &&
427 tok != i::Token::RBRACE && 412 tok != i::Token::RBRACE &&
428 tok != i::Token::EOS) { 413 tok != i::Token::EOS) {
429 ParseIdentifier(CHECK_OK); 414 ParseIdentifier(CHECK_OK);
430 } 415 }
431 ExpectSemicolon(CHECK_OK); 416 ExpectSemicolon(CHECK_OK);
432 return Statement::Default(); 417 return Statement::Default();
433 } 418 }
434 419
435 420
436 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { 421 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
437 // ReturnStatement :: 422 // ReturnStatement ::
438 // 'return' [no line terminator] Expression? ';' 423 // 'return' [no line terminator] Expression? ';'
439 424
440 // Consume the return token. It is necessary to do the before 425 // Consume the return token. It is necessary to do the before
441 // reporting any errors on it, because of the way errors are 426 // reporting any errors on it, because of the way errors are
442 // reported (underlining). 427 // reported (underlining).
443 Expect(i::Token::RETURN, CHECK_OK); 428 Expect(i::Token::RETURN, CHECK_OK);
444 429
445 // An ECMAScript program is considered syntactically incorrect if it 430 // An ECMAScript program is considered syntactically incorrect if it
446 // contains a return statement that is not within the body of a 431 // contains a return statement that is not within the body of a
447 // function. See ECMA-262, section 12.9, page 67. 432 // function. See ECMA-262, section 12.9, page 67.
448 // This is not handled during preparsing. 433 // This is not handled during preparsing.
449 434
450 i::Token::Value tok = peek(); 435 i::Token::Value tok = peek();
451 if (!scanner_->has_line_terminator_before_next() && 436 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
452 tok != i::Token::SEMICOLON && 437 tok != i::Token::SEMICOLON &&
453 tok != i::Token::RBRACE && 438 tok != i::Token::RBRACE &&
454 tok != i::Token::EOS) { 439 tok != i::Token::EOS) {
455 ParseExpression(true, CHECK_OK); 440 ParseExpression(true, CHECK_OK);
456 } 441 }
457 ExpectSemicolon(CHECK_OK); 442 ExpectSemicolon(CHECK_OK);
458 return Statement::Default(); 443 return Statement::Default();
459 } 444 }
460 445
461 446
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 ParseStatement(ok); 577 ParseStatement(ok);
593 return Statement::Default(); 578 return Statement::Default();
594 } 579 }
595 580
596 581
597 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 582 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
598 // ThrowStatement :: 583 // ThrowStatement ::
599 // 'throw' [no line terminator] Expression ';' 584 // 'throw' [no line terminator] Expression ';'
600 585
601 Expect(i::Token::THROW, CHECK_OK); 586 Expect(i::Token::THROW, CHECK_OK);
602 if (scanner_->has_line_terminator_before_next()) { 587 if (scanner_->HasAnyLineTerminatorBeforeNext()) {
603 i::JavaScriptScanner::Location pos = scanner_->location(); 588 i::JavaScriptScanner::Location pos = scanner_->location();
604 ReportMessageAt(pos.beg_pos, pos.end_pos, 589 ReportMessageAt(pos.beg_pos, pos.end_pos,
605 "newline_after_throw", NULL); 590 "newline_after_throw", NULL);
606 *ok = false; 591 *ok = false;
607 return Statement::Default(); 592 return Statement::Default();
608 } 593 }
609 ParseExpression(true, CHECK_OK); 594 ParseExpression(true, CHECK_OK);
610 ExpectSemicolon(ok); 595 ExpectSemicolon(ok);
611 return Statement::Default(); 596 return Statement::Default();
612 } 597 }
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 } 800 }
816 } 801 }
817 802
818 803
819 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 804 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
820 // PostfixExpression :: 805 // PostfixExpression ::
821 // LeftHandSideExpression ('++' | '--')? 806 // LeftHandSideExpression ('++' | '--')?
822 807
823 i::Scanner::Location before = scanner_->peek_location(); 808 i::Scanner::Location before = scanner_->peek_location();
824 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 809 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
825 if (!scanner_->has_line_terminator_before_next() && 810 if (!scanner_->HasAnyLineTerminatorBeforeNext() &&
826 i::Token::IsCountOp(peek())) { 811 i::Token::IsCountOp(peek())) {
827 if (strict_mode() && expression.IsIdentifier() && 812 if (strict_mode() && expression.IsIdentifier() &&
828 expression.AsIdentifier().IsEvalOrArguments()) { 813 expression.AsIdentifier().IsEvalOrArguments()) {
829 i::Scanner::Location after = scanner_->location(); 814 i::Scanner::Location after = scanner_->location();
830 ReportMessageAt(before.beg_pos, after.end_pos, 815 ReportMessageAt(before.beg_pos, after.end_pos,
831 "strict_lhs_postfix", NULL); 816 "strict_lhs_postfix", NULL);
832 *ok = false; 817 *ok = false;
833 return Expression::Default(); 818 return Expression::Default();
834 } 819 }
835 Next(); 820 Next();
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 // '(' Expression ')' 979 // '(' Expression ')'
995 980
996 Expression result = Expression::Default(); 981 Expression result = Expression::Default();
997 switch (peek()) { 982 switch (peek()) {
998 case i::Token::THIS: { 983 case i::Token::THIS: {
999 Next(); 984 Next();
1000 result = Expression::This(); 985 result = Expression::This();
1001 break; 986 break;
1002 } 987 }
1003 988
1004 case i::Token::FUTURE_RESERVED_WORD: 989 case i::Token::FUTURE_RESERVED_WORD: {
990 Next();
991 i::Scanner::Location location = scanner_->location();
992 ReportMessageAt(location.beg_pos, location.end_pos,
993 "reserved_word", NULL);
994 *ok = false;
995 return Expression::Default();
996 }
997
998 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1005 if (strict_mode()) { 999 if (strict_mode()) {
1006 Next(); 1000 Next();
1007 i::Scanner::Location location = scanner_->location(); 1001 i::Scanner::Location location = scanner_->location();
1008 ReportMessageAt(location.beg_pos, location.end_pos, 1002 ReportMessageAt(location.beg_pos, location.end_pos,
1009 "strict_reserved_word", NULL); 1003 "strict_reserved_word", NULL);
1010 *ok = false; 1004 *ok = false;
1011 return Expression::Default(); 1005 return Expression::Default();
1012 } 1006 }
1013 // FALLTHROUGH 1007 // FALLTHROUGH
1014 case i::Token::IDENTIFIER: { 1008 case i::Token::IDENTIFIER: {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 // '{' ( 1087 // '{' (
1094 // ((IdentifierName | String | Number) ':' AssignmentExpression) 1088 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1095 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1089 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1096 // )*[','] '}' 1090 // )*[','] '}'
1097 1091
1098 Expect(i::Token::LBRACE, CHECK_OK); 1092 Expect(i::Token::LBRACE, CHECK_OK);
1099 while (peek() != i::Token::RBRACE) { 1093 while (peek() != i::Token::RBRACE) {
1100 i::Token::Value next = peek(); 1094 i::Token::Value next = peek();
1101 switch (next) { 1095 switch (next) {
1102 case i::Token::IDENTIFIER: 1096 case i::Token::IDENTIFIER:
1103 case i::Token::FUTURE_RESERVED_WORD: { 1097 case i::Token::FUTURE_RESERVED_WORD:
1098 case i::Token::FUTURE_STRICT_RESERVED_WORD: {
1104 bool is_getter = false; 1099 bool is_getter = false;
1105 bool is_setter = false; 1100 bool is_setter = false;
1106 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1101 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1107 if ((is_getter || is_setter) && peek() != i::Token::COLON) { 1102 if ((is_getter || is_setter) && peek() != i::Token::COLON) {
1108 i::Token::Value name = Next(); 1103 i::Token::Value name = Next();
1109 bool is_keyword = i::Token::IsKeyword(name); 1104 bool is_keyword = i::Token::IsKeyword(name);
1110 if (name != i::Token::IDENTIFIER && 1105 if (name != i::Token::IDENTIFIER &&
1111 name != i::Token::FUTURE_RESERVED_WORD && 1106 name != i::Token::FUTURE_RESERVED_WORD &&
1107 name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1112 name != i::Token::NUMBER && 1108 name != i::Token::NUMBER &&
1113 name != i::Token::STRING && 1109 name != i::Token::STRING &&
1114 !is_keyword) { 1110 !is_keyword) {
1115 *ok = false; 1111 *ok = false;
1116 return Expression::Default(); 1112 return Expression::Default();
1117 } 1113 }
1118 if (!is_keyword) { 1114 if (!is_keyword) {
1119 LogSymbol(); 1115 LogSymbol();
1120 } 1116 }
1121 ParseFunctionLiteral(CHECK_OK); 1117 ParseFunctionLiteral(CHECK_OK);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 ParseSourceElements(i::Token::RBRACE, ok); 1245 ParseSourceElements(i::Token::RBRACE, ok);
1250 log_->ResumeRecording(); 1246 log_->ResumeRecording();
1251 if (!*ok) Expression::Default(); 1247 if (!*ok) Expression::Default();
1252 1248
1253 Expect(i::Token::RBRACE, CHECK_OK); 1249 Expect(i::Token::RBRACE, CHECK_OK);
1254 1250
1255 // Position right after terminal '}'. 1251 // Position right after terminal '}'.
1256 int end_pos = scanner_->location().end_pos; 1252 int end_pos = scanner_->location().end_pos;
1257 log_->LogFunction(function_block_pos, end_pos, 1253 log_->LogFunction(function_block_pos, end_pos,
1258 function_scope.materialized_literal_count(), 1254 function_scope.materialized_literal_count(),
1259 function_scope.expected_properties()); 1255 function_scope.expected_properties(),
1256 strict_mode() ? 1 : 0);
1260 } else { 1257 } else {
1261 ParseSourceElements(i::Token::RBRACE, CHECK_OK); 1258 ParseSourceElements(i::Token::RBRACE, CHECK_OK);
1262 Expect(i::Token::RBRACE, CHECK_OK); 1259 Expect(i::Token::RBRACE, CHECK_OK);
1263 } 1260 }
1264 1261
1265 if (strict_mode()) { 1262 if (strict_mode()) {
1266 int end_position = scanner_->location().end_pos; 1263 int end_position = scanner_->location().end_pos;
1267 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1264 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1268 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); 1265 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1269 return Expression::StrictFunction(); 1266 return Expression::StrictFunction();
(...skipping 18 matching lines...) Expand all
1288 1285
1289 1286
1290 void PreParser::ExpectSemicolon(bool* ok) { 1287 void PreParser::ExpectSemicolon(bool* ok) {
1291 // Check for automatic semicolon insertion according to 1288 // Check for automatic semicolon insertion according to
1292 // the rules given in ECMA-262, section 7.9, page 21. 1289 // the rules given in ECMA-262, section 7.9, page 21.
1293 i::Token::Value tok = peek(); 1290 i::Token::Value tok = peek();
1294 if (tok == i::Token::SEMICOLON) { 1291 if (tok == i::Token::SEMICOLON) {
1295 Next(); 1292 Next();
1296 return; 1293 return;
1297 } 1294 }
1298 if (scanner_->has_line_terminator_before_next() || 1295 if (scanner_->HasAnyLineTerminatorBeforeNext() ||
1299 tok == i::Token::RBRACE || 1296 tok == i::Token::RBRACE ||
1300 tok == i::Token::EOS) { 1297 tok == i::Token::EOS) {
1301 return; 1298 return;
1302 } 1299 }
1303 Expect(i::Token::SEMICOLON, ok); 1300 Expect(i::Token::SEMICOLON, ok);
1304 } 1301 }
1305 1302
1306 1303
1307 void PreParser::LogSymbol() { 1304 void PreParser::LogSymbol() {
1308 int identifier_pos = scanner_->location().beg_pos; 1305 int identifier_pos = scanner_->location().beg_pos;
(...skipping 17 matching lines...) Expand all
1326 return Expression::UseStrictStringLiteral(); 1323 return Expression::UseStrictStringLiteral();
1327 } 1324 }
1328 return Expression::StringLiteral(); 1325 return Expression::StringLiteral();
1329 } 1326 }
1330 1327
1331 1328
1332 PreParser::Identifier PreParser::GetIdentifierSymbol() { 1329 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1333 LogSymbol(); 1330 LogSymbol();
1334 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) { 1331 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
1335 return Identifier::FutureReserved(); 1332 return Identifier::FutureReserved();
1333 } else if (scanner_->current_token() ==
1334 i::Token::FUTURE_STRICT_RESERVED_WORD) {
1335 return Identifier::FutureStrictReserved();
1336 } 1336 }
1337 if (scanner_->is_literal_ascii()) { 1337 if (scanner_->is_literal_ascii()) {
1338 // Detect strict-mode poison words. 1338 // Detect strict-mode poison words.
1339 if (scanner_->literal_length() == 4 && 1339 if (scanner_->literal_length() == 4 &&
1340 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) { 1340 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) {
1341 return Identifier::Eval(); 1341 return Identifier::Eval();
1342 } 1342 }
1343 if (scanner_->literal_length() == 9 && 1343 if (scanner_->literal_length() == 9 &&
1344 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) { 1344 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) {
1345 return Identifier::Arguments(); 1345 return Identifier::Arguments();
1346 } 1346 }
1347 } 1347 }
1348 return Identifier::Default(); 1348 return Identifier::Default();
1349 } 1349 }
1350 1350
1351 1351
1352 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { 1352 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1353 if (!Check(i::Token::FUTURE_RESERVED_WORD)) { 1353 i::Token::Value next = Next();
1354 Expect(i::Token::IDENTIFIER, ok); 1354 switch (next) {
1355 if (!*ok) return Identifier::Default(); 1355 case i::Token::FUTURE_RESERVED_WORD: {
1356 i::Scanner::Location location = scanner_->location();
1357 ReportMessageAt(location.beg_pos, location.end_pos,
1358 "reserved_word", NULL);
1359 *ok = false;
1360 }
1361 // FALLTHROUGH
1362 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1363 case i::Token::IDENTIFIER:
1364 return GetIdentifierSymbol();
1365 default:
1366 *ok = false;
1367 return Identifier::Default();
1356 } 1368 }
1357 return GetIdentifierSymbol();
1358 } 1369 }
1359 1370
1360 1371
1361 void PreParser::SetStrictModeViolation(i::Scanner::Location location, 1372 void PreParser::SetStrictModeViolation(i::Scanner::Location location,
1362 const char* type, 1373 const char* type,
1363 bool* ok) { 1374 bool* ok) {
1364 if (strict_mode()) { 1375 if (strict_mode()) {
1365 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); 1376 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
1366 *ok = false; 1377 *ok = false;
1367 return; 1378 return;
(...skipping 19 matching lines...) Expand all
1387 strict_mode_violation_location_ = i::Scanner::Location::invalid(); 1398 strict_mode_violation_location_ = i::Scanner::Location::invalid();
1388 } 1399 }
1389 1400
1390 1401
1391 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location, 1402 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
1392 const char* eval_args_type, 1403 const char* eval_args_type,
1393 Identifier identifier, 1404 Identifier identifier,
1394 bool* ok) { 1405 bool* ok) {
1395 const char* type = eval_args_type; 1406 const char* type = eval_args_type;
1396 if (identifier.IsFutureReserved()) { 1407 if (identifier.IsFutureReserved()) {
1408 type = "reserved_word";
1409 } else if (identifier.IsFutureStrictReserved()) {
1397 type = "strict_reserved_word"; 1410 type = "strict_reserved_word";
1398 } 1411 }
1399 if (strict_mode()) { 1412 if (strict_mode()) {
1400 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); 1413 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
1401 *ok = false; 1414 *ok = false;
1402 return; 1415 return;
1403 } 1416 }
1404 strict_mode_violation_location_ = location; 1417 strict_mode_violation_location_ = location;
1405 strict_mode_violation_type_ = type; 1418 strict_mode_violation_type_ = type;
1406 } 1419 }
1407 1420
1408 1421
1409 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { 1422 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1410 i::Token::Value next = Next(); 1423 i::Token::Value next = Next();
1411 if (i::Token::IsKeyword(next)) { 1424 if (i::Token::IsKeyword(next)) {
1412 int pos = scanner_->location().beg_pos; 1425 int pos = scanner_->location().beg_pos;
1413 const char* keyword = i::Token::String(next); 1426 const char* keyword = i::Token::String(next);
1414 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, 1427 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
1415 i::StrLength(keyword))); 1428 i::StrLength(keyword)));
1416 return Identifier::Default(); 1429 return Identifier::Default();
1417 } 1430 }
1418 if (next == i::Token::IDENTIFIER || 1431 if (next == i::Token::IDENTIFIER ||
1419 next == i::Token::FUTURE_RESERVED_WORD) { 1432 next == i::Token::FUTURE_RESERVED_WORD ||
1433 next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
1420 return GetIdentifierSymbol(); 1434 return GetIdentifierSymbol();
1421 } 1435 }
1422 *ok = false; 1436 *ok = false;
1423 return Identifier::Default(); 1437 return Identifier::Default();
1424 } 1438 }
1425 1439
1426 #undef CHECK_OK 1440 #undef CHECK_OK
1427 1441
1428 1442
1429 // This function reads an identifier and determines whether or not it 1443 // This function reads an identifier and determines whether or not it
1430 // is 'get' or 'set'. 1444 // is 'get' or 'set'.
1431 PreParser::Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get, 1445 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1432 bool* is_set, 1446 bool* is_set,
1433 bool* ok) { 1447 bool* ok) {
1434 Identifier result = ParseIdentifier(ok); 1448 Identifier result = ParseIdentifierName(ok);
1435 if (!*ok) return Identifier::Default(); 1449 if (!*ok) return Identifier::Default();
1436 if (scanner_->is_literal_ascii() && 1450 if (scanner_->is_literal_ascii() &&
1437 scanner_->literal_length() == 3) { 1451 scanner_->literal_length() == 3) {
1438 const char* token = scanner_->literal_ascii_string().start(); 1452 const char* token = scanner_->literal_ascii_string().start();
1439 *is_get = strncmp(token, "get", 3) == 0; 1453 *is_get = strncmp(token, "get", 3) == 0;
1440 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 1454 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1441 } 1455 }
1442 return result; 1456 return result;
1443 } 1457 }
1444 1458
1445 bool PreParser::peek_any_identifier() { 1459 bool PreParser::peek_any_identifier() {
1446 i::Token::Value next = peek(); 1460 i::Token::Value next = peek();
1447 return next == i::Token::IDENTIFIER || 1461 return next == i::Token::IDENTIFIER ||
1448 next == i::Token::FUTURE_RESERVED_WORD; 1462 next == i::Token::FUTURE_RESERVED_WORD ||
1463 next == i::Token::FUTURE_STRICT_RESERVED_WORD;
1449 } 1464 }
1450 } } // v8::preparser 1465 } } // v8::preparser
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/preparser-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698