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 "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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 | 58 |
| 59 | 59 |
| 60 // Conventions: | 60 // Conventions: |
| 61 // * For throwing a NSM in a class klass we use its runtime type as receiver, | 61 // * For throwing a NSM in a class klass we use its runtime type as receiver, |
| 62 // i.e., klass.RareType(). | 62 // i.e., klass.RareType(). |
| 63 // * For throwing a NSM in a library, we just pass the null instance as | 63 // * For throwing a NSM in a library, we just pass the null instance as |
| 64 // receiver. | 64 // receiver. |
| 65 static void ThrowNoSuchMethod(const Instance& receiver, | 65 static void ThrowNoSuchMethod(const Instance& receiver, |
| 66 const String& function_name, | 66 const String& function_name, |
| 67 const Function& function, | 67 const Function& function, |
| 68 const Array& arguments, | |
| 68 const InvocationMirror::Call call, | 69 const InvocationMirror::Call call, |
| 69 const InvocationMirror::Type type) { | 70 const InvocationMirror::Type type) { |
| 70 const Smi& invocation_type = Smi::Handle(Smi::New( | 71 const Smi& invocation_type = Smi::Handle(Smi::New( |
| 71 InvocationMirror::EncodeType(call, type))); | 72 InvocationMirror::EncodeType(call, type))); |
| 72 | 73 |
| 73 const Array& args = Array::Handle(Array::New(6)); | 74 const Array& args = Array::Handle(Array::New(6)); |
| 74 args.SetAt(0, receiver); | 75 args.SetAt(0, receiver); |
| 75 args.SetAt(1, function_name); | 76 args.SetAt(1, function_name); |
| 76 args.SetAt(2, invocation_type); | 77 args.SetAt(2, invocation_type); |
| 77 // Parameter 3 (actual arguments): We omit this parameter to get the same | 78 args.SetAt(3, arguments); |
| 78 // error message as one would get by invoking the function non-reflectively. | 79 // TODO(rmacnak): Argument 4 (attempted argument names). |
| 79 // Parameter 4 (named arguments): We omit this parameters since we cannot | |
| 80 // invoke functions with named parameters reflectively (using mirrors). | |
| 81 if (!function.IsNull()) { | 80 if (!function.IsNull()) { |
| 82 const intptr_t total_num_parameters = function.NumParameters(); | 81 const intptr_t total_num_parameters = function.NumParameters(); |
| 83 const Array& array = Array::Handle(Array::New(total_num_parameters)); | 82 const Array& array = Array::Handle(Array::New(total_num_parameters)); |
| 84 String& param_name = String::Handle(); | 83 String& param_name = String::Handle(); |
| 85 for (int i = 0; i < total_num_parameters; i++) { | 84 for (int i = 0; i < total_num_parameters; i++) { |
| 86 param_name = function.ParameterNameAt(i); | 85 param_name = function.ParameterNameAt(i); |
| 87 array.SetAt(i, param_name); | 86 array.SetAt(i, param_name); |
| 88 } | 87 } |
| 89 args.SetAt(5, array); | 88 args.SetAt(5, array); |
| 90 } | 89 } |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 653 // Invoke the getter and return the result. | 652 // Invoke the getter and return the result. |
| 654 const Object& result = Object::Handle( | 653 const Object& result = Object::Handle( |
| 655 DartEntry::InvokeFunction(getter, Object::empty_array())); | 654 DartEntry::InvokeFunction(getter, Object::empty_array())); |
| 656 return ReturnResult(result); | 655 return ReturnResult(result); |
| 657 } | 656 } |
| 658 | 657 |
| 659 if (throw_nsm_if_absent) { | 658 if (throw_nsm_if_absent) { |
| 660 ThrowNoSuchMethod(Instance::null_instance(), | 659 ThrowNoSuchMethod(Instance::null_instance(), |
| 661 getter_name, | 660 getter_name, |
| 662 getter, | 661 getter, |
| 662 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.
| |
| 663 InvocationMirror::kTopLevel, | 663 InvocationMirror::kTopLevel, |
| 664 InvocationMirror::kGetter); | 664 InvocationMirror::kGetter); |
| 665 UNREACHABLE(); | 665 UNREACHABLE(); |
| 666 } | 666 } |
| 667 | 667 |
| 668 // Fall through case: Indicate that we didn't find any function or field using | 668 // Fall through case: Indicate that we didn't find any function or field using |
| 669 // a special null instance. This is different from a field being null. Callers | 669 // a special null instance. This is different from a field being null. Callers |
| 670 // make sure that this null does not leak into Dartland. | 670 // make sure that this null does not leak into Dartland. |
| 671 return Object::sentinel().raw(); | 671 return Object::sentinel().raw(); |
| 672 } | 672 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 690 // Looking for a getter but found a regular method: closurize it. | 690 // Looking for a getter but found a regular method: closurize it. |
| 691 const Function& closure_function = | 691 const Function& closure_function = |
| 692 Function::Handle(getter.ImplicitClosureFunction()); | 692 Function::Handle(getter.ImplicitClosureFunction()); |
| 693 return closure_function.ImplicitStaticClosure(); | 693 return closure_function.ImplicitStaticClosure(); |
| 694 } | 694 } |
| 695 } | 695 } |
| 696 if (throw_nsm_if_absent) { | 696 if (throw_nsm_if_absent) { |
| 697 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), | 697 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 698 getter_name, | 698 getter_name, |
| 699 getter, | 699 getter, |
| 700 Array::Handle(), | |
|
siva
2014/06/12 16:59:07
Ditto.
| |
| 700 InvocationMirror::kStatic, | 701 InvocationMirror::kStatic, |
| 701 InvocationMirror::kGetter); | 702 InvocationMirror::kGetter); |
| 702 UNREACHABLE(); | 703 UNREACHABLE(); |
| 703 } | 704 } |
| 704 // Fall through case: Indicate that we didn't find any function or field | 705 // Fall through case: Indicate that we didn't find any function or field |
| 705 // using a special null instance. This is different from a field being | 706 // using a special null instance. This is different from a field being |
| 706 // null. Callers make sure that this null does not leak into Dartland. | 707 // null. Callers make sure that this null does not leak into Dartland. |
| 707 return Object::sentinel().raw(); | 708 return Object::sentinel().raw(); |
| 708 } | 709 } |
| 709 | 710 |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); | 1420 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
| 1420 | 1421 |
| 1421 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 1422 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 1422 | 1423 |
| 1423 if (function.IsNull() || | 1424 if (function.IsNull() || |
| 1424 !function.AreValidArguments(args_descriptor, NULL) || | 1425 !function.AreValidArguments(args_descriptor, NULL) || |
| 1425 !function.is_visible()) { | 1426 !function.is_visible()) { |
| 1426 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), | 1427 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1427 function_name, | 1428 function_name, |
| 1428 function, | 1429 function, |
| 1430 Array::Handle(), | |
|
siva
2014/06/12 16:59:07
Ditto here and other places below.
| |
| 1429 InvocationMirror::kStatic, | 1431 InvocationMirror::kStatic, |
| 1430 InvocationMirror::kMethod); | 1432 InvocationMirror::kMethod); |
| 1431 UNREACHABLE(); | 1433 UNREACHABLE(); |
| 1432 } | 1434 } |
| 1433 | 1435 |
| 1434 Object& result = Object::Handle( | 1436 Object& result = Object::Handle( |
| 1435 DartEntry::InvokeFunction(function, args, args_descriptor_array)); | 1437 DartEntry::InvokeFunction(function, args, args_descriptor_array)); |
| 1436 if (result.IsError()) { | 1438 if (result.IsError()) { |
| 1437 ThrowInvokeError(Error::Cast(result)); | 1439 ThrowInvokeError(Error::Cast(result)); |
| 1438 UNREACHABLE(); | 1440 UNREACHABLE(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1457 // because this native is an instance method in order to be polymorphic | 1459 // because this native is an instance method in order to be polymorphic |
| 1458 // with its cousins. | 1460 // with its cousins. |
| 1459 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1461 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1460 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1462 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1461 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 1463 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
| 1462 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 1464 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
| 1463 | 1465 |
| 1464 // Check for real fields and user-defined setters. | 1466 // Check for real fields and user-defined setters. |
| 1465 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | 1467 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); |
| 1466 Function& setter = Function::Handle(); | 1468 Function& setter = Function::Handle(); |
| 1467 if (field.IsNull()) { | 1469 const String& internal_setter_name = String::Handle( |
| 1468 const String& internal_setter_name = String::Handle( | |
| 1469 Field::SetterName(setter_name)); | 1470 Field::SetterName(setter_name)); |
| 1470 | 1471 |
| 1472 if (field.IsNull()) { | |
| 1471 setter = klass.LookupStaticFunction(internal_setter_name); | 1473 setter = klass.LookupStaticFunction(internal_setter_name); |
| 1472 | 1474 |
| 1475 const int kNumArgs = 1; | |
| 1476 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1477 args.SetAt(0, value); | |
| 1478 | |
| 1473 if (setter.IsNull() || !setter.is_visible()) { | 1479 if (setter.IsNull() || !setter.is_visible()) { |
| 1474 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), | 1480 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1475 setter_name, | 1481 internal_setter_name, |
| 1476 setter, | 1482 setter, |
| 1483 args, | |
| 1477 InvocationMirror::kStatic, | 1484 InvocationMirror::kStatic, |
| 1478 InvocationMirror::kSetter); | 1485 InvocationMirror::kSetter); |
| 1479 UNREACHABLE(); | 1486 UNREACHABLE(); |
| 1480 } | 1487 } |
| 1481 | 1488 |
| 1482 // Invoke the setter and return the result. | 1489 // Invoke the setter and return the result. |
| 1483 const int kNumArgs = 1; | |
| 1484 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1485 args.SetAt(0, value); | |
| 1486 | |
| 1487 Object& result = Object::Handle( | 1490 Object& result = Object::Handle( |
| 1488 DartEntry::InvokeFunction(setter, args)); | 1491 DartEntry::InvokeFunction(setter, args)); |
| 1489 if (result.IsError()) { | 1492 if (result.IsError()) { |
| 1490 ThrowInvokeError(Error::Cast(result)); | 1493 ThrowInvokeError(Error::Cast(result)); |
| 1491 UNREACHABLE(); | 1494 UNREACHABLE(); |
| 1492 } | 1495 } |
| 1493 return result.raw(); | 1496 return result.raw(); |
| 1494 } | 1497 } |
| 1495 | 1498 |
| 1496 if (field.is_final()) { | 1499 if (field.is_final()) { |
| 1497 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), | 1500 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1498 setter_name, | 1501 internal_setter_name, |
| 1499 setter, | 1502 setter, |
| 1503 Array::Handle(), | |
| 1500 InvocationMirror::kStatic, | 1504 InvocationMirror::kStatic, |
| 1501 InvocationMirror::kSetter); | 1505 InvocationMirror::kSetter); |
| 1502 UNREACHABLE(); | 1506 UNREACHABLE(); |
| 1503 } | 1507 } |
| 1504 | 1508 |
| 1505 field.set_value(value); | 1509 field.set_value(value); |
| 1506 return value.raw(); | 1510 return value.raw(); |
| 1507 } | 1511 } |
| 1508 | 1512 |
| 1509 | 1513 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1533 | 1537 |
| 1534 if (lookup_constructor.IsNull() || | 1538 if (lookup_constructor.IsNull() || |
| 1535 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || | 1539 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || |
| 1536 !lookup_constructor.is_visible()) { | 1540 !lookup_constructor.is_visible()) { |
| 1537 // Pretend we didn't find the constructor at all when the arity is wrong | 1541 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1538 // so as to produce the same NoSuchMethodError as the non-reflective case. | 1542 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1539 lookup_constructor = Function::null(); | 1543 lookup_constructor = Function::null(); |
| 1540 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), | 1544 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1541 internal_constructor_name, | 1545 internal_constructor_name, |
| 1542 lookup_constructor, | 1546 lookup_constructor, |
| 1547 Array::Handle(), | |
| 1543 InvocationMirror::kConstructor, | 1548 InvocationMirror::kConstructor, |
| 1544 InvocationMirror::kMethod); | 1549 InvocationMirror::kMethod); |
| 1545 UNREACHABLE(); | 1550 UNREACHABLE(); |
| 1546 } | 1551 } |
| 1547 | 1552 |
| 1548 if (klass.is_abstract() && !lookup_constructor.IsFactory()) { | 1553 if (klass.is_abstract() && !lookup_constructor.IsFactory()) { |
| 1549 const Array& error_args = Array::Handle(Array::New(3)); | 1554 const Array& error_args = Array::Handle(Array::New(3)); |
| 1550 error_args.SetAt(0, klass_name); | 1555 error_args.SetAt(0, klass_name); |
| 1551 // 1 = script url | 1556 // 1 = script url |
| 1552 // 2 = token position | 1557 // 2 = token position |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1610 | 1615 |
| 1611 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 1616 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 1612 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || | 1617 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || |
| 1613 !redirected_constructor.is_visible()) { | 1618 !redirected_constructor.is_visible()) { |
| 1614 // Pretend we didn't find the constructor at all when the arity is wrong | 1619 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1615 // so as to produce the same NoSuchMethodError as the non-reflective case. | 1620 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1616 redirected_constructor = Function::null(); | 1621 redirected_constructor = Function::null(); |
| 1617 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), | 1622 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1618 internal_constructor_name, | 1623 internal_constructor_name, |
| 1619 redirected_constructor, | 1624 redirected_constructor, |
| 1625 Array::Handle(), | |
| 1620 InvocationMirror::kConstructor, | 1626 InvocationMirror::kConstructor, |
| 1621 InvocationMirror::kMethod); | 1627 InvocationMirror::kMethod); |
| 1622 UNREACHABLE(); | 1628 UNREACHABLE(); |
| 1623 } | 1629 } |
| 1624 | 1630 |
| 1625 Instance& new_object = Instance::Handle(); | 1631 Instance& new_object = Instance::Handle(); |
| 1626 if (redirected_constructor.IsConstructor()) { | 1632 if (redirected_constructor.IsConstructor()) { |
| 1627 // Constructors get the uninitialized object and a constructor phase. Note | 1633 // Constructors get the uninitialized object and a constructor phase. Note |
| 1628 // we have delayed allocation until after the function type and argument | 1634 // we have delayed allocation until after the function type and argument |
| 1629 // matching checks. | 1635 // matching checks. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1672 String, function_name, arguments->NativeArgAt(2)); | 1678 String, function_name, arguments->NativeArgAt(2)); |
| 1673 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); | 1679 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3)); |
| 1674 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); | 1680 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
| 1675 | 1681 |
| 1676 Function& function = Function::Handle( | 1682 Function& function = Function::Handle( |
| 1677 library.LookupLocalFunction(function_name)); | 1683 library.LookupLocalFunction(function_name)); |
| 1678 | 1684 |
| 1679 if (function.IsNull()) { | 1685 if (function.IsNull()) { |
| 1680 // Didn't find a method: try to find a getter and invoke call on its result. | 1686 // Didn't find a method: try to find a getter and invoke call on its result. |
| 1681 const Instance& getter_result = | 1687 const Instance& getter_result = |
| 1682 Instance::Handle(InvokeLibraryGetter(library, function_name, true)); | 1688 Instance::Handle(InvokeLibraryGetter(library, function_name, false)); |
| 1689 if (getter_result.raw() != Object::sentinel().raw()) { | |
| 1683 // Make room for the closure (receiver) in arguments. | 1690 // Make room for the closure (receiver) in arguments. |
| 1684 intptr_t numArgs = args.Length(); | 1691 intptr_t numArgs = args.Length(); |
| 1685 const Array& call_args = Array::Handle(Array::New(numArgs + 1)); | 1692 const Array& call_args = Array::Handle(Array::New(numArgs + 1)); |
| 1686 Object& temp = Object::Handle(); | 1693 Object& temp = Object::Handle(); |
| 1687 for (int i = 0; i < numArgs; i++) { | 1694 for (int i = 0; i < numArgs; i++) { |
| 1688 temp = args.At(i); | 1695 temp = args.At(i); |
| 1689 call_args.SetAt(i + 1, temp); | 1696 call_args.SetAt(i + 1, temp); |
| 1690 } | 1697 } |
| 1691 call_args.SetAt(0, getter_result); | 1698 call_args.SetAt(0, getter_result); |
| 1692 const Array& call_args_descriptor_array = | 1699 const Array& call_args_descriptor_array = |
| 1693 Array::Handle(ArgumentsDescriptor::New(call_args.Length(), arg_names)); | 1700 Array::Handle(ArgumentsDescriptor::New(call_args.Length(), arg_names)); |
| 1694 // Call closure. | 1701 // Call closure. |
| 1695 const Object& call_result = Object::Handle( | 1702 const Object& call_result = Object::Handle( |
| 1696 DartEntry::InvokeClosure(call_args, call_args_descriptor_array)); | 1703 DartEntry::InvokeClosure(call_args, call_args_descriptor_array)); |
| 1697 if (call_result.IsError()) { | 1704 if (call_result.IsError()) { |
| 1698 ThrowInvokeError(Error::Cast(call_result)); | 1705 ThrowInvokeError(Error::Cast(call_result)); |
| 1699 UNREACHABLE(); | 1706 UNREACHABLE(); |
| 1700 } | 1707 } |
| 1701 return call_result.raw(); | 1708 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.
| |
| 1709 } | |
| 1702 } | 1710 } |
| 1703 | 1711 |
| 1704 const Array& args_descriptor_array = | 1712 const Array& args_descriptor_array = |
| 1705 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); | 1713 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
| 1706 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 1714 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 1707 | 1715 |
| 1708 if (function.IsNull() || | 1716 if (function.IsNull() || |
| 1709 !function.AreValidArguments(args_descriptor, NULL) || | 1717 !function.AreValidArguments(args_descriptor, NULL) || |
| 1710 !function.is_visible()) { | 1718 !function.is_visible()) { |
| 1711 ThrowNoSuchMethod(Instance::null_instance(), | 1719 ThrowNoSuchMethod(Instance::null_instance(), |
| 1712 function_name, | 1720 function_name, |
| 1713 function, | 1721 function, |
| 1722 Array::Handle(), | |
| 1714 InvocationMirror::kTopLevel, | 1723 InvocationMirror::kTopLevel, |
| 1715 InvocationMirror::kMethod); | 1724 InvocationMirror::kMethod); |
| 1716 UNREACHABLE(); | 1725 UNREACHABLE(); |
| 1717 } | 1726 } |
| 1718 | 1727 |
| 1719 const Object& result = Object::Handle( | 1728 const Object& result = Object::Handle( |
| 1720 DartEntry::InvokeFunction(function, args, args_descriptor_array)); | 1729 DartEntry::InvokeFunction(function, args, args_descriptor_array)); |
| 1721 if (result.IsError()) { | 1730 if (result.IsError()) { |
| 1722 ThrowInvokeError(Error::Cast(result)); | 1731 ThrowInvokeError(Error::Cast(result)); |
| 1723 UNREACHABLE(); | 1732 UNREACHABLE(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1745 const Library& library = Library::Handle(ref.GetLibraryReferent()); | 1754 const Library& library = Library::Handle(ref.GetLibraryReferent()); |
| 1746 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 1755 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
| 1747 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 1756 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
| 1748 | 1757 |
| 1749 // To access a top-level we may need to use the Field or the | 1758 // To access a top-level we may need to use the Field or the |
| 1750 // setter Function. The setter function may either be in the | 1759 // setter Function. The setter function may either be in the |
| 1751 // library or in the field's owner class, depending. | 1760 // library or in the field's owner class, depending. |
| 1752 const Field& field = Field::Handle( | 1761 const Field& field = Field::Handle( |
| 1753 library.LookupLocalField(setter_name)); | 1762 library.LookupLocalField(setter_name)); |
| 1754 Function& setter = Function::Handle(); | 1763 Function& setter = Function::Handle(); |
| 1764 const String& internal_setter_name = | |
| 1765 String::Handle(Field::SetterName(setter_name)); | |
| 1755 | 1766 |
| 1756 if (field.IsNull()) { | 1767 if (field.IsNull()) { |
| 1757 const String& internal_setter_name = | 1768 setter = library.LookupLocalFunction(internal_setter_name); |
| 1758 String::Handle(Field::SetterName(setter_name)); | |
| 1759 | 1769 |
| 1760 setter = library.LookupLocalFunction(internal_setter_name); | 1770 const int kNumArgs = 1; |
| 1771 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1772 args.SetAt(0, value); | |
| 1773 | |
| 1761 if (setter.IsNull() || !setter.is_visible()) { | 1774 if (setter.IsNull() || !setter.is_visible()) { |
| 1762 ThrowNoSuchMethod(Instance::null_instance(), | 1775 ThrowNoSuchMethod(Instance::null_instance(), |
| 1763 setter_name, | 1776 internal_setter_name, |
| 1764 setter, | 1777 setter, |
| 1778 args, | |
| 1765 InvocationMirror::kTopLevel, | 1779 InvocationMirror::kTopLevel, |
| 1766 InvocationMirror::kSetter); | 1780 InvocationMirror::kSetter); |
| 1767 UNREACHABLE(); | 1781 UNREACHABLE(); |
| 1768 } | 1782 } |
| 1769 | 1783 |
| 1770 // Invoke the setter and return the result. | 1784 // Invoke the setter and return the result. |
| 1771 const int kNumArgs = 1; | |
| 1772 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
| 1773 args.SetAt(0, value); | |
| 1774 const Object& result = Object::Handle( | 1785 const Object& result = Object::Handle( |
| 1775 DartEntry::InvokeFunction(setter, args)); | 1786 DartEntry::InvokeFunction(setter, args)); |
| 1776 if (result.IsError()) { | 1787 if (result.IsError()) { |
| 1777 ThrowInvokeError(Error::Cast(result)); | 1788 ThrowInvokeError(Error::Cast(result)); |
| 1778 UNREACHABLE(); | 1789 UNREACHABLE(); |
| 1779 } | 1790 } |
| 1780 return result.raw(); | 1791 return result.raw(); |
| 1781 } | 1792 } |
| 1782 | 1793 |
| 1783 if (field.is_final()) { | 1794 if (field.is_final()) { |
| 1784 ThrowNoSuchMethod(Instance::null_instance(), | 1795 ThrowNoSuchMethod(Instance::null_instance(), |
| 1785 setter_name, | 1796 internal_setter_name, |
| 1786 setter, | 1797 setter, |
| 1798 Array::Handle(), | |
| 1787 InvocationMirror::kTopLevel, | 1799 InvocationMirror::kTopLevel, |
| 1788 InvocationMirror::kSetter); | 1800 InvocationMirror::kSetter); |
| 1789 UNREACHABLE(); | 1801 UNREACHABLE(); |
| 1790 } | 1802 } |
| 1791 | 1803 |
| 1792 field.set_value(value); | 1804 field.set_value(value); |
| 1793 return value.raw(); | 1805 return value.raw(); |
| 1794 } | 1806 } |
| 1795 | 1807 |
| 1796 | 1808 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1949 } | 1961 } |
| 1950 | 1962 |
| 1951 DEFINE_NATIVE_ENTRY(TypeMirror_moreSpecificTest, 2) { | 1963 DEFINE_NATIVE_ENTRY(TypeMirror_moreSpecificTest, 2) { |
| 1952 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); | 1964 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); |
| 1953 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); | 1965 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); |
| 1954 return Bool::Get(a.IsMoreSpecificThan(b, NULL)).raw(); | 1966 return Bool::Get(a.IsMoreSpecificThan(b, NULL)).raw(); |
| 1955 } | 1967 } |
| 1956 | 1968 |
| 1957 | 1969 |
| 1958 } // namespace dart | 1970 } // namespace dart |
| OLD | NEW |