OLD | NEW |
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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 118 |
119 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { | 119 PreParser::Statement PreParser::ParseSourceElement(bool* ok) { |
120 // (Ecma 262 5th Edition, clause 14): | 120 // (Ecma 262 5th Edition, clause 14): |
121 // SourceElement: | 121 // SourceElement: |
122 // Statement | 122 // Statement |
123 // FunctionDeclaration | 123 // FunctionDeclaration |
124 // | 124 // |
125 // In harmony mode we allow additionally the following productions | 125 // In harmony mode we allow additionally the following productions |
126 // SourceElement: | 126 // SourceElement: |
127 // LetDeclaration | 127 // LetDeclaration |
| 128 // ConstDeclaration |
128 | 129 |
129 switch (peek()) { | 130 switch (peek()) { |
130 case i::Token::FUNCTION: | 131 case i::Token::FUNCTION: |
131 return ParseFunctionDeclaration(ok); | 132 return ParseFunctionDeclaration(ok); |
132 case i::Token::LET: | 133 case i::Token::LET: |
| 134 case i::Token::CONST: |
133 return ParseVariableStatement(kSourceElement, ok); | 135 return ParseVariableStatement(kSourceElement, ok); |
134 default: | 136 default: |
135 return ParseStatement(ok); | 137 return ParseStatement(ok); |
136 } | 138 } |
137 } | 139 } |
138 | 140 |
139 | 141 |
140 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, | 142 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
141 bool* ok) { | 143 bool* ok) { |
142 // SourceElements :: | 144 // SourceElements :: |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 case i::Token::THROW: | 235 case i::Token::THROW: |
234 return ParseThrowStatement(ok); | 236 return ParseThrowStatement(ok); |
235 | 237 |
236 case i::Token::TRY: | 238 case i::Token::TRY: |
237 return ParseTryStatement(ok); | 239 return ParseTryStatement(ok); |
238 | 240 |
239 case i::Token::FUNCTION: { | 241 case i::Token::FUNCTION: { |
240 i::Scanner::Location start_location = scanner_->peek_location(); | 242 i::Scanner::Location start_location = scanner_->peek_location(); |
241 Statement statement = ParseFunctionDeclaration(CHECK_OK); | 243 Statement statement = ParseFunctionDeclaration(CHECK_OK); |
242 i::Scanner::Location end_location = scanner_->location(); | 244 i::Scanner::Location end_location = scanner_->location(); |
243 if (strict_mode()) { | 245 if (strict_mode() || harmony_scoping_) { |
244 ReportMessageAt(start_location.beg_pos, end_location.end_pos, | 246 ReportMessageAt(start_location.beg_pos, end_location.end_pos, |
245 "strict_function", NULL); | 247 "strict_function", NULL); |
246 *ok = false; | 248 *ok = false; |
247 return Statement::Default(); | 249 return Statement::Default(); |
248 } else { | 250 } else { |
249 return statement; | 251 return statement; |
250 } | 252 } |
251 } | 253 } |
252 | 254 |
253 case i::Token::DEBUGGER: | 255 case i::Token::DEBUGGER: |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 | 307 |
306 | 308 |
307 PreParser::Statement PreParser::ParseVariableStatement( | 309 PreParser::Statement PreParser::ParseVariableStatement( |
308 VariableDeclarationContext var_context, | 310 VariableDeclarationContext var_context, |
309 bool* ok) { | 311 bool* ok) { |
310 // VariableStatement :: | 312 // VariableStatement :: |
311 // VariableDeclarations ';' | 313 // VariableDeclarations ';' |
312 | 314 |
313 Statement result = ParseVariableDeclarations(var_context, | 315 Statement result = ParseVariableDeclarations(var_context, |
314 NULL, | 316 NULL, |
| 317 NULL, |
315 CHECK_OK); | 318 CHECK_OK); |
316 ExpectSemicolon(CHECK_OK); | 319 ExpectSemicolon(CHECK_OK); |
317 return result; | 320 return result; |
318 } | 321 } |
319 | 322 |
320 | 323 |
321 // If the variable declaration declares exactly one non-const | 324 // If the variable declaration declares exactly one non-const |
322 // variable, then *var is set to that variable. In all other cases, | 325 // variable, then *var is set to that variable. In all other cases, |
323 // *var is untouched; in particular, it is the caller's responsibility | 326 // *var is untouched; in particular, it is the caller's responsibility |
324 // to initialize it properly. This mechanism is also used for the parsing | 327 // to initialize it properly. This mechanism is also used for the parsing |
325 // of 'for-in' loops. | 328 // of 'for-in' loops. |
326 PreParser::Statement PreParser::ParseVariableDeclarations( | 329 PreParser::Statement PreParser::ParseVariableDeclarations( |
327 VariableDeclarationContext var_context, | 330 VariableDeclarationContext var_context, |
| 331 VariableDeclarationProperties* decl_props, |
328 int* num_decl, | 332 int* num_decl, |
329 bool* ok) { | 333 bool* ok) { |
330 // VariableDeclarations :: | 334 // VariableDeclarations :: |
331 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 335 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
332 | 336 // |
| 337 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
| 338 // |
| 339 // ConstDeclaration :: |
| 340 // const ConstBinding (',' ConstBinding)* ';' |
| 341 // ConstBinding :: |
| 342 // Identifier '=' AssignmentExpression |
| 343 // |
| 344 // TODO(ES6): |
| 345 // ConstBinding :: |
| 346 // BindingPattern '=' AssignmentExpression |
| 347 bool require_initializer = false; |
333 if (peek() == i::Token::VAR) { | 348 if (peek() == i::Token::VAR) { |
334 Consume(i::Token::VAR); | 349 Consume(i::Token::VAR); |
335 } else if (peek() == i::Token::CONST) { | 350 } else if (peek() == i::Token::CONST) { |
336 if (strict_mode()) { | 351 if (harmony_scoping_) { |
| 352 if (var_context != kSourceElement && |
| 353 var_context != kForStatement) { |
| 354 i::Scanner::Location location = scanner_->peek_location(); |
| 355 ReportMessageAt(location.beg_pos, location.end_pos, |
| 356 "unprotected_const", NULL); |
| 357 *ok = false; |
| 358 return Statement::Default(); |
| 359 } |
| 360 require_initializer = true; |
| 361 } else if (strict_mode()) { |
337 i::Scanner::Location location = scanner_->peek_location(); | 362 i::Scanner::Location location = scanner_->peek_location(); |
338 ReportMessageAt(location, "strict_const", NULL); | 363 ReportMessageAt(location, "strict_const", NULL); |
339 *ok = false; | 364 *ok = false; |
340 return Statement::Default(); | 365 return Statement::Default(); |
341 } | 366 } |
342 Consume(i::Token::CONST); | 367 Consume(i::Token::CONST); |
343 } else if (peek() == i::Token::LET) { | 368 } else if (peek() == i::Token::LET) { |
344 if (var_context != kSourceElement && | 369 if (var_context != kSourceElement && |
345 var_context != kForStatement) { | 370 var_context != kForStatement) { |
346 i::Scanner::Location location = scanner_->peek_location(); | 371 i::Scanner::Location location = scanner_->peek_location(); |
(...skipping 18 matching lines...) Expand all Loading... |
365 if (nvars > 0) Consume(i::Token::COMMA); | 390 if (nvars > 0) Consume(i::Token::COMMA); |
366 Identifier identifier = ParseIdentifier(CHECK_OK); | 391 Identifier identifier = ParseIdentifier(CHECK_OK); |
367 if (strict_mode() && !identifier.IsValidStrictVariable()) { | 392 if (strict_mode() && !identifier.IsValidStrictVariable()) { |
368 StrictModeIdentifierViolation(scanner_->location(), | 393 StrictModeIdentifierViolation(scanner_->location(), |
369 "strict_var_name", | 394 "strict_var_name", |
370 identifier, | 395 identifier, |
371 ok); | 396 ok); |
372 return Statement::Default(); | 397 return Statement::Default(); |
373 } | 398 } |
374 nvars++; | 399 nvars++; |
375 if (peek() == i::Token::ASSIGN) { | 400 if (peek() == i::Token::ASSIGN || require_initializer) { |
376 Expect(i::Token::ASSIGN, CHECK_OK); | 401 Expect(i::Token::ASSIGN, CHECK_OK); |
377 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 402 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 403 if (decl_props != NULL) *decl_props = kHasInitializers; |
378 } | 404 } |
379 } while (peek() == i::Token::COMMA); | 405 } while (peek() == i::Token::COMMA); |
380 | 406 |
381 if (num_decl != NULL) *num_decl = nvars; | 407 if (num_decl != NULL) *num_decl = nvars; |
382 return Statement::Default(); | 408 return Statement::Default(); |
383 } | 409 } |
384 | 410 |
385 | 411 |
386 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { | 412 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(bool* ok) { |
387 // ExpressionStatement | LabelledStatement :: | 413 // ExpressionStatement | LabelledStatement :: |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 | 588 |
563 PreParser::Statement PreParser::ParseForStatement(bool* ok) { | 589 PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
564 // ForStatement :: | 590 // ForStatement :: |
565 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 591 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
566 | 592 |
567 Expect(i::Token::FOR, CHECK_OK); | 593 Expect(i::Token::FOR, CHECK_OK); |
568 Expect(i::Token::LPAREN, CHECK_OK); | 594 Expect(i::Token::LPAREN, CHECK_OK); |
569 if (peek() != i::Token::SEMICOLON) { | 595 if (peek() != i::Token::SEMICOLON) { |
570 if (peek() == i::Token::VAR || peek() == i::Token::CONST || | 596 if (peek() == i::Token::VAR || peek() == i::Token::CONST || |
571 peek() == i::Token::LET) { | 597 peek() == i::Token::LET) { |
| 598 bool is_let = peek() == i::Token::LET; |
572 int decl_count; | 599 int decl_count; |
573 ParseVariableDeclarations(kForStatement, &decl_count, CHECK_OK); | 600 VariableDeclarationProperties decl_props = kHasNoInitializers; |
574 if (peek() == i::Token::IN && decl_count == 1) { | 601 ParseVariableDeclarations( |
| 602 kForStatement, &decl_props, &decl_count, CHECK_OK); |
| 603 bool accept_IN = decl_count == 1 && |
| 604 !(is_let && decl_props == kHasInitializers); |
| 605 if (peek() == i::Token::IN && accept_IN) { |
575 Expect(i::Token::IN, CHECK_OK); | 606 Expect(i::Token::IN, CHECK_OK); |
576 ParseExpression(true, CHECK_OK); | 607 ParseExpression(true, CHECK_OK); |
577 Expect(i::Token::RPAREN, CHECK_OK); | 608 Expect(i::Token::RPAREN, CHECK_OK); |
578 | 609 |
579 ParseStatement(CHECK_OK); | 610 ParseStatement(CHECK_OK); |
580 return Statement::Default(); | 611 return Statement::Default(); |
581 } | 612 } |
582 } else { | 613 } else { |
583 ParseExpression(false, CHECK_OK); | 614 ParseExpression(false, CHECK_OK); |
584 if (peek() == i::Token::IN) { | 615 if (peek() == i::Token::IN) { |
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1346 return Expression::StrictFunction(); | 1377 return Expression::StrictFunction(); |
1347 } | 1378 } |
1348 | 1379 |
1349 return Expression::Default(); | 1380 return Expression::Default(); |
1350 } | 1381 } |
1351 | 1382 |
1352 | 1383 |
1353 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1384 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
1354 // CallRuntime :: | 1385 // CallRuntime :: |
1355 // '%' Identifier Arguments | 1386 // '%' Identifier Arguments |
1356 | |
1357 Expect(i::Token::MOD, CHECK_OK); | 1387 Expect(i::Token::MOD, CHECK_OK); |
| 1388 if (!allow_natives_syntax_) { |
| 1389 *ok = false; |
| 1390 return Expression::Default(); |
| 1391 } |
1358 ParseIdentifier(CHECK_OK); | 1392 ParseIdentifier(CHECK_OK); |
1359 ParseArguments(ok); | 1393 ParseArguments(ok); |
1360 | 1394 |
1361 return Expression::Default(); | 1395 return Expression::Default(); |
1362 } | 1396 } |
1363 | 1397 |
1364 #undef CHECK_OK | 1398 #undef CHECK_OK |
1365 | 1399 |
1366 | 1400 |
1367 void PreParser::ExpectSemicolon(bool* ok) { | 1401 void PreParser::ExpectSemicolon(bool* ok) { |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 backing_store_.Add(static_cast<byte>((ascii_length >> 14) | 0x80u)); | 1714 backing_store_.Add(static_cast<byte>((ascii_length >> 14) | 0x80u)); |
1681 } | 1715 } |
1682 backing_store_.Add(static_cast<byte>((ascii_length >> 7) | 0x80u)); | 1716 backing_store_.Add(static_cast<byte>((ascii_length >> 7) | 0x80u)); |
1683 } | 1717 } |
1684 backing_store_.Add(static_cast<byte>(ascii_length & 0x7f)); | 1718 backing_store_.Add(static_cast<byte>(ascii_length & 0x7f)); |
1685 | 1719 |
1686 backing_store_.AddBlock(bytes); | 1720 backing_store_.AddBlock(bytes); |
1687 return backing_store_.EndSequence().start(); | 1721 return backing_store_.EndSequence().start(); |
1688 } | 1722 } |
1689 } } // v8::preparser | 1723 } } // v8::preparser |
OLD | NEW |