| 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 "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "include/dart_debugger_api.h" | 6 #include "include/dart_debugger_api.h" |
| 7 #include "include/dart_mirrors_api.h" | 7 #include "include/dart_mirrors_api.h" |
| 8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
| 9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef. | 9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef. |
| 10 #include "vm/bootstrap_natives.h" | 10 #include "vm/bootstrap_natives.h" |
| 11 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
| 12 #include "vm/exceptions.h" | 12 #include "vm/exceptions.h" |
| 13 #include "vm/message.h" | 13 #include "vm/message.h" |
| 14 #include "vm/port.h" | 14 #include "vm/port.h" |
| 15 #include "vm/resolver.h" | 15 #include "vm/resolver.h" |
| 16 #include "vm/symbols.h" | 16 #include "vm/symbols.h" |
| 17 #include "lib/invocation_mirror.h" |
| 17 | 18 |
| 18 namespace dart { | 19 namespace dart { |
| 19 | 20 |
| 20 static RawInstance* CreateMirror(const String& mirror_class_name, | 21 static RawInstance* CreateMirror(const String& mirror_class_name, |
| 21 const Array& constructor_arguments) { | 22 const Array& constructor_arguments) { |
| 22 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); | 23 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); |
| 23 const String& constructor_name = Symbols::Dot(); | 24 const String& constructor_name = Symbols::Dot(); |
| 24 | 25 |
| 25 const Object& result = Object::Handle( | 26 const Object& result = Object::Handle( |
| 26 DartLibraryCalls::InstanceCreate(mirrors_lib, | 27 DartLibraryCalls::InstanceCreate(mirrors_lib, |
| (...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 if (error.IsLanguageError()) { | 1225 if (error.IsLanguageError()) { |
| 1225 // A compilation error that was delayed by lazy compilation. | 1226 // A compilation error that was delayed by lazy compilation. |
| 1226 const LanguageError& compilation_error = LanguageError::Cast(error); | 1227 const LanguageError& compilation_error = LanguageError::Cast(error); |
| 1227 String& message = String::Handle(compilation_error.message()); | 1228 String& message = String::Handle(compilation_error.message()); |
| 1228 ThrowMirroredCompilationError(message); | 1229 ThrowMirroredCompilationError(message); |
| 1229 } | 1230 } |
| 1230 UNREACHABLE(); | 1231 UNREACHABLE(); |
| 1231 } | 1232 } |
| 1232 | 1233 |
| 1233 | 1234 |
| 1234 static RawFunction* ResolveConstructor(const char* current_func, | |
| 1235 const Class& cls, | |
| 1236 const String& class_name, | |
| 1237 const String& constr_name, | |
| 1238 int num_args) { | |
| 1239 // The constructor must be present in the interface. | |
| 1240 const Function& constructor = | |
| 1241 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name)); | |
| 1242 if (constructor.IsNull() || | |
| 1243 (!constructor.IsConstructor() && !constructor.IsFactory())) { | |
| 1244 const String& lookup_class_name = String::Handle(cls.Name()); | |
| 1245 if (!class_name.Equals(lookup_class_name)) { | |
| 1246 // When the class name used to build the constructor name is | |
| 1247 // different than the name of the class in which we are doing | |
| 1248 // the lookup, it can be confusing to the user to figure out | |
| 1249 // what's going on. Be a little more explicit for these error | |
| 1250 // messages. | |
| 1251 const String& message = String::Handle( | |
| 1252 String::NewFormatted( | |
| 1253 "%s: could not find factory '%s' in class '%s'.", | |
| 1254 current_func, | |
| 1255 constr_name.ToCString(), | |
| 1256 lookup_class_name.ToCString())); | |
| 1257 ThrowMirroredCompilationError(message); | |
| 1258 UNREACHABLE(); | |
| 1259 } else { | |
| 1260 const String& message = String::Handle( | |
| 1261 String::NewFormatted("%s: could not find constructor '%s'.", | |
| 1262 current_func, constr_name.ToCString())); | |
| 1263 ThrowMirroredCompilationError(message); | |
| 1264 UNREACHABLE(); | |
| 1265 } | |
| 1266 } | |
| 1267 int extra_args = (constructor.IsConstructor() ? 2 : 1); | |
| 1268 String& error_message = String::Handle(); | |
| 1269 if (!constructor.AreValidArgumentCounts(num_args + extra_args, | |
| 1270 0, | |
| 1271 &error_message)) { | |
| 1272 const String& message = String::Handle( | |
| 1273 String::NewFormatted("%s: wrong argument count for " | |
| 1274 "constructor '%s': %s.", | |
| 1275 current_func, | |
| 1276 constr_name.ToCString(), | |
| 1277 error_message.ToCString())); | |
| 1278 ThrowMirroredCompilationError(message); | |
| 1279 UNREACHABLE(); | |
| 1280 } | |
| 1281 return constructor.raw(); | |
| 1282 } | |
| 1283 | |
| 1284 | |
| 1285 static bool FieldIsUninitialized(const Field& field) { | 1235 static bool FieldIsUninitialized(const Field& field) { |
| 1286 ASSERT(!field.IsNull()); | 1236 ASSERT(!field.IsNull()); |
| 1287 | 1237 |
| 1288 // Return getter method for uninitialized fields, rather than the | 1238 // Return getter method for uninitialized fields, rather than the |
| 1289 // field object, since the value in the field object will not be | 1239 // field object, since the value in the field object will not be |
| 1290 // initialized until the first time the getter is invoked. | 1240 // initialized until the first time the getter is invoked. |
| 1291 const Instance& value = Instance::Handle(field.value()); | 1241 const Instance& value = Instance::Handle(field.value()); |
| 1292 ASSERT(value.raw() != Object::transition_sentinel().raw()); | 1242 ASSERT(value.raw() != Object::transition_sentinel().raw()); |
| 1293 return value.raw() == Object::sentinel().raw(); | 1243 return value.raw() == Object::sentinel().raw(); |
| 1294 } | 1244 } |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1515 | 1465 |
| 1516 obj = DartEntry::InvokeClosure(args); | 1466 obj = DartEntry::InvokeClosure(args); |
| 1517 if (obj.IsError()) { | 1467 if (obj.IsError()) { |
| 1518 ThrowInvokeError(Error::Cast(obj)); | 1468 ThrowInvokeError(Error::Cast(obj)); |
| 1519 UNREACHABLE(); | 1469 UNREACHABLE(); |
| 1520 } | 1470 } |
| 1521 return obj.raw(); | 1471 return obj.raw(); |
| 1522 } | 1472 } |
| 1523 | 1473 |
| 1524 | 1474 |
| 1475 static void ThrowNoSuchMethod(const Instance& receiver, |
| 1476 const String& function_name, |
| 1477 const Function& function, |
| 1478 const InvocationMirror::Call call, |
| 1479 const InvocationMirror::Type type) { |
| 1480 const Smi& invocation_type = Smi::Handle(Smi::New( |
| 1481 InvocationMirror::EncodeType(call, type))); |
| 1482 |
| 1483 const Array& args = Array::Handle(Array::New(6)); |
| 1484 args.SetAt(0, receiver); |
| 1485 args.SetAt(1, function_name); |
| 1486 args.SetAt(2, invocation_type); |
| 1487 if (!function.IsNull()) { |
| 1488 const int total_num_parameters = function.NumParameters(); |
| 1489 const Array& array = Array::Handle(Array::New(total_num_parameters)); |
| 1490 String& param_name = String::Handle(); |
| 1491 for (int i = 0; i < total_num_parameters; i++) { |
| 1492 param_name = function.ParameterNameAt(i); |
| 1493 array.SetAt(i, param_name); |
| 1494 } |
| 1495 args.SetAt(5, array); |
| 1496 } |
| 1497 |
| 1498 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, args); |
| 1499 UNREACHABLE(); |
| 1500 } |
| 1501 |
| 1502 |
| 1503 static void ThrowNoSuchMethod(const Class& klass, |
| 1504 const String& function_name, |
| 1505 const Function& function, |
| 1506 const InvocationMirror::Call call, |
| 1507 const InvocationMirror::Type type) { |
| 1508 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); |
| 1509 Type& pre_type = Type::Handle( |
| 1510 Type::New(klass, type_arguments, Scanner::kDummyTokenIndex)); |
| 1511 pre_type.SetIsFinalized(); |
| 1512 AbstractType& runtime_type = AbstractType::Handle(pre_type.Canonicalize()); |
| 1513 |
| 1514 ThrowNoSuchMethod(runtime_type, |
| 1515 function_name, |
| 1516 function, |
| 1517 call, |
| 1518 type); |
| 1519 UNREACHABLE(); |
| 1520 } |
| 1521 |
| 1522 |
| 1523 static void ThrowNoSuchMethod(const Library& library, |
| 1524 const String& function_name, |
| 1525 const Function& function, |
| 1526 const InvocationMirror::Call call, |
| 1527 const InvocationMirror::Type type) { |
| 1528 ThrowNoSuchMethod(Instance::null_instance(), |
| 1529 function_name, |
| 1530 function, |
| 1531 call, |
| 1532 type); |
| 1533 UNREACHABLE(); |
| 1534 } |
| 1535 |
| 1536 |
| 1525 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { | 1537 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { |
| 1526 // Argument 0 is the mirror, which is unused by the native. It exists | 1538 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1527 // because this native is an instance method in order to be polymorphic | 1539 // because this native is an instance method in order to be polymorphic |
| 1528 // with its cousins. | 1540 // with its cousins. |
| 1529 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1541 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1530 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1542 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1531 GET_NON_NULL_NATIVE_ARGUMENT( | 1543 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1532 String, function_name, arguments->NativeArgAt(2)); | 1544 String, function_name, arguments->NativeArgAt(2)); |
| 1533 GET_NON_NULL_NATIVE_ARGUMENT( | 1545 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1534 Array, positional_args, arguments->NativeArgAt(3)); | 1546 Array, positional_args, arguments->NativeArgAt(3)); |
| 1535 | 1547 |
| 1536 intptr_t number_of_arguments = positional_args.Length(); | 1548 intptr_t number_of_arguments = positional_args.Length(); |
| 1537 | 1549 |
| 1538 // TODO(11771): This won't find private members. | |
| 1539 const Function& function = Function::Handle( | 1550 const Function& function = Function::Handle( |
| 1540 Resolver::ResolveStatic(klass, | 1551 klass.LookupStaticFunctionAllowPrivate(function_name)); |
| 1541 function_name, | 1552 |
| 1542 number_of_arguments, | 1553 if (function.IsNull() || |
| 1543 Object::empty_array(), | 1554 !function.AreValidArgumentCounts(number_of_arguments, |
| 1544 Resolver::kIsQualified)); | 1555 /* named_args */ 0, |
| 1545 if (function.IsNull()) { | 1556 NULL)) { |
| 1546 const String& klass_name = String::Handle(klass.Name()); | 1557 ThrowNoSuchMethod(klass, |
| 1547 const String& message = String::Handle( | 1558 function_name, |
| 1548 String::NewFormatted("%s: did not find static method '%s.%s'.", | 1559 function, |
| 1549 "ClassMirror_invoke", | 1560 InvocationMirror::kStatic, |
| 1550 klass_name.ToCString(), | 1561 InvocationMirror::kMethod); |
| 1551 function_name.ToCString())); | |
| 1552 ThrowMirroredCompilationError(message); | |
| 1553 UNREACHABLE(); | 1562 UNREACHABLE(); |
| 1554 } | 1563 } |
| 1564 |
| 1555 Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 1565 Object& result = Object::Handle(DartEntry::InvokeFunction(function, |
| 1556 positional_args)); | 1566 positional_args)); |
| 1557 if (result.IsError()) { | 1567 if (result.IsError()) { |
| 1558 ThrowInvokeError(Error::Cast(result)); | 1568 ThrowInvokeError(Error::Cast(result)); |
| 1559 UNREACHABLE(); | 1569 UNREACHABLE(); |
| 1560 } | 1570 } |
| 1561 return result.raw(); | 1571 return result.raw(); |
| 1562 } | 1572 } |
| 1563 | 1573 |
| 1564 | 1574 |
| 1565 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { | 1575 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { |
| 1566 // Argument 0 is the mirror, which is unused by the native. It exists | 1576 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1567 // because this native is an instance method in order to be polymorphic | 1577 // because this native is an instance method in order to be polymorphic |
| 1568 // with its cousins. | 1578 // with its cousins. |
| 1569 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1579 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1570 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1580 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1571 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); | 1581 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); |
| 1572 | 1582 |
| 1573 // Note static fields do not have implicit getters. | 1583 // Note static fields do not have implicit getters. |
| 1574 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); | 1584 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); |
| 1575 if (field.IsNull() || FieldIsUninitialized(field)) { | 1585 if (field.IsNull() || FieldIsUninitialized(field)) { |
| 1576 const String& internal_getter_name = String::Handle( | 1586 const String& internal_getter_name = String::Handle( |
| 1577 Field::GetterName(getter_name)); | 1587 Field::GetterName(getter_name)); |
| 1578 const Function& getter = Function::Handle( | 1588 const Function& getter = Function::Handle( |
| 1579 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); | 1589 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); |
| 1580 | 1590 |
| 1581 if (getter.IsNull()) { | 1591 if (getter.IsNull()) { |
| 1582 const String& message = String::Handle( | 1592 ThrowNoSuchMethod(klass, |
| 1583 String::NewFormatted("%s: did not find static getter '%s'.", | 1593 getter_name, |
| 1584 "ClassMirror_invokeGetter", | 1594 getter, |
| 1585 getter_name.ToCString())); | 1595 InvocationMirror::kStatic, |
| 1586 ThrowMirroredCompilationError(message); | 1596 InvocationMirror::kGetter); |
| 1587 UNREACHABLE(); | 1597 UNREACHABLE(); |
| 1588 } | 1598 } |
| 1589 | 1599 |
| 1590 // Invoke the getter and return the result. | 1600 // Invoke the getter and return the result. |
| 1591 Object& result = Object::Handle( | 1601 Object& result = Object::Handle( |
| 1592 DartEntry::InvokeFunction(getter, Object::empty_array())); | 1602 DartEntry::InvokeFunction(getter, Object::empty_array())); |
| 1593 if (result.IsError()) { | 1603 if (result.IsError()) { |
| 1594 ThrowInvokeError(Error::Cast(result)); | 1604 ThrowInvokeError(Error::Cast(result)); |
| 1595 UNREACHABLE(); | 1605 UNREACHABLE(); |
| 1596 } | 1606 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1611 | 1621 |
| 1612 // Check for real fields and user-defined setters. | 1622 // Check for real fields and user-defined setters. |
| 1613 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | 1623 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); |
| 1614 if (field.IsNull()) { | 1624 if (field.IsNull()) { |
| 1615 const String& internal_setter_name = String::Handle( | 1625 const String& internal_setter_name = String::Handle( |
| 1616 Field::SetterName(setter_name)); | 1626 Field::SetterName(setter_name)); |
| 1617 const Function& setter = Function::Handle( | 1627 const Function& setter = Function::Handle( |
| 1618 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); | 1628 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); |
| 1619 | 1629 |
| 1620 if (setter.IsNull()) { | 1630 if (setter.IsNull()) { |
| 1621 const String& message = String::Handle( | 1631 ThrowNoSuchMethod(klass, |
| 1622 String::NewFormatted("%s: did not find static setter '%s'.", | 1632 setter_name, |
| 1623 "ClassMirror_invokeSetter", | 1633 setter, |
| 1624 setter_name.ToCString())); | 1634 InvocationMirror::kStatic, |
| 1625 ThrowMirroredCompilationError(message); | 1635 InvocationMirror::kSetter); |
| 1626 UNREACHABLE(); | 1636 UNREACHABLE(); |
| 1627 } | 1637 } |
| 1628 | 1638 |
| 1629 // Invoke the setter and return the result. | 1639 // Invoke the setter and return the result. |
| 1630 const int kNumArgs = 1; | 1640 const int kNumArgs = 1; |
| 1631 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1641 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1632 args.SetAt(0, value); | 1642 args.SetAt(0, value); |
| 1633 | 1643 |
| 1634 Object& result = Object::Handle( | 1644 Object& result = Object::Handle( |
| 1635 DartEntry::InvokeFunction(setter, args)); | 1645 DartEntry::InvokeFunction(setter, args)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 // unnamed constructor for class 'A' is labeled 'A.'. | 1679 // unnamed constructor for class 'A' is labeled 'A.'. |
| 1670 // This convention prevents users from explicitly calling constructors. | 1680 // This convention prevents users from explicitly calling constructors. |
| 1671 const String& klass_name = String::Handle(klass.Name()); | 1681 const String& klass_name = String::Handle(klass.Name()); |
| 1672 String& internal_constructor_name = | 1682 String& internal_constructor_name = |
| 1673 String::Handle(String::Concat(klass_name, Symbols::Dot())); | 1683 String::Handle(String::Concat(klass_name, Symbols::Dot())); |
| 1674 if (!constructor_name.IsNull()) { | 1684 if (!constructor_name.IsNull()) { |
| 1675 internal_constructor_name = | 1685 internal_constructor_name = |
| 1676 String::Concat(internal_constructor_name, constructor_name); | 1686 String::Concat(internal_constructor_name, constructor_name); |
| 1677 } | 1687 } |
| 1678 | 1688 |
| 1679 const Function& constructor = | 1689 Function& constructor = Function::Handle( |
| 1680 Function::Handle(ResolveConstructor("ClassMirror_invokeConstructor", | 1690 klass.LookupFunctionAllowPrivate(internal_constructor_name)); |
| 1681 klass, | 1691 |
| 1682 klass_name, | 1692 if (constructor.IsNull() || |
| 1683 internal_constructor_name, | 1693 (!constructor.IsConstructor() && !constructor.IsFactory()) || |
| 1684 number_of_arguments)); | 1694 !constructor.AreValidArgumentCounts(number_of_arguments + |
| 1695 constructor.NumImplicitParameters(), |
| 1696 /* named args */ 0, |
| 1697 NULL)) { |
| 1698 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1699 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1700 constructor = Function::null(); |
| 1701 ThrowNoSuchMethod(klass, |
| 1702 internal_constructor_name, |
| 1703 constructor, |
| 1704 InvocationMirror::kConstructor, |
| 1705 InvocationMirror::kMethod); |
| 1706 UNREACHABLE(); |
| 1707 } |
| 1685 | 1708 |
| 1686 const Object& result = | 1709 const Object& result = |
| 1687 Object::Handle(DartEntry::InvokeConstructor(klass, | 1710 Object::Handle(DartEntry::InvokeConstructor(klass, |
| 1688 constructor, | 1711 constructor, |
| 1689 positional_args)); | 1712 positional_args)); |
| 1690 if (result.IsError()) { | 1713 if (result.IsError()) { |
| 1691 ThrowInvokeError(Error::Cast(result)); | 1714 ThrowInvokeError(Error::Cast(result)); |
| 1692 UNREACHABLE(); | 1715 UNREACHABLE(); |
| 1693 } | 1716 } |
| 1694 // Factories may return null. | 1717 // Factories may return null. |
| 1695 ASSERT(result.IsInstance() || result.IsNull()); | 1718 ASSERT(result.IsInstance() || result.IsNull()); |
| 1696 return result.raw(); | 1719 return result.raw(); |
| 1697 } | 1720 } |
| 1698 | 1721 |
| 1699 | 1722 |
| 1700 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { | 1723 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { |
| 1701 // Argument 0 is the mirror, which is unused by the native. It exists | 1724 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1702 // because this native is an instance method in order to be polymorphic | 1725 // because this native is an instance method in order to be polymorphic |
| 1703 // with its cousins. | 1726 // with its cousins. |
| 1704 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1727 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1705 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1728 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
| 1706 GET_NON_NULL_NATIVE_ARGUMENT( | 1729 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1707 String, function_name, arguments->NativeArgAt(2)); | 1730 String, function_name, arguments->NativeArgAt(2)); |
| 1708 GET_NON_NULL_NATIVE_ARGUMENT( | 1731 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1709 Array, positional_args, arguments->NativeArgAt(3)); | 1732 Array, positional_args, arguments->NativeArgAt(3)); |
| 1710 | 1733 |
| 1711 intptr_t number_of_arguments = positional_args.Length(); | 1734 intptr_t number_of_arguments = positional_args.Length(); |
| 1712 | 1735 |
| 1713 | |
| 1714 String& ambiguity_error_msg = String::Handle(isolate); | 1736 String& ambiguity_error_msg = String::Handle(isolate); |
| 1715 const Function& function = Function::Handle( | 1737 const Function& function = Function::Handle( |
| 1716 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); | 1738 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); |
| 1717 | 1739 |
| 1718 if (function.IsNull()) { | 1740 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { |
| 1719 if (ambiguity_error_msg.IsNull()) { | 1741 ThrowMirroredCompilationError(ambiguity_error_msg); |
| 1720 const String& message = String::Handle( | |
| 1721 String::NewFormatted("%s: did not find top-level function '%s'.", | |
| 1722 "LibraryMirror_invoke", | |
| 1723 function_name.ToCString())); | |
| 1724 ThrowMirroredCompilationError(message); | |
| 1725 } else { | |
| 1726 ThrowMirroredCompilationError(ambiguity_error_msg); | |
| 1727 } | |
| 1728 UNREACHABLE(); | 1742 UNREACHABLE(); |
| 1729 } | 1743 } |
| 1730 | 1744 |
| 1731 // LookupFunctionAllowPrivate does not check argument arity, so we | 1745 if (function.IsNull() || |
| 1732 // do it here. | 1746 !function.AreValidArgumentCounts(number_of_arguments, |
| 1733 String& error_message = String::Handle(); | 1747 0, |
| 1734 if (!function.AreValidArgumentCounts(number_of_arguments, | 1748 NULL) ) { |
| 1735 /* num_named_args */ 0, | 1749 ThrowNoSuchMethod(library, |
| 1736 &error_message)) { | 1750 function_name, |
| 1737 const String& message = String::Handle( | 1751 function, |
| 1738 String::NewFormatted("%s: wrong argument count for function '%s': %s.", | 1752 InvocationMirror::kTopLevel, |
| 1739 "LibraryMirror_invoke", | 1753 InvocationMirror::kMethod); |
| 1740 function_name.ToCString(), | |
| 1741 error_message.ToCString())); | |
| 1742 ThrowMirroredCompilationError(message); | |
| 1743 UNREACHABLE(); | 1754 UNREACHABLE(); |
| 1744 } | 1755 } |
| 1745 | 1756 |
| 1746 const Object& result = Object::Handle( | 1757 const Object& result = Object::Handle( |
| 1747 DartEntry::InvokeFunction(function, positional_args)); | 1758 DartEntry::InvokeFunction(function, positional_args)); |
| 1748 if (result.IsError()) { | 1759 if (result.IsError()) { |
| 1749 ThrowInvokeError(Error::Cast(result)); | 1760 ThrowInvokeError(Error::Cast(result)); |
| 1750 UNREACHABLE(); | 1761 UNREACHABLE(); |
| 1751 } | 1762 } |
| 1752 return result.raw(); | 1763 return result.raw(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 if (result.IsError()) { | 1800 if (result.IsError()) { |
| 1790 ThrowInvokeError(Error::Cast(result)); | 1801 ThrowInvokeError(Error::Cast(result)); |
| 1791 UNREACHABLE(); | 1802 UNREACHABLE(); |
| 1792 } | 1803 } |
| 1793 return result.raw(); | 1804 return result.raw(); |
| 1794 } | 1805 } |
| 1795 if (!field.IsNull()) { | 1806 if (!field.IsNull()) { |
| 1796 return field.value(); | 1807 return field.value(); |
| 1797 } | 1808 } |
| 1798 if (ambiguity_error_msg.IsNull()) { | 1809 if (ambiguity_error_msg.IsNull()) { |
| 1799 const String& message = String::Handle( | 1810 ThrowNoSuchMethod(library, |
| 1800 String::NewFormatted("%s: did not find top-level variable '%s'.", | 1811 getter_name, |
| 1801 "LibraryMirror_invokeGetter", | 1812 getter, |
| 1802 getter_name.ToCString())); | 1813 InvocationMirror::kTopLevel, |
| 1803 ThrowMirroredCompilationError(message); | 1814 InvocationMirror::kGetter); |
| 1804 } else { | 1815 } else { |
| 1805 ThrowMirroredCompilationError(ambiguity_error_msg); | 1816 ThrowMirroredCompilationError(ambiguity_error_msg); |
| 1806 } | 1817 } |
| 1807 UNREACHABLE(); | 1818 UNREACHABLE(); |
| 1808 return Instance::null(); | 1819 return Instance::null(); |
| 1809 } | 1820 } |
| 1810 | 1821 |
| 1811 | 1822 |
| 1812 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { | 1823 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { |
| 1813 // Argument 0 is the mirror, which is unused by the native. It exists | 1824 // Argument 0 is the mirror, which is unused by the native. It exists |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1826 library.LookupFieldAllowPrivate(setter_name, &ambiguity_error_msg)); | 1837 library.LookupFieldAllowPrivate(setter_name, &ambiguity_error_msg)); |
| 1827 | 1838 |
| 1828 if (field.IsNull() && ambiguity_error_msg.IsNull()) { | 1839 if (field.IsNull() && ambiguity_error_msg.IsNull()) { |
| 1829 const String& internal_setter_name = | 1840 const String& internal_setter_name = |
| 1830 String::Handle(Field::SetterName(setter_name)); | 1841 String::Handle(Field::SetterName(setter_name)); |
| 1831 const Function& setter = Function::Handle( | 1842 const Function& setter = Function::Handle( |
| 1832 library.LookupFunctionAllowPrivate(internal_setter_name, | 1843 library.LookupFunctionAllowPrivate(internal_setter_name, |
| 1833 &ambiguity_error_msg)); | 1844 &ambiguity_error_msg)); |
| 1834 if (setter.IsNull()) { | 1845 if (setter.IsNull()) { |
| 1835 if (ambiguity_error_msg.IsNull()) { | 1846 if (ambiguity_error_msg.IsNull()) { |
| 1836 const String& message = String::Handle( | 1847 ThrowNoSuchMethod(library, |
| 1837 String::NewFormatted("%s: did not find top-level variable '%s'.", | 1848 setter_name, |
| 1838 "LibraryMirror_invokeSetter", | 1849 setter, |
| 1839 setter_name.ToCString())); | 1850 InvocationMirror::kTopLevel, |
| 1840 ThrowMirroredCompilationError(message); | 1851 InvocationMirror::kSetter); |
| 1841 } else { | 1852 } else { |
| 1842 ThrowMirroredCompilationError(ambiguity_error_msg); | 1853 ThrowMirroredCompilationError(ambiguity_error_msg); |
| 1843 } | 1854 } |
| 1844 UNREACHABLE(); | 1855 UNREACHABLE(); |
| 1845 } | 1856 } |
| 1846 | 1857 |
| 1847 // Invoke the setter and return the result. | 1858 // Invoke the setter and return the result. |
| 1848 const int kNumArgs = 1; | 1859 const int kNumArgs = 1; |
| 1849 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1860 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1850 args.SetAt(0, value); | 1861 args.SetAt(0, value); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1915 | 1926 |
| 1916 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1927 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
| 1917 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1928 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1918 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1929 const Field& field = Field::Handle(ref.GetFieldReferent()); |
| 1919 | 1930 |
| 1920 const AbstractType& type = AbstractType::Handle(field.type()); | 1931 const AbstractType& type = AbstractType::Handle(field.type()); |
| 1921 return CreateTypeMirror(type); | 1932 return CreateTypeMirror(type); |
| 1922 } | 1933 } |
| 1923 | 1934 |
| 1924 } // namespace dart | 1935 } // namespace dart |
| OLD | NEW |