| OLD | NEW |
| 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 35 #include "func-name-inferrer.h" | 35 #include "func-name-inferrer.h" |
| 36 #include "messages.h" | 36 #include "messages.h" |
| 37 #include "parser.h" | 37 #include "parser.h" |
| 38 #include "platform.h" | 38 #include "platform.h" |
| 39 #include "preparser.h" | 39 #include "preparser.h" |
| 40 #include "runtime.h" | 40 #include "runtime.h" |
| 41 #include "scopeinfo.h" | 41 #include "scopeinfo.h" |
| 42 #include "string-stream.h" | 42 #include "string-stream.h" |
| 43 | 43 |
| 44 #include "ast-inl.h" | 44 #include "ast-inl.h" |
| 45 #include "jump-target-inl.h" | |
| 46 | 45 |
| 47 namespace v8 { | 46 namespace v8 { |
| 48 namespace internal { | 47 namespace internal { |
| 49 | 48 |
| 50 // PositionStack is used for on-stack allocation of token positions for | 49 // PositionStack is used for on-stack allocation of token positions for |
| 51 // new expressions. Please look at ParseNewExpression. | 50 // new expressions. Please look at ParseNewExpression. |
| 52 | 51 |
| 53 class PositionStack { | 52 class PositionStack { |
| 54 public: | 53 public: |
| 55 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} | 54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} |
| (...skipping 1846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1902 ExpectSemicolon(CHECK_OK); | 1901 ExpectSemicolon(CHECK_OK); |
| 1903 return new(zone()) ReturnStatement(expr); | 1902 return new(zone()) ReturnStatement(expr); |
| 1904 } | 1903 } |
| 1905 | 1904 |
| 1906 | 1905 |
| 1907 Block* Parser::WithHelper(Expression* obj, | 1906 Block* Parser::WithHelper(Expression* obj, |
| 1908 ZoneStringList* labels, | 1907 ZoneStringList* labels, |
| 1909 bool is_catch_block, | 1908 bool is_catch_block, |
| 1910 bool* ok) { | 1909 bool* ok) { |
| 1911 // Parse the statement and collect escaping labels. | 1910 // Parse the statement and collect escaping labels. |
| 1912 ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0); | 1911 ZoneList<Label*>* target_list = new ZoneList<Label*>(0); |
| 1913 TargetCollector collector(target_list); | 1912 TargetCollector collector(target_list); |
| 1914 Statement* stat; | 1913 Statement* stat; |
| 1915 { Target target(&this->target_stack_, &collector); | 1914 { Target target(&this->target_stack_, &collector); |
| 1916 with_nesting_level_++; | 1915 with_nesting_level_++; |
| 1917 top_scope_->RecordWithStatement(); | 1916 top_scope_->RecordWithStatement(); |
| 1918 stat = ParseStatement(labels, CHECK_OK); | 1917 stat = ParseStatement(labels, CHECK_OK); |
| 1919 with_nesting_level_--; | 1918 with_nesting_level_--; |
| 1920 } | 1919 } |
| 1921 // Create resulting block with two statements. | 1920 // Create resulting block with two statements. |
| 1922 // 1: Evaluate the with expression. | 1921 // 1: Evaluate the with expression. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2048 // 'try' Block Catch Finally | 2047 // 'try' Block Catch Finally |
| 2049 // | 2048 // |
| 2050 // Catch :: | 2049 // Catch :: |
| 2051 // 'catch' '(' Identifier ')' Block | 2050 // 'catch' '(' Identifier ')' Block |
| 2052 // | 2051 // |
| 2053 // Finally :: | 2052 // Finally :: |
| 2054 // 'finally' Block | 2053 // 'finally' Block |
| 2055 | 2054 |
| 2056 Expect(Token::TRY, CHECK_OK); | 2055 Expect(Token::TRY, CHECK_OK); |
| 2057 | 2056 |
| 2058 ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0); | 2057 ZoneList<Label*>* target_list = new ZoneList<Label*>(0); |
| 2059 TargetCollector collector(target_list); | 2058 TargetCollector collector(target_list); |
| 2060 Block* try_block; | 2059 Block* try_block; |
| 2061 | 2060 |
| 2062 { Target target(&this->target_stack_, &collector); | 2061 { Target target(&this->target_stack_, &collector); |
| 2063 try_block = ParseBlock(NULL, CHECK_OK); | 2062 try_block = ParseBlock(NULL, CHECK_OK); |
| 2064 } | 2063 } |
| 2065 | 2064 |
| 2066 Block* catch_block = NULL; | 2065 Block* catch_block = NULL; |
| 2067 Variable* catch_var = NULL; | 2066 Variable* catch_var = NULL; |
| 2068 Block* finally_block = NULL; | 2067 Block* finally_block = NULL; |
| 2069 | 2068 |
| 2070 Token::Value tok = peek(); | 2069 Token::Value tok = peek(); |
| 2071 if (tok != Token::CATCH && tok != Token::FINALLY) { | 2070 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| 2072 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); | 2071 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); |
| 2073 *ok = false; | 2072 *ok = false; |
| 2074 return NULL; | 2073 return NULL; |
| 2075 } | 2074 } |
| 2076 | 2075 |
| 2077 // If we can break out from the catch block and there is a finally block, | 2076 // If we can break out from the catch block and there is a finally block, |
| 2078 // then we will need to collect jump targets from the catch block. Since | 2077 // then we will need to collect jump targets from the catch block. Since |
| 2079 // we don't know yet if there will be a finally block, we always collect | 2078 // we don't know yet if there will be a finally block, we always collect |
| 2080 // the jump targets. | 2079 // the jump targets. |
| 2081 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); | 2080 ZoneList<Label*>* catch_target_list = new ZoneList<Label*>(0); |
| 2082 TargetCollector catch_collector(catch_target_list); | 2081 TargetCollector catch_collector(catch_target_list); |
| 2083 bool has_catch = false; | 2082 bool has_catch = false; |
| 2084 if (tok == Token::CATCH) { | 2083 if (tok == Token::CATCH) { |
| 2085 has_catch = true; | 2084 has_catch = true; |
| 2086 Consume(Token::CATCH); | 2085 Consume(Token::CATCH); |
| 2087 | 2086 |
| 2088 Expect(Token::LPAREN, CHECK_OK); | 2087 Expect(Token::LPAREN, CHECK_OK); |
| 2089 Handle<String> name = ParseIdentifier(CHECK_OK); | 2088 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2090 | 2089 |
| 2091 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { | 2090 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2171 Statement* body = ParseStatement(NULL, CHECK_OK); | 2170 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2172 Expect(Token::WHILE, CHECK_OK); | 2171 Expect(Token::WHILE, CHECK_OK); |
| 2173 Expect(Token::LPAREN, CHECK_OK); | 2172 Expect(Token::LPAREN, CHECK_OK); |
| 2174 | 2173 |
| 2175 if (loop != NULL) { | 2174 if (loop != NULL) { |
| 2176 int position = scanner().location().beg_pos; | 2175 int position = scanner().location().beg_pos; |
| 2177 loop->set_condition_position(position); | 2176 loop->set_condition_position(position); |
| 2178 } | 2177 } |
| 2179 | 2178 |
| 2180 Expression* cond = ParseExpression(true, CHECK_OK); | 2179 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2181 if (cond != NULL) cond->set_is_loop_condition(true); | |
| 2182 Expect(Token::RPAREN, CHECK_OK); | 2180 Expect(Token::RPAREN, CHECK_OK); |
| 2183 | 2181 |
| 2184 // Allow do-statements to be terminated with and without | 2182 // Allow do-statements to be terminated with and without |
| 2185 // semi-colons. This allows code such as 'do;while(0)return' to | 2183 // semi-colons. This allows code such as 'do;while(0)return' to |
| 2186 // parse, which would not be the case if we had used the | 2184 // parse, which would not be the case if we had used the |
| 2187 // ExpectSemicolon() functionality here. | 2185 // ExpectSemicolon() functionality here. |
| 2188 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); | 2186 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); |
| 2189 | 2187 |
| 2190 if (loop != NULL) loop->Initialize(cond, body); | 2188 if (loop != NULL) loop->Initialize(cond, body); |
| 2191 return loop; | 2189 return loop; |
| 2192 } | 2190 } |
| 2193 | 2191 |
| 2194 | 2192 |
| 2195 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2193 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2196 // WhileStatement :: | 2194 // WhileStatement :: |
| 2197 // 'while' '(' Expression ')' Statement | 2195 // 'while' '(' Expression ')' Statement |
| 2198 | 2196 |
| 2199 lexical_scope_->AddLoop(); | 2197 lexical_scope_->AddLoop(); |
| 2200 WhileStatement* loop = new(zone()) WhileStatement(labels); | 2198 WhileStatement* loop = new(zone()) WhileStatement(labels); |
| 2201 Target target(&this->target_stack_, loop); | 2199 Target target(&this->target_stack_, loop); |
| 2202 | 2200 |
| 2203 Expect(Token::WHILE, CHECK_OK); | 2201 Expect(Token::WHILE, CHECK_OK); |
| 2204 Expect(Token::LPAREN, CHECK_OK); | 2202 Expect(Token::LPAREN, CHECK_OK); |
| 2205 Expression* cond = ParseExpression(true, CHECK_OK); | 2203 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2206 if (cond != NULL) cond->set_is_loop_condition(true); | |
| 2207 Expect(Token::RPAREN, CHECK_OK); | 2204 Expect(Token::RPAREN, CHECK_OK); |
| 2208 Statement* body = ParseStatement(NULL, CHECK_OK); | 2205 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2209 | 2206 |
| 2210 if (loop != NULL) loop->Initialize(cond, body); | 2207 if (loop != NULL) loop->Initialize(cond, body); |
| 2211 return loop; | 2208 return loop; |
| 2212 } | 2209 } |
| 2213 | 2210 |
| 2214 | 2211 |
| 2215 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2212 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2216 // ForStatement :: | 2213 // ForStatement :: |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2278 // Standard 'for' loop | 2275 // Standard 'for' loop |
| 2279 ForStatement* loop = new(zone()) ForStatement(labels); | 2276 ForStatement* loop = new(zone()) ForStatement(labels); |
| 2280 Target target(&this->target_stack_, loop); | 2277 Target target(&this->target_stack_, loop); |
| 2281 | 2278 |
| 2282 // Parsed initializer at this point. | 2279 // Parsed initializer at this point. |
| 2283 Expect(Token::SEMICOLON, CHECK_OK); | 2280 Expect(Token::SEMICOLON, CHECK_OK); |
| 2284 | 2281 |
| 2285 Expression* cond = NULL; | 2282 Expression* cond = NULL; |
| 2286 if (peek() != Token::SEMICOLON) { | 2283 if (peek() != Token::SEMICOLON) { |
| 2287 cond = ParseExpression(true, CHECK_OK); | 2284 cond = ParseExpression(true, CHECK_OK); |
| 2288 if (cond != NULL) cond->set_is_loop_condition(true); | |
| 2289 } | 2285 } |
| 2290 Expect(Token::SEMICOLON, CHECK_OK); | 2286 Expect(Token::SEMICOLON, CHECK_OK); |
| 2291 | 2287 |
| 2292 Statement* next = NULL; | 2288 Statement* next = NULL; |
| 2293 if (peek() != Token::RPAREN) { | 2289 if (peek() != Token::RPAREN) { |
| 2294 Expression* exp = ParseExpression(true, CHECK_OK); | 2290 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2295 next = new(zone()) ExpressionStatement(exp); | 2291 next = new(zone()) ExpressionStatement(exp); |
| 2296 } | 2292 } |
| 2297 Expect(Token::RPAREN, CHECK_OK); | 2293 Expect(Token::RPAREN, CHECK_OK); |
| 2298 | 2294 |
| (...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3938 ASSERT(stat->is_target_for_anonymous()); | 3934 ASSERT(stat->is_target_for_anonymous()); |
| 3939 if (anonymous || ContainsLabel(stat->labels(), label)) { | 3935 if (anonymous || ContainsLabel(stat->labels(), label)) { |
| 3940 RegisterTargetUse(stat->continue_target(), t->previous()); | 3936 RegisterTargetUse(stat->continue_target(), t->previous()); |
| 3941 return stat; | 3937 return stat; |
| 3942 } | 3938 } |
| 3943 } | 3939 } |
| 3944 return NULL; | 3940 return NULL; |
| 3945 } | 3941 } |
| 3946 | 3942 |
| 3947 | 3943 |
| 3948 void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) { | 3944 void Parser::RegisterTargetUse(Label* target, Target* stop) { |
| 3949 // Register that a break target found at the given stop in the | 3945 // Register that a break target found at the given stop in the |
| 3950 // target stack has been used from the top of the target stack. Add | 3946 // target stack has been used from the top of the target stack. Add |
| 3951 // the break target to any TargetCollectors passed on the stack. | 3947 // the break target to any TargetCollectors passed on the stack. |
| 3952 for (Target* t = target_stack_; t != stop; t = t->previous()) { | 3948 for (Target* t = target_stack_; t != stop; t = t->previous()) { |
| 3953 TargetCollector* collector = t->node()->AsTargetCollector(); | 3949 TargetCollector* collector = t->node()->AsTargetCollector(); |
| 3954 if (collector != NULL) collector->AddTarget(target); | 3950 if (collector != NULL) collector->AddTarget(target); |
| 3955 } | 3951 } |
| 3956 } | 3952 } |
| 3957 | 3953 |
| 3958 | 3954 |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5159 info->is_global(), | 5155 info->is_global(), |
| 5160 info->StrictMode()); | 5156 info->StrictMode()); |
| 5161 } | 5157 } |
| 5162 } | 5158 } |
| 5163 | 5159 |
| 5164 info->SetFunction(result); | 5160 info->SetFunction(result); |
| 5165 return (result != NULL); | 5161 return (result != NULL); |
| 5166 } | 5162 } |
| 5167 | 5163 |
| 5168 } } // namespace v8::internal | 5164 } } // namespace v8::internal |
| OLD | NEW |