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

Side by Side Diff: src/parser.cc

Issue 7618007: Simplify handling of exits from with and catch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporate review comments Created 9 years, 4 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/parser.h ('k') | src/prettyprinter.cc » ('j') | 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 1994 matching lines...) Expand 10 before | Expand all | Expand 10 after
2005 ExpectSemicolon(CHECK_OK); 2005 ExpectSemicolon(CHECK_OK);
2006 return new(zone()) ReturnStatement(GetLiteralUndefined()); 2006 return new(zone()) ReturnStatement(GetLiteralUndefined());
2007 } 2007 }
2008 2008
2009 Expression* expr = ParseExpression(true, CHECK_OK); 2009 Expression* expr = ParseExpression(true, CHECK_OK);
2010 ExpectSemicolon(CHECK_OK); 2010 ExpectSemicolon(CHECK_OK);
2011 return new(zone()) ReturnStatement(expr); 2011 return new(zone()) ReturnStatement(expr);
2012 } 2012 }
2013 2013
2014 2014
2015 Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) {
2016 // Parse the statement and collect escaping labels.
2017 TargetCollector collector;
2018 Statement* stat;
2019 { Target target(&this->target_stack_, &collector);
2020 with_nesting_level_++;
2021 top_scope_->DeclarationScope()->RecordWithStatement();
2022 stat = ParseStatement(labels, CHECK_OK);
2023 with_nesting_level_--;
2024 }
2025 // Create resulting block with two statements.
2026 // 1: Evaluate the with expression.
2027 // 2: The try-finally block evaluating the body.
2028 Block* result = new(zone()) Block(isolate(), NULL, 2, false);
2029
2030 if (result != NULL) {
2031 result->AddStatement(new(zone()) EnterWithContextStatement(obj));
2032
2033 // Create body block.
2034 Block* body = new(zone()) Block(isolate(), NULL, 1, false);
2035 body->AddStatement(stat);
2036
2037 // Create exit block.
2038 Block* exit = new(zone()) Block(isolate(), NULL, 1, false);
2039 exit->AddStatement(new(zone()) ExitContextStatement());
2040
2041 // Return a try-finally statement.
2042 TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit);
2043 wrapper->set_escaping_targets(collector.targets());
2044 result->AddStatement(wrapper);
2045 }
2046 return result;
2047 }
2048
2049
2050 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 2015 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
2051 // WithStatement :: 2016 // WithStatement ::
2052 // 'with' '(' Expression ')' Statement 2017 // 'with' '(' Expression ')' Statement
2053 2018
2054 Expect(Token::WITH, CHECK_OK); 2019 Expect(Token::WITH, CHECK_OK);
2055 2020
2056 if (top_scope_->is_strict_mode()) { 2021 if (top_scope_->is_strict_mode()) {
2057 ReportMessage("strict_mode_with", Vector<const char*>::empty()); 2022 ReportMessage("strict_mode_with", Vector<const char*>::empty());
2058 *ok = false; 2023 *ok = false;
2059 return NULL; 2024 return NULL;
2060 } 2025 }
2061 2026
2062 Expect(Token::LPAREN, CHECK_OK); 2027 Expect(Token::LPAREN, CHECK_OK);
2063 Expression* expr = ParseExpression(true, CHECK_OK); 2028 Expression* expr = ParseExpression(true, CHECK_OK);
2064 Expect(Token::RPAREN, CHECK_OK); 2029 Expect(Token::RPAREN, CHECK_OK);
2065 2030
2066 return WithHelper(expr, labels, CHECK_OK); 2031 ++with_nesting_level_;
2032 top_scope_->DeclarationScope()->RecordWithStatement();
2033 Statement* stmt = ParseStatement(labels, CHECK_OK);
2034 --with_nesting_level_;
2035 return new(zone()) WithStatement(expr, stmt);
2067 } 2036 }
2068 2037
2069 2038
2070 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 2039 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
2071 // CaseClause :: 2040 // CaseClause ::
2072 // 'case' Expression ':' Statement* 2041 // 'case' Expression ':' Statement*
2073 // 'default' ':' Statement* 2042 // 'default' ':' Statement*
2074 2043
2075 Expression* label = NULL; // NULL expression indicates default case 2044 Expression* label = NULL; // NULL expression indicates default case
2076 if (peek() == Token::CASE) { 2045 if (peek() == Token::CASE) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 2160
2192 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 2161 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
2193 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 2162 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2194 *ok = false; 2163 *ok = false;
2195 return NULL; 2164 return NULL;
2196 } 2165 }
2197 2166
2198 Expect(Token::RPAREN, CHECK_OK); 2167 Expect(Token::RPAREN, CHECK_OK);
2199 2168
2200 if (peek() == Token::LBRACE) { 2169 if (peek() == Token::LBRACE) {
2201 // Rewrite the catch body B to a single statement block 2170 // Rewrite the catch body { B } to a block:
2202 // { try B finally { PopContext }}. 2171 // { { B } ExitContext; }.
2203 Block* inner_body; 2172 Target target(&this->target_stack_, &catch_collector);
2204 // We need to collect escapes from the body for both the inner 2173 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
2205 // try/finally used to pop the catch context and any possible outer 2174 if (top_scope_->is_strict_mode()) {
2206 // try/finally. 2175 catch_scope->EnableStrictMode();
2207 TargetCollector inner_collector; 2176 }
2208 { Target target(&this->target_stack_, &catch_collector); 2177 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR);
2209 { Target target(&this->target_stack_, &inner_collector); 2178 catch_block = new(zone()) Block(isolate(), NULL, 2, false);
2210 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with());
2211 if (top_scope_->is_strict_mode()) {
2212 catch_scope->EnableStrictMode();
2213 }
2214 catch_variable = catch_scope->DeclareLocal(name, Variable::VAR);
2215 2179
2216 Scope* saved_scope = top_scope_; 2180 Scope* saved_scope = top_scope_;
2217 top_scope_ = catch_scope; 2181 top_scope_ = catch_scope;
2218 inner_body = ParseBlock(NULL, CHECK_OK); 2182 Block* catch_body = ParseBlock(NULL, CHECK_OK);
2219 top_scope_ = saved_scope; 2183 top_scope_ = saved_scope;
2220 } 2184 catch_block->AddStatement(catch_body);
2221 } 2185 catch_block->AddStatement(new(zone()) ExitContextStatement());
2222
2223 // Create exit block.
2224 Block* inner_finally = new(zone()) Block(isolate(), NULL, 1, false);
2225 inner_finally->AddStatement(new(zone()) ExitContextStatement());
2226
2227 // Create a try/finally statement.
2228 TryFinallyStatement* inner_try_finally =
2229 new(zone()) TryFinallyStatement(inner_body, inner_finally);
2230 inner_try_finally->set_escaping_targets(inner_collector.targets());
2231
2232 catch_block = new(zone()) Block(isolate(), NULL, 1, false);
2233 catch_block->AddStatement(inner_try_finally);
2234 } else { 2186 } else {
2235 Expect(Token::LBRACE, CHECK_OK); 2187 Expect(Token::LBRACE, CHECK_OK);
2236 } 2188 }
2237 2189
2238 tok = peek(); 2190 tok = peek();
2239 } 2191 }
2240 2192
2241 Block* finally_block = NULL; 2193 Block* finally_block = NULL;
2242 if (tok == Token::FINALLY || catch_block == NULL) { 2194 if (tok == Token::FINALLY || catch_block == NULL) {
2243 Consume(Token::FINALLY); 2195 Consume(Token::FINALLY);
(...skipping 2944 matching lines...) Expand 10 before | Expand all | Expand 10 after
5188 result = parser.ParseProgram(source, 5140 result = parser.ParseProgram(source,
5189 info->is_global(), 5141 info->is_global(),
5190 info->StrictMode()); 5142 info->StrictMode());
5191 } 5143 }
5192 } 5144 }
5193 info->SetFunction(result); 5145 info->SetFunction(result);
5194 return (result != NULL); 5146 return (result != NULL);
5195 } 5147 }
5196 5148
5197 } } // namespace v8::internal 5149 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/prettyprinter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698