OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 1801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1812 case Token::DO: | 1812 case Token::DO: |
1813 return ParseDoWhileStatement(labels, ok); | 1813 return ParseDoWhileStatement(labels, ok); |
1814 | 1814 |
1815 case Token::WHILE: | 1815 case Token::WHILE: |
1816 return ParseWhileStatement(labels, ok); | 1816 return ParseWhileStatement(labels, ok); |
1817 | 1817 |
1818 case Token::FOR: | 1818 case Token::FOR: |
1819 return ParseForStatement(labels, ok); | 1819 return ParseForStatement(labels, ok); |
1820 | 1820 |
1821 case Token::CONTINUE: | 1821 case Token::CONTINUE: |
1822 return ParseContinueStatement(ok); | |
1823 | |
1824 case Token::BREAK: | 1822 case Token::BREAK: |
1825 return ParseBreakStatement(labels, ok); | |
1826 | |
1827 case Token::RETURN: | 1823 case Token::RETURN: |
1828 return ParseReturnStatement(ok); | 1824 case Token::THROW: |
| 1825 case Token::TRY: { |
| 1826 // These statements must have their labels preserved in an enclosing |
| 1827 // block |
| 1828 if (labels == NULL) { |
| 1829 return ParseStatementAsUnlabelled(labels, ok); |
| 1830 } else { |
| 1831 Block* result = |
| 1832 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); |
| 1833 Target target(&this->target_stack_, result); |
| 1834 Statement* statement = ParseStatementAsUnlabelled(labels, CHECK_OK); |
| 1835 if (result) result->AddStatement(statement, zone()); |
| 1836 return result; |
| 1837 } |
| 1838 } |
1829 | 1839 |
1830 case Token::WITH: | 1840 case Token::WITH: |
1831 return ParseWithStatement(labels, ok); | 1841 return ParseWithStatement(labels, ok); |
1832 | 1842 |
1833 case Token::SWITCH: | 1843 case Token::SWITCH: |
1834 return ParseSwitchStatement(labels, ok); | 1844 return ParseSwitchStatement(labels, ok); |
1835 | 1845 |
1836 case Token::THROW: | |
1837 return ParseThrowStatement(ok); | |
1838 | |
1839 case Token::TRY: { | |
1840 // NOTE: It is somewhat complicated to have labels on | |
1841 // try-statements. When breaking out of a try-finally statement, | |
1842 // one must take great care not to treat it as a | |
1843 // fall-through. It is much easier just to wrap the entire | |
1844 // try-statement in a statement block and put the labels there | |
1845 Block* result = | |
1846 factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); | |
1847 Target target(&this->target_stack_, result); | |
1848 TryStatement* statement = ParseTryStatement(CHECK_OK); | |
1849 if (result) result->AddStatement(statement, zone()); | |
1850 return result; | |
1851 } | |
1852 | |
1853 case Token::FUNCTION: { | 1846 case Token::FUNCTION: { |
1854 // FunctionDeclaration is only allowed in the context of SourceElements | 1847 // FunctionDeclaration is only allowed in the context of SourceElements |
1855 // (Ecma 262 5th Edition, clause 14): | 1848 // (Ecma 262 5th Edition, clause 14): |
1856 // SourceElement: | 1849 // SourceElement: |
1857 // Statement | 1850 // Statement |
1858 // FunctionDeclaration | 1851 // FunctionDeclaration |
1859 // Common language extension is to allow function declaration in place | 1852 // Common language extension is to allow function declaration in place |
1860 // of any statement. This language extension is disabled in strict mode. | 1853 // of any statement. This language extension is disabled in strict mode. |
1861 // | 1854 // |
1862 // In Harmony mode, this case also handles the extension: | 1855 // In Harmony mode, this case also handles the extension: |
(...skipping 20 matching lines...) Expand all Loading... |
1883 if (is_sloppy(language_mode())) { | 1876 if (is_sloppy(language_mode())) { |
1884 return ParseVariableStatement(kStatement, NULL, ok); | 1877 return ParseVariableStatement(kStatement, NULL, ok); |
1885 } | 1878 } |
1886 | 1879 |
1887 // Fall through. | 1880 // Fall through. |
1888 default: | 1881 default: |
1889 return ParseExpressionOrLabelledStatement(labels, ok); | 1882 return ParseExpressionOrLabelledStatement(labels, ok); |
1890 } | 1883 } |
1891 } | 1884 } |
1892 | 1885 |
| 1886 Statement* Parser::ParseStatementAsUnlabelled( |
| 1887 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 1888 switch (peek()) { |
| 1889 case Token::CONTINUE: |
| 1890 return ParseContinueStatement(ok); |
| 1891 |
| 1892 case Token::BREAK: |
| 1893 return ParseBreakStatement(labels, ok); |
| 1894 |
| 1895 case Token::RETURN: |
| 1896 return ParseReturnStatement(ok); |
| 1897 |
| 1898 case Token::THROW: |
| 1899 return ParseThrowStatement(ok); |
| 1900 |
| 1901 case Token::TRY: |
| 1902 return ParseTryStatement(ok); |
| 1903 |
| 1904 default: |
| 1905 UNREACHABLE(); |
| 1906 return NULL; |
| 1907 } |
| 1908 } |
| 1909 |
1893 | 1910 |
1894 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1911 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
1895 VariableMode mode) { | 1912 VariableMode mode) { |
1896 // If we are inside a function, a declaration of a var/const variable is a | 1913 // If we are inside a function, a declaration of a var/const variable is a |
1897 // truly local variable, and the scope of the variable is always the function | 1914 // truly local variable, and the scope of the variable is always the function |
1898 // scope. | 1915 // scope. |
1899 // Let/const variables in harmony mode are always added to the immediately | 1916 // Let/const variables in harmony mode are always added to the immediately |
1900 // enclosing scope. | 1917 // enclosing scope. |
1901 return DeclarationScope(mode)->NewUnresolved(factory(), name, | 1918 return DeclarationScope(mode)->NewUnresolved(factory(), name, |
1902 scanner()->location().beg_pos, | 1919 scanner()->location().beg_pos, |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2838 ReportMessage("multiple_defaults_in_switch"); | 2855 ReportMessage("multiple_defaults_in_switch"); |
2839 *ok = false; | 2856 *ok = false; |
2840 return NULL; | 2857 return NULL; |
2841 } | 2858 } |
2842 *default_seen_ptr = true; | 2859 *default_seen_ptr = true; |
2843 } | 2860 } |
2844 Expect(Token::COLON, CHECK_OK); | 2861 Expect(Token::COLON, CHECK_OK); |
2845 int pos = position(); | 2862 int pos = position(); |
2846 ZoneList<Statement*>* statements = | 2863 ZoneList<Statement*>* statements = |
2847 new(zone()) ZoneList<Statement*>(5, zone()); | 2864 new(zone()) ZoneList<Statement*>(5, zone()); |
| 2865 Statement* stat = NULL; |
2848 while (peek() != Token::CASE && | 2866 while (peek() != Token::CASE && |
2849 peek() != Token::DEFAULT && | 2867 peek() != Token::DEFAULT && |
2850 peek() != Token::RBRACE) { | 2868 peek() != Token::RBRACE) { |
2851 Statement* stat = ParseStatementListItem(CHECK_OK); | 2869 stat = ParseStatementListItem(CHECK_OK); |
2852 statements->Add(stat, zone()); | 2870 statements->Add(stat, zone()); |
2853 } | 2871 } |
2854 | 2872 if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() && |
| 2873 peek() != Token::RBRACE) { |
| 2874 ReportMessageAt(scanner()->location(), "strong_switch_fallthrough"); |
| 2875 *ok = false; |
| 2876 return NULL; |
| 2877 } |
2855 return factory()->NewCaseClause(label, statements, pos); | 2878 return factory()->NewCaseClause(label, statements, pos); |
2856 } | 2879 } |
2857 | 2880 |
2858 | 2881 |
2859 SwitchStatement* Parser::ParseSwitchStatement( | 2882 SwitchStatement* Parser::ParseSwitchStatement( |
2860 ZoneList<const AstRawString*>* labels, bool* ok) { | 2883 ZoneList<const AstRawString*>* labels, bool* ok) { |
2861 // SwitchStatement :: | 2884 // SwitchStatement :: |
2862 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2885 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
2863 | 2886 |
2864 SwitchStatement* statement = | 2887 SwitchStatement* statement = |
(...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4461 : Scanner::Location(position, position + 1); | 4484 : Scanner::Location(position, position + 1); |
4462 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); | 4485 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); |
4463 *ok = false; | 4486 *ok = false; |
4464 } | 4487 } |
4465 } | 4488 } |
4466 | 4489 |
4467 | 4490 |
4468 // ---------------------------------------------------------------------------- | 4491 // ---------------------------------------------------------------------------- |
4469 // Parser support | 4492 // Parser support |
4470 | 4493 |
4471 | |
4472 bool Parser::TargetStackContainsLabel(const AstRawString* label) { | 4494 bool Parser::TargetStackContainsLabel(const AstRawString* label) { |
4473 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4495 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
4474 if (ContainsLabel(t->statement()->labels(), label)) return true; | 4496 if (ContainsLabel(t->statement()->labels(), label)) return true; |
4475 } | 4497 } |
4476 return false; | 4498 return false; |
4477 } | 4499 } |
4478 | 4500 |
4479 | 4501 |
4480 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, | 4502 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, |
4481 bool* ok) { | 4503 bool* ok) { |
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5773 | 5795 |
5774 Expression* Parser::SpreadCallNew(Expression* function, | 5796 Expression* Parser::SpreadCallNew(Expression* function, |
5775 ZoneList<v8::internal::Expression*>* args, | 5797 ZoneList<v8::internal::Expression*>* args, |
5776 int pos) { | 5798 int pos) { |
5777 args->InsertAt(0, function, zone()); | 5799 args->InsertAt(0, function, zone()); |
5778 | 5800 |
5779 return factory()->NewCallRuntime( | 5801 return factory()->NewCallRuntime( |
5780 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5802 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5781 } | 5803 } |
5782 } } // namespace v8::internal | 5804 } } // namespace v8::internal |
OLD | NEW |