Chromium Code Reviews| Index: runtime/lib/mirrors.cc |
| diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc |
| index b66088c1f8b18be66dd5e17c7d03333899b39799..4505f07f875304e2aea0e64542bc78e4e7ccee2f 100644 |
| --- a/runtime/lib/mirrors.cc |
| +++ b/runtime/lib/mirrors.cc |
| @@ -65,6 +65,7 @@ static void ThrowInvokeError(const Error& error) { |
| static void ThrowNoSuchMethod(const Instance& receiver, |
| const String& function_name, |
| const Function& function, |
| + const Array& arguments, |
| const InvocationMirror::Call call, |
| const InvocationMirror::Type type) { |
| const Smi& invocation_type = Smi::Handle(Smi::New( |
| @@ -74,10 +75,8 @@ static void ThrowNoSuchMethod(const Instance& receiver, |
| args.SetAt(0, receiver); |
| args.SetAt(1, function_name); |
| args.SetAt(2, invocation_type); |
| - // Parameter 3 (actual arguments): We omit this parameter to get the same |
| - // error message as one would get by invoking the function non-reflectively. |
| - // Parameter 4 (named arguments): We omit this parameters since we cannot |
| - // invoke functions with named parameters reflectively (using mirrors). |
| + args.SetAt(3, arguments); |
| + // TODO(rmacnak): Argument 4 (attempted argument names). |
| if (!function.IsNull()) { |
| const intptr_t total_num_parameters = function.NumParameters(); |
| const Array& array = Array::Handle(Array::New(total_num_parameters)); |
| @@ -660,6 +659,7 @@ static RawInstance* InvokeLibraryGetter(const Library& library, |
| ThrowNoSuchMethod(Instance::null_instance(), |
| getter_name, |
| getter, |
| + Array::Handle(), |
|
siva
2014/06/12 16:59:07
Use Object::null_array() instead of creating a new
rmacnak
2014/06/12 22:52:08
Done.
|
| InvocationMirror::kTopLevel, |
| InvocationMirror::kGetter); |
| UNREACHABLE(); |
| @@ -697,6 +697,7 @@ static RawInstance* InvokeClassGetter(const Class& klass, |
| ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| getter_name, |
| getter, |
| + Array::Handle(), |
|
siva
2014/06/12 16:59:07
Ditto.
|
| InvocationMirror::kStatic, |
| InvocationMirror::kGetter); |
| UNREACHABLE(); |
| @@ -1426,6 +1427,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 5) { |
| ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| function_name, |
| function, |
| + Array::Handle(), |
|
siva
2014/06/12 16:59:07
Ditto here and other places below.
|
| InvocationMirror::kStatic, |
| InvocationMirror::kMethod); |
| UNREACHABLE(); |
| @@ -1464,26 +1466,27 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) { |
| // Check for real fields and user-defined setters. |
| const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); |
| Function& setter = Function::Handle(); |
| - if (field.IsNull()) { |
| - const String& internal_setter_name = String::Handle( |
| + const String& internal_setter_name = String::Handle( |
| Field::SetterName(setter_name)); |
| + if (field.IsNull()) { |
| setter = klass.LookupStaticFunction(internal_setter_name); |
| + const int kNumArgs = 1; |
| + const Array& args = Array::Handle(Array::New(kNumArgs)); |
| + args.SetAt(0, value); |
| + |
| if (setter.IsNull() || !setter.is_visible()) { |
| ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| - setter_name, |
| + internal_setter_name, |
| setter, |
| + args, |
| InvocationMirror::kStatic, |
| InvocationMirror::kSetter); |
| UNREACHABLE(); |
| } |
| // Invoke the setter and return the result. |
| - const int kNumArgs = 1; |
| - const Array& args = Array::Handle(Array::New(kNumArgs)); |
| - args.SetAt(0, value); |
| - |
| Object& result = Object::Handle( |
| DartEntry::InvokeFunction(setter, args)); |
| if (result.IsError()) { |
| @@ -1495,8 +1498,9 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) { |
| if (field.is_final()) { |
| ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| - setter_name, |
| + internal_setter_name, |
| setter, |
| + Array::Handle(), |
| InvocationMirror::kStatic, |
| InvocationMirror::kSetter); |
| UNREACHABLE(); |
| @@ -1540,6 +1544,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) { |
| ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| internal_constructor_name, |
| lookup_constructor, |
| + Array::Handle(), |
| InvocationMirror::kConstructor, |
| InvocationMirror::kMethod); |
| UNREACHABLE(); |
| @@ -1617,6 +1622,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) { |
| ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| internal_constructor_name, |
| redirected_constructor, |
| + Array::Handle(), |
| InvocationMirror::kConstructor, |
| InvocationMirror::kMethod); |
| UNREACHABLE(); |
| @@ -1679,7 +1685,8 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) { |
| if (function.IsNull()) { |
| // Didn't find a method: try to find a getter and invoke call on its result. |
| const Instance& getter_result = |
| - Instance::Handle(InvokeLibraryGetter(library, function_name, true)); |
| + Instance::Handle(InvokeLibraryGetter(library, function_name, false)); |
| + if (getter_result.raw() != Object::sentinel().raw()) { |
| // Make room for the closure (receiver) in arguments. |
| intptr_t numArgs = args.Length(); |
| const Array& call_args = Array::Handle(Array::New(numArgs + 1)); |
| @@ -1699,6 +1706,7 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) { |
| UNREACHABLE(); |
| } |
| return call_result.raw(); |
|
siva
2014/06/12 16:59:07
Indentation of this block seems off.
rmacnak
2014/06/12 22:52:08
Fixed.
|
| + } |
| } |
| const Array& args_descriptor_array = |
| @@ -1711,6 +1719,7 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 5) { |
| ThrowNoSuchMethod(Instance::null_instance(), |
| function_name, |
| function, |
| + Array::Handle(), |
| InvocationMirror::kTopLevel, |
| InvocationMirror::kMethod); |
| UNREACHABLE(); |
| @@ -1752,25 +1761,27 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { |
| const Field& field = Field::Handle( |
| library.LookupLocalField(setter_name)); |
| Function& setter = Function::Handle(); |
| + const String& internal_setter_name = |
| + String::Handle(Field::SetterName(setter_name)); |
| if (field.IsNull()) { |
| - const String& internal_setter_name = |
| - String::Handle(Field::SetterName(setter_name)); |
| - |
| setter = library.LookupLocalFunction(internal_setter_name); |
| + |
| + const int kNumArgs = 1; |
| + const Array& args = Array::Handle(Array::New(kNumArgs)); |
| + args.SetAt(0, value); |
| + |
| if (setter.IsNull() || !setter.is_visible()) { |
| ThrowNoSuchMethod(Instance::null_instance(), |
| - setter_name, |
| + internal_setter_name, |
| setter, |
| + args, |
| InvocationMirror::kTopLevel, |
| InvocationMirror::kSetter); |
| UNREACHABLE(); |
| } |
| // Invoke the setter and return the result. |
| - const int kNumArgs = 1; |
| - const Array& args = Array::Handle(Array::New(kNumArgs)); |
| - args.SetAt(0, value); |
| const Object& result = Object::Handle( |
| DartEntry::InvokeFunction(setter, args)); |
| if (result.IsError()) { |
| @@ -1782,8 +1793,9 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { |
| if (field.is_final()) { |
| ThrowNoSuchMethod(Instance::null_instance(), |
| - setter_name, |
| + internal_setter_name, |
| setter, |
| + Array::Handle(), |
| InvocationMirror::kTopLevel, |
| InvocationMirror::kSetter); |
| UNREACHABLE(); |