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

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

Issue 14980002: Fix for issue 10395, call noSUchMethod if a method is not found when using the Dart C API. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | « no previous file | runtime/vm/dart_api_impl_test.cc » ('j') | runtime/vm/dart_api_impl_test.cc » ('J')
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 "include/dart_api.h" 5 #include "include/dart_api.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/class_finalizer.h" 9 #include "vm/class_finalizer.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 3787 matching lines...) Expand 10 before | Expand all | Expand 10 after
3798 } else { 3798 } else {
3799 return Api::NewError( 3799 return Api::NewError(
3800 "%s expects arguments[%d] to be an Instance handle.", 3800 "%s expects arguments[%d] to be an Instance handle.",
3801 CURRENT_FUNC, i); 3801 CURRENT_FUNC, i);
3802 } 3802 }
3803 } 3803 }
3804 args.SetAt((i + num_receiver), arg); 3804 args.SetAt((i + num_receiver), arg);
3805 } 3805 }
3806 3806
3807 if (obj.IsNull() || obj.IsInstance()) { 3807 if (obj.IsNull() || obj.IsInstance()) {
3808 Instance& instance = Instance::Handle(isolate); 3808 Instance& instance = Instance::Handle();
Ivan Posva 2013/05/07 09:58:43 Any particular reason for dropping the isolate par
siva 2013/05/07 15:40:52 No particular reason. I initially tries to change
3809 instance ^= obj.raw(); 3809 instance ^= obj.raw();
3810 const Function& function = Function::Handle( 3810 const Function& function = Function::Handle(
3811 isolate, 3811 isolate,
3812 Resolver::ResolveDynamic(instance, 3812 Resolver::ResolveDynamic(instance,
3813 function_name, 3813 function_name,
3814 (number_of_arguments + 1), 3814 (number_of_arguments + 1),
3815 Resolver::kIsQualified)); 3815 Resolver::kIsQualified));
3816 // TODO(5415268): Invoke noSuchMethod instead of failing. 3816 args.SetAt(0, instance);
3817 if (function.IsNull()) { 3817 if (function.IsNull()) {
3818 const Type& type = Type::Handle(isolate, instance.GetType()); 3818 const Array& args_descriptor =
3819 const String& cls_name = String::Handle(isolate, type.ClassName()); 3819 Array::Handle(ArgumentsDescriptor::New(args.Length()));
3820 return Api::NewError("%s: did not find instance method '%s.%s'.", 3820 return Api::NewHandle(isolate,
3821 CURRENT_FUNC, 3821 DartEntry::InvokeNoSuchMethod(instance,
3822 cls_name.ToCString(), 3822 function_name,
3823 function_name.ToCString()); 3823 args,
3824 args_descriptor));
3824 } 3825 }
3825 args.SetAt(0, instance);
3826 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); 3826 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
3827 3827
3828 } else if (obj.IsClass()) { 3828 } else if (obj.IsClass()) {
3829 // Finalize all classes. 3829 // Finalize all classes.
3830 Dart_Handle state = Api::CheckIsolateState(isolate); 3830 Dart_Handle state = Api::CheckIsolateState(isolate);
3831 if (::Dart_IsError(state)) { 3831 if (::Dart_IsError(state)) {
3832 return state; 3832 return state;
3833 } 3833 }
3834 3834
3835 const Class& cls = Class::Cast(obj); 3835 const Class& cls = Class::Cast(obj);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3926 Function& getter = Function::Handle(isolate); 3926 Function& getter = Function::Handle(isolate);
3927 if (obj.IsNull()) { 3927 if (obj.IsNull()) {
3928 return Api::NewError("%s expects argument 'container' to be non-null.", 3928 return Api::NewError("%s expects argument 'container' to be non-null.",
3929 CURRENT_FUNC); 3929 CURRENT_FUNC);
3930 } else if (obj.IsInstance()) { 3930 } else if (obj.IsInstance()) {
3931 // Every instance field has a getter Function. Try to find the 3931 // Every instance field has a getter Function. Try to find the
3932 // getter in any superclass and use that function to access the 3932 // getter in any superclass and use that function to access the
3933 // field. 3933 // field.
3934 const Instance& instance = Instance::Cast(obj); 3934 const Instance& instance = Instance::Cast(obj);
3935 Class& cls = Class::Handle(isolate, instance.clazz()); 3935 Class& cls = Class::Handle(isolate, instance.clazz());
3936 String& getter_name =
3937 String::Handle(isolate, Field::GetterName(field_name));
3936 while (!cls.IsNull()) { 3938 while (!cls.IsNull()) {
3937 String& getter_name =
3938 String::Handle(isolate, Field::GetterName(field_name));
3939 getter = cls.LookupDynamicFunctionAllowPrivate(getter_name); 3939 getter = cls.LookupDynamicFunctionAllowPrivate(getter_name);
3940 if (!getter.IsNull()) { 3940 if (!getter.IsNull()) {
3941 break; 3941 break;
3942 } 3942 }
3943 cls = cls.SuperClass(); 3943 cls = cls.SuperClass();
3944 } 3944 }
3945 3945
3946 if (getter.IsNull()) {
3947 return Api::NewError("%s: did not find instance field '%s'.",
3948 CURRENT_FUNC, field_name.ToCString());
3949 }
3950
3951 // Invoke the getter and return the result. 3946 // Invoke the getter and return the result.
3952 const int kNumArgs = 1; 3947 const int kNumArgs = 1;
3953 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); 3948 const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
3954 args.SetAt(0, instance); 3949 args.SetAt(0, instance);
3950 if (getter.IsNull()) {
3951 const Array& args_descriptor =
3952 Array::Handle(ArgumentsDescriptor::New(args.Length()));
3953 return Api::NewHandle(isolate,
3954 DartEntry::InvokeNoSuchMethod(instance,
3955 getter_name,
3956 args,
3957 args_descriptor));
3958 }
3955 return Api::NewHandle(isolate, DartEntry::InvokeFunction(getter, args)); 3959 return Api::NewHandle(isolate, DartEntry::InvokeFunction(getter, args));
3956 3960
3957 } else if (obj.IsClass()) { 3961 } else if (obj.IsClass()) {
3958 // Finalize all classes. 3962 // Finalize all classes.
3959 Dart_Handle state = Api::CheckIsolateState(isolate); 3963 Dart_Handle state = Api::CheckIsolateState(isolate);
3960 if (::Dart_IsError(state)) { 3964 if (::Dart_IsError(state)) {
3961 return state; 3965 return state;
3962 } 3966 }
3963 // To access a static field we may need to use the Field or the 3967 // To access a static field we may need to use the Field or the
3964 // getter Function. 3968 // getter Function.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
4048 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container)); 4052 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container));
4049 if (obj.IsNull()) { 4053 if (obj.IsNull()) {
4050 return Api::NewError("%s expects argument 'container' to be non-null.", 4054 return Api::NewError("%s expects argument 'container' to be non-null.",
4051 CURRENT_FUNC); 4055 CURRENT_FUNC);
4052 } else if (obj.IsInstance()) { 4056 } else if (obj.IsInstance()) {
4053 // Every instance field has a setter Function. Try to find the 4057 // Every instance field has a setter Function. Try to find the
4054 // setter in any superclass and use that function to access the 4058 // setter in any superclass and use that function to access the
4055 // field. 4059 // field.
4056 const Instance& instance = Instance::Cast(obj); 4060 const Instance& instance = Instance::Cast(obj);
4057 Class& cls = Class::Handle(isolate, instance.clazz()); 4061 Class& cls = Class::Handle(isolate, instance.clazz());
4062 String& setter_name =
4063 String::Handle(isolate, Field::SetterName(field_name));
4058 while (!cls.IsNull()) { 4064 while (!cls.IsNull()) {
4059 field = cls.LookupInstanceField(field_name); 4065 field = cls.LookupInstanceField(field_name);
4060 if (!field.IsNull() && field.is_final()) { 4066 if (!field.IsNull() && field.is_final()) {
4061 return Api::NewError("%s: cannot set final field '%s'.", 4067 return Api::NewError("%s: cannot set final field '%s'.",
4062 CURRENT_FUNC, field_name.ToCString()); 4068 CURRENT_FUNC, field_name.ToCString());
4063 } 4069 }
4064 String& setter_name =
4065 String::Handle(isolate, Field::SetterName(field_name));
4066 setter = cls.LookupDynamicFunctionAllowPrivate(setter_name); 4070 setter = cls.LookupDynamicFunctionAllowPrivate(setter_name);
4067 if (!setter.IsNull()) { 4071 if (!setter.IsNull()) {
4068 break; 4072 break;
4069 } 4073 }
4070 cls = cls.SuperClass(); 4074 cls = cls.SuperClass();
4071 } 4075 }
4072 4076
4073 if (setter.IsNull()) {
4074 return Api::NewError("%s: did not find instance field '%s'.",
4075 CURRENT_FUNC, field_name.ToCString());
4076 }
4077
4078 // Invoke the setter and return the result. 4077 // Invoke the setter and return the result.
4079 const int kNumArgs = 2; 4078 const int kNumArgs = 2;
4080 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); 4079 const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
4081 args.SetAt(0, instance); 4080 args.SetAt(0, instance);
4082 args.SetAt(1, value_instance); 4081 args.SetAt(1, value_instance);
4082 if (setter.IsNull()) {
4083 const Array& args_descriptor =
4084 Array::Handle(ArgumentsDescriptor::New(args.Length()));
4085 return Api::NewHandle(isolate,
4086 DartEntry::InvokeNoSuchMethod(instance,
4087 setter_name,
4088 args,
4089 args_descriptor));
4090 }
4083 return Api::NewHandle(isolate, DartEntry::InvokeFunction(setter, args)); 4091 return Api::NewHandle(isolate, DartEntry::InvokeFunction(setter, args));
4084 4092
4085 } else if (obj.IsClass()) { 4093 } else if (obj.IsClass()) {
4086 // To access a static field we may need to use the Field or the 4094 // To access a static field we may need to use the Field or the
4087 // setter Function. 4095 // setter Function.
4088 const Class& cls = Class::Cast(obj); 4096 const Class& cls = Class::Cast(obj);
4089 field = cls.LookupStaticField(field_name); 4097 field = cls.LookupStaticField(field_name);
4090 if (field.IsNull()) { 4098 if (field.IsNull()) {
4091 String& setter_name = 4099 String& setter_name =
4092 String::Handle(isolate, Field::SetterName(field_name)); 4100 String::Handle(isolate, Field::SetterName(field_name));
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
4848 } 4856 }
4849 { 4857 {
4850 NoGCScope no_gc; 4858 NoGCScope no_gc;
4851 RawObject* raw_obj = obj.raw(); 4859 RawObject* raw_obj = obj.raw();
4852 isolate->heap()->SetPeer(raw_obj, peer); 4860 isolate->heap()->SetPeer(raw_obj, peer);
4853 } 4861 }
4854 return Api::Success(isolate); 4862 return Api::Success(isolate);
4855 } 4863 }
4856 4864
4857 } // namespace dart 4865 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/dart_api_impl_test.cc » ('j') | runtime/vm/dart_api_impl_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698