| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/invocation_mirror.h" | 5 #include "lib/invocation_mirror.h" |
| 6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 | 1369 |
| 1370 | 1370 |
| 1371 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { | 1371 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { |
| 1372 // Argument 0 is the mirror, which is unused by the native. It exists | 1372 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1373 // because this native is an instance method in order to be polymorphic | 1373 // because this native is an instance method in order to be polymorphic |
| 1374 // with its cousins. | 1374 // with its cousins. |
| 1375 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); | 1375 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); |
| 1376 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 1376 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
| 1377 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 1377 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
| 1378 | 1378 |
| 1379 String& internal_setter_name = | 1379 const Class& klass = Class::Handle(reflectee.clazz()); |
| 1380 const String& internal_setter_name = |
| 1380 String::Handle(Field::SetterName(setter_name)); | 1381 String::Handle(Field::SetterName(setter_name)); |
| 1381 Function& setter = Function::Handle(); | 1382 const Function& setter = Function::Handle( |
| 1383 Resolver::ResolveDynamicAnyArgs(klass, internal_setter_name)); |
| 1382 | 1384 |
| 1383 Class& klass = Class::Handle(reflectee.clazz()); | |
| 1384 Field& field = Field::Handle(); | |
| 1385 | |
| 1386 while (!klass.IsNull()) { | |
| 1387 field = klass.LookupInstanceField(setter_name); | |
| 1388 if (!field.IsNull() && field.is_final()) { | |
| 1389 const String& message = String::Handle( | |
| 1390 String::NewFormatted("%s: cannot set final field '%s'.", | |
| 1391 "InstanceMirror_invokeSetter", | |
| 1392 setter_name.ToCString())); | |
| 1393 ThrowMirroredCompilationError(message); | |
| 1394 UNREACHABLE(); | |
| 1395 } | |
| 1396 setter = klass.LookupDynamicFunction(internal_setter_name); | |
| 1397 if (!setter.IsNull()) { | |
| 1398 break; | |
| 1399 } | |
| 1400 klass = klass.SuperClass(); | |
| 1401 } | |
| 1402 | |
| 1403 // Invoke the setter and return the result. | |
| 1404 const int kNumArgs = 2; | 1385 const int kNumArgs = 2; |
| 1405 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1386 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1406 args.SetAt(0, reflectee); | 1387 args.SetAt(0, reflectee); |
| 1407 args.SetAt(1, value); | 1388 args.SetAt(1, value); |
| 1408 const Array& args_descriptor = | 1389 const Array& args_descriptor = |
| 1409 Array::Handle(ArgumentsDescriptor::New(args.Length())); | 1390 Array::Handle(ArgumentsDescriptor::New(args.Length())); |
| 1410 | 1391 |
| 1411 return InvokeDynamicFunction(reflectee, | 1392 return InvokeDynamicFunction(reflectee, |
| 1412 setter, | 1393 setter, |
| 1413 internal_setter_name, | 1394 internal_setter_name, |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 // Argument 0 is the mirror, which is unused by the native. It exists | 1570 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1590 // because this native is an instance method in order to be polymorphic | 1571 // because this native is an instance method in order to be polymorphic |
| 1591 // with its cousins. | 1572 // with its cousins. |
| 1592 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1573 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1593 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1574 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1594 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 1575 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
| 1595 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 1576 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
| 1596 | 1577 |
| 1597 // Check for real fields and user-defined setters. | 1578 // Check for real fields and user-defined setters. |
| 1598 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | 1579 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); |
| 1580 Function& setter = Function::Handle(); |
| 1599 if (field.IsNull()) { | 1581 if (field.IsNull()) { |
| 1600 const String& internal_setter_name = String::Handle( | 1582 const String& internal_setter_name = String::Handle( |
| 1601 Field::SetterName(setter_name)); | 1583 Field::SetterName(setter_name)); |
| 1602 const Function& setter = Function::Handle( | 1584 |
| 1603 klass.LookupStaticFunction(internal_setter_name)); | 1585 setter = klass.LookupStaticFunction(internal_setter_name); |
| 1604 | 1586 |
| 1605 if (setter.IsNull() || !setter.is_visible()) { | 1587 if (setter.IsNull() || !setter.is_visible()) { |
| 1606 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), | 1588 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1607 setter_name, | 1589 setter_name, |
| 1608 setter, | 1590 setter, |
| 1609 InvocationMirror::kStatic, | 1591 InvocationMirror::kStatic, |
| 1610 InvocationMirror::kSetter); | 1592 InvocationMirror::kSetter); |
| 1611 UNREACHABLE(); | 1593 UNREACHABLE(); |
| 1612 } | 1594 } |
| 1613 | 1595 |
| 1614 // Invoke the setter and return the result. | 1596 // Invoke the setter and return the result. |
| 1615 const int kNumArgs = 1; | 1597 const int kNumArgs = 1; |
| 1616 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1598 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1617 args.SetAt(0, value); | 1599 args.SetAt(0, value); |
| 1618 | 1600 |
| 1619 Object& result = Object::Handle( | 1601 Object& result = Object::Handle( |
| 1620 DartEntry::InvokeFunction(setter, args)); | 1602 DartEntry::InvokeFunction(setter, args)); |
| 1621 if (result.IsError()) { | 1603 if (result.IsError()) { |
| 1622 ThrowInvokeError(Error::Cast(result)); | 1604 ThrowInvokeError(Error::Cast(result)); |
| 1623 UNREACHABLE(); | 1605 UNREACHABLE(); |
| 1624 } | 1606 } |
| 1625 return result.raw(); | 1607 return result.raw(); |
| 1626 } | 1608 } |
| 1627 | 1609 |
| 1628 if (field.is_final()) { | 1610 if (field.is_final()) { |
| 1629 const String& message = String::Handle( | 1611 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1630 String::NewFormatted("%s: cannot set final field '%s'.", | 1612 setter_name, |
| 1631 "ClassMirror_invokeSetter", | 1613 setter, |
| 1632 setter_name.ToCString())); | 1614 InvocationMirror::kStatic, |
| 1633 ThrowMirroredCompilationError(message); | 1615 InvocationMirror::kSetter); |
| 1634 UNREACHABLE(); | 1616 UNREACHABLE(); |
| 1635 } | 1617 } |
| 1636 | 1618 |
| 1637 field.set_value(value); | 1619 field.set_value(value); |
| 1638 return value.raw(); | 1620 return value.raw(); |
| 1639 } | 1621 } |
| 1640 | 1622 |
| 1641 | 1623 |
| 1642 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) { | 1624 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) { |
| 1643 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1625 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1841 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1823 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1842 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1824 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
| 1843 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 1825 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
| 1844 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 1826 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
| 1845 | 1827 |
| 1846 // To access a top-level we may need to use the Field or the | 1828 // To access a top-level we may need to use the Field or the |
| 1847 // setter Function. The setter function may either be in the | 1829 // setter Function. The setter function may either be in the |
| 1848 // library or in the field's owner class, depending. | 1830 // library or in the field's owner class, depending. |
| 1849 const Field& field = Field::Handle( | 1831 const Field& field = Field::Handle( |
| 1850 library.LookupLocalField(setter_name)); | 1832 library.LookupLocalField(setter_name)); |
| 1833 Function& setter = Function::Handle(); |
| 1851 | 1834 |
| 1852 if (field.IsNull()) { | 1835 if (field.IsNull()) { |
| 1853 const String& internal_setter_name = | 1836 const String& internal_setter_name = |
| 1854 String::Handle(Field::SetterName(setter_name)); | 1837 String::Handle(Field::SetterName(setter_name)); |
| 1855 const Function& setter = Function::Handle( | 1838 |
| 1856 library.LookupLocalFunction(internal_setter_name)); | 1839 setter = library.LookupLocalFunction(internal_setter_name); |
| 1857 if (setter.IsNull() || !setter.is_visible()) { | 1840 if (setter.IsNull() || !setter.is_visible()) { |
| 1858 ThrowNoSuchMethod(Instance::null_instance(), | 1841 ThrowNoSuchMethod(Instance::null_instance(), |
| 1859 setter_name, | 1842 setter_name, |
| 1860 setter, | 1843 setter, |
| 1861 InvocationMirror::kTopLevel, | 1844 InvocationMirror::kTopLevel, |
| 1862 InvocationMirror::kSetter); | 1845 InvocationMirror::kSetter); |
| 1863 UNREACHABLE(); | 1846 UNREACHABLE(); |
| 1864 } | 1847 } |
| 1865 | 1848 |
| 1866 // Invoke the setter and return the result. | 1849 // Invoke the setter and return the result. |
| 1867 const int kNumArgs = 1; | 1850 const int kNumArgs = 1; |
| 1868 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1851 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1869 args.SetAt(0, value); | 1852 args.SetAt(0, value); |
| 1870 const Object& result = Object::Handle( | 1853 const Object& result = Object::Handle( |
| 1871 DartEntry::InvokeFunction(setter, args)); | 1854 DartEntry::InvokeFunction(setter, args)); |
| 1872 if (result.IsError()) { | 1855 if (result.IsError()) { |
| 1873 ThrowInvokeError(Error::Cast(result)); | 1856 ThrowInvokeError(Error::Cast(result)); |
| 1874 UNREACHABLE(); | 1857 UNREACHABLE(); |
| 1875 } | 1858 } |
| 1876 return result.raw(); | 1859 return result.raw(); |
| 1877 } | 1860 } |
| 1878 | 1861 |
| 1879 if (field.is_final()) { | 1862 if (field.is_final()) { |
| 1880 const String& message = String::Handle( | 1863 ThrowNoSuchMethod(Instance::null_instance(), |
| 1881 String::NewFormatted("%s: cannot set final top-level variable '%s'.", | 1864 setter_name, |
| 1882 "LibraryMirror_invokeSetter", | 1865 setter, |
| 1883 setter_name.ToCString())); | 1866 InvocationMirror::kTopLevel, |
| 1884 ThrowMirroredCompilationError(message); | 1867 InvocationMirror::kSetter); |
| 1885 UNREACHABLE(); | 1868 UNREACHABLE(); |
| 1886 } | 1869 } |
| 1887 | 1870 |
| 1888 field.set_value(value); | 1871 field.set_value(value); |
| 1889 return value.raw(); | 1872 return value.raw(); |
| 1890 } | 1873 } |
| 1891 | 1874 |
| 1892 | 1875 |
| 1893 DEFINE_NATIVE_ENTRY(MethodMirror_owner, 1) { | 1876 DEFINE_NATIVE_ENTRY(MethodMirror_owner, 1) { |
| 1894 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1877 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1974 } | 1957 } |
| 1975 | 1958 |
| 1976 | 1959 |
| 1977 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1960 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
| 1978 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1961 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1979 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1962 const Field& field = Field::Handle(ref.GetFieldReferent()); |
| 1980 return field.type(); | 1963 return field.type(); |
| 1981 } | 1964 } |
| 1982 | 1965 |
| 1983 } // namespace dart | 1966 } // namespace dart |
| OLD | NEW |