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

Side by Side Diff: src/preparser.cc

Issue 7037024: Added preparser strict-mode tests. (Closed)
Patch Set: Address review comment. Created 9 years, 7 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
« no previous file with comments | « src/preparser.h ('k') | test/preparser/nonstrict-arguments.js » ('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 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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | test/preparser/nonstrict-arguments.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698