| OLD | NEW |
| 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_entry.h" | 10 #include "vm/dart_entry.h" |
| 11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
| 12 #include "vm/ic_data.h" |
| 12 #include "vm/ic_stubs.h" | 13 #include "vm/ic_stubs.h" |
| 13 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
| 14 #include "vm/resolver.h" | 15 #include "vm/resolver.h" |
| 15 #include "vm/runtime_entry.h" | 16 #include "vm/runtime_entry.h" |
| 16 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
| 17 #include "vm/verifier.h" | 18 #include "vm/verifier.h" |
| 18 | 19 |
| 19 namespace dart { | 20 namespace dart { |
| 20 | 21 |
| 21 DEFINE_FLAG(bool, inline_cache, true, "enable inline caches"); | 22 DEFINE_FLAG(bool, inline_cache, true, "enable inline caches"); |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 } | 546 } |
| 546 cls = cls.SuperClass(); | 547 cls = cls.SuperClass(); |
| 547 } | 548 } |
| 548 return function.raw(); | 549 return function.raw(); |
| 549 } | 550 } |
| 550 | 551 |
| 551 | 552 |
| 552 // Resolve an implicit closure by checking if an instance function | 553 // Resolve an implicit closure by checking if an instance function |
| 553 // of the same name exists and creating a closure object of the function. | 554 // of the same name exists and creating a closure object of the function. |
| 554 // Arg0: receiver object. | 555 // Arg0: receiver object. |
| 555 // Arg1: original function name. | 556 // Arg1: ic-data array. |
| 556 // Returns: Closure object or NULL (instance function not found). | 557 // Returns: Closure object or NULL (instance function not found). |
| 557 // This is called by the megamorphic stub when it is unable to resolve an | 558 // This is called by the megamorphic stub when it is unable to resolve an |
| 558 // instance method. This is done just before the call to noSuchMethod. | 559 // instance method. This is done just before the call to noSuchMethod. |
| 559 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) { | 560 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureFunction, 2) { |
| 560 ASSERT(arguments.Count() == | 561 ASSERT(arguments.Count() == |
| 561 kResolveImplicitClosureFunctionRuntimeEntry.argument_count()); | 562 kResolveImplicitClosureFunctionRuntimeEntry.argument_count()); |
| 562 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 563 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); |
| 563 const String& original_func_name = String::CheckedHandle(arguments.At(1)); | 564 const Array& ic_data_array = Array::CheckedHandle(arguments.At(1)); |
| 565 ICData ic_data(ic_data_array); |
| 566 const String& original_function_name = String::Handle(ic_data.FunctionName()); |
| 564 const String& getter_prefix = String::Handle(String::New("get:")); | 567 const String& getter_prefix = String::Handle(String::New("get:")); |
| 565 Closure& closure = Closure::Handle(); | 568 Closure& closure = Closure::Handle(); |
| 566 if (!original_func_name.StartsWith(getter_prefix)) { | 569 if (!original_function_name.StartsWith(getter_prefix)) { |
| 567 // This is not a getter so can't be the case where we are trying to | 570 // This is not a getter so can't be the case where we are trying to |
| 568 // create an implicit closure of an instance function. | 571 // create an implicit closure of an instance function. |
| 569 arguments.SetReturn(closure); | 572 arguments.SetReturn(closure); |
| 570 return; | 573 return; |
| 571 } | 574 } |
| 572 Class& receiver_class = Class::Handle(); | 575 Class& receiver_class = Class::Handle(); |
| 573 receiver_class ^= receiver.clazz(); | 576 receiver_class ^= receiver.clazz(); |
| 574 ASSERT(!receiver_class.IsNull()); | 577 ASSERT(!receiver_class.IsNull()); |
| 575 String& func_name = String::Handle(); | 578 String& func_name = String::Handle(); |
| 576 func_name = String::SubString(original_func_name, getter_prefix.Length()); | 579 func_name = String::SubString(original_function_name, getter_prefix.Length()); |
| 577 func_name = String::NewSymbol(func_name); | 580 func_name = String::NewSymbol(func_name); |
| 578 const Function& function = | 581 const Function& function = |
| 579 Function::Handle(LookupDynamicFunction(receiver_class, func_name)); | 582 Function::Handle(LookupDynamicFunction(receiver_class, func_name)); |
| 580 if (function.IsNull()) { | 583 if (function.IsNull()) { |
| 581 // There is no function of the same name so can't be the case where | 584 // There is no function of the same name so can't be the case where |
| 582 // we are trying to create an implicit closure of an instance function. | 585 // we are trying to create an implicit closure of an instance function. |
| 583 arguments.SetReturn(closure); | 586 arguments.SetReturn(closure); |
| 584 return; | 587 return; |
| 585 } | 588 } |
| 586 Function& implicit_closure_function = | 589 Function& implicit_closure_function = |
| 587 Function::Handle(function.ImplicitClosureFunction()); | 590 Function::Handle(function.ImplicitClosureFunction()); |
| 588 // Create a closure object for the implicit closure function. | 591 // Create a closure object for the implicit closure function. |
| 589 const Context& context = Context::Handle(Context::New(1)); | 592 const Context& context = Context::Handle(Context::New(1)); |
| 590 context.SetAt(0, receiver); | 593 context.SetAt(0, receiver); |
| 591 closure = Closure::New(implicit_closure_function, context); | 594 closure = Closure::New(implicit_closure_function, context); |
| 592 arguments.SetReturn(closure); | 595 arguments.SetReturn(closure); |
| 593 } | 596 } |
| 594 | 597 |
| 595 | 598 |
| 596 // Resolve an implicit closure by invoking getter and checking if the return | 599 // Resolve an implicit closure by invoking getter and checking if the return |
| 597 // value from getter is a closure. | 600 // value from getter is a closure. |
| 598 // Arg0: receiver object. | 601 // Arg0: receiver object. |
| 599 // Arg1: original function name. | 602 // Arg1: ic-data array. |
| 600 // Returns: Closure object or NULL (closure not found). | 603 // Returns: Closure object or NULL (closure not found). |
| 601 // This is called by the megamorphic stub when it is unable to resolve an | 604 // This is called by the megamorphic stub when it is unable to resolve an |
| 602 // instance method. This is done just before the call to noSuchMethod. | 605 // instance method. This is done just before the call to noSuchMethod. |
| 603 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureThroughGetter, 2) { | 606 DEFINE_RUNTIME_ENTRY(ResolveImplicitClosureThroughGetter, 2) { |
| 604 ASSERT(arguments.Count() == | 607 ASSERT(arguments.Count() == |
| 605 kResolveImplicitClosureThroughGetterRuntimeEntry.argument_count()); | 608 kResolveImplicitClosureThroughGetterRuntimeEntry.argument_count()); |
| 606 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 609 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); |
| 607 const String& original_function_name = String::CheckedHandle(arguments.At(1)); | 610 const Array& ic_data_array = Array::CheckedHandle(arguments.At(1)); |
| 611 ICData ic_data(ic_data_array); |
| 612 const String& original_function_name = String::Handle(ic_data.FunctionName()); |
| 608 const int kNumArguments = 1; | 613 const int kNumArguments = 1; |
| 609 const int kNumNamedArguments = 0; | 614 const int kNumNamedArguments = 0; |
| 610 const String& getter_function_name = | 615 const String& getter_function_name = |
| 611 String::Handle(Field::GetterName(original_function_name)); | 616 String::Handle(Field::GetterName(original_function_name)); |
| 612 Function& function = Function::ZoneHandle( | 617 Function& function = Function::ZoneHandle( |
| 613 Resolver::ResolveDynamic(receiver, | 618 Resolver::ResolveDynamic(receiver, |
| 614 getter_function_name, | 619 getter_function_name, |
| 615 kNumArguments, | 620 kNumArguments, |
| 616 kNumNamedArguments)); | 621 kNumNamedArguments)); |
| 617 Code& code = Code::Handle(); | 622 Code& code = Code::Handle(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 adjusted_arg_descriptor, | 716 adjusted_arg_descriptor, |
| 712 invoke_arguments.data(), | 717 invoke_arguments.data(), |
| 713 context)); | 718 context)); |
| 714 CheckResultException(result); | 719 CheckResultException(result); |
| 715 arguments.SetReturn(result); | 720 arguments.SetReturn(result); |
| 716 } | 721 } |
| 717 | 722 |
| 718 | 723 |
| 719 // Invoke appropriate noSuchMethod function. | 724 // Invoke appropriate noSuchMethod function. |
| 720 // Arg0: receiver. | 725 // Arg0: receiver. |
| 721 // Arg1: original function name. | 726 // Arg1: ic-data array. |
| 722 // Arg2: original arguments descriptor array. | 727 // Arg2: original arguments descriptor array. |
| 723 // Arg3: original arguments array. | 728 // Arg3: original arguments array. |
| 724 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { | 729 DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodFunction, 4) { |
| 725 ASSERT(arguments.Count() == | 730 ASSERT(arguments.Count() == |
| 726 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); | 731 kInvokeNoSuchMethodFunctionRuntimeEntry.argument_count()); |
| 727 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); | 732 const Instance& receiver = Instance::CheckedHandle(arguments.At(0)); |
| 728 const String& original_function_name = String::CheckedHandle(arguments.At(1)); | 733 const Array& ic_data_array = Array::CheckedHandle(arguments.At(1)); |
| 734 ICData ic_data(ic_data_array); |
| 735 const String& original_function_name = String::Handle(ic_data.FunctionName()); |
| 729 ASSERT(!Array::CheckedHandle(arguments.At(2)).IsNull()); | 736 ASSERT(!Array::CheckedHandle(arguments.At(2)).IsNull()); |
| 730 const Array& orig_arguments = Array::CheckedHandle(arguments.At(3)); | 737 const Array& orig_arguments = Array::CheckedHandle(arguments.At(3)); |
| 731 // TODO(regis): The signature of the "noSuchMethod" method has to change from | 738 // TODO(regis): The signature of the "noSuchMethod" method has to change from |
| 732 // noSuchMethod(String name, Array arguments) to something like | 739 // noSuchMethod(String name, Array arguments) to something like |
| 733 // noSuchMethod(InvocationMirror call). | 740 // noSuchMethod(InvocationMirror call). |
| 734 const int kNumArguments = 3; | 741 const int kNumArguments = 3; |
| 735 const int kNumNamedArguments = 0; | 742 const int kNumNamedArguments = 0; |
| 736 const Array& kNoArgumentNames = Array::Handle(); | 743 const Array& kNoArgumentNames = Array::Handle(); |
| 737 const String& function_name = | 744 const String& function_name = |
| 738 String::Handle(String::NewSymbol("noSuchMethod")); | 745 String::Handle(String::NewSymbol("noSuchMethod")); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 } | 1015 } |
| 1009 } | 1016 } |
| 1010 } | 1017 } |
| 1011 // The cache is null terminated, therefore the loop above should never | 1018 // The cache is null terminated, therefore the loop above should never |
| 1012 // terminate by itself. | 1019 // terminate by itself. |
| 1013 UNREACHABLE(); | 1020 UNREACHABLE(); |
| 1014 return Code::null(); | 1021 return Code::null(); |
| 1015 } | 1022 } |
| 1016 | 1023 |
| 1017 } // namespace dart | 1024 } // namespace dart |
| OLD | NEW |