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

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

Issue 9664029: Fix type check to perform a subtype test at top level instead of an (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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/lib/error.dart ('k') | runtime/vm/exceptions.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/code_index_table.h" 7 #include "vm/code_index_table.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_api_impl.h" 10 #include "vm/dart_api_impl.h"
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 String::New(malformed_error.ToErrorCString())); 406 String::New(malformed_error.ToErrorCString()));
407 const String& no_name = String::Handle(String::NewSymbol("")); 407 const String& no_name = String::Handle(String::NewSymbol(""));
408 Exceptions::CreateAndThrowTypeError( 408 Exceptions::CreateAndThrowTypeError(
409 location, no_name, no_name, no_name, malformed_error_message); 409 location, no_name, no_name, no_name, malformed_error_message);
410 UNREACHABLE(); 410 UNREACHABLE();
411 } 411 }
412 arguments.SetReturn(result); 412 arguments.SetReturn(result);
413 } 413 }
414 414
415 415
416 // Check that the type of the given instance is assignable to the given type. 416 // Check that the type of the given instance is a subtype of the given type and
417 // can therefore be assigned.
417 // Arg0: index of the token of the assignment (source location). 418 // Arg0: index of the token of the assignment (source location).
418 // Arg1: instance being assigned. 419 // Arg1: instance being assigned.
419 // Arg2: type being assigned to. 420 // Arg2: type being assigned to.
420 // Arg3: type arguments of the instantiator of the type being assigned to. 421 // Arg3: type arguments of the instantiator of the type being assigned to.
421 // Arg4: name of instance being assigned to. 422 // Arg4: name of variable being assigned to.
422 // Return value: instance if assignable, otherwise throw a TypeError. 423 // Return value: instance if a subtype, otherwise throw a TypeError.
423 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) { 424 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) {
424 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); 425 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count());
425 // TODO(regis): Get the token index from the PcDesc (via DartFrame). 426 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
426 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 427 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
427 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); 428 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1));
428 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(2)); 429 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(2));
429 const AbstractTypeArguments& dst_type_instantiator = 430 const AbstractTypeArguments& dst_type_instantiator =
430 AbstractTypeArguments::CheckedHandle(arguments.At(3)); 431 AbstractTypeArguments::CheckedHandle(arguments.At(3));
431 const String& dst_name = String::CheckedHandle(arguments.At(4)); 432 const String& dst_name = String::CheckedHandle(arguments.At(4));
432 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. 433 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
434 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
433 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. 435 ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
434 436
435 Error& malformed_error = Error::Handle(); 437 Error& malformed_error = Error::Handle();
436 const bool is_assignable = src_instance.IsAssignableTo( 438 const bool is_instance_of = src_instance.IsInstanceOf(
437 dst_type, dst_type_instantiator, &malformed_error); 439 dst_type, dst_type_instantiator, &malformed_error);
438 440
439 if (FLAG_trace_type_checks) { 441 if (FLAG_trace_type_checks) {
440 const Type& src_type = Type::Handle(src_instance.GetType()); 442 const Type& src_type = Type::Handle(src_instance.GetType());
441 if (dst_type.IsInstantiated()) { 443 if (dst_type.IsInstantiated()) {
442 OS::Print("TypeCheck: '%s' %s assignable to '%s' of '%s'.\n", 444 OS::Print("TypeCheck: type '%s' %s a subtype of type '%s' of '%s'.\n",
443 String::Handle(src_type.Name()).ToCString(), 445 String::Handle(src_type.Name()).ToCString(),
444 is_assignable ? "is" : "is not", 446 is_instance_of ? "is" : "is not",
445 String::Handle(dst_type.Name()).ToCString(), 447 String::Handle(dst_type.Name()).ToCString(),
446 dst_name.ToCString()); 448 dst_name.ToCString());
447 } else { 449 } else {
448 // Instantiate dst_type before printing. 450 // Instantiate dst_type before printing.
449 const AbstractType& instantiated_dst_type = AbstractType::Handle( 451 const AbstractType& instantiated_dst_type = AbstractType::Handle(
450 dst_type.InstantiateFrom(dst_type_instantiator)); 452 dst_type.InstantiateFrom(dst_type_instantiator));
451 OS::Print("TypeCheck: '%s' %s assignable to '%s' of '%s' " 453 OS::Print("TypeCheck: type '%s' %s a subtype of type '%s' of '%s' "
452 "instantiated from '%s'.\n", 454 "instantiated from '%s'.\n",
453 String::Handle(src_type.Name()).ToCString(), 455 String::Handle(src_type.Name()).ToCString(),
454 is_assignable ? "is" : "is not", 456 is_instance_of ? "is" : "is not",
455 String::Handle(instantiated_dst_type.Name()).ToCString(), 457 String::Handle(instantiated_dst_type.Name()).ToCString(),
456 dst_name.ToCString(), 458 dst_name.ToCString(),
457 String::Handle(dst_type.Name()).ToCString()); 459 String::Handle(dst_type.Name()).ToCString());
458 } 460 }
459 DartFrameIterator iterator; 461 DartFrameIterator iterator;
460 DartFrame* caller_frame = iterator.NextFrame(); 462 DartFrame* caller_frame = iterator.NextFrame();
461 ASSERT(caller_frame != NULL); 463 ASSERT(caller_frame != NULL);
462 const Function& function = Function::Handle( 464 const Function& function = Function::Handle(
463 caller_frame->LookupDartFunction()); 465 caller_frame->LookupDartFunction());
464 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString()); 466 OS::Print(" -> Function %s\n", function.ToFullyQualifiedCString());
465 } 467 }
466 if (!is_assignable) { 468 if (!is_instance_of) {
467 const Type& src_type = Type::Handle(src_instance.GetType()); 469 const Type& src_type = Type::Handle(src_instance.GetType());
468 const String& src_type_name = String::Handle(src_type.Name()); 470 const String& src_type_name = String::Handle(src_type.Name());
469 String& dst_type_name = String::Handle(); 471 String& dst_type_name = String::Handle();
470 if (!dst_type.IsInstantiated()) { 472 if (!dst_type.IsInstantiated()) {
471 // Instantiate dst_type before reporting the error. 473 // Instantiate dst_type before reporting the error.
472 const AbstractType& instantiated_dst_type = AbstractType::Handle( 474 const AbstractType& instantiated_dst_type = AbstractType::Handle(
473 dst_type.InstantiateFrom(dst_type_instantiator)); 475 dst_type.InstantiateFrom(dst_type_instantiator));
474 dst_type_name = instantiated_dst_type.Name(); 476 dst_type_name = instantiated_dst_type.Name();
475 } else { 477 } else {
476 dst_type_name = dst_type.Name(); 478 dst_type_name = dst_type.Name();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 const String& malformed_error = String::CheckedHandle(arguments.At(3)); 529 const String& malformed_error = String::CheckedHandle(arguments.At(3));
528 const String& dst_type_name = String::Handle(String::NewSymbol("malformed")); 530 const String& dst_type_name = String::Handle(String::NewSymbol("malformed"));
529 const String& src_type_name = 531 const String& src_type_name =
530 String::Handle(Type::Handle(src_value.GetType()).Name()); 532 String::Handle(Type::Handle(src_value.GetType()).Name());
531 Exceptions::CreateAndThrowTypeError(location, src_type_name, 533 Exceptions::CreateAndThrowTypeError(location, src_type_name,
532 dst_type_name, dst_name, malformed_error); 534 dst_type_name, dst_name, malformed_error);
533 UNREACHABLE(); 535 UNREACHABLE();
534 } 536 }
535 537
536 538
539 // TODO(regis): Function rest arguments are not supported anymore, but they may
540 // come back.
537 // Check that the type of each element of the given array is assignable to the 541 // Check that the type of each element of the given array is assignable to the
538 // given type. 542 // given type.
539 // Arg0: index of the token of the rest argument declaration (source location). 543 // Arg0: index of the token of the rest argument declaration (source location).
540 // Arg1: rest argument array. 544 // Arg1: rest argument array.
541 // Arg2: element declaration type. 545 // Arg2: element declaration type.
542 // Arg3: type arguments of the instantiator of the element declaration type. 546 // Arg3: type arguments of the instantiator of the element declaration type.
543 // Arg4: name of object being assigned to, i.e. name of rest argument. 547 // Arg4: name of object being assigned to, i.e. name of rest argument.
544 // Return value: null if assignable, otherwise allocate and throw a TypeError. 548 // Return value: null if assignable, otherwise allocate and throw a TypeError.
545 DEFINE_RUNTIME_ENTRY(RestArgumentTypeCheck, 5) { 549 DEFINE_RUNTIME_ENTRY(RestArgumentTypeCheck, 5) {
546 ASSERT(arguments.Count() == 550 ASSERT(arguments.Count() ==
547 kRestArgumentTypeCheckRuntimeEntry.argument_count()); 551 kRestArgumentTypeCheckRuntimeEntry.argument_count());
548 // TODO(regis): Get the token index from the PcDesc (via DartFrame). 552 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
549 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 553 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
550 const Array& rest_array = Array::CheckedHandle(arguments.At(1)); 554 const Array& rest_array = Array::CheckedHandle(arguments.At(1));
551 const AbstractType& element_type = 555 const AbstractType& element_type =
552 AbstractType::CheckedHandle(arguments.At(2)); 556 AbstractType::CheckedHandle(arguments.At(2));
553 const AbstractTypeArguments& element_type_instantiator = 557 const AbstractTypeArguments& element_type_instantiator =
554 AbstractTypeArguments::CheckedHandle(arguments.At(3)); 558 AbstractTypeArguments::CheckedHandle(arguments.At(3));
555 const String& rest_name = String::CheckedHandle(arguments.At(4)); 559 const String& rest_name = String::CheckedHandle(arguments.At(4));
556 ASSERT(!element_type.IsDynamicType()); // No need to check assignment. 560 ASSERT(!element_type.IsDynamicType()); // No need to check assignment.
561 ASSERT(!element_type.IsMalformed()); // Already checked in code generator.
557 ASSERT(!rest_array.IsNull()); 562 ASSERT(!rest_array.IsNull());
558 563
559 Instance& elem = Instance::Handle(); 564 Instance& elem = Instance::Handle();
560 Error& malformed_error = Error::Handle(); 565 Error& malformed_error = Error::Handle();
561 for (intptr_t i = 0; i < rest_array.Length(); i++) { 566 for (intptr_t i = 0; i < rest_array.Length(); i++) {
562 elem ^= rest_array.At(i); 567 elem ^= rest_array.At(i);
563 // The previous successful type check may have set malformed_error. 568 // The previous successful type check may have set malformed_error.
564 // Note that a returned malformed_error is ignored if a type check succeeds. 569 // Note that a returned malformed_error is ignored if a type check succeeds.
565 malformed_error = Error::null(); 570 malformed_error = Error::null();
566 if (!elem.IsNull() && !elem.IsAssignableTo(element_type, 571 if (!elem.IsNull() && !elem.IsInstanceOf(element_type,
567 element_type_instantiator, 572 element_type_instantiator,
568 &malformed_error)) { 573 &malformed_error)) {
569 // Allocate and throw a new instance of TypeError. 574 // Allocate and throw a new instance of TypeError.
570 char buf[256]; 575 char buf[256];
571 OS::SNPrint(buf, sizeof(buf), "%s[%d]", 576 OS::SNPrint(buf, sizeof(buf), "%s[%d]",
572 rest_name.ToCString(), static_cast<int>(i)); 577 rest_name.ToCString(), static_cast<int>(i));
573 const String& src_type_name = 578 const String& src_type_name =
574 String::Handle(Type::Handle(elem.GetType()).Name()); 579 String::Handle(Type::Handle(elem.GetType()).Name());
575 String& dst_type_name = String::Handle(); 580 String& dst_type_name = String::Handle();
576 if (!element_type.IsInstantiated()) { 581 if (!element_type.IsInstantiated()) {
577 // Instantiate element_type before reporting the error. 582 // Instantiate element_type before reporting the error.
578 const AbstractType& instantiated_element_type = AbstractType::Handle( 583 const AbstractType& instantiated_element_type = AbstractType::Handle(
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 } 1433 }
1429 } 1434 }
1430 } 1435 }
1431 // The cache is null terminated, therefore the loop above should never 1436 // The cache is null terminated, therefore the loop above should never
1432 // terminate by itself. 1437 // terminate by itself.
1433 UNREACHABLE(); 1438 UNREACHABLE();
1434 return Code::null(); 1439 return Code::null();
1435 } 1440 }
1436 1441
1437 } // namespace dart 1442 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/error.dart ('k') | runtime/vm/exceptions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698