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

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

Issue 25954003: - Harden coverage generation, by not attempting to compile (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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
« runtime/vm/coverage.cc ('K') | « runtime/vm/flow_graph_builder.cc ('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 "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 5430 matching lines...) Expand 10 before | Expand all | Expand 10 after
5441 5441
5442 5442
5443 AstNode* Parser::ParseFunctionStatement(bool is_literal) { 5443 AstNode* Parser::ParseFunctionStatement(bool is_literal) {
5444 TRACE_PARSER("ParseFunctionStatement"); 5444 TRACE_PARSER("ParseFunctionStatement");
5445 AbstractType& result_type = AbstractType::Handle(); 5445 AbstractType& result_type = AbstractType::Handle();
5446 const String* variable_name = NULL; 5446 const String* variable_name = NULL;
5447 const String* function_name = NULL; 5447 const String* function_name = NULL;
5448 5448
5449 result_type = Type::DynamicType(); 5449 result_type = Type::DynamicType();
5450 5450
5451 intptr_t ident_pos = TokenPos(); 5451 const intptr_t function_pos = TokenPos();
5452 if (is_literal) { 5452 if (is_literal) {
5453 ASSERT(CurrentToken() == Token::kLPAREN); 5453 ASSERT(CurrentToken() == Token::kLPAREN);
5454 function_name = &Symbols::AnonymousClosure(); 5454 function_name = &Symbols::AnonymousClosure();
5455 } else { 5455 } else {
5456 if (CurrentToken() == Token::kVOID) { 5456 if (CurrentToken() == Token::kVOID) {
5457 ConsumeToken(); 5457 ConsumeToken();
5458 result_type = Type::VoidType(); 5458 result_type = Type::VoidType();
5459 } else if ((CurrentToken() == Token::kIDENT) && 5459 } else if ((CurrentToken() == Token::kIDENT) &&
5460 (LookaheadToken(1) != Token::kLPAREN)) { 5460 (LookaheadToken(1) != Token::kLPAREN)) {
5461 result_type = ParseType(ClassFinalizer::kCanonicalize); 5461 result_type = ParseType(ClassFinalizer::kCanonicalize);
5462 } 5462 }
5463 variable_name = ExpectIdentifier("function name expected"); 5463 variable_name = ExpectIdentifier("function name expected");
5464 function_name = variable_name; 5464 function_name = variable_name;
5465 } 5465 }
5466 5466
5467 if (CurrentToken() != Token::kLPAREN) { 5467 if (CurrentToken() != Token::kLPAREN) {
5468 ErrorMsg("'(' expected"); 5468 ErrorMsg("'(' expected");
5469 } 5469 }
5470 intptr_t function_pos = TokenPos();
5471 5470
5472 // Check whether we have parsed this closure function before, in a previous 5471 // Check whether we have parsed this closure function before, in a previous
5473 // compilation. If so, reuse the function object, else create a new one 5472 // compilation. If so, reuse the function object, else create a new one
5474 // and register it in the current class. 5473 // and register it in the current class.
5475 // Note that we cannot share the same closure function between the closurized 5474 // Note that we cannot share the same closure function between the closurized
5476 // and non-closurized versions of the same parent function. 5475 // and non-closurized versions of the same parent function.
5477 Function& function = Function::ZoneHandle(); 5476 Function& function = Function::ZoneHandle();
5478 bool is_new_closure = false; 5477 bool is_new_closure = false;
5479 // TODO(hausner): There could be two different closures at the given 5478 // TODO(hausner): There could be two different closures at the given
5480 // function_pos, one enclosed in a closurized function and one enclosed in the 5479 // function_pos, one enclosed in a closurized function and one enclosed in the
5481 // non-closurized version of this same function. 5480 // non-closurized version of this same function.
5482 function = current_class().LookupClosureFunction(function_pos); 5481 function = current_class().LookupClosureFunction(function_pos);
5483 if (function.IsNull() || (function.token_pos() != function_pos) || 5482 if (function.IsNull() || (function.token_pos() != function_pos) ||
5484 (function.parent_function() != innermost_function().raw())) { 5483 (function.parent_function() != innermost_function().raw())) {
5484 // The function will be registered in the lookup table by the
5485 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure
5486 // function has been properly setup.
5485 is_new_closure = true; 5487 is_new_closure = true;
5486 function = Function::NewClosureFunction(*function_name, 5488 function = Function::NewClosureFunction(*function_name,
5487 innermost_function(), 5489 innermost_function(),
5488 ident_pos); 5490 function_pos);
5489 function.set_result_type(result_type); 5491 function.set_result_type(result_type);
5490 current_class().AddClosureFunction(function);
5491 } 5492 }
5492 5493
5493 // The function type needs to be finalized at compile time, since the closure 5494 // The function type needs to be finalized at compile time, since the closure
5494 // may be type checked at run time when assigned to a function variable, 5495 // may be type checked at run time when assigned to a function variable,
5495 // passed as a function argument, or returned as a function result. 5496 // passed as a function argument, or returned as a function result.
5496 5497
5497 LocalVariable* function_variable = NULL; 5498 LocalVariable* function_variable = NULL;
5498 Type& function_type = Type::ZoneHandle(); 5499 Type& function_type = Type::ZoneHandle();
5499 if (variable_name != NULL) { 5500 if (variable_name != NULL) {
5500 // Since the function type depends on the signature of the closure function, 5501 // Since the function type depends on the signature of the closure function,
5501 // it cannot be determined before the formal parameter list of the closure 5502 // it cannot be determined before the formal parameter list of the closure
5502 // function is parsed. Therefore, we set the function type to a new 5503 // function is parsed. Therefore, we set the function type to a new
5503 // parameterized type to be patched after the actual type is known. 5504 // parameterized type to be patched after the actual type is known.
5504 // We temporarily use the class of the Function interface. 5505 // We temporarily use the class of the Function interface.
5505 const Class& unknown_signature_class = Class::Handle( 5506 const Class& unknown_signature_class = Class::Handle(
5506 Type::Handle(Type::Function()).type_class()); 5507 Type::Handle(Type::Function()).type_class());
5507 function_type = Type::New( 5508 function_type = Type::New(
5508 unknown_signature_class, TypeArguments::Handle(), ident_pos); 5509 unknown_signature_class, TypeArguments::Handle(), function_pos);
5509 function_type.SetIsFinalized(); // No finalization needed. 5510 function_type.SetIsFinalized(); // No finalization needed.
5510 5511
5511 // Add the function variable to the scope before parsing the function in 5512 // Add the function variable to the scope before parsing the function in
5512 // order to allow self reference from inside the function. 5513 // order to allow self reference from inside the function.
5513 function_variable = new LocalVariable(ident_pos, 5514 function_variable = new LocalVariable(function_pos,
5514 *variable_name, 5515 *variable_name,
5515 function_type); 5516 function_type);
5516 function_variable->set_is_final(); 5517 function_variable->set_is_final();
5517 ASSERT(current_block_ != NULL); 5518 ASSERT(current_block_ != NULL);
5518 ASSERT(current_block_->scope != NULL); 5519 ASSERT(current_block_->scope != NULL);
5519 if (!current_block_->scope->AddVariable(function_variable)) { 5520 if (!current_block_->scope->AddVariable(function_variable)) {
5520 LocalVariable* existing_var = 5521 LocalVariable* existing_var =
5521 current_block_->scope->LookupVariable(function_variable->name(), 5522 current_block_->scope->LookupVariable(function_variable->name(),
5522 true); 5523 true);
5523 ASSERT(existing_var != NULL); 5524 ASSERT(existing_var != NULL);
5524 if (existing_var->owner() == current_block_->scope) { 5525 if (existing_var->owner() == current_block_->scope) {
5525 ErrorMsg(ident_pos, "identifier '%s' already defined", 5526 ErrorMsg(function_pos, "identifier '%s' already defined",
5526 function_variable->name().ToCString()); 5527 function_variable->name().ToCString());
5527 } else { 5528 } else {
5528 ErrorMsg(ident_pos, 5529 ErrorMsg(function_pos,
5529 "'%s' from outer scope has already been used, cannot redefine", 5530 "'%s' from outer scope has already been used, cannot redefine",
5530 function_variable->name().ToCString()); 5531 function_variable->name().ToCString());
5531 } 5532 }
5532 } 5533 }
5533 } 5534 }
5534 5535
5535 // Parse the local function. 5536 // Parse the local function.
5536 Array& default_parameter_values = Array::Handle(); 5537 Array& default_parameter_values = Array::Handle();
5537 SequenceNode* statements = Parser::ParseFunc(function, 5538 SequenceNode* statements = Parser::ParseFunc(function,
5538 default_parameter_values); 5539 default_parameter_values);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
5631 // allocation information in a Scope object stored in the function object. 5632 // allocation information in a Scope object stored in the function object.
5632 // This Scope object is then provided to the compiler when compiling the local 5633 // This Scope object is then provided to the compiler when compiling the local
5633 // function. It would be too early to record the captured variables here, 5634 // function. It would be too early to record the captured variables here,
5634 // since further closure functions may capture more variables. 5635 // since further closure functions may capture more variables.
5635 // This Scope object is constructed after all variables have been allocated. 5636 // This Scope object is constructed after all variables have been allocated.
5636 // The local scope of the parsed function can be pruned, since contained 5637 // The local scope of the parsed function can be pruned, since contained
5637 // variables are not relevant for the compilation of the enclosing function. 5638 // variables are not relevant for the compilation of the enclosing function.
5638 // This pruning is done by omitting to hook the local scope in its parent 5639 // This pruning is done by omitting to hook the local scope in its parent
5639 // scope in the constructor of LocalScope. 5640 // scope in the constructor of LocalScope.
5640 AstNode* closure = 5641 AstNode* closure =
5641 new ClosureNode(ident_pos, function, NULL, statements->scope()); 5642 new ClosureNode(function_pos, function, NULL, statements->scope());
5642 5643
5643 if (function_variable == NULL) { 5644 if (function_variable == NULL) {
5644 ASSERT(is_literal); 5645 ASSERT(is_literal);
5645 return closure; 5646 return closure;
5646 } else { 5647 } else {
5647 AstNode* initialization = 5648 AstNode* initialization =
5648 new StoreLocalNode(ident_pos, function_variable, closure); 5649 new StoreLocalNode(function_pos, function_variable, closure);
5649 return initialization; 5650 return initialization;
5650 } 5651 }
5651 } 5652 }
5652 5653
5653 5654
5654 // Returns true if the current and next tokens can be parsed as type 5655 // Returns true if the current and next tokens can be parsed as type
5655 // parameters. Current token position is not saved and restored. 5656 // parameters. Current token position is not saved and restored.
5656 bool Parser::TryParseTypeParameter() { 5657 bool Parser::TryParseTypeParameter() {
5657 if (CurrentToken() == Token::kLT) { 5658 if (CurrentToken() == Token::kLT) {
5658 // We are possibly looking at type parameters. Find closing ">". 5659 // We are possibly looking at type parameters. Find closing ">".
(...skipping 4961 matching lines...) Expand 10 before | Expand all | Expand 10 after
10620 void Parser::SkipQualIdent() { 10621 void Parser::SkipQualIdent() {
10621 ASSERT(IsIdentifier()); 10622 ASSERT(IsIdentifier());
10622 ConsumeToken(); 10623 ConsumeToken();
10623 if (CurrentToken() == Token::kPERIOD) { 10624 if (CurrentToken() == Token::kPERIOD) {
10624 ConsumeToken(); // Consume the kPERIOD token. 10625 ConsumeToken(); // Consume the kPERIOD token.
10625 ExpectIdentifier("identifier expected after '.'"); 10626 ExpectIdentifier("identifier expected after '.'");
10626 } 10627 }
10627 } 10628 }
10628 10629
10629 } // namespace dart 10630 } // namespace dart
OLDNEW
« runtime/vm/coverage.cc ('K') | « runtime/vm/flow_graph_builder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698