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

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

Issue 10797031: Add missing type finalization for function literals not assigned to a function (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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/object.cc ('k') | tests/language/comparison_test.dart » ('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 (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 4226 matching lines...) Expand 10 before | Expand all | Expand 10 after
4237 if (function.IsNull() || (function.token_pos() != function_pos) || 4237 if (function.IsNull() || (function.token_pos() != function_pos) ||
4238 (function.parent_function() != innermost_function().raw())) { 4238 (function.parent_function() != innermost_function().raw())) {
4239 is_new_closure = true; 4239 is_new_closure = true;
4240 function = Function::NewClosureFunction(*function_name, 4240 function = Function::NewClosureFunction(*function_name,
4241 innermost_function(), 4241 innermost_function(),
4242 function_pos); 4242 function_pos);
4243 function.set_result_type(result_type); 4243 function.set_result_type(result_type);
4244 current_class().AddClosureFunction(function); 4244 current_class().AddClosureFunction(function);
4245 } 4245 }
4246 4246
4247 // The function type does not need to be determined at compile time, unless 4247 // The function type needs to be finalized at compile time, since the closure
4248 // the closure is assigned to a function variable and type checks are enabled. 4248 // may be type checked at run time when assigned to a function variable,
4249 // At run time, the function type is derived from the signature class of the 4249 // passed as a function argument, or returned as a function result.
4250 // closure function and from the type arguments of the instantiator.
4251 4250
4252 LocalVariable* function_variable = NULL; 4251 LocalVariable* function_variable = NULL;
4253 Type& function_type = Type::ZoneHandle(); 4252 Type& function_type = Type::ZoneHandle();
4254 if (variable_name != NULL) { 4253 if (variable_name != NULL) {
4255 // Since the function type depends on the signature of the closure function, 4254 // Since the function type depends on the signature of the closure function,
4256 // it cannot be determined before the formal parameter list of the closure 4255 // it cannot be determined before the formal parameter list of the closure
4257 // function is parsed. Therefore, we set the function type to a new 4256 // function is parsed. Therefore, we set the function type to a new
4258 // parameterized type to be patched after the actual type is known. 4257 // parameterized type to be patched after the actual type is known.
4259 // We temporarily use the class of the Function interface. 4258 // We temporarily use the class of the Function interface.
4260 const Class& unknown_signature_class = Class::Handle( 4259 const Class& unknown_signature_class = Class::Handle(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4309 // ignored during class finalization. The enclosing class has 4308 // ignored during class finalization. The enclosing class has
4310 // already been finalized. 4309 // already been finalized.
4311 ASSERT(current_class().is_finalized()); 4310 ASSERT(current_class().is_finalized());
4312 4311
4313 // Make sure that the instantiator is captured. 4312 // Make sure that the instantiator is captured.
4314 if ((signature_class.NumTypeParameters() > 0) && 4313 if ((signature_class.NumTypeParameters() > 0) &&
4315 (current_block_->scope->function_level() > 0)) { 4314 (current_block_->scope->function_level() > 0)) {
4316 CaptureReceiver(); 4315 CaptureReceiver();
4317 } 4316 }
4318 4317
4318 // Since the signature type is cached by the signature class, it may have
4319 // been finalized already.
4320 Type& signature_type = Type::Handle(signature_class.SignatureType());
4321 const AbstractTypeArguments& signature_type_arguments =
4322 AbstractTypeArguments::Handle(signature_type.arguments());
4323
4324 if (!signature_type.IsFinalized()) {
4325 signature_type ^= ClassFinalizer::FinalizeType(
4326 signature_class, signature_type, ClassFinalizer::kCanonicalize);
4327 // The call to ClassFinalizer::FinalizeType may have
4328 // extended the vector of type arguments.
4329 ASSERT(signature_type_arguments.IsNull() ||
4330 (signature_type_arguments.Length() ==
4331 signature_class.NumTypeArguments()));
4332 // The signature_class should not have changed.
4333 ASSERT(signature_type.type_class() == signature_class.raw());
4334 }
4335
4319 if (variable_name != NULL) { 4336 if (variable_name != NULL) {
4320 // Patch the function type now that the signature is known. 4337 // Patch the function type of the variable now that the signature is known.
4321 // We need to create a new type for proper finalization, since the existing
4322 // type is already marked as finalized.
4323 Type& signature_type = Type::Handle(signature_class.SignatureType());
4324 const AbstractTypeArguments& signature_type_arguments =
4325 AbstractTypeArguments::Handle(signature_type.arguments());
4326
4327 // Since the signature type is cached by the signature class, it may have
4328 // been finalized already.
4329 if (!signature_type.IsFinalized()) {
4330 signature_type ^= ClassFinalizer::FinalizeType(
4331 signature_class, signature_type, ClassFinalizer::kCanonicalize);
4332 // The call to ClassFinalizer::FinalizeType may have
4333 // extended the vector of type arguments.
4334 ASSERT(signature_type_arguments.IsNull() ||
4335 (signature_type_arguments.Length() ==
4336 signature_class.NumTypeArguments()));
4337 // The signature_class should not have changed.
4338 ASSERT(signature_type.type_class() == signature_class.raw());
4339 }
4340
4341 // Now patch the function type of the variable.
4342 function_type.set_type_class(signature_class); 4338 function_type.set_type_class(signature_class);
4343 function_type.set_arguments(signature_type_arguments); 4339 function_type.set_arguments(signature_type_arguments);
4344 4340
4345 // The function variable type should have been patched above. 4341 // The function variable type should have been patched above.
4346 ASSERT((function_variable == NULL) || 4342 ASSERT((function_variable == NULL) ||
4347 (function_variable->type().raw() == function_type.raw())); 4343 (function_variable->type().raw() == function_type.raw()));
4348 } 4344 }
4349 4345
4350 // The code generator does not compile the closure function when visiting 4346 // The code generator does not compile the closure function when visiting
4351 // a ClosureNode. The generated code allocates a new Closure object containing 4347 // a ClosureNode. The generated code allocates a new Closure object containing
(...skipping 4307 matching lines...) Expand 10 before | Expand all | Expand 10 after
8659 void Parser::SkipQualIdent() { 8655 void Parser::SkipQualIdent() {
8660 ASSERT(IsIdentifier()); 8656 ASSERT(IsIdentifier());
8661 ConsumeToken(); 8657 ConsumeToken();
8662 if (CurrentToken() == Token::kPERIOD) { 8658 if (CurrentToken() == Token::kPERIOD) {
8663 ConsumeToken(); // Consume the kPERIOD token. 8659 ConsumeToken(); // Consume the kPERIOD token.
8664 ExpectIdentifier("identifier expected after '.'"); 8660 ExpectIdentifier("identifier expected after '.'");
8665 } 8661 }
8666 } 8662 }
8667 8663
8668 } // namespace dart 8664 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | tests/language/comparison_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698