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

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

Issue 25284003: Fix expression evaluation in library context (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
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/compiler.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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/class_finalizer.h" 5 #include "vm/class_finalizer.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/heap.h" 8 #include "vm/heap.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 factory.SetRedirectionType(type); 330 factory.SetRedirectionType(type);
331 if (type.IsMalformed()) { 331 if (type.IsMalformed()) {
332 ASSERT(factory.RedirectionTarget() == Function::null()); 332 ASSERT(factory.RedirectionTarget() == Function::null());
333 return; 333 return;
334 } 334 }
335 ASSERT(!type.IsTypeParameter()); // Resolved in parser. 335 ASSERT(!type.IsTypeParameter()); // Resolved in parser.
336 if (type.IsDynamicType()) { 336 if (type.IsDynamicType()) {
337 // Replace the type with a malformed type and compile a throw when called. 337 // Replace the type with a malformed type and compile a throw when called.
338 type = NewFinalizedMalformedType( 338 type = NewFinalizedMalformedType(
339 Error::Handle(), // No previous error. 339 Error::Handle(), // No previous error.
340 cls, 340 Script::Handle(cls.script()),
341 factory.token_pos(), 341 factory.token_pos(),
342 "factory may not redirect to 'dynamic'"); 342 "factory may not redirect to 'dynamic'");
343 factory.SetRedirectionType(type); 343 factory.SetRedirectionType(type);
344 ASSERT(factory.RedirectionTarget() == Function::null()); 344 ASSERT(factory.RedirectionTarget() == Function::null());
345 return; 345 return;
346 } 346 }
347 const Class& target_class = Class::Handle(type.type_class()); 347 const Class& target_class = Class::Handle(type.type_class());
348 String& target_class_name = String::Handle(target_class.Name()); 348 String& target_class_name = String::Handle(target_class.Name());
349 String& target_name = String::Handle( 349 String& target_name = String::Handle(
350 String::Concat(target_class_name, Symbols::Dot())); 350 String::Concat(target_class_name, Symbols::Dot()));
351 const String& identifier = String::Handle(factory.RedirectionIdentifier()); 351 const String& identifier = String::Handle(factory.RedirectionIdentifier());
352 if (!identifier.IsNull()) { 352 if (!identifier.IsNull()) {
353 target_name = String::Concat(target_name, identifier); 353 target_name = String::Concat(target_name, identifier);
354 } 354 }
355 355
356 // Verify that the target constructor of the redirection exists. 356 // Verify that the target constructor of the redirection exists.
357 target = target_class.LookupConstructor(target_name); 357 target = target_class.LookupConstructor(target_name);
358 if (target.IsNull()) { 358 if (target.IsNull()) {
359 target = target_class.LookupFactory(target_name); 359 target = target_class.LookupFactory(target_name);
360 } 360 }
361 if (target.IsNull()) { 361 if (target.IsNull()) {
362 const String& user_visible_target_name = 362 const String& user_visible_target_name =
363 identifier.IsNull() ? target_class_name : target_name; 363 identifier.IsNull() ? target_class_name : target_name;
364 // Replace the type with a malformed type and compile a throw when called. 364 // Replace the type with a malformed type and compile a throw when called.
365 type = NewFinalizedMalformedType( 365 type = NewFinalizedMalformedType(
366 Error::Handle(), // No previous error. 366 Error::Handle(), // No previous error.
367 cls, 367 Script::Handle(target_class.script()),
368 factory.token_pos(), 368 factory.token_pos(),
369 "class '%s' has no constructor or factory named '%s'", 369 "class '%s' has no constructor or factory named '%s'",
370 target_class_name.ToCString(), 370 target_class_name.ToCString(),
371 user_visible_target_name.ToCString()); 371 user_visible_target_name.ToCString());
372 factory.SetRedirectionType(type); 372 factory.SetRedirectionType(type);
373 ASSERT(factory.RedirectionTarget() == Function::null()); 373 ASSERT(factory.RedirectionTarget() == Function::null());
374 return; 374 return;
375 } 375 }
376 376
377 if (FLAG_error_on_bad_override) { 377 if (FLAG_error_on_bad_override) {
378 // Verify that the target is compatible with the redirecting factory. 378 // Verify that the target is compatible with the redirecting factory.
379 Error& error = Error::Handle(); 379 Error& error = Error::Handle();
380 if (!target.HasCompatibleParametersWith(factory, &error)) { 380 if (!target.HasCompatibleParametersWith(factory, &error)) {
381 const Script& script = Script::Handle(target_class.script());
381 type = NewFinalizedMalformedType( 382 type = NewFinalizedMalformedType(
382 error, target_class, target.token_pos(), 383 error, script, target.token_pos(),
383 "constructor '%s' has incompatible parameters with " 384 "constructor '%s' has incompatible parameters with "
384 "redirecting factory '%s'", 385 "redirecting factory '%s'",
385 String::Handle(target.name()).ToCString(), 386 String::Handle(target.name()).ToCString(),
386 String::Handle(factory.name()).ToCString()); 387 String::Handle(factory.name()).ToCString());
387 factory.SetRedirectionType(type); 388 factory.SetRedirectionType(type);
388 ASSERT(factory.RedirectionTarget() == Function::null()); 389 ASSERT(factory.RedirectionTarget() == Function::null());
389 return; 390 return;
390 } 391 }
391 } 392 }
392 393
(...skipping 28 matching lines...) Expand all
421 // If the target type refers to type parameters, substitute them with the 422 // If the target type refers to type parameters, substitute them with the
422 // type arguments of the redirection type. 423 // type arguments of the redirection type.
423 if (!target_type.IsInstantiated()) { 424 if (!target_type.IsInstantiated()) {
424 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( 425 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle(
425 type.arguments()); 426 type.arguments());
426 Error& malformed_error = Error::Handle(); 427 Error& malformed_error = Error::Handle();
427 target_type ^= target_type.InstantiateFrom(type_args, &malformed_error); 428 target_type ^= target_type.InstantiateFrom(type_args, &malformed_error);
428 if (malformed_error.IsNull()) { 429 if (malformed_error.IsNull()) {
429 target_type ^= FinalizeType(cls, target_type, kCanonicalize); 430 target_type ^= FinalizeType(cls, target_type, kCanonicalize);
430 } else { 431 } else {
431 FinalizeMalformedType(malformed_error, cls, target_type, 432 const Script& script = Script::Handle(target_class.script());
433 FinalizeMalformedType(malformed_error, script, target_type,
432 "cannot resolve redirecting factory"); 434 "cannot resolve redirecting factory");
433 target_target = Function::null(); 435 target_target = Function::null();
434 } 436 }
435 } 437 }
436 } 438 }
437 factory.SetRedirectionType(target_type); 439 factory.SetRedirectionType(target_type);
438 factory.SetRedirectionTarget(target_target); 440 factory.SetRedirectionTarget(target_target);
439 } 441 }
440 442
441 443
(...skipping 22 matching lines...) Expand all
464 Class::Handle(ResolveClass(cls, unresolved_class)); 466 Class::Handle(ResolveClass(cls, unresolved_class));
465 467
466 // Replace unresolved class with resolved type class. 468 // Replace unresolved class with resolved type class.
467 const Type& parameterized_type = Type::Cast(type); 469 const Type& parameterized_type = Type::Cast(type);
468 if (type_class.IsNull()) { 470 if (type_class.IsNull()) {
469 if ((finalization == kCanonicalizeWellFormed) || 471 if ((finalization == kCanonicalizeWellFormed) ||
470 FLAG_error_on_bad_type) { 472 FLAG_error_on_bad_type) {
471 // The type class could not be resolved. The type is malformed. 473 // The type class could not be resolved. The type is malformed.
472 FinalizeMalformedType( 474 FinalizeMalformedType(
473 Error::Handle(), // No previous error. 475 Error::Handle(), // No previous error.
474 cls, 476 Script::Handle(cls.script()),
475 parameterized_type, 477 parameterized_type,
476 "cannot resolve class '%s' from '%s'", 478 "cannot resolve class '%s' from '%s'",
477 String::Handle(unresolved_class.Name()).ToCString(), 479 String::Handle(unresolved_class.Name()).ToCString(),
478 String::Handle(cls.Name()).ToCString()); 480 String::Handle(cls.Name()).ToCString());
479 } else { 481 } else {
480 // Map the malformed type to dynamic and ignore type arguments. 482 // Map the malformed type to dynamic and ignore type arguments.
481 parameterized_type.set_type_class(Class::Handle( 483 parameterized_type.set_type_class(Class::Handle(
482 Object::dynamic_class())); 484 Object::dynamic_class()));
483 parameterized_type.set_arguments( 485 parameterized_type.set_arguments(
484 Object::null_abstract_type_arguments()); 486 Object::null_abstract_type_arguments());
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 } 901 }
900 902
901 // If a bound error occurred, return a BoundedType with a malformed bound. 903 // If a bound error occurred, return a BoundedType with a malformed bound.
902 // The malformed bound will be ignored in production mode. 904 // The malformed bound will be ignored in production mode.
903 if (!bound_error.IsNull()) { 905 if (!bound_error.IsNull()) {
904 // No compile-time error during finalization. 906 // No compile-time error during finalization.
905 const String& parameterized_type_name = String::Handle( 907 const String& parameterized_type_name = String::Handle(
906 parameterized_type.UserVisibleName()); 908 parameterized_type.UserVisibleName());
907 const Type& malformed_bound = Type::Handle( 909 const Type& malformed_bound = Type::Handle(
908 NewFinalizedMalformedType(bound_error, 910 NewFinalizedMalformedType(bound_error,
909 cls, 911 Script::Handle(cls.script()),
910 parameterized_type.token_pos(), 912 parameterized_type.token_pos(),
911 "type '%s' has an out of bound type argument", 913 "type '%s' has an out of bound type argument",
912 parameterized_type_name.ToCString())); 914 parameterized_type_name.ToCString()));
913 return BoundedType::New(parameterized_type, 915 return BoundedType::New(parameterized_type,
914 malformed_bound, 916 malformed_bound,
915 TypeParameter::Handle()); 917 TypeParameter::Handle());
916 } 918 }
917 919
918 if (finalization >= kCanonicalize) { 920 if (finalization >= kCanonicalize) {
919 return parameterized_type.Canonicalize(); 921 return parameterized_type.Canonicalize();
(...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 Field& field = Field::Handle(); 2441 Field& field = Field::Handle();
2440 len = fields_array.Length(); 2442 len = fields_array.Length();
2441 for (intptr_t i = 0; i < len; i++) { 2443 for (intptr_t i = 0; i < len; i++) {
2442 field ^= fields_array.At(i); 2444 field ^= fields_array.At(i);
2443 OS::Print(" %s\n", field.ToCString()); 2445 OS::Print(" %s\n", field.ToCString());
2444 } 2446 }
2445 } 2447 }
2446 2448
2447 // Either report an error or mark the type as malformed. 2449 // Either report an error or mark the type as malformed.
2448 void ClassFinalizer::ReportMalformedType(const Error& prev_error, 2450 void ClassFinalizer::ReportMalformedType(const Error& prev_error,
2449 const Class& cls, 2451 const Script& script,
2450 const Type& type, 2452 const Type& type,
2451 const char* format, 2453 const char* format,
2452 va_list args) { 2454 va_list args) {
2453 LanguageError& error = LanguageError::Handle(); 2455 LanguageError& error = LanguageError::Handle();
2454 const Script& script = Script::Handle(cls.script());
2455 if (prev_error.IsNull()) { 2456 if (prev_error.IsNull()) {
2456 error ^= Parser::FormatError( 2457 error ^= Parser::FormatError(
2457 script, type.token_pos(), "Error", format, args); 2458 script, type.token_pos(), "Error", format, args);
2458 } else { 2459 } else {
2459 error ^= Parser::FormatErrorWithAppend( 2460 error ^= Parser::FormatErrorWithAppend(
2460 prev_error, script, type.token_pos(), "Error", format, args); 2461 prev_error, script, type.token_pos(), "Error", format, args);
2461 } 2462 }
2462 if (FLAG_error_on_bad_type) { 2463 if (FLAG_error_on_bad_type) {
2463 ReportError(error); 2464 ReportError(error);
2464 } 2465 }
2465 type.set_malformed_error(error); 2466 type.set_malformed_error(error);
2466 // Make the type raw, since it may not be possible to 2467 // Make the type raw, since it may not be possible to
2467 // properly finalize its type arguments. 2468 // properly finalize its type arguments.
2468 type.set_type_class(Class::Handle(Object::dynamic_class())); 2469 type.set_type_class(Class::Handle(Object::dynamic_class()));
2469 type.set_arguments(Object::null_abstract_type_arguments()); 2470 type.set_arguments(Object::null_abstract_type_arguments());
2470 if (!type.IsFinalized()) { 2471 if (!type.IsFinalized()) {
2471 type.SetIsFinalized(); 2472 type.SetIsFinalized();
2472 // Do not canonicalize malformed types, since they may not be resolved. 2473 // Do not canonicalize malformed types, since they may not be resolved.
2473 } else { 2474 } else {
2474 // The only case where the malformed type was already finalized is when its 2475 // The only case where the malformed type was already finalized is when its
2475 // type arguments are not within bounds. In that case, we have a prev_error. 2476 // type arguments are not within bounds. In that case, we have a prev_error.
2476 ASSERT(!prev_error.IsNull()); 2477 ASSERT(!prev_error.IsNull());
2477 } 2478 }
2478 } 2479 }
2479 2480
2480 2481
2481 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, 2482 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error,
2482 const Class& cls, 2483 const Script& script,
2483 intptr_t type_pos, 2484 intptr_t type_pos,
2484 const char* format, ...) { 2485 const char* format, ...) {
2485 va_list args; 2486 va_list args;
2486 va_start(args, format); 2487 va_start(args, format);
2487 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( 2488 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle(
2488 UnresolvedClass::New(LibraryPrefix::Handle(), 2489 UnresolvedClass::New(LibraryPrefix::Handle(),
2489 Symbols::Empty(), 2490 Symbols::Empty(),
2490 type_pos)); 2491 type_pos));
2491 const Type& type = Type::Handle( 2492 const Type& type = Type::Handle(
2492 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); 2493 Type::New(unresolved_class, TypeArguments::Handle(), type_pos));
2493 ReportMalformedType(prev_error, cls, type, format, args); 2494 ReportMalformedType(prev_error, script, type, format, args);
2494 va_end(args); 2495 va_end(args);
2495 ASSERT(type.IsMalformed()); 2496 ASSERT(type.IsMalformed());
2496 ASSERT(type.IsFinalized()); 2497 ASSERT(type.IsFinalized());
2497 return type.raw(); 2498 return type.raw();
2498 } 2499 }
2499 2500
2500 2501
2501 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, 2502 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error,
2502 const Class& cls, 2503 const Script& script,
2503 const Type& type, 2504 const Type& type,
2504 const char* format, ...) { 2505 const char* format, ...) {
2505 va_list args; 2506 va_list args;
2506 va_start(args, format); 2507 va_start(args, format);
2507 ReportMalformedType(prev_error, cls, type, format, args); 2508 ReportMalformedType(prev_error, script, type, format, args);
2508 va_end(args); 2509 va_end(args);
2509 } 2510 }
2510 2511
2511 2512
2512 void ClassFinalizer::ReportError(const Error& error) { 2513 void ClassFinalizer::ReportError(const Error& error) {
2513 Isolate::Current()->long_jump_base()->Jump(1, error); 2514 Isolate::Current()->long_jump_base()->Jump(1, error);
2514 UNREACHABLE(); 2515 UNREACHABLE();
2515 } 2516 }
2516 2517
2517 2518
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2596 expected_name ^= String::New("_offset"); 2597 expected_name ^= String::New("_offset");
2597 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2598 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2598 field ^= fields_array.At(2); 2599 field ^= fields_array.At(2);
2599 ASSERT(field.Offset() == TypedDataView::length_offset()); 2600 ASSERT(field.Offset() == TypedDataView::length_offset());
2600 name ^= field.name(); 2601 name ^= field.name();
2601 ASSERT(name.Equals("length")); 2602 ASSERT(name.Equals("length"));
2602 #endif 2603 #endif
2603 } 2604 }
2604 2605
2605 } // namespace dart 2606 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698