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 ParseWrappedStatement(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 = ParseWrappedStatement(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::ParseWrappedStatement(ZoneList<const AstRawString*>* labels, | |
rossberg
2015/04/15 19:56:34
In fact, I would just inline the switch instead of
conradw
2015/04/16 10:59:57
Inlining would mean duplicating the code, it has t
| |
1887 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 *ok = false; | |
rossberg
2015/04/15 19:56:34
This case should be UNREACHABLE();
conradw
2015/04/16 10:59:57
Done.
| |
1906 ReportUnexpectedToken(scanner()->current_token()); | |
1907 return NULL; | |
1908 } | |
1909 } | |
1910 | |
1893 | 1911 |
1894 VariableProxy* Parser::NewUnresolved(const AstRawString* name, | 1912 VariableProxy* Parser::NewUnresolved(const AstRawString* name, |
1895 VariableMode mode) { | 1913 VariableMode mode) { |
1896 // If we are inside a function, a declaration of a var/const variable is a | 1914 // 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 | 1915 // truly local variable, and the scope of the variable is always the function |
1898 // scope. | 1916 // scope. |
1899 // Let/const variables in harmony mode are always added to the immediately | 1917 // Let/const variables in harmony mode are always added to the immediately |
1900 // enclosing scope. | 1918 // enclosing scope. |
1901 return DeclarationScope(mode)->NewUnresolved(factory(), name, | 1919 return DeclarationScope(mode)->NewUnresolved(factory(), name, |
1902 scanner()->location().beg_pos, | 1920 scanner()->location().beg_pos, |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2838 ReportMessage("multiple_defaults_in_switch"); | 2856 ReportMessage("multiple_defaults_in_switch"); |
2839 *ok = false; | 2857 *ok = false; |
2840 return NULL; | 2858 return NULL; |
2841 } | 2859 } |
2842 *default_seen_ptr = true; | 2860 *default_seen_ptr = true; |
2843 } | 2861 } |
2844 Expect(Token::COLON, CHECK_OK); | 2862 Expect(Token::COLON, CHECK_OK); |
2845 int pos = position(); | 2863 int pos = position(); |
2846 ZoneList<Statement*>* statements = | 2864 ZoneList<Statement*>* statements = |
2847 new(zone()) ZoneList<Statement*>(5, zone()); | 2865 new(zone()) ZoneList<Statement*>(5, zone()); |
2866 Statement* stat = NULL; | |
2848 while (peek() != Token::CASE && | 2867 while (peek() != Token::CASE && |
2849 peek() != Token::DEFAULT && | 2868 peek() != Token::DEFAULT && |
2850 peek() != Token::RBRACE) { | 2869 peek() != Token::RBRACE) { |
2851 Statement* stat = ParseStatementListItem(CHECK_OK); | 2870 stat = ParseStatementListItem(CHECK_OK); |
2852 statements->Add(stat, zone()); | 2871 statements->Add(stat, zone()); |
2853 } | 2872 } |
2854 | 2873 if (is_strong(language_mode()) && stat != NULL && |
2874 !stat->IsJump()) { | |
rossberg
2015/04/15 19:56:34
Nit: stray line break
conradw
2015/04/16 10:59:57
Done.
| |
2875 ReportMessageAt(scanner()->location(), "strong_switch_fallthrough"); | |
2876 *ok = false; | |
2877 return NULL; | |
2878 } | |
2855 return factory()->NewCaseClause(label, statements, pos); | 2879 return factory()->NewCaseClause(label, statements, pos); |
2856 } | 2880 } |
2857 | 2881 |
2858 | 2882 |
2859 SwitchStatement* Parser::ParseSwitchStatement( | 2883 SwitchStatement* Parser::ParseSwitchStatement( |
2860 ZoneList<const AstRawString*>* labels, bool* ok) { | 2884 ZoneList<const AstRawString*>* labels, bool* ok) { |
2861 // SwitchStatement :: | 2885 // SwitchStatement :: |
2862 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 2886 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
2863 | 2887 |
2864 SwitchStatement* statement = | 2888 SwitchStatement* statement = |
(...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4461 : Scanner::Location(position, position + 1); | 4485 : Scanner::Location(position, position + 1); |
4462 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); | 4486 ParserTraits::ReportMessageAt(location, "var_redeclaration", name); |
4463 *ok = false; | 4487 *ok = false; |
4464 } | 4488 } |
4465 } | 4489 } |
4466 | 4490 |
4467 | 4491 |
4468 // ---------------------------------------------------------------------------- | 4492 // ---------------------------------------------------------------------------- |
4469 // Parser support | 4493 // Parser support |
4470 | 4494 |
4471 | |
4472 bool Parser::TargetStackContainsLabel(const AstRawString* label) { | 4495 bool Parser::TargetStackContainsLabel(const AstRawString* label) { |
4473 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4496 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
4474 if (ContainsLabel(t->statement()->labels(), label)) return true; | 4497 if (ContainsLabel(t->statement()->labels(), label)) return true; |
4475 } | 4498 } |
4476 return false; | 4499 return false; |
4477 } | 4500 } |
4478 | 4501 |
4479 | 4502 |
4480 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, | 4503 BreakableStatement* Parser::LookupBreakTarget(const AstRawString* label, |
4481 bool* ok) { | 4504 bool* ok) { |
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5773 | 5796 |
5774 Expression* Parser::SpreadCallNew(Expression* function, | 5797 Expression* Parser::SpreadCallNew(Expression* function, |
5775 ZoneList<v8::internal::Expression*>* args, | 5798 ZoneList<v8::internal::Expression*>* args, |
5776 int pos) { | 5799 int pos) { |
5777 args->InsertAt(0, function, zone()); | 5800 args->InsertAt(0, function, zone()); |
5778 | 5801 |
5779 return factory()->NewCallRuntime( | 5802 return factory()->NewCallRuntime( |
5780 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 5803 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5781 } | 5804 } |
5782 } } // namespace v8::internal | 5805 } } // namespace v8::internal |
OLD | NEW |