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

Side by Side Diff: src/preparser.cc

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 49
50 // The PreParser checks that the syntax follows the grammar for JavaScript, 50 // The PreParser checks that the syntax follows the grammar for JavaScript,
51 // and collects some information about the program along the way. 51 // and collects some information about the program along the way.
52 // 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
53 // sufficiently to deduce some information about it, that can be used 53 // sufficiently to deduce some information about it, that can be used
54 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 54 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
55 // rather it is to speed up properly written and correct programs. 55 // rather it is to speed up properly written and correct programs.
56 // That means that contextual checks (like a label being declared where 56 // That means that contextual checks (like a label being declared where
57 // it is used) are generally omitted. 57 // it is used) are generally omitted.
58 58
59 namespace i = ::v8::internal;
60
61 void PreParser::ReportUnexpectedToken(i::Token::Value token) { 59 void PreParser::ReportUnexpectedToken(i::Token::Value token) {
62 // We don't report stack overflows here, to avoid increasing the 60 // We don't report stack overflows here, to avoid increasing the
63 // stack depth even further. Instead we report it after parsing is 61 // stack depth even further. Instead we report it after parsing is
64 // over, in ParseProgram. 62 // over, in ParseProgram.
65 if (token == i::Token::ILLEGAL && stack_overflow_) { 63 if (token == i::Token::ILLEGAL && stack_overflow_) {
66 return; 64 return;
67 } 65 }
68 i::JavaScriptScanner::Location source_location = scanner_->location(); 66 i::JavaScriptScanner::Location source_location = scanner_->location();
69 67
70 // Four of the tokens are treated specially 68 // Four of the tokens are treated specially
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 105 }
108 106
109 107
110 #define CHECK_OK ok); \ 108 #define CHECK_OK ok); \
111 if (!*ok) return kUnknownSourceElements; \ 109 if (!*ok) return kUnknownSourceElements; \
112 ((void)0 110 ((void)0
113 #define DUMMY ) // to make indentation work 111 #define DUMMY ) // to make indentation work
114 #undef DUMMY 112 #undef DUMMY
115 113
116 114
115 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
116 switch (peek()) {
117 case i::Token::LET:
118 return ParseVariableStatement(kSourceElement, ok);
119 default:
120 return ParseStatement(ok);
121 }
122 }
123
124
117 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 125 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
118 bool* ok) { 126 bool* ok) {
119 // SourceElements :: 127 // SourceElements ::
120 // (Statement)* <end_token> 128 // (Statement)* <end_token>
121 129
122 bool allow_directive_prologue = true; 130 bool allow_directive_prologue = true;
123 while (peek() != end_token) { 131 while (peek() != end_token) {
124 Statement statement = ParseStatement(CHECK_OK); 132 Statement statement = ParseSourceElement(CHECK_OK);
125 if (allow_directive_prologue) { 133 if (allow_directive_prologue) {
126 if (statement.IsUseStrictLiteral()) { 134 if (statement.IsUseStrictLiteral()) {
127 set_strict_mode(); 135 set_strict_mode();
128 } else if (!statement.IsStringLiteral()) { 136 } else if (!statement.IsStringLiteral()) {
129 allow_directive_prologue = false; 137 allow_directive_prologue = false;
130 } 138 }
131 } 139 }
132 } 140 }
133 return kUnknownSourceElements; 141 return kUnknownSourceElements;
134 } 142 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 // trivial labeled break statements 'label: break label' which is 175 // trivial labeled break statements 'label: break label' which is
168 // parsed into an empty statement. 176 // parsed into an empty statement.
169 177
170 // Keep the source position of the statement 178 // Keep the source position of the statement
171 switch (peek()) { 179 switch (peek()) {
172 case i::Token::LBRACE: 180 case i::Token::LBRACE:
173 return ParseBlock(ok); 181 return ParseBlock(ok);
174 182
175 case i::Token::CONST: 183 case i::Token::CONST:
176 case i::Token::VAR: 184 case i::Token::VAR:
177 return ParseVariableStatement(ok); 185 return ParseVariableStatement(kStatement, ok);
178 186
179 case i::Token::SEMICOLON: 187 case i::Token::SEMICOLON:
180 Next(); 188 Next();
181 return Statement::Default(); 189 return Statement::Default();
182 190
183 case i::Token::IF: 191 case i::Token::IF:
184 return ParseIfStatement(ok); 192 return ParseIfStatement(ok);
185 193
186 case i::Token::DO: 194 case i::Token::DO:
187 return ParseDoWhileStatement(ok); 195 return ParseDoWhileStatement(ok);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 PreParser::Statement PreParser::ParseBlock(bool* ok) { 261 PreParser::Statement PreParser::ParseBlock(bool* ok) {
254 // Block :: 262 // Block ::
255 // '{' Statement* '}' 263 // '{' Statement* '}'
256 264
257 // Note that a Block does not introduce a new execution scope! 265 // Note that a Block does not introduce a new execution scope!
258 // (ECMA-262, 3rd, 12.2) 266 // (ECMA-262, 3rd, 12.2)
259 // 267 //
260 Expect(i::Token::LBRACE, CHECK_OK); 268 Expect(i::Token::LBRACE, CHECK_OK);
261 while (peek() != i::Token::RBRACE) { 269 while (peek() != i::Token::RBRACE) {
262 i::Scanner::Location start_location = scanner_->peek_location(); 270 i::Scanner::Location start_location = scanner_->peek_location();
263 Statement statement = ParseStatement(CHECK_OK); 271 Statement statement = ParseSourceElement(CHECK_OK);
264 i::Scanner::Location end_location = scanner_->location(); 272 i::Scanner::Location end_location = scanner_->location();
265 if (strict_mode() && statement.IsFunctionDeclaration()) { 273 if (strict_mode() && statement.IsFunctionDeclaration()) {
266 ReportMessageAt(start_location.beg_pos, end_location.end_pos, 274 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
267 "strict_function", NULL); 275 "strict_function", NULL);
268 *ok = false; 276 *ok = false;
269 return Statement::Default(); 277 return Statement::Default();
270 } 278 }
271 } 279 }
272 Expect(i::Token::RBRACE, ok); 280 Expect(i::Token::RBRACE, ok);
273 return Statement::Default(); 281 return Statement::Default();
274 } 282 }
275 283
276 284
277 PreParser::Statement PreParser::ParseVariableStatement(bool* ok) { 285 PreParser::Statement PreParser::ParseVariableStatement(
286 VariableDeclarationContext var_context,
287 bool* ok) {
278 // VariableStatement :: 288 // VariableStatement ::
279 // VariableDeclarations ';' 289 // VariableDeclarations ';'
280 290
281 Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); 291 Statement result = ParseVariableDeclarations(var_context,
292 NULL,
293 CHECK_OK);
282 ExpectSemicolon(CHECK_OK); 294 ExpectSemicolon(CHECK_OK);
283 return result; 295 return result;
284 } 296 }
285 297
286 298
287 // If the variable declaration declares exactly one non-const 299 // If the variable declaration declares exactly one non-const
288 // variable, then *var is set to that variable. In all other cases, 300 // variable, then *var is set to that variable. In all other cases,
289 // *var is untouched; in particular, it is the caller's responsibility 301 // *var is untouched; in particular, it is the caller's responsibility
290 // to initialize it properly. This mechanism is also used for the parsing 302 // to initialize it properly. This mechanism is also used for the parsing
291 // of 'for-in' loops. 303 // of 'for-in' loops.
292 PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN, 304 PreParser::Statement PreParser::ParseVariableDeclarations(
293 int* num_decl, 305 VariableDeclarationContext var_context,
294 bool* ok) { 306 int* num_decl,
307 bool* ok) {
295 // VariableDeclarations :: 308 // VariableDeclarations ::
296 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 309 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
297 310
298 if (peek() == i::Token::VAR) { 311 if (peek() == i::Token::VAR) {
299 Consume(i::Token::VAR); 312 Consume(i::Token::VAR);
300 } else if (peek() == i::Token::CONST) { 313 } else if (peek() == i::Token::CONST) {
301 if (strict_mode()) { 314 if (strict_mode()) {
302 i::Scanner::Location location = scanner_->peek_location(); 315 i::Scanner::Location location = scanner_->peek_location();
303 ReportMessageAt(location.beg_pos, location.end_pos, 316 ReportMessageAt(location.beg_pos, location.end_pos,
304 "strict_const", NULL); 317 "strict_const", NULL);
305 *ok = false; 318 *ok = false;
306 return Statement::Default(); 319 return Statement::Default();
307 } 320 }
308 Consume(i::Token::CONST); 321 Consume(i::Token::CONST);
322 } else if (peek() == i::Token::LET) {
323 if (var_context != kSourceElement &&
324 var_context != kForStatement) {
325 i::Scanner::Location location = scanner_->peek_location();
326 ReportMessageAt(location.beg_pos, location.end_pos,
327 "unprotected_let", NULL);
328 *ok = false;
329 return Statement::Default();
330 }
331 Consume(i::Token::LET);
309 } else { 332 } else {
310 *ok = false; 333 *ok = false;
311 return Statement::Default(); 334 return Statement::Default();
312 } 335 }
313 336
314 // The scope of a variable/const declared anywhere inside a function 337 // The scope of a var/const declared variable anywhere inside a function
315 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). . 338 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
339 // of a let declared variable is the scope of the immediately enclosing
340 // block.
316 int nvars = 0; // the number of variables declared 341 int nvars = 0; // the number of variables declared
317 do { 342 do {
318 // Parse variable name. 343 // Parse variable name.
319 if (nvars > 0) Consume(i::Token::COMMA); 344 if (nvars > 0) Consume(i::Token::COMMA);
320 Identifier identifier = ParseIdentifier(CHECK_OK); 345 Identifier identifier = ParseIdentifier(CHECK_OK);
321 if (strict_mode() && !identifier.IsValidStrictVariable()) { 346 if (strict_mode() && !identifier.IsValidStrictVariable()) {
322 StrictModeIdentifierViolation(scanner_->location(), 347 StrictModeIdentifierViolation(scanner_->location(),
323 "strict_var_name", 348 "strict_var_name",
324 identifier, 349 identifier,
325 ok); 350 ok);
326 return Statement::Default(); 351 return Statement::Default();
327 } 352 }
328 nvars++; 353 nvars++;
329 if (peek() == i::Token::ASSIGN) { 354 if (peek() == i::Token::ASSIGN) {
330 Expect(i::Token::ASSIGN, CHECK_OK); 355 Expect(i::Token::ASSIGN, CHECK_OK);
331 ParseAssignmentExpression(accept_IN, CHECK_OK); 356 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
332 } 357 }
333 } while (peek() == i::Token::COMMA); 358 } while (peek() == i::Token::COMMA);
334 359
335 if (num_decl != NULL) *num_decl = nvars; 360 if (num_decl != NULL) *num_decl = nvars;
336 return Statement::Default(); 361 return Statement::Default();
337 } 362 }
338 363
339 364
340 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 365 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
341 // ExpressionStatement | LabelledStatement :: 366 // ExpressionStatement | LabelledStatement ::
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 } 555 }
531 556
532 557
533 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 558 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
534 // ForStatement :: 559 // ForStatement ::
535 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 560 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
536 561
537 Expect(i::Token::FOR, CHECK_OK); 562 Expect(i::Token::FOR, CHECK_OK);
538 Expect(i::Token::LPAREN, CHECK_OK); 563 Expect(i::Token::LPAREN, CHECK_OK);
539 if (peek() != i::Token::SEMICOLON) { 564 if (peek() != i::Token::SEMICOLON) {
540 if (peek() == i::Token::VAR || peek() == i::Token::CONST) { 565 if (peek() == i::Token::VAR || peek() == i::Token::CONST ||
566 peek() == i::Token::LET) {
541 int decl_count; 567 int decl_count;
542 ParseVariableDeclarations(false, &decl_count, CHECK_OK); 568 ParseVariableDeclarations(kForStatement, &decl_count, CHECK_OK);
543 if (peek() == i::Token::IN && decl_count == 1) { 569 if (peek() == i::Token::IN && decl_count == 1) {
544 Expect(i::Token::IN, CHECK_OK); 570 Expect(i::Token::IN, CHECK_OK);
545 ParseExpression(true, CHECK_OK); 571 ParseExpression(true, CHECK_OK);
546 Expect(i::Token::RPAREN, CHECK_OK); 572 Expect(i::Token::RPAREN, CHECK_OK);
547 573
548 ParseStatement(CHECK_OK); 574 ParseStatement(CHECK_OK);
549 return Statement::Default(); 575 return Statement::Default();
550 } 576 }
551 } else { 577 } else {
552 ParseExpression(false, CHECK_OK); 578 ParseExpression(false, CHECK_OK);
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 return result; 1482 return result;
1457 } 1483 }
1458 1484
1459 bool PreParser::peek_any_identifier() { 1485 bool PreParser::peek_any_identifier() {
1460 i::Token::Value next = peek(); 1486 i::Token::Value next = peek();
1461 return next == i::Token::IDENTIFIER || 1487 return next == i::Token::IDENTIFIER ||
1462 next == i::Token::FUTURE_RESERVED_WORD || 1488 next == i::Token::FUTURE_RESERVED_WORD ||
1463 next == i::Token::FUTURE_STRICT_RESERVED_WORD; 1489 next == i::Token::FUTURE_STRICT_RESERVED_WORD;
1464 } 1490 }
1465 } } // v8::preparser 1491 } } // 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