Chromium Code Reviews| 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 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1229 if (error.IsLanguageError()) { | 1230 if (error.IsLanguageError()) { |
| 1230 // A compilation error that was delayed by lazy compilation. | 1231 // A compilation error that was delayed by lazy compilation. |
| 1231 const LanguageError& compilation_error = LanguageError::Cast(error); | 1232 const LanguageError& compilation_error = LanguageError::Cast(error); |
| 1232 String& message = String::Handle(compilation_error.message()); | 1233 String& message = String::Handle(compilation_error.message()); |
| 1233 ThrowMirroredCompilationError(message); | 1234 ThrowMirroredCompilationError(message); |
| 1234 } | 1235 } |
| 1235 UNREACHABLE(); | 1236 UNREACHABLE(); |
| 1236 } | 1237 } |
| 1237 | 1238 |
| 1238 | 1239 |
| 1239 static RawFunction* ResolveConstructor(const char* current_func, | |
| 1240 const Class& cls, | |
| 1241 const String& class_name, | |
| 1242 const String& constr_name, | |
| 1243 int num_args) { | |
| 1244 // The constructor must be present in the interface. | |
| 1245 const Function& constructor = | |
| 1246 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name)); | |
| 1247 if (constructor.IsNull() || | |
| 1248 (!constructor.IsConstructor() && !constructor.IsFactory())) { | |
| 1249 const String& lookup_class_name = String::Handle(cls.Name()); | |
| 1250 if (!class_name.Equals(lookup_class_name)) { | |
| 1251 // When the class name used to build the constructor name is | |
| 1252 // different than the name of the class in which we are doing | |
| 1253 // the lookup, it can be confusing to the user to figure out | |
| 1254 // what's going on. Be a little more explicit for these error | |
| 1255 // messages. | |
| 1256 const String& message = String::Handle( | |
| 1257 String::NewFormatted( | |
| 1258 "%s: could not find factory '%s' in class '%s'.", | |
| 1259 current_func, | |
| 1260 constr_name.ToCString(), | |
| 1261 lookup_class_name.ToCString())); | |
| 1262 ThrowMirroredCompilationError(message); | |
| 1263 UNREACHABLE(); | |
| 1264 } else { | |
| 1265 const String& message = String::Handle( | |
| 1266 String::NewFormatted("%s: could not find constructor '%s'.", | |
| 1267 current_func, constr_name.ToCString())); | |
| 1268 ThrowMirroredCompilationError(message); | |
| 1269 UNREACHABLE(); | |
| 1270 } | |
| 1271 } | |
| 1272 int extra_args = (constructor.IsConstructor() ? 2 : 1); | |
| 1273 String& error_message = String::Handle(); | |
| 1274 if (!constructor.AreValidArgumentCounts(num_args + extra_args, | |
| 1275 0, | |
| 1276 &error_message)) { | |
| 1277 const String& message = String::Handle( | |
| 1278 String::NewFormatted("%s: wrong argument count for " | |
| 1279 "constructor '%s': %s.", | |
| 1280 current_func, | |
| 1281 constr_name.ToCString(), | |
| 1282 error_message.ToCString())); | |
| 1283 ThrowMirroredCompilationError(message); | |
| 1284 UNREACHABLE(); | |
| 1285 } | |
| 1286 return constructor.raw(); | |
| 1287 } | |
| 1288 | |
| 1289 | |
| 1290 static bool FieldIsUninitialized(const Field& field) { | 1240 static bool FieldIsUninitialized(const Field& field) { |
| 1291 ASSERT(!field.IsNull()); | 1241 ASSERT(!field.IsNull()); |
| 1292 | 1242 |
| 1293 // Return getter method for uninitialized fields, rather than the | 1243 // Return getter method for uninitialized fields, rather than the |
| 1294 // field object, since the value in the field object will not be | 1244 // field object, since the value in the field object will not be |
| 1295 // initialized until the first time the getter is invoked. | 1245 // initialized until the first time the getter is invoked. |
| 1296 const Instance& value = Instance::Handle(field.value()); | 1246 const Instance& value = Instance::Handle(field.value()); |
| 1297 ASSERT(value.raw() != Object::transition_sentinel().raw()); | 1247 ASSERT(value.raw() != Object::transition_sentinel().raw()); |
| 1298 return value.raw() == Object::sentinel().raw(); | 1248 return value.raw() == Object::sentinel().raw(); |
| 1299 } | 1249 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1475 | 1425 |
| 1476 obj = DartEntry::InvokeClosure(args); | 1426 obj = DartEntry::InvokeClosure(args); |
| 1477 if (obj.IsError()) { | 1427 if (obj.IsError()) { |
| 1478 ThrowInvokeError(Error::Cast(obj)); | 1428 ThrowInvokeError(Error::Cast(obj)); |
| 1479 UNREACHABLE(); | 1429 UNREACHABLE(); |
| 1480 } | 1430 } |
| 1481 return obj.raw(); | 1431 return obj.raw(); |
| 1482 } | 1432 } |
| 1483 | 1433 |
| 1484 | 1434 |
| 1435 static void ThrowNoSuchMethod(const Instance& receiver, | |
| 1436 const String& function_name, | |
| 1437 const Function& function, | |
| 1438 const InvocationMirror::Call call, | |
| 1439 const InvocationMirror::Type type) { | |
| 1440 const Smi& invocation_type = Smi::Handle(Smi::New( | |
| 1441 InvocationMirror::EncodeType(call, type))); | |
| 1442 | |
| 1443 const Array& args = Array::Handle(Array::New(6)); | |
| 1444 args.SetAt(0, receiver); | |
| 1445 args.SetAt(1, function_name); | |
| 1446 args.SetAt(2, invocation_type); | |
| 1447 if (!function.IsNull()) { | |
| 1448 const int total_num_parameters = function.NumParameters(); | |
| 1449 const Array& array = Array::Handle(Array::New(total_num_parameters)); | |
| 1450 for (int i = 0; i < total_num_parameters; i++) { | |
| 1451 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); | |
|
siva
2013/07/24 00:06:52
String::Handle() outside the loop.
rmacnak
2013/07/24 00:25:49
Done.
| |
| 1452 } | |
| 1453 args.SetAt(5, array); | |
| 1454 } | |
| 1455 | |
| 1456 Exceptions::ThrowByType(Exceptions::kNoSuchMethod, args); | |
| 1457 UNREACHABLE(); | |
| 1458 } | |
| 1459 | |
| 1460 | |
| 1461 static void ThrowNoSuchMethod(const Class& klass, | |
| 1462 const String& function_name, | |
| 1463 const Function& function, | |
| 1464 const InvocationMirror::Call call, | |
| 1465 const InvocationMirror::Type type) { | |
| 1466 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); | |
| 1467 Type& pre_type = Type::Handle( | |
| 1468 Type::New(klass, type_arguments, Scanner::kDummyTokenIndex)); | |
| 1469 pre_type.SetIsFinalized(); | |
| 1470 AbstractType& runtime_type = AbstractType::Handle(pre_type.Canonicalize()); | |
| 1471 | |
| 1472 ThrowNoSuchMethod(runtime_type, | |
| 1473 function_name, | |
| 1474 function, | |
| 1475 call, | |
| 1476 type); | |
| 1477 UNREACHABLE(); | |
| 1478 } | |
| 1479 | |
| 1480 | |
| 1481 static void ThrowNoSuchMethod(const Library& library, | |
| 1482 const String& function_name, | |
| 1483 const Function& function, | |
| 1484 const InvocationMirror::Call call, | |
| 1485 const InvocationMirror::Type type) { | |
| 1486 ThrowNoSuchMethod(Instance::Handle(), | |
|
siva
2013/07/24 00:06:52
Object::null_instance(),
rmacnak
2013/07/24 00:25:49
Done.
| |
| 1487 function_name, | |
| 1488 function, | |
| 1489 call, | |
| 1490 type); | |
| 1491 UNREACHABLE(); | |
| 1492 } | |
| 1493 | |
| 1494 | |
| 1485 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { | 1495 DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 4) { |
| 1486 // Argument 0 is the mirror, which is unused by the native. It exists | 1496 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1487 // because this native is an instance method in order to be polymorphic | 1497 // because this native is an instance method in order to be polymorphic |
| 1488 // with its cousins. | 1498 // with its cousins. |
| 1489 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1499 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1490 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1500 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1491 GET_NON_NULL_NATIVE_ARGUMENT( | 1501 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1492 String, function_name, arguments->NativeArgAt(2)); | 1502 String, function_name, arguments->NativeArgAt(2)); |
| 1493 GET_NON_NULL_NATIVE_ARGUMENT( | 1503 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1494 Array, positional_args, arguments->NativeArgAt(3)); | 1504 Array, positional_args, arguments->NativeArgAt(3)); |
| 1495 | 1505 |
| 1496 intptr_t number_of_arguments = positional_args.Length(); | 1506 intptr_t number_of_arguments = positional_args.Length(); |
| 1497 | 1507 |
| 1498 // TODO(11771): This won't find private members. | |
| 1499 const Function& function = Function::Handle( | 1508 const Function& function = Function::Handle( |
| 1500 Resolver::ResolveStatic(klass, | 1509 klass.LookupStaticFunctionAllowPrivate(function_name)); |
| 1501 function_name, | 1510 |
| 1502 number_of_arguments, | 1511 if (function.IsNull() || |
| 1503 Object::empty_array(), | 1512 !function.AreValidArgumentCounts(number_of_arguments, |
| 1504 Resolver::kIsQualified)); | 1513 /* named_args */ 0, |
| 1505 if (function.IsNull()) { | 1514 NULL)) { |
| 1506 const String& klass_name = String::Handle(klass.Name()); | 1515 ThrowNoSuchMethod(klass, |
| 1507 const String& message = String::Handle( | 1516 function_name, |
| 1508 String::NewFormatted("%s: did not find static method '%s.%s'.", | 1517 function, |
| 1509 "ClassMirror_invoke", | 1518 InvocationMirror::kStatic, |
| 1510 klass_name.ToCString(), | 1519 InvocationMirror::kMethod); |
| 1511 function_name.ToCString())); | |
| 1512 ThrowMirroredCompilationError(message); | |
| 1513 UNREACHABLE(); | 1520 UNREACHABLE(); |
| 1514 } | 1521 } |
| 1522 | |
| 1515 Object& result = Object::Handle(DartEntry::InvokeFunction(function, | 1523 Object& result = Object::Handle(DartEntry::InvokeFunction(function, |
| 1516 positional_args)); | 1524 positional_args)); |
| 1517 if (result.IsError()) { | 1525 if (result.IsError()) { |
| 1518 ThrowInvokeError(Error::Cast(result)); | 1526 ThrowInvokeError(Error::Cast(result)); |
| 1519 UNREACHABLE(); | 1527 UNREACHABLE(); |
| 1520 } | 1528 } |
| 1521 return result.raw(); | 1529 return result.raw(); |
| 1522 } | 1530 } |
| 1523 | 1531 |
| 1524 | 1532 |
| 1525 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { | 1533 DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) { |
| 1526 // Argument 0 is the mirror, which is unused by the native. It exists | 1534 // 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 | 1535 // because this native is an instance method in order to be polymorphic |
| 1528 // with its cousins. | 1536 // with its cousins. |
| 1529 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1537 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1530 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1538 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1531 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); | 1539 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); |
| 1532 | 1540 |
| 1533 // Note static fields do not have implicit getters. | 1541 // Note static fields do not have implicit getters. |
| 1534 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); | 1542 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); |
| 1535 if (field.IsNull() || FieldIsUninitialized(field)) { | 1543 if (field.IsNull() || FieldIsUninitialized(field)) { |
| 1536 const String& internal_getter_name = String::Handle( | 1544 const String& internal_getter_name = String::Handle( |
| 1537 Field::GetterName(getter_name)); | 1545 Field::GetterName(getter_name)); |
| 1538 const Function& getter = Function::Handle( | 1546 const Function& getter = Function::Handle( |
| 1539 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); | 1547 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); |
| 1540 | 1548 |
| 1541 if (getter.IsNull()) { | 1549 if (getter.IsNull()) { |
| 1542 const String& message = String::Handle( | 1550 ThrowNoSuchMethod(klass, |
| 1543 String::NewFormatted("%s: did not find static getter '%s'.", | 1551 getter_name, |
| 1544 "ClassMirror_invokeGetter", | 1552 getter, |
| 1545 getter_name.ToCString())); | 1553 InvocationMirror::kStatic, |
| 1546 ThrowMirroredCompilationError(message); | 1554 InvocationMirror::kGetter); |
| 1547 UNREACHABLE(); | 1555 UNREACHABLE(); |
| 1548 } | 1556 } |
| 1549 | 1557 |
| 1550 // Invoke the getter and return the result. | 1558 // Invoke the getter and return the result. |
| 1551 Object& result = Object::Handle( | 1559 Object& result = Object::Handle( |
| 1552 DartEntry::InvokeFunction(getter, Object::empty_array())); | 1560 DartEntry::InvokeFunction(getter, Object::empty_array())); |
| 1553 if (result.IsError()) { | 1561 if (result.IsError()) { |
| 1554 ThrowInvokeError(Error::Cast(result)); | 1562 ThrowInvokeError(Error::Cast(result)); |
| 1555 UNREACHABLE(); | 1563 UNREACHABLE(); |
| 1556 } | 1564 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1571 | 1579 |
| 1572 // Check for real fields and user-defined setters. | 1580 // Check for real fields and user-defined setters. |
| 1573 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | 1581 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); |
| 1574 if (field.IsNull()) { | 1582 if (field.IsNull()) { |
| 1575 const String& internal_setter_name = String::Handle( | 1583 const String& internal_setter_name = String::Handle( |
| 1576 Field::SetterName(setter_name)); | 1584 Field::SetterName(setter_name)); |
| 1577 const Function& setter = Function::Handle( | 1585 const Function& setter = Function::Handle( |
| 1578 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); | 1586 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); |
| 1579 | 1587 |
| 1580 if (setter.IsNull()) { | 1588 if (setter.IsNull()) { |
| 1581 const String& message = String::Handle( | 1589 ThrowNoSuchMethod(klass, |
| 1582 String::NewFormatted("%s: did not find static setter '%s'.", | 1590 setter_name, |
| 1583 "ClassMirror_invokeSetter", | 1591 setter, |
| 1584 setter_name.ToCString())); | 1592 InvocationMirror::kStatic, |
| 1585 ThrowMirroredCompilationError(message); | 1593 InvocationMirror::kSetter); |
| 1586 UNREACHABLE(); | 1594 UNREACHABLE(); |
| 1587 } | 1595 } |
| 1588 | 1596 |
| 1589 // Invoke the setter and return the result. | 1597 // Invoke the setter and return the result. |
| 1590 const int kNumArgs = 1; | 1598 const int kNumArgs = 1; |
| 1591 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1599 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1592 args.SetAt(0, value); | 1600 args.SetAt(0, value); |
| 1593 | 1601 |
| 1594 Object& result = Object::Handle( | 1602 Object& result = Object::Handle( |
| 1595 DartEntry::InvokeFunction(setter, args)); | 1603 DartEntry::InvokeFunction(setter, args)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1629 // unnamed constructor for class 'A' is labeled 'A.'. | 1637 // unnamed constructor for class 'A' is labeled 'A.'. |
| 1630 // This convention prevents users from explicitly calling constructors. | 1638 // This convention prevents users from explicitly calling constructors. |
| 1631 const String& klass_name = String::Handle(klass.Name()); | 1639 const String& klass_name = String::Handle(klass.Name()); |
| 1632 String& internal_constructor_name = | 1640 String& internal_constructor_name = |
| 1633 String::Handle(String::Concat(klass_name, Symbols::Dot())); | 1641 String::Handle(String::Concat(klass_name, Symbols::Dot())); |
| 1634 if (!constructor_name.IsNull()) { | 1642 if (!constructor_name.IsNull()) { |
| 1635 internal_constructor_name = | 1643 internal_constructor_name = |
| 1636 String::Concat(internal_constructor_name, constructor_name); | 1644 String::Concat(internal_constructor_name, constructor_name); |
| 1637 } | 1645 } |
| 1638 | 1646 |
| 1639 const Function& constructor = | 1647 Function& constructor = Function::Handle( |
| 1640 Function::Handle(ResolveConstructor("ClassMirror_invokeConstructor", | 1648 klass.LookupFunctionAllowPrivate(internal_constructor_name)); |
| 1641 klass, | 1649 |
| 1642 klass_name, | 1650 if (constructor.IsNull() || |
| 1643 internal_constructor_name, | 1651 (!constructor.IsConstructor() && !constructor.IsFactory()) || |
| 1644 number_of_arguments)); | 1652 !constructor.AreValidArgumentCounts(number_of_arguments + |
| 1653 constructor.NumImplicitParameters(), | |
| 1654 /* named args */ 0, | |
| 1655 NULL)) { | |
| 1656 // Pretend we didn't find the constructor at all when the arity is wrong | |
| 1657 // so as to produce the same NoSuchMethodError as the non-reflective case. | |
| 1658 constructor = Function::null(); | |
| 1659 ThrowNoSuchMethod(klass, | |
| 1660 internal_constructor_name, | |
| 1661 constructor, | |
| 1662 InvocationMirror::kConstructor, | |
| 1663 InvocationMirror::kMethod); | |
| 1664 UNREACHABLE(); | |
| 1665 } | |
| 1645 | 1666 |
| 1646 const Object& result = | 1667 const Object& result = |
| 1647 Object::Handle(DartEntry::InvokeConstructor(klass, | 1668 Object::Handle(DartEntry::InvokeConstructor(klass, |
| 1648 constructor, | 1669 constructor, |
| 1649 positional_args)); | 1670 positional_args)); |
| 1650 if (result.IsError()) { | 1671 if (result.IsError()) { |
| 1651 ThrowInvokeError(Error::Cast(result)); | 1672 ThrowInvokeError(Error::Cast(result)); |
| 1652 UNREACHABLE(); | 1673 UNREACHABLE(); |
| 1653 } | 1674 } |
| 1654 // Factories may return null. | 1675 // Factories may return null. |
| 1655 ASSERT(result.IsInstance() || result.IsNull()); | 1676 ASSERT(result.IsInstance() || result.IsNull()); |
| 1656 return result.raw(); | 1677 return result.raw(); |
| 1657 } | 1678 } |
| 1658 | 1679 |
| 1659 | 1680 |
| 1660 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { | 1681 DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 4) { |
| 1661 // Argument 0 is the mirror, which is unused by the native. It exists | 1682 // Argument 0 is the mirror, which is unused by the native. It exists |
| 1662 // because this native is an instance method in order to be polymorphic | 1683 // because this native is an instance method in order to be polymorphic |
| 1663 // with its cousins. | 1684 // with its cousins. |
| 1664 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1685 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1665 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1686 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
| 1666 GET_NON_NULL_NATIVE_ARGUMENT( | 1687 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1667 String, function_name, arguments->NativeArgAt(2)); | 1688 String, function_name, arguments->NativeArgAt(2)); |
| 1668 GET_NON_NULL_NATIVE_ARGUMENT( | 1689 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1669 Array, positional_args, arguments->NativeArgAt(3)); | 1690 Array, positional_args, arguments->NativeArgAt(3)); |
| 1670 | 1691 |
| 1671 intptr_t number_of_arguments = positional_args.Length(); | 1692 intptr_t number_of_arguments = positional_args.Length(); |
| 1672 | 1693 |
| 1673 | |
| 1674 String& ambiguity_error_msg = String::Handle(isolate); | 1694 String& ambiguity_error_msg = String::Handle(isolate); |
| 1675 const Function& function = Function::Handle( | 1695 const Function& function = Function::Handle( |
| 1676 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); | 1696 library.LookupFunctionAllowPrivate(function_name, &ambiguity_error_msg)); |
| 1677 | 1697 |
| 1678 if (function.IsNull()) { | 1698 if (function.IsNull() && !ambiguity_error_msg.IsNull()) { |
| 1679 if (ambiguity_error_msg.IsNull()) { | 1699 ThrowMirroredCompilationError(ambiguity_error_msg); |
| 1680 const String& message = String::Handle( | |
| 1681 String::NewFormatted("%s: did not find top-level function '%s'.", | |
| 1682 "LibraryMirror_invoke", | |
| 1683 function_name.ToCString())); | |
| 1684 ThrowMirroredCompilationError(message); | |
| 1685 } else { | |
| 1686 ThrowMirroredCompilationError(ambiguity_error_msg); | |
| 1687 } | |
| 1688 UNREACHABLE(); | 1700 UNREACHABLE(); |
| 1689 } | 1701 } |
| 1690 | 1702 |
| 1691 // LookupFunctionAllowPrivate does not check argument arity, so we | 1703 if (function.IsNull() || |
| 1692 // do it here. | 1704 !function.AreValidArgumentCounts(number_of_arguments, |
| 1693 String& error_message = String::Handle(); | 1705 0, |
| 1694 if (!function.AreValidArgumentCounts(number_of_arguments, | 1706 NULL) ) { |
| 1695 /* num_named_args */ 0, | 1707 ThrowNoSuchMethod(library, |
| 1696 &error_message)) { | 1708 function_name, |
| 1697 const String& message = String::Handle( | 1709 function, |
| 1698 String::NewFormatted("%s: wrong argument count for function '%s': %s.", | 1710 InvocationMirror::kTopLevel, |
| 1699 "LibraryMirror_invoke", | 1711 InvocationMirror::kMethod); |
| 1700 function_name.ToCString(), | |
| 1701 error_message.ToCString())); | |
| 1702 ThrowMirroredCompilationError(message); | |
| 1703 UNREACHABLE(); | 1712 UNREACHABLE(); |
| 1704 } | 1713 } |
| 1705 | 1714 |
| 1706 const Object& result = Object::Handle( | 1715 const Object& result = Object::Handle( |
| 1707 DartEntry::InvokeFunction(function, positional_args)); | 1716 DartEntry::InvokeFunction(function, positional_args)); |
| 1708 if (result.IsError()) { | 1717 if (result.IsError()) { |
| 1709 ThrowInvokeError(Error::Cast(result)); | 1718 ThrowInvokeError(Error::Cast(result)); |
| 1710 UNREACHABLE(); | 1719 UNREACHABLE(); |
| 1711 } | 1720 } |
| 1712 return result.raw(); | 1721 return result.raw(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1749 if (result.IsError()) { | 1758 if (result.IsError()) { |
| 1750 ThrowInvokeError(Error::Cast(result)); | 1759 ThrowInvokeError(Error::Cast(result)); |
| 1751 UNREACHABLE(); | 1760 UNREACHABLE(); |
| 1752 } | 1761 } |
| 1753 return result.raw(); | 1762 return result.raw(); |
| 1754 } | 1763 } |
| 1755 if (!field.IsNull()) { | 1764 if (!field.IsNull()) { |
| 1756 return field.value(); | 1765 return field.value(); |
| 1757 } | 1766 } |
| 1758 if (ambiguity_error_msg.IsNull()) { | 1767 if (ambiguity_error_msg.IsNull()) { |
| 1759 const String& message = String::Handle( | 1768 ThrowNoSuchMethod(library, |
| 1760 String::NewFormatted("%s: did not find top-level variable '%s'.", | 1769 getter_name, |
| 1761 "LibraryMirror_invokeGetter", | 1770 getter, |
| 1762 getter_name.ToCString())); | 1771 InvocationMirror::kTopLevel, |
| 1763 ThrowMirroredCompilationError(message); | 1772 InvocationMirror::kGetter); |
| 1764 } else { | 1773 } else { |
| 1765 ThrowMirroredCompilationError(ambiguity_error_msg); | 1774 ThrowMirroredCompilationError(ambiguity_error_msg); |
| 1766 } | 1775 } |
| 1767 UNREACHABLE(); | 1776 UNREACHABLE(); |
| 1768 return Instance::null(); | 1777 return Instance::null(); |
| 1769 } | 1778 } |
| 1770 | 1779 |
| 1771 | 1780 |
| 1772 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { | 1781 DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 4) { |
| 1773 // Argument 0 is the mirror, which is unused by the native. It exists | 1782 // Argument 0 is the mirror, which is unused by the native. It exists |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1786 library.LookupFieldAllowPrivate(setter_name, &ambiguity_error_msg)); | 1795 library.LookupFieldAllowPrivate(setter_name, &ambiguity_error_msg)); |
| 1787 | 1796 |
| 1788 if (field.IsNull() && ambiguity_error_msg.IsNull()) { | 1797 if (field.IsNull() && ambiguity_error_msg.IsNull()) { |
| 1789 const String& internal_setter_name = | 1798 const String& internal_setter_name = |
| 1790 String::Handle(Field::SetterName(setter_name)); | 1799 String::Handle(Field::SetterName(setter_name)); |
| 1791 const Function& setter = Function::Handle( | 1800 const Function& setter = Function::Handle( |
| 1792 library.LookupFunctionAllowPrivate(internal_setter_name, | 1801 library.LookupFunctionAllowPrivate(internal_setter_name, |
| 1793 &ambiguity_error_msg)); | 1802 &ambiguity_error_msg)); |
| 1794 if (setter.IsNull()) { | 1803 if (setter.IsNull()) { |
| 1795 if (ambiguity_error_msg.IsNull()) { | 1804 if (ambiguity_error_msg.IsNull()) { |
| 1796 const String& message = String::Handle( | 1805 ThrowNoSuchMethod(library, |
| 1797 String::NewFormatted("%s: did not find top-level variable '%s'.", | 1806 setter_name, |
| 1798 "LibraryMirror_invokeSetter", | 1807 setter, |
| 1799 setter_name.ToCString())); | 1808 InvocationMirror::kTopLevel, |
| 1800 ThrowMirroredCompilationError(message); | 1809 InvocationMirror::kSetter); |
| 1801 } else { | 1810 } else { |
| 1802 ThrowMirroredCompilationError(ambiguity_error_msg); | 1811 ThrowMirroredCompilationError(ambiguity_error_msg); |
| 1803 } | 1812 } |
| 1804 UNREACHABLE(); | 1813 UNREACHABLE(); |
| 1805 } | 1814 } |
| 1806 | 1815 |
| 1807 // Invoke the setter and return the result. | 1816 // Invoke the setter and return the result. |
| 1808 const int kNumArgs = 1; | 1817 const int kNumArgs = 1; |
| 1809 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1818 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1810 args.SetAt(0, value); | 1819 args.SetAt(0, value); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1875 | 1884 |
| 1876 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1885 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
| 1877 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1886 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1878 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1887 const Field& field = Field::Handle(ref.GetFieldReferent()); |
| 1879 | 1888 |
| 1880 const AbstractType& type = AbstractType::Handle(field.type()); | 1889 const AbstractType& type = AbstractType::Handle(field.type()); |
| 1881 return CreateTypeMirror(type); | 1890 return CreateTypeMirror(type); |
| 1882 } | 1891 } |
| 1883 | 1892 |
| 1884 } // namespace dart | 1893 } // namespace dart |
| OLD | NEW |