| OLD | NEW |
| 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 if (dst_type.IsVoidType()) { | 332 if (dst_type.IsVoidType()) { |
| 333 return true; | 333 return true; |
| 334 } | 334 } |
| 335 | 335 |
| 336 // If nothing is known about the value, as is the case for passed-in | 336 // If nothing is known about the value, as is the case for passed-in |
| 337 // parameters, the test cannot be eliminated. | 337 // parameters, the test cannot be eliminated. |
| 338 if (value == NULL) { | 338 if (value == NULL) { |
| 339 return false; | 339 return false; |
| 340 } | 340 } |
| 341 | 341 |
| 342 // If nothing is known about the static type of the value, the test cannot be | 342 // Consider the static type of the value. |
| 343 // eliminated. | |
| 344 const AbstractType& static_type = AbstractType::Handle(value->StaticType()); | 343 const AbstractType& static_type = AbstractType::Handle(value->StaticType()); |
| 345 ASSERT(!static_type.IsMalformed()); | 344 ASSERT(!static_type.IsMalformed()); |
| 346 if (static_type.IsDynamicType()) { | |
| 347 return false; | |
| 348 } | |
| 349 | 345 |
| 350 // If the static type of the value is void, the only allowed value is null, | 346 // If the static type of the value is void, the only allowed value is null, |
| 351 // which must be verified by the type test. | 347 // which must be verified by the type test. |
| 352 if (static_type.IsVoidType()) { | 348 if (static_type.IsVoidType()) { |
| 353 // TODO(regis): Eliminate the test if the value is constant null. | 349 // TODO(regis): Eliminate the test if the value is constant null. |
| 354 return false; | 350 return false; |
| 355 } | 351 } |
| 356 | 352 |
| 357 // Eliminate the test if it can be performed successfully at compile time. | 353 // If the static type of the value is NullType, the type test is eliminated. |
| 358 if (static_type.IsNullType()) { | 354 if (static_type.IsNullType()) { |
| 359 // There are only three instances that can be of Class Null: | 355 // There are only three instances that can be of Class Null: |
| 360 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). | 356 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). |
| 361 // The inline code and run time code performing the type check will never | 357 // The inline code and run time code performing the type check will never |
| 362 // encounter the 2 sentinel values. The type check of a sentinel value | 358 // encounter the 2 sentinel values. The type check of a sentinel value |
| 363 // will always be eliminated here, because these sentinel values can only | 359 // will always be eliminated here, because these sentinel values can only |
| 364 // be encountered as constants, never as actual value of a heap object | 360 // be encountered as constants, never as actual value of a heap object |
| 365 // being type checked. | 361 // being type checked. |
| 366 return true; | 362 return true; |
| 367 } | 363 } |
| 368 if (static_type.IsType() && | 364 |
| 369 Class::Handle(static_type.type_class()).HasTypeArguments()) { | 365 // The run time type of the value is guaranteed to be a subtype of the compile |
| 370 // TODO(regis): Special tests need to be added. | 366 // time static type of the value. However, establishing here that the static |
| 371 return false; | 367 // type is a subtype of the destination type does not guarantee that the run |
| 372 } | 368 // time type will also be a subtype of the destination type, because the |
| 369 // subtype relation is not transitive. |
| 370 // However, the 'more specific than' relation is transitive and is used here. |
| 371 // In other words, if the static type of the value is more specific than the |
| 372 // destination type, the run time type of the value, which is guaranteed to |
| 373 // be a subtype of the static type, is also guaranteed to be a subtype of the |
| 374 // destination type and the type check can therefore be eliminated. |
| 373 Error& malformed_error = Error::Handle(); | 375 Error& malformed_error = Error::Handle(); |
| 374 if (!dst_type.IsMalformed() && | 376 if (static_type.IsMoreSpecificThan(dst_type, &malformed_error)) { |
| 375 static_type.IsSubtypeOf(dst_type, &malformed_error)) { | |
| 376 return true; | 377 return true; |
| 377 } | 378 } |
| 378 | 379 |
| 379 return false; | 380 return false; |
| 380 } | 381 } |
| 381 | 382 |
| 382 | 383 |
| 383 // <Expression> :: Assignable { expr: <Expression> | 384 // <Expression> :: Assignable { expr: <Expression> |
| 384 // type: AbstractType | 385 // type: AbstractType |
| 385 // dst_name: String } | 386 // dst_name: String } |
| (...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2728 char* chars = reinterpret_cast<char*>( | 2729 char* chars = reinterpret_cast<char*>( |
| 2729 Isolate::Current()->current_zone()->Allocate(len)); | 2730 Isolate::Current()->current_zone()->Allocate(len)); |
| 2730 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2731 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2731 const Error& error = Error::Handle( | 2732 const Error& error = Error::Handle( |
| 2732 LanguageError::New(String::Handle(String::New(chars)))); | 2733 LanguageError::New(String::Handle(String::New(chars)))); |
| 2733 Isolate::Current()->long_jump_base()->Jump(1, error); | 2734 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2734 } | 2735 } |
| 2735 | 2736 |
| 2736 | 2737 |
| 2737 } // namespace dart | 2738 } // namespace dart |
| OLD | NEW |