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(); |