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

Side by Side Diff: runtime/vm/parser.cc

Issue 10665009: Fix parent function of deeply nested closures (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 Parser::Parser(const Script& script, 247 Parser::Parser(const Script& script,
248 const Library& library) 248 const Library& library)
249 : script_(script), 249 : script_(script),
250 tokens_(TokenStream::Handle(script.tokens())), 250 tokens_(TokenStream::Handle(script.tokens())),
251 token_index_(0), 251 token_index_(0),
252 current_block_(NULL), 252 current_block_(NULL),
253 is_top_level_(false), 253 is_top_level_(false),
254 current_member_(NULL), 254 current_member_(NULL),
255 allow_function_literals_(true), 255 allow_function_literals_(true),
256 current_function_(Function::Handle()), 256 current_function_(Function::Handle()),
257 innermost_function_(Function::Handle()),
257 current_class_(Class::Handle()), 258 current_class_(Class::Handle()),
258 library_(library), 259 library_(library),
259 try_blocks_list_(NULL), 260 try_blocks_list_(NULL),
260 expression_temp_(NULL) { 261 expression_temp_(NULL) {
261 ASSERT(!tokens_.IsNull()); 262 ASSERT(!tokens_.IsNull());
262 ASSERT(!library.IsNull()); 263 ASSERT(!library.IsNull());
263 SetPosition(0); 264 SetPosition(0);
264 } 265 }
265 266
266 267
267 // For parsing a function. 268 // For parsing a function.
268 Parser::Parser(const Script& script, 269 Parser::Parser(const Script& script,
269 const Function& function, 270 const Function& function,
270 intptr_t token_index) 271 intptr_t token_index)
271 : script_(script), 272 : script_(script),
272 tokens_(TokenStream::Handle(script.tokens())), 273 tokens_(TokenStream::Handle(script.tokens())),
273 token_index_(0), 274 token_index_(0),
274 current_block_(NULL), 275 current_block_(NULL),
275 is_top_level_(false), 276 is_top_level_(false),
276 current_member_(NULL), 277 current_member_(NULL),
277 allow_function_literals_(true), 278 allow_function_literals_(true),
278 current_function_(function), 279 current_function_(function),
280 innermost_function_(Function::Handle(function.raw())),
279 current_class_(Class::Handle(current_function_.owner())), 281 current_class_(Class::Handle(current_function_.owner())),
280 library_(Library::Handle(current_class_.library())), 282 library_(Library::Handle(current_class_.library())),
281 try_blocks_list_(NULL), 283 try_blocks_list_(NULL),
282 expression_temp_(NULL) { 284 expression_temp_(NULL) {
283 ASSERT(!tokens_.IsNull()); 285 ASSERT(!tokens_.IsNull());
284 ASSERT(!function.IsNull()); 286 ASSERT(!function.IsNull());
285 SetPosition(token_index); 287 SetPosition(token_index);
286 if (FLAG_enable_type_checks) { 288 if (FLAG_enable_type_checks) {
287 EnsureExpressionTemp(); 289 EnsureExpressionTemp();
288 } 290 }
289 } 291 }
290 292
291 293
292 bool Parser::SetAllowFunctionLiterals(bool value) { 294 bool Parser::SetAllowFunctionLiterals(bool value) {
293 bool current_value = allow_function_literals_; 295 bool current_value = allow_function_literals_;
294 allow_function_literals_ = value; 296 allow_function_literals_ = value;
295 return current_value; 297 return current_value;
296 } 298 }
297 299
298 300
299 const Function& Parser::current_function() const { 301 const Function& Parser::current_function() const {
300 return current_function_; 302 return current_function_;
301 } 303 }
302 304
303 305
306 const Function& Parser::innermost_function() const {
307 return innermost_function_;
308 }
309
310
304 const Class& Parser::current_class() const { 311 const Class& Parser::current_class() const {
305 return current_class_; 312 return current_class_;
306 } 313 }
307 314
308 315
309 void Parser::set_current_class(const Class& value) { 316 void Parser::set_current_class(const Class& value) {
310 current_class_ = value.raw(); 317 current_class_ = value.raw();
311 } 318 }
312 319
313 320
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 return statements; 2075 return statements;
2069 } 2076 }
2070 2077
2071 2078
2072 // Parser is at the opening parenthesis of the formal parameter 2079 // Parser is at the opening parenthesis of the formal parameter
2073 // declaration of the function or constructor. 2080 // declaration of the function or constructor.
2074 // Parse the formal parameters and code. 2081 // Parse the formal parameters and code.
2075 SequenceNode* Parser::ParseFunc(const Function& func, 2082 SequenceNode* Parser::ParseFunc(const Function& func,
2076 Array& default_parameter_values) { 2083 Array& default_parameter_values) {
2077 TRACE_PARSER("ParseFunc"); 2084 TRACE_PARSER("ParseFunc");
2085 Function& saved_innermost_function =
2086 Function::Handle(innermost_function().raw());
2087 innermost_function_ = func.raw();
2088
2078 if (func.IsConstructor()) { 2089 if (func.IsConstructor()) {
2079 return ParseConstructor(func, default_parameter_values); 2090 SequenceNode* statements = ParseConstructor(func, default_parameter_values);
2091 innermost_function_ = saved_innermost_function.raw();
2092 return statements;
2080 } 2093 }
2081 2094
2082 ASSERT(!func.IsConstructor()); 2095 ASSERT(!func.IsConstructor());
2083 OpenFunctionBlock(func); // Build local scope for function. 2096 OpenFunctionBlock(func); // Build local scope for function.
2084 2097
2085 ParamList params; 2098 ParamList params;
2086 // Static functions do not have a receiver. 2099 // Static functions do not have a receiver.
2087 // An instance closure may capture and access the receiver, but via the 2100 // An instance closure may capture and access the receiver, but via the
2088 // context and not via the first formal parameter. 2101 // context and not via the first formal parameter.
2089 // The first parameter of a factory is the AbstractTypeArguments vector of the 2102 // The first parameter of a factory is the AbstractTypeArguments vector of the
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 AstNode* expr = ParseExpr(kAllowConst); 2157 AstNode* expr = ParseExpr(kAllowConst);
2145 ASSERT(expr != NULL); 2158 ASSERT(expr != NULL);
2146 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 2159 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
2147 } else if (IsLiteral("native")) { 2160 } else if (IsLiteral("native")) {
2148 ParseNativeFunctionBlock(&params, func); 2161 ParseNativeFunctionBlock(&params, func);
2149 } else { 2162 } else {
2150 UnexpectedToken(); 2163 UnexpectedToken();
2151 } 2164 }
2152 SequenceNode* body = CloseBlock(); 2165 SequenceNode* body = CloseBlock();
2153 current_block_->statements->Add(body); 2166 current_block_->statements->Add(body);
2167 innermost_function_ = saved_innermost_function.raw();
2154 return CloseBlock(); 2168 return CloseBlock();
2155 } 2169 }
2156 2170
2157 2171
2158 void Parser::SkipIf(Token::Kind token) { 2172 void Parser::SkipIf(Token::Kind token) {
2159 if (CurrentToken() == token) { 2173 if (CurrentToken() == token) {
2160 ConsumeToken(); 2174 ConsumeToken();
2161 } 2175 }
2162 } 2176 }
2163 2177
(...skipping 2026 matching lines...) Expand 10 before | Expand all | Expand 10 after
4190 // and register it in the current class. 4204 // and register it in the current class.
4191 // Note that we cannot share the same closure function between the closurized 4205 // Note that we cannot share the same closure function between the closurized
4192 // and non-closurized versions of the same parent function. 4206 // and non-closurized versions of the same parent function.
4193 Function& function = Function::ZoneHandle(); 4207 Function& function = Function::ZoneHandle();
4194 bool is_new_closure = false; 4208 bool is_new_closure = false;
4195 // TODO(hausner): There could be two different closures at the given 4209 // TODO(hausner): There could be two different closures at the given
4196 // function_pos, one enclosed in a closurized function and one enclosed in the 4210 // function_pos, one enclosed in a closurized function and one enclosed in the
4197 // non-closurized version of this same function. 4211 // non-closurized version of this same function.
4198 function = current_class().LookupClosureFunction(function_pos); 4212 function = current_class().LookupClosureFunction(function_pos);
4199 if (function.IsNull() || (function.token_index() != function_pos) || 4213 if (function.IsNull() || (function.token_index() != function_pos) ||
4200 (function.parent_function() != current_function().raw())) { 4214 (function.parent_function() != innermost_function().raw())) {
4201 is_new_closure = true; 4215 is_new_closure = true;
4202 function = Function::NewClosureFunction(*function_name, 4216 function = Function::NewClosureFunction(*function_name,
4203 current_function(), 4217 innermost_function(),
4204 function_pos); 4218 function_pos);
4205 function.set_result_type(result_type); 4219 function.set_result_type(result_type);
4206 current_class().AddClosureFunction(function); 4220 current_class().AddClosureFunction(function);
4207 } 4221 }
4208 4222
4209 // The function type does not need to be determined at compile time, unless 4223 // The function type does not need to be determined at compile time, unless
4210 // the closure is assigned to a function variable and type checks are enabled. 4224 // the closure is assigned to a function variable and type checks are enabled.
4211 // At run time, the function type is derived from the signature class of the 4225 // At run time, the function type is derived from the signature class of the
4212 // closure function and from the type arguments of the instantiator. 4226 // closure function and from the type arguments of the instantiator.
4213 4227
(...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after
5379 5393
5380 // Add this individual catch handler to the catch handlers list. 5394 // Add this individual catch handler to the catch handlers list.
5381 current_block_->statements->Add(catch_clause); 5395 current_block_->statements->Add(catch_clause);
5382 } 5396 }
5383 catch_handler_list = CloseBlock(); 5397 catch_handler_list = CloseBlock();
5384 TryBlocks* inner_try_block = PopTryBlock(); 5398 TryBlocks* inner_try_block = PopTryBlock();
5385 5399
5386 // Finally parse the 'finally' block. 5400 // Finally parse the 'finally' block.
5387 SequenceNode* finally_block = NULL; 5401 SequenceNode* finally_block = NULL;
5388 if (CurrentToken() == Token::kFINALLY) { 5402 if (CurrentToken() == Token::kFINALLY) {
5389 current_function_.set_is_optimizable(false); 5403 current_function().set_is_optimizable(false);
5390 ConsumeToken(); // Consume the 'finally'. 5404 ConsumeToken(); // Consume the 'finally'.
5391 const intptr_t finally_pos = token_index_; 5405 const intptr_t finally_pos = token_index_;
5392 // Add the finally block to the exit points recorded so far. 5406 // Add the finally block to the exit points recorded so far.
5393 intptr_t node_index = 0; 5407 intptr_t node_index = 0;
5394 AstNode* node_to_inline = 5408 AstNode* node_to_inline =
5395 inner_try_block->GetNodeToInlineFinally(node_index); 5409 inner_try_block->GetNodeToInlineFinally(node_index);
5396 while (node_to_inline != NULL) { 5410 while (node_to_inline != NULL) {
5397 finally_block = ParseFinallyBlock(); 5411 finally_block = ParseFinallyBlock();
5398 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, 5412 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos,
5399 finally_block, 5413 finally_block,
(...skipping 3187 matching lines...) Expand 10 before | Expand all | Expand 10 after
8587 void Parser::SkipQualIdent() { 8601 void Parser::SkipQualIdent() {
8588 ASSERT(IsIdentifier()); 8602 ASSERT(IsIdentifier());
8589 ConsumeToken(); 8603 ConsumeToken();
8590 if (CurrentToken() == Token::kPERIOD) { 8604 if (CurrentToken() == Token::kPERIOD) {
8591 ConsumeToken(); // Consume the kPERIOD token. 8605 ConsumeToken(); // Consume the kPERIOD token.
8592 ExpectIdentifier("identifier expected after '.'"); 8606 ExpectIdentifier("identifier expected after '.'");
8593 } 8607 }
8594 } 8608 }
8595 8609
8596 } // namespace dart 8610 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698