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

Side by Side Diff: src/preparser.cc

Issue 26296006: Remove deprecated "i::" prefix from the preparser. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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') | no next file » | 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 // Abstracted to work 49 // Abstracted to work
50 int isfinite(double value); 50 int isfinite(double value);
51 51
52 } // namespace std 52 } // namespace std
53 #endif 53 #endif
54 54
55 namespace v8 { 55 namespace v8 {
56 namespace internal { 56 namespace internal {
57 57
58 PreParser::PreParseResult PreParser::PreParseLazyFunction( 58 PreParser::PreParseResult PreParser::PreParseLazyFunction(
59 i::LanguageMode mode, bool is_generator, i::ParserRecorder* log) { 59 LanguageMode mode, bool is_generator, ParserRecorder* log) {
60 log_ = log; 60 log_ = log;
61 // Lazy functions always have trivial outer scopes (no with/catch scopes). 61 // Lazy functions always have trivial outer scopes (no with/catch scopes).
62 Scope top_scope(&scope_, kTopLevelScope); 62 Scope top_scope(&scope_, kTopLevelScope);
63 set_language_mode(mode); 63 set_language_mode(mode);
64 Scope function_scope(&scope_, kFunctionScope); 64 Scope function_scope(&scope_, kFunctionScope);
65 function_scope.set_is_generator(is_generator); 65 function_scope.set_is_generator(is_generator);
66 ASSERT_EQ(i::Token::LBRACE, scanner()->current_token()); 66 ASSERT_EQ(Token::LBRACE, scanner()->current_token());
67 bool ok = true; 67 bool ok = true;
68 int start_position = peek_position(); 68 int start_position = peek_position();
69 ParseLazyFunctionLiteralBody(&ok); 69 ParseLazyFunctionLiteralBody(&ok);
70 if (stack_overflow()) return kPreParseStackOverflow; 70 if (stack_overflow()) return kPreParseStackOverflow;
71 if (!ok) { 71 if (!ok) {
72 ReportUnexpectedToken(scanner()->current_token()); 72 ReportUnexpectedToken(scanner()->current_token());
73 } else { 73 } else {
74 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); 74 ASSERT_EQ(Token::RBRACE, scanner()->peek());
75 if (!is_classic_mode()) { 75 if (!is_classic_mode()) {
76 int end_pos = scanner()->location().end_pos; 76 int end_pos = scanner()->location().end_pos;
77 CheckOctalLiteral(start_position, end_pos, &ok); 77 CheckOctalLiteral(start_position, end_pos, &ok);
78 if (ok) { 78 if (ok) {
79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok); 79 CheckDelayedStrictModeViolation(start_position, end_pos, &ok);
80 } 80 }
81 } 81 }
82 } 82 }
83 return kPreParseSuccess; 83 return kPreParseSuccess;
84 } 84 }
85 85
86 86
87 // Preparsing checks a JavaScript program and emits preparse-data that helps 87 // Preparsing checks a JavaScript program and emits preparse-data that helps
88 // a later parsing to be faster. 88 // a later parsing to be faster.
89 // See preparser-data.h for the data. 89 // See preparser-data.h for the data.
90 90
91 // The PreParser checks that the syntax follows the grammar for JavaScript, 91 // The PreParser checks that the syntax follows the grammar for JavaScript,
92 // and collects some information about the program along the way. 92 // and collects some information about the program along the way.
93 // The grammar check is only performed in order to understand the program 93 // The grammar check is only performed in order to understand the program
94 // sufficiently to deduce some information about it, that can be used 94 // sufficiently to deduce some information about it, that can be used
95 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 95 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
96 // rather it is to speed up properly written and correct programs. 96 // rather it is to speed up properly written and correct programs.
97 // That means that contextual checks (like a label being declared where 97 // That means that contextual checks (like a label being declared where
98 // it is used) are generally omitted. 98 // it is used) are generally omitted.
99 99
100 void PreParser::ReportUnexpectedToken(i::Token::Value token) { 100 void PreParser::ReportUnexpectedToken(Token::Value token) {
101 // We don't report stack overflows here, to avoid increasing the 101 // We don't report stack overflows here, to avoid increasing the
102 // stack depth even further. Instead we report it after parsing is 102 // stack depth even further. Instead we report it after parsing is
103 // over, in ParseProgram. 103 // over, in ParseProgram.
104 if (token == i::Token::ILLEGAL && stack_overflow()) { 104 if (token == Token::ILLEGAL && stack_overflow()) {
105 return; 105 return;
106 } 106 }
107 i::Scanner::Location source_location = scanner()->location(); 107 Scanner::Location source_location = scanner()->location();
108 108
109 // Four of the tokens are treated specially 109 // Four of the tokens are treated specially
110 switch (token) { 110 switch (token) {
111 case i::Token::EOS: 111 case Token::EOS:
112 return ReportMessageAt(source_location, "unexpected_eos", NULL); 112 return ReportMessageAt(source_location, "unexpected_eos", NULL);
113 case i::Token::NUMBER: 113 case Token::NUMBER:
114 return ReportMessageAt(source_location, "unexpected_token_number", NULL); 114 return ReportMessageAt(source_location, "unexpected_token_number", NULL);
115 case i::Token::STRING: 115 case Token::STRING:
116 return ReportMessageAt(source_location, "unexpected_token_string", NULL); 116 return ReportMessageAt(source_location, "unexpected_token_string", NULL);
117 case i::Token::IDENTIFIER: 117 case Token::IDENTIFIER:
118 return ReportMessageAt(source_location, 118 return ReportMessageAt(source_location,
119 "unexpected_token_identifier", NULL); 119 "unexpected_token_identifier", NULL);
120 case i::Token::FUTURE_RESERVED_WORD: 120 case Token::FUTURE_RESERVED_WORD:
121 return ReportMessageAt(source_location, "unexpected_reserved", NULL); 121 return ReportMessageAt(source_location, "unexpected_reserved", NULL);
122 case i::Token::FUTURE_STRICT_RESERVED_WORD: 122 case Token::FUTURE_STRICT_RESERVED_WORD:
123 return ReportMessageAt(source_location, 123 return ReportMessageAt(source_location,
124 "unexpected_strict_reserved", NULL); 124 "unexpected_strict_reserved", NULL);
125 default: 125 default:
126 const char* name = i::Token::String(token); 126 const char* name = Token::String(token);
127 ReportMessageAt(source_location, "unexpected_token", name); 127 ReportMessageAt(source_location, "unexpected_token", name);
128 } 128 }
129 } 129 }
130 130
131 131
132 #define CHECK_OK ok); \ 132 #define CHECK_OK ok); \
133 if (!*ok) return kUnknownSourceElements; \ 133 if (!*ok) return kUnknownSourceElements; \
134 ((void)0 134 ((void)0
135 #define DUMMY ) // to make indentation work 135 #define DUMMY ) // to make indentation work
136 #undef DUMMY 136 #undef DUMMY
137 137
138 138
139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { 139 PreParser::Statement PreParser::ParseSourceElement(bool* ok) {
140 // (Ecma 262 5th Edition, clause 14): 140 // (Ecma 262 5th Edition, clause 14):
141 // SourceElement: 141 // SourceElement:
142 // Statement 142 // Statement
143 // FunctionDeclaration 143 // FunctionDeclaration
144 // 144 //
145 // In harmony mode we allow additionally the following productions 145 // In harmony mode we allow additionally the following productions
146 // SourceElement: 146 // SourceElement:
147 // LetDeclaration 147 // LetDeclaration
148 // ConstDeclaration 148 // ConstDeclaration
149 // GeneratorDeclaration 149 // GeneratorDeclaration
150 150
151 switch (peek()) { 151 switch (peek()) {
152 case i::Token::FUNCTION: 152 case Token::FUNCTION:
153 return ParseFunctionDeclaration(ok); 153 return ParseFunctionDeclaration(ok);
154 case i::Token::LET: 154 case Token::LET:
155 case i::Token::CONST: 155 case Token::CONST:
156 return ParseVariableStatement(kSourceElement, ok); 156 return ParseVariableStatement(kSourceElement, ok);
157 default: 157 default:
158 return ParseStatement(ok); 158 return ParseStatement(ok);
159 } 159 }
160 } 160 }
161 161
162 162
163 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 163 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
164 bool* ok) { 164 bool* ok) {
165 // SourceElements :: 165 // SourceElements ::
166 // (Statement)* <end_token> 166 // (Statement)* <end_token>
167 167
168 bool allow_directive_prologue = true; 168 bool allow_directive_prologue = true;
169 while (peek() != end_token) { 169 while (peek() != end_token) {
170 Statement statement = ParseSourceElement(CHECK_OK); 170 Statement statement = ParseSourceElement(CHECK_OK);
171 if (allow_directive_prologue) { 171 if (allow_directive_prologue) {
172 if (statement.IsUseStrictLiteral()) { 172 if (statement.IsUseStrictLiteral()) {
173 set_language_mode(allow_harmony_scoping() ? 173 set_language_mode(allow_harmony_scoping() ?
174 i::EXTENDED_MODE : i::STRICT_MODE); 174 EXTENDED_MODE : STRICT_MODE);
175 } else if (!statement.IsStringLiteral()) { 175 } else if (!statement.IsStringLiteral()) {
176 allow_directive_prologue = false; 176 allow_directive_prologue = false;
177 } 177 }
178 } 178 }
179 } 179 }
180 return kUnknownSourceElements; 180 return kUnknownSourceElements;
181 } 181 }
182 182
183 183
184 #undef CHECK_OK 184 #undef CHECK_OK
(...skipping 24 matching lines...) Expand all
209 209
210 // Note: Since labels can only be used by 'break' and 'continue' 210 // Note: Since labels can only be used by 'break' and 'continue'
211 // statements, which themselves are only valid within blocks, 211 // statements, which themselves are only valid within blocks,
212 // iterations or 'switch' statements (i.e., BreakableStatements), 212 // iterations or 'switch' statements (i.e., BreakableStatements),
213 // labels can be simply ignored in all other cases; except for 213 // labels can be simply ignored in all other cases; except for
214 // trivial labeled break statements 'label: break label' which is 214 // trivial labeled break statements 'label: break label' which is
215 // parsed into an empty statement. 215 // parsed into an empty statement.
216 216
217 // Keep the source position of the statement 217 // Keep the source position of the statement
218 switch (peek()) { 218 switch (peek()) {
219 case i::Token::LBRACE: 219 case Token::LBRACE:
220 return ParseBlock(ok); 220 return ParseBlock(ok);
221 221
222 case i::Token::CONST: 222 case Token::CONST:
223 case i::Token::LET: 223 case Token::LET:
224 case i::Token::VAR: 224 case Token::VAR:
225 return ParseVariableStatement(kStatement, ok); 225 return ParseVariableStatement(kStatement, ok);
226 226
227 case i::Token::SEMICOLON: 227 case Token::SEMICOLON:
228 Next(); 228 Next();
229 return Statement::Default(); 229 return Statement::Default();
230 230
231 case i::Token::IF: 231 case Token::IF:
232 return ParseIfStatement(ok); 232 return ParseIfStatement(ok);
233 233
234 case i::Token::DO: 234 case Token::DO:
235 return ParseDoWhileStatement(ok); 235 return ParseDoWhileStatement(ok);
236 236
237 case i::Token::WHILE: 237 case Token::WHILE:
238 return ParseWhileStatement(ok); 238 return ParseWhileStatement(ok);
239 239
240 case i::Token::FOR: 240 case Token::FOR:
241 return ParseForStatement(ok); 241 return ParseForStatement(ok);
242 242
243 case i::Token::CONTINUE: 243 case Token::CONTINUE:
244 return ParseContinueStatement(ok); 244 return ParseContinueStatement(ok);
245 245
246 case i::Token::BREAK: 246 case Token::BREAK:
247 return ParseBreakStatement(ok); 247 return ParseBreakStatement(ok);
248 248
249 case i::Token::RETURN: 249 case Token::RETURN:
250 return ParseReturnStatement(ok); 250 return ParseReturnStatement(ok);
251 251
252 case i::Token::WITH: 252 case Token::WITH:
253 return ParseWithStatement(ok); 253 return ParseWithStatement(ok);
254 254
255 case i::Token::SWITCH: 255 case Token::SWITCH:
256 return ParseSwitchStatement(ok); 256 return ParseSwitchStatement(ok);
257 257
258 case i::Token::THROW: 258 case Token::THROW:
259 return ParseThrowStatement(ok); 259 return ParseThrowStatement(ok);
260 260
261 case i::Token::TRY: 261 case Token::TRY:
262 return ParseTryStatement(ok); 262 return ParseTryStatement(ok);
263 263
264 case i::Token::FUNCTION: { 264 case Token::FUNCTION: {
265 i::Scanner::Location start_location = scanner()->peek_location(); 265 Scanner::Location start_location = scanner()->peek_location();
266 Statement statement = ParseFunctionDeclaration(CHECK_OK); 266 Statement statement = ParseFunctionDeclaration(CHECK_OK);
267 i::Scanner::Location end_location = scanner()->location(); 267 Scanner::Location end_location = scanner()->location();
268 if (!is_classic_mode()) { 268 if (!is_classic_mode()) {
269 ReportMessageAt(start_location.beg_pos, end_location.end_pos, 269 ReportMessageAt(start_location.beg_pos, end_location.end_pos,
270 "strict_function", NULL); 270 "strict_function", NULL);
271 *ok = false; 271 *ok = false;
272 return Statement::Default(); 272 return Statement::Default();
273 } else { 273 } else {
274 return statement; 274 return statement;
275 } 275 }
276 } 276 }
277 277
278 case i::Token::DEBUGGER: 278 case Token::DEBUGGER:
279 return ParseDebuggerStatement(ok); 279 return ParseDebuggerStatement(ok);
280 280
281 default: 281 default:
282 return ParseExpressionOrLabelledStatement(ok); 282 return ParseExpressionOrLabelledStatement(ok);
283 } 283 }
284 } 284 }
285 285
286 286
287 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 287 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
288 // FunctionDeclaration :: 288 // FunctionDeclaration ::
289 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 289 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
290 // GeneratorDeclaration :: 290 // GeneratorDeclaration ::
291 // 'function' '*' Identifier '(' FormalParameterListopt ')' 291 // 'function' '*' Identifier '(' FormalParameterListopt ')'
292 // '{' FunctionBody '}' 292 // '{' FunctionBody '}'
293 Expect(i::Token::FUNCTION, CHECK_OK); 293 Expect(Token::FUNCTION, CHECK_OK);
294 294
295 bool is_generator = allow_generators() && Check(i::Token::MUL); 295 bool is_generator = allow_generators() && Check(Token::MUL);
296 Identifier identifier = ParseIdentifier(CHECK_OK); 296 Identifier identifier = ParseIdentifier(CHECK_OK);
297 i::Scanner::Location location = scanner()->location(); 297 Scanner::Location location = scanner()->location();
298 298
299 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); 299 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
300 300
301 if (function_value.IsStrictFunction() && 301 if (function_value.IsStrictFunction() &&
302 !identifier.IsValidStrictVariable()) { 302 !identifier.IsValidStrictVariable()) {
303 // Strict mode violation, using either reserved word or eval/arguments 303 // Strict mode violation, using either reserved word or eval/arguments
304 // as name of strict function. 304 // as name of strict function.
305 const char* type = "strict_function_name"; 305 const char* type = "strict_function_name";
306 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { 306 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
307 type = "strict_reserved_word"; 307 type = "strict_reserved_word";
308 } 308 }
309 ReportMessageAt(location, type, NULL); 309 ReportMessageAt(location, type, NULL);
310 *ok = false; 310 *ok = false;
311 } 311 }
312 return Statement::FunctionDeclaration(); 312 return Statement::FunctionDeclaration();
313 } 313 }
314 314
315 315
316 PreParser::Statement PreParser::ParseBlock(bool* ok) { 316 PreParser::Statement PreParser::ParseBlock(bool* ok) {
317 // Block :: 317 // Block ::
318 // '{' Statement* '}' 318 // '{' Statement* '}'
319 319
320 // Note that a Block does not introduce a new execution scope! 320 // Note that a Block does not introduce a new execution scope!
321 // (ECMA-262, 3rd, 12.2) 321 // (ECMA-262, 3rd, 12.2)
322 // 322 //
323 Expect(i::Token::LBRACE, CHECK_OK); 323 Expect(Token::LBRACE, CHECK_OK);
324 while (peek() != i::Token::RBRACE) { 324 while (peek() != Token::RBRACE) {
325 if (is_extended_mode()) { 325 if (is_extended_mode()) {
326 ParseSourceElement(CHECK_OK); 326 ParseSourceElement(CHECK_OK);
327 } else { 327 } else {
328 ParseStatement(CHECK_OK); 328 ParseStatement(CHECK_OK);
329 } 329 }
330 } 330 }
331 Expect(i::Token::RBRACE, ok); 331 Expect(Token::RBRACE, ok);
332 return Statement::Default(); 332 return Statement::Default();
333 } 333 }
334 334
335 335
336 PreParser::Statement PreParser::ParseVariableStatement( 336 PreParser::Statement PreParser::ParseVariableStatement(
337 VariableDeclarationContext var_context, 337 VariableDeclarationContext var_context,
338 bool* ok) { 338 bool* ok) {
339 // VariableStatement :: 339 // VariableStatement ::
340 // VariableDeclarations ';' 340 // VariableDeclarations ';'
341 341
(...skipping 23 matching lines...) Expand all
365 // 365 //
366 // ConstDeclaration :: 366 // ConstDeclaration ::
367 // const ConstBinding (',' ConstBinding)* ';' 367 // const ConstBinding (',' ConstBinding)* ';'
368 // ConstBinding :: 368 // ConstBinding ::
369 // Identifier '=' AssignmentExpression 369 // Identifier '=' AssignmentExpression
370 // 370 //
371 // TODO(ES6): 371 // TODO(ES6):
372 // ConstBinding :: 372 // ConstBinding ::
373 // BindingPattern '=' AssignmentExpression 373 // BindingPattern '=' AssignmentExpression
374 bool require_initializer = false; 374 bool require_initializer = false;
375 if (peek() == i::Token::VAR) { 375 if (peek() == Token::VAR) {
376 Consume(i::Token::VAR); 376 Consume(Token::VAR);
377 } else if (peek() == i::Token::CONST) { 377 } else if (peek() == Token::CONST) {
378 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: 378 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads:
379 // 379 //
380 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' 380 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';'
381 // 381 //
382 // * It is a Syntax Error if the code that matches this production is not 382 // * It is a Syntax Error if the code that matches this production is not
383 // contained in extended code. 383 // contained in extended code.
384 // 384 //
385 // However disallowing const in classic mode will break compatibility with 385 // However disallowing const in classic mode will break compatibility with
386 // existing pages. Therefore we keep allowing const with the old 386 // existing pages. Therefore we keep allowing const with the old
387 // non-harmony semantics in classic mode. 387 // non-harmony semantics in classic mode.
388 Consume(i::Token::CONST); 388 Consume(Token::CONST);
389 switch (language_mode()) { 389 switch (language_mode()) {
390 case i::CLASSIC_MODE: 390 case CLASSIC_MODE:
391 break; 391 break;
392 case i::STRICT_MODE: { 392 case STRICT_MODE: {
393 i::Scanner::Location location = scanner()->peek_location(); 393 Scanner::Location location = scanner()->peek_location();
394 ReportMessageAt(location, "strict_const", NULL); 394 ReportMessageAt(location, "strict_const", NULL);
395 *ok = false; 395 *ok = false;
396 return Statement::Default(); 396 return Statement::Default();
397 } 397 }
398 case i::EXTENDED_MODE: 398 case EXTENDED_MODE:
399 if (var_context != kSourceElement && 399 if (var_context != kSourceElement &&
400 var_context != kForStatement) { 400 var_context != kForStatement) {
401 i::Scanner::Location location = scanner()->peek_location(); 401 Scanner::Location location = scanner()->peek_location();
402 ReportMessageAt(location.beg_pos, location.end_pos, 402 ReportMessageAt(location.beg_pos, location.end_pos,
403 "unprotected_const", NULL); 403 "unprotected_const", NULL);
404 *ok = false; 404 *ok = false;
405 return Statement::Default(); 405 return Statement::Default();
406 } 406 }
407 require_initializer = true; 407 require_initializer = true;
408 break; 408 break;
409 } 409 }
410 } else if (peek() == i::Token::LET) { 410 } else if (peek() == Token::LET) {
411 // ES6 Draft Rev4 section 12.2.1: 411 // ES6 Draft Rev4 section 12.2.1:
412 // 412 //
413 // LetDeclaration : let LetBindingList ; 413 // LetDeclaration : let LetBindingList ;
414 // 414 //
415 // * It is a Syntax Error if the code that matches this production is not 415 // * It is a Syntax Error if the code that matches this production is not
416 // contained in extended code. 416 // contained in extended code.
417 if (!is_extended_mode()) { 417 if (!is_extended_mode()) {
418 i::Scanner::Location location = scanner()->peek_location(); 418 Scanner::Location location = scanner()->peek_location();
419 ReportMessageAt(location.beg_pos, location.end_pos, 419 ReportMessageAt(location.beg_pos, location.end_pos,
420 "illegal_let", NULL); 420 "illegal_let", NULL);
421 *ok = false; 421 *ok = false;
422 return Statement::Default(); 422 return Statement::Default();
423 } 423 }
424 Consume(i::Token::LET); 424 Consume(Token::LET);
425 if (var_context != kSourceElement && 425 if (var_context != kSourceElement &&
426 var_context != kForStatement) { 426 var_context != kForStatement) {
427 i::Scanner::Location location = scanner()->peek_location(); 427 Scanner::Location location = scanner()->peek_location();
428 ReportMessageAt(location.beg_pos, location.end_pos, 428 ReportMessageAt(location.beg_pos, location.end_pos,
429 "unprotected_let", NULL); 429 "unprotected_let", NULL);
430 *ok = false; 430 *ok = false;
431 return Statement::Default(); 431 return Statement::Default();
432 } 432 }
433 } else { 433 } else {
434 *ok = false; 434 *ok = false;
435 return Statement::Default(); 435 return Statement::Default();
436 } 436 }
437 437
438 // The scope of a var/const declared variable anywhere inside a function 438 // The scope of a var/const declared variable anywhere inside a function
439 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope 439 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope
440 // of a let declared variable is the scope of the immediately enclosing 440 // of a let declared variable is the scope of the immediately enclosing
441 // block. 441 // block.
442 int nvars = 0; // the number of variables declared 442 int nvars = 0; // the number of variables declared
443 do { 443 do {
444 // Parse variable name. 444 // Parse variable name.
445 if (nvars > 0) Consume(i::Token::COMMA); 445 if (nvars > 0) Consume(Token::COMMA);
446 Identifier identifier = ParseIdentifier(CHECK_OK); 446 Identifier identifier = ParseIdentifier(CHECK_OK);
447 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { 447 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) {
448 StrictModeIdentifierViolation(scanner()->location(), 448 StrictModeIdentifierViolation(scanner()->location(),
449 "strict_var_name", 449 "strict_var_name",
450 identifier, 450 identifier,
451 ok); 451 ok);
452 return Statement::Default(); 452 return Statement::Default();
453 } 453 }
454 nvars++; 454 nvars++;
455 if (peek() == i::Token::ASSIGN || require_initializer) { 455 if (peek() == Token::ASSIGN || require_initializer) {
456 Expect(i::Token::ASSIGN, CHECK_OK); 456 Expect(Token::ASSIGN, CHECK_OK);
457 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); 457 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
458 if (decl_props != NULL) *decl_props = kHasInitializers; 458 if (decl_props != NULL) *decl_props = kHasInitializers;
459 } 459 }
460 } while (peek() == i::Token::COMMA); 460 } while (peek() == Token::COMMA);
461 461
462 if (num_decl != NULL) *num_decl = nvars; 462 if (num_decl != NULL) *num_decl = nvars;
463 return Statement::Default(); 463 return Statement::Default();
464 } 464 }
465 465
466 466
467 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { 467 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) {
468 // ExpressionStatement | LabelledStatement :: 468 // ExpressionStatement | LabelledStatement ::
469 // Expression ';' 469 // Expression ';'
470 // Identifier ':' Statement 470 // Identifier ':' Statement
471 471
472 Expression expr = ParseExpression(true, CHECK_OK); 472 Expression expr = ParseExpression(true, CHECK_OK);
473 if (expr.IsRawIdentifier()) { 473 if (expr.IsRawIdentifier()) {
474 ASSERT(!expr.AsIdentifier().IsFutureReserved()); 474 ASSERT(!expr.AsIdentifier().IsFutureReserved());
475 ASSERT(is_classic_mode() || 475 ASSERT(is_classic_mode() ||
476 (!expr.AsIdentifier().IsFutureStrictReserved() && 476 (!expr.AsIdentifier().IsFutureStrictReserved() &&
477 !expr.AsIdentifier().IsYield())); 477 !expr.AsIdentifier().IsYield()));
478 if (peek() == i::Token::COLON) { 478 if (peek() == Token::COLON) {
479 Consume(i::Token::COLON); 479 Consume(Token::COLON);
480 return ParseStatement(ok); 480 return ParseStatement(ok);
481 } 481 }
482 // Preparsing is disabled for extensions (because the extension details 482 // Preparsing is disabled for extensions (because the extension details
483 // aren't passed to lazily compiled functions), so we don't 483 // aren't passed to lazily compiled functions), so we don't
484 // accept "native function" in the preparser. 484 // accept "native function" in the preparser.
485 } 485 }
486 // Parsed expression statement. 486 // Parsed expression statement.
487 ExpectSemicolon(CHECK_OK); 487 ExpectSemicolon(CHECK_OK);
488 return Statement::ExpressionStatement(expr); 488 return Statement::ExpressionStatement(expr);
489 } 489 }
490 490
491 491
492 PreParser::Statement PreParser::ParseIfStatement(bool* ok) { 492 PreParser::Statement PreParser::ParseIfStatement(bool* ok) {
493 // IfStatement :: 493 // IfStatement ::
494 // 'if' '(' Expression ')' Statement ('else' Statement)? 494 // 'if' '(' Expression ')' Statement ('else' Statement)?
495 495
496 Expect(i::Token::IF, CHECK_OK); 496 Expect(Token::IF, CHECK_OK);
497 Expect(i::Token::LPAREN, CHECK_OK); 497 Expect(Token::LPAREN, CHECK_OK);
498 ParseExpression(true, CHECK_OK); 498 ParseExpression(true, CHECK_OK);
499 Expect(i::Token::RPAREN, CHECK_OK); 499 Expect(Token::RPAREN, CHECK_OK);
500 ParseStatement(CHECK_OK); 500 ParseStatement(CHECK_OK);
501 if (peek() == i::Token::ELSE) { 501 if (peek() == Token::ELSE) {
502 Next(); 502 Next();
503 ParseStatement(CHECK_OK); 503 ParseStatement(CHECK_OK);
504 } 504 }
505 return Statement::Default(); 505 return Statement::Default();
506 } 506 }
507 507
508 508
509 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { 509 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
510 // ContinueStatement :: 510 // ContinueStatement ::
511 // 'continue' [no line terminator] Identifier? ';' 511 // 'continue' [no line terminator] Identifier? ';'
512 512
513 Expect(i::Token::CONTINUE, CHECK_OK); 513 Expect(Token::CONTINUE, CHECK_OK);
514 i::Token::Value tok = peek(); 514 Token::Value tok = peek();
515 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 515 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
516 tok != i::Token::SEMICOLON && 516 tok != Token::SEMICOLON &&
517 tok != i::Token::RBRACE && 517 tok != Token::RBRACE &&
518 tok != i::Token::EOS) { 518 tok != Token::EOS) {
519 ParseIdentifier(CHECK_OK); 519 ParseIdentifier(CHECK_OK);
520 } 520 }
521 ExpectSemicolon(CHECK_OK); 521 ExpectSemicolon(CHECK_OK);
522 return Statement::Default(); 522 return Statement::Default();
523 } 523 }
524 524
525 525
526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { 526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) {
527 // BreakStatement :: 527 // BreakStatement ::
528 // 'break' [no line terminator] Identifier? ';' 528 // 'break' [no line terminator] Identifier? ';'
529 529
530 Expect(i::Token::BREAK, CHECK_OK); 530 Expect(Token::BREAK, CHECK_OK);
531 i::Token::Value tok = peek(); 531 Token::Value tok = peek();
532 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 532 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
533 tok != i::Token::SEMICOLON && 533 tok != Token::SEMICOLON &&
534 tok != i::Token::RBRACE && 534 tok != Token::RBRACE &&
535 tok != i::Token::EOS) { 535 tok != Token::EOS) {
536 ParseIdentifier(CHECK_OK); 536 ParseIdentifier(CHECK_OK);
537 } 537 }
538 ExpectSemicolon(CHECK_OK); 538 ExpectSemicolon(CHECK_OK);
539 return Statement::Default(); 539 return Statement::Default();
540 } 540 }
541 541
542 542
543 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { 543 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
544 // ReturnStatement :: 544 // ReturnStatement ::
545 // 'return' [no line terminator] Expression? ';' 545 // 'return' [no line terminator] Expression? ';'
546 546
547 // Consume the return token. It is necessary to do the before 547 // Consume the return token. It is necessary to do the before
548 // reporting any errors on it, because of the way errors are 548 // reporting any errors on it, because of the way errors are
549 // reported (underlining). 549 // reported (underlining).
550 Expect(i::Token::RETURN, CHECK_OK); 550 Expect(Token::RETURN, CHECK_OK);
551 551
552 // An ECMAScript program is considered syntactically incorrect if it 552 // An ECMAScript program is considered syntactically incorrect if it
553 // contains a return statement that is not within the body of a 553 // contains a return statement that is not within the body of a
554 // function. See ECMA-262, section 12.9, page 67. 554 // function. See ECMA-262, section 12.9, page 67.
555 // This is not handled during preparsing. 555 // This is not handled during preparsing.
556 556
557 i::Token::Value tok = peek(); 557 Token::Value tok = peek();
558 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 558 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
559 tok != i::Token::SEMICOLON && 559 tok != Token::SEMICOLON &&
560 tok != i::Token::RBRACE && 560 tok != Token::RBRACE &&
561 tok != i::Token::EOS) { 561 tok != Token::EOS) {
562 ParseExpression(true, CHECK_OK); 562 ParseExpression(true, CHECK_OK);
563 } 563 }
564 ExpectSemicolon(CHECK_OK); 564 ExpectSemicolon(CHECK_OK);
565 return Statement::Default(); 565 return Statement::Default();
566 } 566 }
567 567
568 568
569 PreParser::Statement PreParser::ParseWithStatement(bool* ok) { 569 PreParser::Statement PreParser::ParseWithStatement(bool* ok) {
570 // WithStatement :: 570 // WithStatement ::
571 // 'with' '(' Expression ')' Statement 571 // 'with' '(' Expression ')' Statement
572 Expect(i::Token::WITH, CHECK_OK); 572 Expect(Token::WITH, CHECK_OK);
573 if (!is_classic_mode()) { 573 if (!is_classic_mode()) {
574 i::Scanner::Location location = scanner()->location(); 574 Scanner::Location location = scanner()->location();
575 ReportMessageAt(location, "strict_mode_with", NULL); 575 ReportMessageAt(location, "strict_mode_with", NULL);
576 *ok = false; 576 *ok = false;
577 return Statement::Default(); 577 return Statement::Default();
578 } 578 }
579 Expect(i::Token::LPAREN, CHECK_OK); 579 Expect(Token::LPAREN, CHECK_OK);
580 ParseExpression(true, CHECK_OK); 580 ParseExpression(true, CHECK_OK);
581 Expect(i::Token::RPAREN, CHECK_OK); 581 Expect(Token::RPAREN, CHECK_OK);
582 582
583 Scope::InsideWith iw(scope_); 583 Scope::InsideWith iw(scope_);
584 ParseStatement(CHECK_OK); 584 ParseStatement(CHECK_OK);
585 return Statement::Default(); 585 return Statement::Default();
586 } 586 }
587 587
588 588
589 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) { 589 PreParser::Statement PreParser::ParseSwitchStatement(bool* ok) {
590 // SwitchStatement :: 590 // SwitchStatement ::
591 // 'switch' '(' Expression ')' '{' CaseClause* '}' 591 // 'switch' '(' Expression ')' '{' CaseClause* '}'
592 592
593 Expect(i::Token::SWITCH, CHECK_OK); 593 Expect(Token::SWITCH, CHECK_OK);
594 Expect(i::Token::LPAREN, CHECK_OK); 594 Expect(Token::LPAREN, CHECK_OK);
595 ParseExpression(true, CHECK_OK); 595 ParseExpression(true, CHECK_OK);
596 Expect(i::Token::RPAREN, CHECK_OK); 596 Expect(Token::RPAREN, CHECK_OK);
597 597
598 Expect(i::Token::LBRACE, CHECK_OK); 598 Expect(Token::LBRACE, CHECK_OK);
599 i::Token::Value token = peek(); 599 Token::Value token = peek();
600 while (token != i::Token::RBRACE) { 600 while (token != Token::RBRACE) {
601 if (token == i::Token::CASE) { 601 if (token == Token::CASE) {
602 Expect(i::Token::CASE, CHECK_OK); 602 Expect(Token::CASE, CHECK_OK);
603 ParseExpression(true, CHECK_OK); 603 ParseExpression(true, CHECK_OK);
604 } else { 604 } else {
605 Expect(i::Token::DEFAULT, CHECK_OK); 605 Expect(Token::DEFAULT, CHECK_OK);
606 } 606 }
607 Expect(i::Token::COLON, CHECK_OK); 607 Expect(Token::COLON, CHECK_OK);
608 token = peek(); 608 token = peek();
609 while (token != i::Token::CASE && 609 while (token != Token::CASE &&
610 token != i::Token::DEFAULT && 610 token != Token::DEFAULT &&
611 token != i::Token::RBRACE) { 611 token != Token::RBRACE) {
612 ParseStatement(CHECK_OK); 612 ParseStatement(CHECK_OK);
613 token = peek(); 613 token = peek();
614 } 614 }
615 } 615 }
616 Expect(i::Token::RBRACE, ok); 616 Expect(Token::RBRACE, ok);
617 return Statement::Default(); 617 return Statement::Default();
618 } 618 }
619 619
620 620
621 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { 621 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
622 // DoStatement :: 622 // DoStatement ::
623 // 'do' Statement 'while' '(' Expression ')' ';' 623 // 'do' Statement 'while' '(' Expression ')' ';'
624 624
625 Expect(i::Token::DO, CHECK_OK); 625 Expect(Token::DO, CHECK_OK);
626 ParseStatement(CHECK_OK); 626 ParseStatement(CHECK_OK);
627 Expect(i::Token::WHILE, CHECK_OK); 627 Expect(Token::WHILE, CHECK_OK);
628 Expect(i::Token::LPAREN, CHECK_OK); 628 Expect(Token::LPAREN, CHECK_OK);
629 ParseExpression(true, CHECK_OK); 629 ParseExpression(true, CHECK_OK);
630 Expect(i::Token::RPAREN, ok); 630 Expect(Token::RPAREN, ok);
631 if (peek() == i::Token::SEMICOLON) Consume(i::Token::SEMICOLON); 631 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON);
632 return Statement::Default(); 632 return Statement::Default();
633 } 633 }
634 634
635 635
636 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) { 636 PreParser::Statement PreParser::ParseWhileStatement(bool* ok) {
637 // WhileStatement :: 637 // WhileStatement ::
638 // 'while' '(' Expression ')' Statement 638 // 'while' '(' Expression ')' Statement
639 639
640 Expect(i::Token::WHILE, CHECK_OK); 640 Expect(Token::WHILE, CHECK_OK);
641 Expect(i::Token::LPAREN, CHECK_OK); 641 Expect(Token::LPAREN, CHECK_OK);
642 ParseExpression(true, CHECK_OK); 642 ParseExpression(true, CHECK_OK);
643 Expect(i::Token::RPAREN, CHECK_OK); 643 Expect(Token::RPAREN, CHECK_OK);
644 ParseStatement(ok); 644 ParseStatement(ok);
645 return Statement::Default(); 645 return Statement::Default();
646 } 646 }
647 647
648 648
649 bool PreParser::CheckInOrOf(bool accept_OF) { 649 bool PreParser::CheckInOrOf(bool accept_OF) {
650 if (Check(Token::IN) || 650 if (Check(Token::IN) ||
651 (allow_for_of() && accept_OF && 651 (allow_for_of() && accept_OF &&
652 CheckContextualKeyword(CStrVector("of")))) { 652 CheckContextualKeyword(CStrVector("of")))) {
653 return true; 653 return true;
654 } 654 }
655 return false; 655 return false;
656 } 656 }
657 657
658 658
659 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 659 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
660 // ForStatement :: 660 // ForStatement ::
661 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 661 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
662 662
663 Expect(i::Token::FOR, CHECK_OK); 663 Expect(Token::FOR, CHECK_OK);
664 Expect(i::Token::LPAREN, CHECK_OK); 664 Expect(Token::LPAREN, CHECK_OK);
665 if (peek() != i::Token::SEMICOLON) { 665 if (peek() != Token::SEMICOLON) {
666 if (peek() == i::Token::VAR || peek() == i::Token::CONST || 666 if (peek() == Token::VAR || peek() == Token::CONST ||
667 peek() == i::Token::LET) { 667 peek() == Token::LET) {
668 bool is_let = peek() == i::Token::LET; 668 bool is_let = peek() == Token::LET;
669 int decl_count; 669 int decl_count;
670 VariableDeclarationProperties decl_props = kHasNoInitializers; 670 VariableDeclarationProperties decl_props = kHasNoInitializers;
671 ParseVariableDeclarations( 671 ParseVariableDeclarations(
672 kForStatement, &decl_props, &decl_count, CHECK_OK); 672 kForStatement, &decl_props, &decl_count, CHECK_OK);
673 bool has_initializers = decl_props == kHasInitializers; 673 bool has_initializers = decl_props == kHasInitializers;
674 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); 674 bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
675 bool accept_OF = !has_initializers; 675 bool accept_OF = !has_initializers;
676 if (accept_IN && CheckInOrOf(accept_OF)) { 676 if (accept_IN && CheckInOrOf(accept_OF)) {
677 ParseExpression(true, CHECK_OK); 677 ParseExpression(true, CHECK_OK);
678 Expect(i::Token::RPAREN, CHECK_OK); 678 Expect(Token::RPAREN, CHECK_OK);
679 679
680 ParseStatement(CHECK_OK); 680 ParseStatement(CHECK_OK);
681 return Statement::Default(); 681 return Statement::Default();
682 } 682 }
683 } else { 683 } else {
684 Expression lhs = ParseExpression(false, CHECK_OK); 684 Expression lhs = ParseExpression(false, CHECK_OK);
685 if (CheckInOrOf(lhs.IsIdentifier())) { 685 if (CheckInOrOf(lhs.IsIdentifier())) {
686 ParseExpression(true, CHECK_OK); 686 ParseExpression(true, CHECK_OK);
687 Expect(i::Token::RPAREN, CHECK_OK); 687 Expect(Token::RPAREN, CHECK_OK);
688 688
689 ParseStatement(CHECK_OK); 689 ParseStatement(CHECK_OK);
690 return Statement::Default(); 690 return Statement::Default();
691 } 691 }
692 } 692 }
693 } 693 }
694 694
695 // Parsed initializer at this point. 695 // Parsed initializer at this point.
696 Expect(i::Token::SEMICOLON, CHECK_OK); 696 Expect(Token::SEMICOLON, CHECK_OK);
697 697
698 if (peek() != i::Token::SEMICOLON) { 698 if (peek() != Token::SEMICOLON) {
699 ParseExpression(true, CHECK_OK); 699 ParseExpression(true, CHECK_OK);
700 } 700 }
701 Expect(i::Token::SEMICOLON, CHECK_OK); 701 Expect(Token::SEMICOLON, CHECK_OK);
702 702
703 if (peek() != i::Token::RPAREN) { 703 if (peek() != Token::RPAREN) {
704 ParseExpression(true, CHECK_OK); 704 ParseExpression(true, CHECK_OK);
705 } 705 }
706 Expect(i::Token::RPAREN, CHECK_OK); 706 Expect(Token::RPAREN, CHECK_OK);
707 707
708 ParseStatement(ok); 708 ParseStatement(ok);
709 return Statement::Default(); 709 return Statement::Default();
710 } 710 }
711 711
712 712
713 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) { 713 PreParser::Statement PreParser::ParseThrowStatement(bool* ok) {
714 // ThrowStatement :: 714 // ThrowStatement ::
715 // 'throw' [no line terminator] Expression ';' 715 // 'throw' [no line terminator] Expression ';'
716 716
717 Expect(i::Token::THROW, CHECK_OK); 717 Expect(Token::THROW, CHECK_OK);
718 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 718 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
719 i::Scanner::Location pos = scanner()->location(); 719 Scanner::Location pos = scanner()->location();
720 ReportMessageAt(pos, "newline_after_throw", NULL); 720 ReportMessageAt(pos, "newline_after_throw", NULL);
721 *ok = false; 721 *ok = false;
722 return Statement::Default(); 722 return Statement::Default();
723 } 723 }
724 ParseExpression(true, CHECK_OK); 724 ParseExpression(true, CHECK_OK);
725 ExpectSemicolon(ok); 725 ExpectSemicolon(ok);
726 return Statement::Default(); 726 return Statement::Default();
727 } 727 }
728 728
729 729
730 PreParser::Statement PreParser::ParseTryStatement(bool* ok) { 730 PreParser::Statement PreParser::ParseTryStatement(bool* ok) {
731 // TryStatement :: 731 // TryStatement ::
732 // 'try' Block Catch 732 // 'try' Block Catch
733 // 'try' Block Finally 733 // 'try' Block Finally
734 // 'try' Block Catch Finally 734 // 'try' Block Catch Finally
735 // 735 //
736 // Catch :: 736 // Catch ::
737 // 'catch' '(' Identifier ')' Block 737 // 'catch' '(' Identifier ')' Block
738 // 738 //
739 // Finally :: 739 // Finally ::
740 // 'finally' Block 740 // 'finally' Block
741 741
742 // In preparsing, allow any number of catch/finally blocks, including zero 742 // In preparsing, allow any number of catch/finally blocks, including zero
743 // of both. 743 // of both.
744 744
745 Expect(i::Token::TRY, CHECK_OK); 745 Expect(Token::TRY, CHECK_OK);
746 746
747 ParseBlock(CHECK_OK); 747 ParseBlock(CHECK_OK);
748 748
749 bool catch_or_finally_seen = false; 749 bool catch_or_finally_seen = false;
750 if (peek() == i::Token::CATCH) { 750 if (peek() == Token::CATCH) {
751 Consume(i::Token::CATCH); 751 Consume(Token::CATCH);
752 Expect(i::Token::LPAREN, CHECK_OK); 752 Expect(Token::LPAREN, CHECK_OK);
753 Identifier id = ParseIdentifier(CHECK_OK); 753 Identifier id = ParseIdentifier(CHECK_OK);
754 if (!is_classic_mode() && !id.IsValidStrictVariable()) { 754 if (!is_classic_mode() && !id.IsValidStrictVariable()) {
755 StrictModeIdentifierViolation(scanner()->location(), 755 StrictModeIdentifierViolation(scanner()->location(),
756 "strict_catch_variable", 756 "strict_catch_variable",
757 id, 757 id,
758 ok); 758 ok);
759 return Statement::Default(); 759 return Statement::Default();
760 } 760 }
761 Expect(i::Token::RPAREN, CHECK_OK); 761 Expect(Token::RPAREN, CHECK_OK);
762 { Scope::InsideWith iw(scope_); 762 { Scope::InsideWith iw(scope_);
763 ParseBlock(CHECK_OK); 763 ParseBlock(CHECK_OK);
764 } 764 }
765 catch_or_finally_seen = true; 765 catch_or_finally_seen = true;
766 } 766 }
767 if (peek() == i::Token::FINALLY) { 767 if (peek() == Token::FINALLY) {
768 Consume(i::Token::FINALLY); 768 Consume(Token::FINALLY);
769 ParseBlock(CHECK_OK); 769 ParseBlock(CHECK_OK);
770 catch_or_finally_seen = true; 770 catch_or_finally_seen = true;
771 } 771 }
772 if (!catch_or_finally_seen) { 772 if (!catch_or_finally_seen) {
773 *ok = false; 773 *ok = false;
774 } 774 }
775 return Statement::Default(); 775 return Statement::Default();
776 } 776 }
777 777
778 778
779 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) { 779 PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
780 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 780 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
781 // contexts this is used as a statement which invokes the debugger as if a 781 // contexts this is used as a statement which invokes the debugger as if a
782 // break point is present. 782 // break point is present.
783 // DebuggerStatement :: 783 // DebuggerStatement ::
784 // 'debugger' ';' 784 // 'debugger' ';'
785 785
786 Expect(i::Token::DEBUGGER, CHECK_OK); 786 Expect(Token::DEBUGGER, CHECK_OK);
787 ExpectSemicolon(ok); 787 ExpectSemicolon(ok);
788 return Statement::Default(); 788 return Statement::Default();
789 } 789 }
790 790
791 791
792 #undef CHECK_OK 792 #undef CHECK_OK
793 #define CHECK_OK ok); \ 793 #define CHECK_OK ok); \
794 if (!*ok) return Expression::Default(); \ 794 if (!*ok) return Expression::Default(); \
795 ((void)0 795 ((void)0
796 #define DUMMY ) // to make indentation work 796 #define DUMMY ) // to make indentation work
797 #undef DUMMY 797 #undef DUMMY
798 798
799 799
800 // Precedence = 1 800 // Precedence = 1
801 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) { 801 PreParser::Expression PreParser::ParseExpression(bool accept_IN, bool* ok) {
802 // Expression :: 802 // Expression ::
803 // AssignmentExpression 803 // AssignmentExpression
804 // Expression ',' AssignmentExpression 804 // Expression ',' AssignmentExpression
805 805
806 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK); 806 Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
807 while (peek() == i::Token::COMMA) { 807 while (peek() == Token::COMMA) {
808 Expect(i::Token::COMMA, CHECK_OK); 808 Expect(Token::COMMA, CHECK_OK);
809 ParseAssignmentExpression(accept_IN, CHECK_OK); 809 ParseAssignmentExpression(accept_IN, CHECK_OK);
810 result = Expression::Default(); 810 result = Expression::Default();
811 } 811 }
812 return result; 812 return result;
813 } 813 }
814 814
815 815
816 // Precedence = 2 816 // Precedence = 2
817 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN, 817 PreParser::Expression PreParser::ParseAssignmentExpression(bool accept_IN,
818 bool* ok) { 818 bool* ok) {
819 // AssignmentExpression :: 819 // AssignmentExpression ::
820 // ConditionalExpression 820 // ConditionalExpression
821 // YieldExpression 821 // YieldExpression
822 // LeftHandSideExpression AssignmentOperator AssignmentExpression 822 // LeftHandSideExpression AssignmentOperator AssignmentExpression
823 823
824 if (scope_->is_generator() && peek() == i::Token::YIELD) { 824 if (scope_->is_generator() && peek() == Token::YIELD) {
825 return ParseYieldExpression(ok); 825 return ParseYieldExpression(ok);
826 } 826 }
827 827
828 i::Scanner::Location before = scanner()->peek_location(); 828 Scanner::Location before = scanner()->peek_location();
829 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK); 829 Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
830 830
831 if (!i::Token::IsAssignmentOp(peek())) { 831 if (!Token::IsAssignmentOp(peek())) {
832 // Parsed conditional expression only (no assignment). 832 // Parsed conditional expression only (no assignment).
833 return expression; 833 return expression;
834 } 834 }
835 835
836 if (!is_classic_mode() && 836 if (!is_classic_mode() &&
837 expression.IsIdentifier() && 837 expression.IsIdentifier() &&
838 expression.AsIdentifier().IsEvalOrArguments()) { 838 expression.AsIdentifier().IsEvalOrArguments()) {
839 i::Scanner::Location after = scanner()->location(); 839 Scanner::Location after = scanner()->location();
840 ReportMessageAt(before.beg_pos, after.end_pos, 840 ReportMessageAt(before.beg_pos, after.end_pos,
841 "strict_lhs_assignment", NULL); 841 "strict_lhs_assignment", NULL);
842 *ok = false; 842 *ok = false;
843 return Expression::Default(); 843 return Expression::Default();
844 } 844 }
845 845
846 i::Token::Value op = Next(); // Get assignment operator. 846 Token::Value op = Next(); // Get assignment operator.
847 ParseAssignmentExpression(accept_IN, CHECK_OK); 847 ParseAssignmentExpression(accept_IN, CHECK_OK);
848 848
849 if ((op == i::Token::ASSIGN) && expression.IsThisProperty()) { 849 if ((op == Token::ASSIGN) && expression.IsThisProperty()) {
850 scope_->AddProperty(); 850 scope_->AddProperty();
851 } 851 }
852 852
853 return Expression::Default(); 853 return Expression::Default();
854 } 854 }
855 855
856 856
857 // Precedence = 3 857 // Precedence = 3
858 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) { 858 PreParser::Expression PreParser::ParseYieldExpression(bool* ok) {
859 // YieldExpression :: 859 // YieldExpression ::
860 // 'yield' '*'? AssignmentExpression 860 // 'yield' '*'? AssignmentExpression
861 Consume(i::Token::YIELD); 861 Consume(Token::YIELD);
862 Check(i::Token::MUL); 862 Check(Token::MUL);
863 863
864 ParseAssignmentExpression(false, CHECK_OK); 864 ParseAssignmentExpression(false, CHECK_OK);
865 865
866 return Expression::Default(); 866 return Expression::Default();
867 } 867 }
868 868
869 869
870 // Precedence = 3 870 // Precedence = 3
871 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN, 871 PreParser::Expression PreParser::ParseConditionalExpression(bool accept_IN,
872 bool* ok) { 872 bool* ok) {
873 // ConditionalExpression :: 873 // ConditionalExpression ::
874 // LogicalOrExpression 874 // LogicalOrExpression
875 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 875 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
876 876
877 // We start using the binary expression parser for prec >= 4 only! 877 // We start using the binary expression parser for prec >= 4 only!
878 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 878 Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
879 if (peek() != i::Token::CONDITIONAL) return expression; 879 if (peek() != Token::CONDITIONAL) return expression;
880 Consume(i::Token::CONDITIONAL); 880 Consume(Token::CONDITIONAL);
881 // In parsing the first assignment expression in conditional 881 // In parsing the first assignment expression in conditional
882 // expressions we always accept the 'in' keyword; see ECMA-262, 882 // expressions we always accept the 'in' keyword; see ECMA-262,
883 // section 11.12, page 58. 883 // section 11.12, page 58.
884 ParseAssignmentExpression(true, CHECK_OK); 884 ParseAssignmentExpression(true, CHECK_OK);
885 Expect(i::Token::COLON, CHECK_OK); 885 Expect(Token::COLON, CHECK_OK);
886 ParseAssignmentExpression(accept_IN, CHECK_OK); 886 ParseAssignmentExpression(accept_IN, CHECK_OK);
887 return Expression::Default(); 887 return Expression::Default();
888 } 888 }
889 889
890 890
891 // Precedence >= 4 891 // Precedence >= 4
892 PreParser::Expression PreParser::ParseBinaryExpression(int prec, 892 PreParser::Expression PreParser::ParseBinaryExpression(int prec,
893 bool accept_IN, 893 bool accept_IN,
894 bool* ok) { 894 bool* ok) {
895 Expression result = ParseUnaryExpression(CHECK_OK); 895 Expression result = ParseUnaryExpression(CHECK_OK);
(...skipping 15 matching lines...) Expand all
911 // 'delete' UnaryExpression 911 // 'delete' UnaryExpression
912 // 'void' UnaryExpression 912 // 'void' UnaryExpression
913 // 'typeof' UnaryExpression 913 // 'typeof' UnaryExpression
914 // '++' UnaryExpression 914 // '++' UnaryExpression
915 // '--' UnaryExpression 915 // '--' UnaryExpression
916 // '+' UnaryExpression 916 // '+' UnaryExpression
917 // '-' UnaryExpression 917 // '-' UnaryExpression
918 // '~' UnaryExpression 918 // '~' UnaryExpression
919 // '!' UnaryExpression 919 // '!' UnaryExpression
920 920
921 i::Token::Value op = peek(); 921 Token::Value op = peek();
922 if (i::Token::IsUnaryOp(op)) { 922 if (Token::IsUnaryOp(op)) {
923 op = Next(); 923 op = Next();
924 ParseUnaryExpression(ok); 924 ParseUnaryExpression(ok);
925 return Expression::Default(); 925 return Expression::Default();
926 } else if (i::Token::IsCountOp(op)) { 926 } else if (Token::IsCountOp(op)) {
927 op = Next(); 927 op = Next();
928 i::Scanner::Location before = scanner()->peek_location(); 928 Scanner::Location before = scanner()->peek_location();
929 Expression expression = ParseUnaryExpression(CHECK_OK); 929 Expression expression = ParseUnaryExpression(CHECK_OK);
930 if (!is_classic_mode() && 930 if (!is_classic_mode() &&
931 expression.IsIdentifier() && 931 expression.IsIdentifier() &&
932 expression.AsIdentifier().IsEvalOrArguments()) { 932 expression.AsIdentifier().IsEvalOrArguments()) {
933 i::Scanner::Location after = scanner()->location(); 933 Scanner::Location after = scanner()->location();
934 ReportMessageAt(before.beg_pos, after.end_pos, 934 ReportMessageAt(before.beg_pos, after.end_pos,
935 "strict_lhs_prefix", NULL); 935 "strict_lhs_prefix", NULL);
936 *ok = false; 936 *ok = false;
937 } 937 }
938 return Expression::Default(); 938 return Expression::Default();
939 } else { 939 } else {
940 return ParsePostfixExpression(ok); 940 return ParsePostfixExpression(ok);
941 } 941 }
942 } 942 }
943 943
944 944
945 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { 945 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) {
946 // PostfixExpression :: 946 // PostfixExpression ::
947 // LeftHandSideExpression ('++' | '--')? 947 // LeftHandSideExpression ('++' | '--')?
948 948
949 i::Scanner::Location before = scanner()->peek_location(); 949 Scanner::Location before = scanner()->peek_location();
950 Expression expression = ParseLeftHandSideExpression(CHECK_OK); 950 Expression expression = ParseLeftHandSideExpression(CHECK_OK);
951 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 951 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
952 i::Token::IsCountOp(peek())) { 952 Token::IsCountOp(peek())) {
953 if (!is_classic_mode() && 953 if (!is_classic_mode() &&
954 expression.IsIdentifier() && 954 expression.IsIdentifier() &&
955 expression.AsIdentifier().IsEvalOrArguments()) { 955 expression.AsIdentifier().IsEvalOrArguments()) {
956 i::Scanner::Location after = scanner()->location(); 956 Scanner::Location after = scanner()->location();
957 ReportMessageAt(before.beg_pos, after.end_pos, 957 ReportMessageAt(before.beg_pos, after.end_pos,
958 "strict_lhs_postfix", NULL); 958 "strict_lhs_postfix", NULL);
959 *ok = false; 959 *ok = false;
960 return Expression::Default(); 960 return Expression::Default();
961 } 961 }
962 Next(); 962 Next();
963 return Expression::Default(); 963 return Expression::Default();
964 } 964 }
965 return expression; 965 return expression;
966 } 966 }
967 967
968 968
969 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { 969 PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
970 // LeftHandSideExpression :: 970 // LeftHandSideExpression ::
971 // (NewExpression | MemberExpression) ... 971 // (NewExpression | MemberExpression) ...
972 972
973 Expression result = Expression::Default(); 973 Expression result = Expression::Default();
974 if (peek() == i::Token::NEW) { 974 if (peek() == Token::NEW) {
975 result = ParseNewExpression(CHECK_OK); 975 result = ParseNewExpression(CHECK_OK);
976 } else { 976 } else {
977 result = ParseMemberExpression(CHECK_OK); 977 result = ParseMemberExpression(CHECK_OK);
978 } 978 }
979 979
980 while (true) { 980 while (true) {
981 switch (peek()) { 981 switch (peek()) {
982 case i::Token::LBRACK: { 982 case Token::LBRACK: {
983 Consume(i::Token::LBRACK); 983 Consume(Token::LBRACK);
984 ParseExpression(true, CHECK_OK); 984 ParseExpression(true, CHECK_OK);
985 Expect(i::Token::RBRACK, CHECK_OK); 985 Expect(Token::RBRACK, CHECK_OK);
986 if (result.IsThis()) { 986 if (result.IsThis()) {
987 result = Expression::ThisProperty(); 987 result = Expression::ThisProperty();
988 } else { 988 } else {
989 result = Expression::Default(); 989 result = Expression::Default();
990 } 990 }
991 break; 991 break;
992 } 992 }
993 993
994 case i::Token::LPAREN: { 994 case Token::LPAREN: {
995 ParseArguments(CHECK_OK); 995 ParseArguments(CHECK_OK);
996 result = Expression::Default(); 996 result = Expression::Default();
997 break; 997 break;
998 } 998 }
999 999
1000 case i::Token::PERIOD: { 1000 case Token::PERIOD: {
1001 Consume(i::Token::PERIOD); 1001 Consume(Token::PERIOD);
1002 ParseIdentifierName(CHECK_OK); 1002 ParseIdentifierName(CHECK_OK);
1003 if (result.IsThis()) { 1003 if (result.IsThis()) {
1004 result = Expression::ThisProperty(); 1004 result = Expression::ThisProperty();
1005 } else { 1005 } else {
1006 result = Expression::Default(); 1006 result = Expression::Default();
1007 } 1007 }
1008 break; 1008 break;
1009 } 1009 }
1010 1010
1011 default: 1011 default:
(...skipping 10 matching lines...) Expand all
1022 // The grammar for new expressions is pretty warped. The keyword 1022 // The grammar for new expressions is pretty warped. The keyword
1023 // 'new' can either be a part of the new expression (where it isn't 1023 // 'new' can either be a part of the new expression (where it isn't
1024 // followed by an argument list) or a part of the member expression, 1024 // followed by an argument list) or a part of the member expression,
1025 // where it must be followed by an argument list. To accommodate 1025 // where it must be followed by an argument list. To accommodate
1026 // this, we parse the 'new' keywords greedily and keep track of how 1026 // this, we parse the 'new' keywords greedily and keep track of how
1027 // many we have parsed. This information is then passed on to the 1027 // many we have parsed. This information is then passed on to the
1028 // member expression parser, which is only allowed to match argument 1028 // member expression parser, which is only allowed to match argument
1029 // lists as long as it has 'new' prefixes left 1029 // lists as long as it has 'new' prefixes left
1030 unsigned new_count = 0; 1030 unsigned new_count = 0;
1031 do { 1031 do {
1032 Consume(i::Token::NEW); 1032 Consume(Token::NEW);
1033 new_count++; 1033 new_count++;
1034 } while (peek() == i::Token::NEW); 1034 } while (peek() == Token::NEW);
1035 1035
1036 return ParseMemberWithNewPrefixesExpression(new_count, ok); 1036 return ParseMemberWithNewPrefixesExpression(new_count, ok);
1037 } 1037 }
1038 1038
1039 1039
1040 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) { 1040 PreParser::Expression PreParser::ParseMemberExpression(bool* ok) {
1041 return ParseMemberWithNewPrefixesExpression(0, ok); 1041 return ParseMemberWithNewPrefixesExpression(0, ok);
1042 } 1042 }
1043 1043
1044 1044
1045 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( 1045 PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
1046 unsigned new_count, bool* ok) { 1046 unsigned new_count, bool* ok) {
1047 // MemberExpression :: 1047 // MemberExpression ::
1048 // (PrimaryExpression | FunctionLiteral) 1048 // (PrimaryExpression | FunctionLiteral)
1049 // ('[' Expression ']' | '.' Identifier | Arguments)* 1049 // ('[' Expression ']' | '.' Identifier | Arguments)*
1050 1050
1051 // Parse the initial primary or function expression. 1051 // Parse the initial primary or function expression.
1052 Expression result = Expression::Default(); 1052 Expression result = Expression::Default();
1053 if (peek() == i::Token::FUNCTION) { 1053 if (peek() == Token::FUNCTION) {
1054 Consume(i::Token::FUNCTION); 1054 Consume(Token::FUNCTION);
1055 1055
1056 bool is_generator = allow_generators() && Check(i::Token::MUL); 1056 bool is_generator = allow_generators() && Check(Token::MUL);
1057 Identifier identifier = Identifier::Default(); 1057 Identifier identifier = Identifier::Default();
1058 if (peek_any_identifier()) { 1058 if (peek_any_identifier()) {
1059 identifier = ParseIdentifier(CHECK_OK); 1059 identifier = ParseIdentifier(CHECK_OK);
1060 } 1060 }
1061 result = ParseFunctionLiteral(is_generator, CHECK_OK); 1061 result = ParseFunctionLiteral(is_generator, CHECK_OK);
1062 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { 1062 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
1063 StrictModeIdentifierViolation(scanner()->location(), 1063 StrictModeIdentifierViolation(scanner()->location(),
1064 "strict_function_name", 1064 "strict_function_name",
1065 identifier, 1065 identifier,
1066 ok); 1066 ok);
1067 return Expression::Default(); 1067 return Expression::Default();
1068 } 1068 }
1069 } else { 1069 } else {
1070 result = ParsePrimaryExpression(CHECK_OK); 1070 result = ParsePrimaryExpression(CHECK_OK);
1071 } 1071 }
1072 1072
1073 while (true) { 1073 while (true) {
1074 switch (peek()) { 1074 switch (peek()) {
1075 case i::Token::LBRACK: { 1075 case Token::LBRACK: {
1076 Consume(i::Token::LBRACK); 1076 Consume(Token::LBRACK);
1077 ParseExpression(true, CHECK_OK); 1077 ParseExpression(true, CHECK_OK);
1078 Expect(i::Token::RBRACK, CHECK_OK); 1078 Expect(Token::RBRACK, CHECK_OK);
1079 if (result.IsThis()) { 1079 if (result.IsThis()) {
1080 result = Expression::ThisProperty(); 1080 result = Expression::ThisProperty();
1081 } else { 1081 } else {
1082 result = Expression::Default(); 1082 result = Expression::Default();
1083 } 1083 }
1084 break; 1084 break;
1085 } 1085 }
1086 case i::Token::PERIOD: { 1086 case Token::PERIOD: {
1087 Consume(i::Token::PERIOD); 1087 Consume(Token::PERIOD);
1088 ParseIdentifierName(CHECK_OK); 1088 ParseIdentifierName(CHECK_OK);
1089 if (result.IsThis()) { 1089 if (result.IsThis()) {
1090 result = Expression::ThisProperty(); 1090 result = Expression::ThisProperty();
1091 } else { 1091 } else {
1092 result = Expression::Default(); 1092 result = Expression::Default();
1093 } 1093 }
1094 break; 1094 break;
1095 } 1095 }
1096 case i::Token::LPAREN: { 1096 case Token::LPAREN: {
1097 if (new_count == 0) return result; 1097 if (new_count == 0) return result;
1098 // Consume one of the new prefixes (already parsed). 1098 // Consume one of the new prefixes (already parsed).
1099 ParseArguments(CHECK_OK); 1099 ParseArguments(CHECK_OK);
1100 new_count--; 1100 new_count--;
1101 result = Expression::Default(); 1101 result = Expression::Default();
1102 break; 1102 break;
1103 } 1103 }
1104 default: 1104 default:
1105 return result; 1105 return result;
1106 } 1106 }
(...skipping 10 matching lines...) Expand all
1117 // Identifier 1117 // Identifier
1118 // Number 1118 // Number
1119 // String 1119 // String
1120 // ArrayLiteral 1120 // ArrayLiteral
1121 // ObjectLiteral 1121 // ObjectLiteral
1122 // RegExpLiteral 1122 // RegExpLiteral
1123 // '(' Expression ')' 1123 // '(' Expression ')'
1124 1124
1125 Expression result = Expression::Default(); 1125 Expression result = Expression::Default();
1126 switch (peek()) { 1126 switch (peek()) {
1127 case i::Token::THIS: { 1127 case Token::THIS: {
1128 Next(); 1128 Next();
1129 result = Expression::This(); 1129 result = Expression::This();
1130 break; 1130 break;
1131 } 1131 }
1132 1132
1133 case i::Token::FUTURE_RESERVED_WORD: 1133 case Token::FUTURE_RESERVED_WORD:
1134 case i::Token::FUTURE_STRICT_RESERVED_WORD: 1134 case Token::FUTURE_STRICT_RESERVED_WORD:
1135 case i::Token::YIELD: 1135 case Token::YIELD:
1136 case i::Token::IDENTIFIER: { 1136 case Token::IDENTIFIER: {
1137 Identifier id = ParseIdentifier(CHECK_OK); 1137 Identifier id = ParseIdentifier(CHECK_OK);
1138 result = Expression::FromIdentifier(id); 1138 result = Expression::FromIdentifier(id);
1139 break; 1139 break;
1140 } 1140 }
1141 1141
1142 case i::Token::NULL_LITERAL: 1142 case Token::NULL_LITERAL:
1143 case i::Token::TRUE_LITERAL: 1143 case Token::TRUE_LITERAL:
1144 case i::Token::FALSE_LITERAL: 1144 case Token::FALSE_LITERAL:
1145 case i::Token::NUMBER: { 1145 case Token::NUMBER: {
1146 Next(); 1146 Next();
1147 break; 1147 break;
1148 } 1148 }
1149 case i::Token::STRING: { 1149 case Token::STRING: {
1150 Next(); 1150 Next();
1151 result = GetStringSymbol(); 1151 result = GetStringSymbol();
1152 break; 1152 break;
1153 } 1153 }
1154 1154
1155 case i::Token::ASSIGN_DIV: 1155 case Token::ASSIGN_DIV:
1156 result = ParseRegExpLiteral(true, CHECK_OK); 1156 result = ParseRegExpLiteral(true, CHECK_OK);
1157 break; 1157 break;
1158 1158
1159 case i::Token::DIV: 1159 case Token::DIV:
1160 result = ParseRegExpLiteral(false, CHECK_OK); 1160 result = ParseRegExpLiteral(false, CHECK_OK);
1161 break; 1161 break;
1162 1162
1163 case i::Token::LBRACK: 1163 case Token::LBRACK:
1164 result = ParseArrayLiteral(CHECK_OK); 1164 result = ParseArrayLiteral(CHECK_OK);
1165 break; 1165 break;
1166 1166
1167 case i::Token::LBRACE: 1167 case Token::LBRACE:
1168 result = ParseObjectLiteral(CHECK_OK); 1168 result = ParseObjectLiteral(CHECK_OK);
1169 break; 1169 break;
1170 1170
1171 case i::Token::LPAREN: 1171 case Token::LPAREN:
1172 Consume(i::Token::LPAREN); 1172 Consume(Token::LPAREN);
1173 parenthesized_function_ = (peek() == i::Token::FUNCTION); 1173 parenthesized_function_ = (peek() == Token::FUNCTION);
1174 result = ParseExpression(true, CHECK_OK); 1174 result = ParseExpression(true, CHECK_OK);
1175 Expect(i::Token::RPAREN, CHECK_OK); 1175 Expect(Token::RPAREN, CHECK_OK);
1176 result = result.Parenthesize(); 1176 result = result.Parenthesize();
1177 break; 1177 break;
1178 1178
1179 case i::Token::MOD: 1179 case Token::MOD:
1180 result = ParseV8Intrinsic(CHECK_OK); 1180 result = ParseV8Intrinsic(CHECK_OK);
1181 break; 1181 break;
1182 1182
1183 default: { 1183 default: {
1184 Next(); 1184 Next();
1185 *ok = false; 1185 *ok = false;
1186 return Expression::Default(); 1186 return Expression::Default();
1187 } 1187 }
1188 } 1188 }
1189 1189
1190 return result; 1190 return result;
1191 } 1191 }
1192 1192
1193 1193
1194 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) { 1194 PreParser::Expression PreParser::ParseArrayLiteral(bool* ok) {
1195 // ArrayLiteral :: 1195 // ArrayLiteral ::
1196 // '[' Expression? (',' Expression?)* ']' 1196 // '[' Expression? (',' Expression?)* ']'
1197 Expect(i::Token::LBRACK, CHECK_OK); 1197 Expect(Token::LBRACK, CHECK_OK);
1198 while (peek() != i::Token::RBRACK) { 1198 while (peek() != Token::RBRACK) {
1199 if (peek() != i::Token::COMMA) { 1199 if (peek() != Token::COMMA) {
1200 ParseAssignmentExpression(true, CHECK_OK); 1200 ParseAssignmentExpression(true, CHECK_OK);
1201 } 1201 }
1202 if (peek() != i::Token::RBRACK) { 1202 if (peek() != Token::RBRACK) {
1203 Expect(i::Token::COMMA, CHECK_OK); 1203 Expect(Token::COMMA, CHECK_OK);
1204 } 1204 }
1205 } 1205 }
1206 Expect(i::Token::RBRACK, CHECK_OK); 1206 Expect(Token::RBRACK, CHECK_OK);
1207 1207
1208 scope_->NextMaterializedLiteralIndex(); 1208 scope_->NextMaterializedLiteralIndex();
1209 return Expression::Default(); 1209 return Expression::Default();
1210 } 1210 }
1211 1211
1212 1212
1213 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) { 1213 PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
1214 // ObjectLiteral :: 1214 // ObjectLiteral ::
1215 // '{' ( 1215 // '{' (
1216 // ((IdentifierName | String | Number) ':' AssignmentExpression) 1216 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1217 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1217 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1218 // )*[','] '}' 1218 // )*[','] '}'
1219 1219
1220 ObjectLiteralChecker checker(this, language_mode()); 1220 ObjectLiteralChecker checker(this, language_mode());
1221 1221
1222 Expect(i::Token::LBRACE, CHECK_OK); 1222 Expect(Token::LBRACE, CHECK_OK);
1223 while (peek() != i::Token::RBRACE) { 1223 while (peek() != Token::RBRACE) {
1224 i::Token::Value next = peek(); 1224 Token::Value next = peek();
1225 switch (next) { 1225 switch (next) {
1226 case i::Token::IDENTIFIER: 1226 case Token::IDENTIFIER:
1227 case i::Token::FUTURE_RESERVED_WORD: 1227 case Token::FUTURE_RESERVED_WORD:
1228 case i::Token::FUTURE_STRICT_RESERVED_WORD: { 1228 case Token::FUTURE_STRICT_RESERVED_WORD: {
1229 bool is_getter = false; 1229 bool is_getter = false;
1230 bool is_setter = false; 1230 bool is_setter = false;
1231 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1231 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1232 if ((is_getter || is_setter) && peek() != i::Token::COLON) { 1232 if ((is_getter || is_setter) && peek() != Token::COLON) {
1233 i::Token::Value name = Next(); 1233 Token::Value name = Next();
1234 bool is_keyword = i::Token::IsKeyword(name); 1234 bool is_keyword = Token::IsKeyword(name);
1235 if (name != i::Token::IDENTIFIER && 1235 if (name != Token::IDENTIFIER &&
1236 name != i::Token::FUTURE_RESERVED_WORD && 1236 name != Token::FUTURE_RESERVED_WORD &&
1237 name != i::Token::FUTURE_STRICT_RESERVED_WORD && 1237 name != Token::FUTURE_STRICT_RESERVED_WORD &&
1238 name != i::Token::NUMBER && 1238 name != Token::NUMBER &&
1239 name != i::Token::STRING && 1239 name != Token::STRING &&
1240 !is_keyword) { 1240 !is_keyword) {
1241 *ok = false; 1241 *ok = false;
1242 return Expression::Default(); 1242 return Expression::Default();
1243 } 1243 }
1244 if (!is_keyword) { 1244 if (!is_keyword) {
1245 LogSymbol(); 1245 LogSymbol();
1246 } 1246 }
1247 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1247 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1248 checker.CheckProperty(name, type, CHECK_OK); 1248 checker.CheckProperty(name, type, CHECK_OK);
1249 ParseFunctionLiteral(false, CHECK_OK); 1249 ParseFunctionLiteral(false, CHECK_OK);
1250 if (peek() != i::Token::RBRACE) { 1250 if (peek() != Token::RBRACE) {
1251 Expect(i::Token::COMMA, CHECK_OK); 1251 Expect(Token::COMMA, CHECK_OK);
1252 } 1252 }
1253 continue; // restart the while 1253 continue; // restart the while
1254 } 1254 }
1255 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1255 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1256 break; 1256 break;
1257 } 1257 }
1258 case i::Token::STRING: 1258 case Token::STRING:
1259 Consume(next); 1259 Consume(next);
1260 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1260 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1261 GetStringSymbol(); 1261 GetStringSymbol();
1262 break; 1262 break;
1263 case i::Token::NUMBER: 1263 case Token::NUMBER:
1264 Consume(next); 1264 Consume(next);
1265 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1265 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1266 break; 1266 break;
1267 default: 1267 default:
1268 if (i::Token::IsKeyword(next)) { 1268 if (Token::IsKeyword(next)) {
1269 Consume(next); 1269 Consume(next);
1270 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1270 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1271 } else { 1271 } else {
1272 // Unexpected token. 1272 // Unexpected token.
1273 *ok = false; 1273 *ok = false;
1274 return Expression::Default(); 1274 return Expression::Default();
1275 } 1275 }
1276 } 1276 }
1277 1277
1278 Expect(i::Token::COLON, CHECK_OK); 1278 Expect(Token::COLON, CHECK_OK);
1279 ParseAssignmentExpression(true, CHECK_OK); 1279 ParseAssignmentExpression(true, CHECK_OK);
1280 1280
1281 // TODO(1240767): Consider allowing trailing comma. 1281 // TODO(1240767): Consider allowing trailing comma.
1282 if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK); 1282 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
1283 } 1283 }
1284 Expect(i::Token::RBRACE, CHECK_OK); 1284 Expect(Token::RBRACE, CHECK_OK);
1285 1285
1286 scope_->NextMaterializedLiteralIndex(); 1286 scope_->NextMaterializedLiteralIndex();
1287 return Expression::Default(); 1287 return Expression::Default();
1288 } 1288 }
1289 1289
1290 1290
1291 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal, 1291 PreParser::Expression PreParser::ParseRegExpLiteral(bool seen_equal,
1292 bool* ok) { 1292 bool* ok) {
1293 if (!scanner()->ScanRegExpPattern(seen_equal)) { 1293 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1294 Next(); 1294 Next();
(...skipping 12 matching lines...) Expand all
1307 } 1307 }
1308 Next(); 1308 Next();
1309 return Expression::Default(); 1309 return Expression::Default();
1310 } 1310 }
1311 1311
1312 1312
1313 PreParser::Arguments PreParser::ParseArguments(bool* ok) { 1313 PreParser::Arguments PreParser::ParseArguments(bool* ok) {
1314 // Arguments :: 1314 // Arguments ::
1315 // '(' (AssignmentExpression)*[','] ')' 1315 // '(' (AssignmentExpression)*[','] ')'
1316 1316
1317 Expect(i::Token::LPAREN, ok); 1317 Expect(Token::LPAREN, ok);
1318 if (!*ok) return -1; 1318 if (!*ok) return -1;
1319 bool done = (peek() == i::Token::RPAREN); 1319 bool done = (peek() == Token::RPAREN);
1320 int argc = 0; 1320 int argc = 0;
1321 while (!done) { 1321 while (!done) {
1322 ParseAssignmentExpression(true, ok); 1322 ParseAssignmentExpression(true, ok);
1323 if (!*ok) return -1; 1323 if (!*ok) return -1;
1324 argc++; 1324 argc++;
1325 done = (peek() == i::Token::RPAREN); 1325 done = (peek() == Token::RPAREN);
1326 if (!done) { 1326 if (!done) {
1327 Expect(i::Token::COMMA, ok); 1327 Expect(Token::COMMA, ok);
1328 if (!*ok) return -1; 1328 if (!*ok) return -1;
1329 } 1329 }
1330 } 1330 }
1331 Expect(i::Token::RPAREN, ok); 1331 Expect(Token::RPAREN, ok);
1332 return argc; 1332 return argc;
1333 } 1333 }
1334 1334
1335 1335
1336 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator, 1336 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
1337 bool* ok) { 1337 bool* ok) {
1338 // Function :: 1338 // Function ::
1339 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1339 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1340 1340
1341 // Parse function body. 1341 // Parse function body.
1342 ScopeType outer_scope_type = scope_->type(); 1342 ScopeType outer_scope_type = scope_->type();
1343 bool inside_with = scope_->IsInsideWith(); 1343 bool inside_with = scope_->IsInsideWith();
1344 Scope function_scope(&scope_, kFunctionScope); 1344 Scope function_scope(&scope_, kFunctionScope);
1345 function_scope.set_is_generator(is_generator); 1345 function_scope.set_is_generator(is_generator);
1346 // FormalParameterList :: 1346 // FormalParameterList ::
1347 // '(' (Identifier)*[','] ')' 1347 // '(' (Identifier)*[','] ')'
1348 Expect(i::Token::LPAREN, CHECK_OK); 1348 Expect(Token::LPAREN, CHECK_OK);
1349 int start_position = position(); 1349 int start_position = position();
1350 bool done = (peek() == i::Token::RPAREN); 1350 bool done = (peek() == Token::RPAREN);
1351 i::DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 1351 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
1352 while (!done) { 1352 while (!done) {
1353 Identifier id = ParseIdentifier(CHECK_OK); 1353 Identifier id = ParseIdentifier(CHECK_OK);
1354 if (!id.IsValidStrictVariable()) { 1354 if (!id.IsValidStrictVariable()) {
1355 StrictModeIdentifierViolation(scanner()->location(), 1355 StrictModeIdentifierViolation(scanner()->location(),
1356 "strict_param_name", 1356 "strict_param_name",
1357 id, 1357 id,
1358 CHECK_OK); 1358 CHECK_OK);
1359 } 1359 }
1360 int prev_value; 1360 int prev_value;
1361 if (scanner()->is_literal_ascii()) { 1361 if (scanner()->is_literal_ascii()) {
1362 prev_value = 1362 prev_value =
1363 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); 1363 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1);
1364 } else { 1364 } else {
1365 prev_value = 1365 prev_value =
1366 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); 1366 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1);
1367 } 1367 }
1368 1368
1369 if (prev_value != 0) { 1369 if (prev_value != 0) {
1370 SetStrictModeViolation(scanner()->location(), 1370 SetStrictModeViolation(scanner()->location(),
1371 "strict_param_dupe", 1371 "strict_param_dupe",
1372 CHECK_OK); 1372 CHECK_OK);
1373 } 1373 }
1374 done = (peek() == i::Token::RPAREN); 1374 done = (peek() == Token::RPAREN);
1375 if (!done) { 1375 if (!done) {
1376 Expect(i::Token::COMMA, CHECK_OK); 1376 Expect(Token::COMMA, CHECK_OK);
1377 } 1377 }
1378 } 1378 }
1379 Expect(i::Token::RPAREN, CHECK_OK); 1379 Expect(Token::RPAREN, CHECK_OK);
1380 1380
1381 // Determine if the function will be lazily compiled. 1381 // Determine if the function will be lazily compiled.
1382 // Currently only happens to top-level functions. 1382 // Currently only happens to top-level functions.
1383 // Optimistically assume that all top-level functions are lazily compiled. 1383 // Optimistically assume that all top-level functions are lazily compiled.
1384 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope && 1384 bool is_lazily_compiled = (outer_scope_type == kTopLevelScope &&
1385 !inside_with && allow_lazy() && 1385 !inside_with && allow_lazy() &&
1386 !parenthesized_function_); 1386 !parenthesized_function_);
1387 parenthesized_function_ = false; 1387 parenthesized_function_ = false;
1388 1388
1389 Expect(i::Token::LBRACE, CHECK_OK); 1389 Expect(Token::LBRACE, CHECK_OK);
1390 if (is_lazily_compiled) { 1390 if (is_lazily_compiled) {
1391 ParseLazyFunctionLiteralBody(CHECK_OK); 1391 ParseLazyFunctionLiteralBody(CHECK_OK);
1392 } else { 1392 } else {
1393 ParseSourceElements(i::Token::RBRACE, ok); 1393 ParseSourceElements(Token::RBRACE, ok);
1394 } 1394 }
1395 Expect(i::Token::RBRACE, CHECK_OK); 1395 Expect(Token::RBRACE, CHECK_OK);
1396 1396
1397 if (!is_classic_mode()) { 1397 if (!is_classic_mode()) {
1398 int end_position = scanner()->location().end_pos; 1398 int end_position = scanner()->location().end_pos;
1399 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1399 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1400 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); 1400 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1401 return Expression::StrictFunction(); 1401 return Expression::StrictFunction();
1402 } 1402 }
1403 1403
1404 return Expression::Default(); 1404 return Expression::Default();
1405 } 1405 }
1406 1406
1407 1407
1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) { 1408 void PreParser::ParseLazyFunctionLiteralBody(bool* ok) {
1409 int body_start = position(); 1409 int body_start = position();
1410 log_->PauseRecording(); 1410 log_->PauseRecording();
1411 ParseSourceElements(i::Token::RBRACE, ok); 1411 ParseSourceElements(Token::RBRACE, ok);
1412 log_->ResumeRecording(); 1412 log_->ResumeRecording();
1413 if (!*ok) return; 1413 if (!*ok) return;
1414 1414
1415 // Position right after terminal '}'. 1415 // Position right after terminal '}'.
1416 ASSERT_EQ(i::Token::RBRACE, scanner()->peek()); 1416 ASSERT_EQ(Token::RBRACE, scanner()->peek());
1417 int body_end = scanner()->peek_location().end_pos; 1417 int body_end = scanner()->peek_location().end_pos;
1418 log_->LogFunction(body_start, body_end, 1418 log_->LogFunction(body_start, body_end,
1419 scope_->materialized_literal_count(), 1419 scope_->materialized_literal_count(),
1420 scope_->expected_properties(), 1420 scope_->expected_properties(),
1421 language_mode()); 1421 language_mode());
1422 } 1422 }
1423 1423
1424 1424
1425 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1425 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
1426 // CallRuntime :: 1426 // CallRuntime ::
1427 // '%' Identifier Arguments 1427 // '%' Identifier Arguments
1428 Expect(i::Token::MOD, CHECK_OK); 1428 Expect(Token::MOD, CHECK_OK);
1429 if (!allow_natives_syntax()) { 1429 if (!allow_natives_syntax()) {
1430 *ok = false; 1430 *ok = false;
1431 return Expression::Default(); 1431 return Expression::Default();
1432 } 1432 }
1433 ParseIdentifier(CHECK_OK); 1433 ParseIdentifier(CHECK_OK);
1434 ParseArguments(ok); 1434 ParseArguments(ok);
1435 1435
1436 return Expression::Default(); 1436 return Expression::Default();
1437 } 1437 }
1438 1438
(...skipping 20 matching lines...) Expand all
1459 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars, 1459 !strncmp(scanner()->literal_ascii_string().start(), kUseStrictChars,
1460 kUseStrictLength)) { 1460 kUseStrictLength)) {
1461 return Expression::UseStrictStringLiteral(); 1461 return Expression::UseStrictStringLiteral();
1462 } 1462 }
1463 return Expression::StringLiteral(); 1463 return Expression::StringLiteral();
1464 } 1464 }
1465 1465
1466 1466
1467 PreParser::Identifier PreParser::GetIdentifierSymbol() { 1467 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1468 LogSymbol(); 1468 LogSymbol();
1469 if (scanner()->current_token() == i::Token::FUTURE_RESERVED_WORD) { 1469 if (scanner()->current_token() == Token::FUTURE_RESERVED_WORD) {
1470 return Identifier::FutureReserved(); 1470 return Identifier::FutureReserved();
1471 } else if (scanner()->current_token() == 1471 } else if (scanner()->current_token() ==
1472 i::Token::FUTURE_STRICT_RESERVED_WORD) { 1472 Token::FUTURE_STRICT_RESERVED_WORD) {
1473 return Identifier::FutureStrictReserved(); 1473 return Identifier::FutureStrictReserved();
1474 } else if (scanner()->current_token() == i::Token::YIELD) { 1474 } else if (scanner()->current_token() == Token::YIELD) {
1475 return Identifier::Yield(); 1475 return Identifier::Yield();
1476 } 1476 }
1477 if (scanner()->is_literal_ascii()) { 1477 if (scanner()->is_literal_ascii()) {
1478 // Detect strict-mode poison words. 1478 // Detect strict-mode poison words.
1479 if (scanner()->literal_length() == 4 && 1479 if (scanner()->literal_length() == 4 &&
1480 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) { 1480 !strncmp(scanner()->literal_ascii_string().start(), "eval", 4)) {
1481 return Identifier::Eval(); 1481 return Identifier::Eval();
1482 } 1482 }
1483 if (scanner()->literal_length() == 9 && 1483 if (scanner()->literal_length() == 9 &&
1484 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) { 1484 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) {
1485 return Identifier::Arguments(); 1485 return Identifier::Arguments();
1486 } 1486 }
1487 } 1487 }
1488 return Identifier::Default(); 1488 return Identifier::Default();
1489 } 1489 }
1490 1490
1491 1491
1492 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { 1492 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1493 i::Token::Value next = Next(); 1493 Token::Value next = Next();
1494 switch (next) { 1494 switch (next) {
1495 case i::Token::FUTURE_RESERVED_WORD: { 1495 case Token::FUTURE_RESERVED_WORD: {
1496 i::Scanner::Location location = scanner()->location(); 1496 Scanner::Location location = scanner()->location();
1497 ReportMessageAt(location.beg_pos, location.end_pos, 1497 ReportMessageAt(location.beg_pos, location.end_pos,
1498 "reserved_word", NULL); 1498 "reserved_word", NULL);
1499 *ok = false; 1499 *ok = false;
1500 return GetIdentifierSymbol(); 1500 return GetIdentifierSymbol();
1501 } 1501 }
1502 case i::Token::YIELD: 1502 case Token::YIELD:
1503 if (scope_->is_generator()) { 1503 if (scope_->is_generator()) {
1504 // 'yield' in a generator is only valid as part of a YieldExpression. 1504 // 'yield' in a generator is only valid as part of a YieldExpression.
1505 ReportMessageAt(scanner()->location(), "unexpected_token", "yield"); 1505 ReportMessageAt(scanner()->location(), "unexpected_token", "yield");
1506 *ok = false; 1506 *ok = false;
1507 return Identifier::Yield(); 1507 return Identifier::Yield();
1508 } 1508 }
1509 // FALLTHROUGH 1509 // FALLTHROUGH
1510 case i::Token::FUTURE_STRICT_RESERVED_WORD: 1510 case Token::FUTURE_STRICT_RESERVED_WORD:
1511 if (!is_classic_mode()) { 1511 if (!is_classic_mode()) {
1512 i::Scanner::Location location = scanner()->location(); 1512 Scanner::Location location = scanner()->location();
1513 ReportMessageAt(location.beg_pos, location.end_pos, 1513 ReportMessageAt(location.beg_pos, location.end_pos,
1514 "strict_reserved_word", NULL); 1514 "strict_reserved_word", NULL);
1515 *ok = false; 1515 *ok = false;
1516 } 1516 }
1517 // FALLTHROUGH 1517 // FALLTHROUGH
1518 case i::Token::IDENTIFIER: 1518 case Token::IDENTIFIER:
1519 return GetIdentifierSymbol(); 1519 return GetIdentifierSymbol();
1520 default: 1520 default:
1521 *ok = false; 1521 *ok = false;
1522 return Identifier::Default(); 1522 return Identifier::Default();
1523 } 1523 }
1524 } 1524 }
1525 1525
1526 1526
1527 void PreParser::SetStrictModeViolation(i::Scanner::Location location, 1527 void PreParser::SetStrictModeViolation(Scanner::Location location,
1528 const char* type, 1528 const char* type,
1529 bool* ok) { 1529 bool* ok) {
1530 if (!is_classic_mode()) { 1530 if (!is_classic_mode()) {
1531 ReportMessageAt(location, type, NULL); 1531 ReportMessageAt(location, type, NULL);
1532 *ok = false; 1532 *ok = false;
1533 return; 1533 return;
1534 } 1534 }
1535 // Delay report in case this later turns out to be strict code 1535 // Delay report in case this later turns out to be strict code
1536 // (i.e., for function names and parameters prior to a "use strict" 1536 // (i.e., for function names and parameters prior to a "use strict"
1537 // directive). 1537 // directive).
1538 // It's safe to overwrite an existing violation. 1538 // It's safe to overwrite an existing violation.
1539 // It's either from a function that turned out to be non-strict, 1539 // It's either from a function that turned out to be non-strict,
1540 // or it's in the current function (and we just need to report 1540 // or it's in the current function (and we just need to report
1541 // one error), or it's in a unclosed nesting function that wasn't 1541 // one error), or it's in a unclosed nesting function that wasn't
1542 // strict (otherwise we would already be in strict mode). 1542 // strict (otherwise we would already be in strict mode).
1543 strict_mode_violation_location_ = location; 1543 strict_mode_violation_location_ = location;
1544 strict_mode_violation_type_ = type; 1544 strict_mode_violation_type_ = type;
1545 } 1545 }
1546 1546
1547 1547
1548 void PreParser::CheckDelayedStrictModeViolation(int beg_pos, 1548 void PreParser::CheckDelayedStrictModeViolation(int beg_pos,
1549 int end_pos, 1549 int end_pos,
1550 bool* ok) { 1550 bool* ok) {
1551 i::Scanner::Location location = strict_mode_violation_location_; 1551 Scanner::Location location = strict_mode_violation_location_;
1552 if (location.IsValid() && 1552 if (location.IsValid() &&
1553 location.beg_pos > beg_pos && location.end_pos < end_pos) { 1553 location.beg_pos > beg_pos && location.end_pos < end_pos) {
1554 ReportMessageAt(location, strict_mode_violation_type_, NULL); 1554 ReportMessageAt(location, strict_mode_violation_type_, NULL);
1555 *ok = false; 1555 *ok = false;
1556 } 1556 }
1557 } 1557 }
1558 1558
1559 1559
1560 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location, 1560 void PreParser::StrictModeIdentifierViolation(Scanner::Location location,
1561 const char* eval_args_type, 1561 const char* eval_args_type,
1562 Identifier identifier, 1562 Identifier identifier,
1563 bool* ok) { 1563 bool* ok) {
1564 const char* type = eval_args_type; 1564 const char* type = eval_args_type;
1565 if (identifier.IsFutureReserved()) { 1565 if (identifier.IsFutureReserved()) {
1566 type = "reserved_word"; 1566 type = "reserved_word";
1567 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { 1567 } else if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
1568 type = "strict_reserved_word"; 1568 type = "strict_reserved_word";
1569 } 1569 }
1570 if (!is_classic_mode()) { 1570 if (!is_classic_mode()) {
1571 ReportMessageAt(location, type, NULL); 1571 ReportMessageAt(location, type, NULL);
1572 *ok = false; 1572 *ok = false;
1573 return; 1573 return;
1574 } 1574 }
1575 strict_mode_violation_location_ = location; 1575 strict_mode_violation_location_ = location;
1576 strict_mode_violation_type_ = type; 1576 strict_mode_violation_type_ = type;
1577 } 1577 }
1578 1578
1579 1579
1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { 1580 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1581 i::Token::Value next = Next(); 1581 Token::Value next = Next();
1582 if (i::Token::IsKeyword(next)) { 1582 if (Token::IsKeyword(next)) {
1583 int pos = position(); 1583 int pos = position();
1584 const char* keyword = i::Token::String(next); 1584 const char* keyword = Token::String(next);
1585 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, 1585 log_->LogAsciiSymbol(pos, Vector<const char>(keyword, StrLength(keyword)));
1586 i::StrLength(keyword)));
1587 return Identifier::Default(); 1586 return Identifier::Default();
1588 } 1587 }
1589 if (next == i::Token::IDENTIFIER || 1588 if (next == Token::IDENTIFIER ||
1590 next == i::Token::FUTURE_RESERVED_WORD || 1589 next == Token::FUTURE_RESERVED_WORD ||
1591 next == i::Token::FUTURE_STRICT_RESERVED_WORD) { 1590 next == Token::FUTURE_STRICT_RESERVED_WORD) {
1592 return GetIdentifierSymbol(); 1591 return GetIdentifierSymbol();
1593 } 1592 }
1594 *ok = false; 1593 *ok = false;
1595 return Identifier::Default(); 1594 return Identifier::Default();
1596 } 1595 }
1597 1596
1598 #undef CHECK_OK 1597 #undef CHECK_OK
1599 1598
1600 1599
1601 // This function reads an identifier and determines whether or not it 1600 // This function reads an identifier and determines whether or not it
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 ASSERT(IsAccessorAccessorConflict(old_type, type)); 1640 ASSERT(IsAccessorAccessorConflict(old_type, type));
1642 // Both accessors of the same type. 1641 // Both accessors of the same type.
1643 parser()->ReportMessageAt(scanner()->location(), 1642 parser()->ReportMessageAt(scanner()->location(),
1644 "accessor_get_set"); 1643 "accessor_get_set");
1645 } 1644 }
1646 *ok = false; 1645 *ok = false;
1647 } 1646 }
1648 } 1647 }
1649 1648
1650 } } // v8::internal 1649 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698