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 | 6 |
7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "vm/timer.h" | 27 #include "vm/timer.h" |
28 #include "vm/unicode.h" | 28 #include "vm/unicode.h" |
29 #include "vm/verifier.h" | 29 #include "vm/verifier.h" |
30 | 30 |
31 namespace dart { | 31 namespace dart { |
32 | 32 |
33 DECLARE_FLAG(bool, print_class_table); | 33 DECLARE_FLAG(bool, print_class_table); |
34 | 34 |
35 ThreadLocalKey Api::api_native_key_ = Thread::kUnsetThreadLocalKey; | 35 ThreadLocalKey Api::api_native_key_ = Thread::kUnsetThreadLocalKey; |
36 | 36 |
| 37 |
37 const char* CanonicalFunction(const char* func) { | 38 const char* CanonicalFunction(const char* func) { |
38 if (strncmp(func, "dart::", 6) == 0) { | 39 if (strncmp(func, "dart::", 6) == 0) { |
39 return func + 6; | 40 return func + 6; |
40 } else { | 41 } else { |
41 return func; | 42 return func; |
42 } | 43 } |
43 } | 44 } |
44 | 45 |
| 46 |
45 #define RETURN_TYPE_ERROR(isolate, dart_handle, type) \ | 47 #define RETURN_TYPE_ERROR(isolate, dart_handle, type) \ |
46 do { \ | 48 do { \ |
47 const Object& tmp = \ | 49 const Object& tmp = \ |
48 Object::Handle(isolate, Api::UnwrapHandle((dart_handle))); \ | 50 Object::Handle(isolate, Api::UnwrapHandle((dart_handle))); \ |
49 if (tmp.IsNull()) { \ | 51 if (tmp.IsNull()) { \ |
50 return Api::NewError("%s expects argument '%s' to be non-null.", \ | 52 return Api::NewError("%s expects argument '%s' to be non-null.", \ |
51 CURRENT_FUNC, #dart_handle); \ | 53 CURRENT_FUNC, #dart_handle); \ |
52 } else if (tmp.IsError()) { \ | 54 } else if (tmp.IsError()) { \ |
53 return dart_handle; \ | 55 return dart_handle; \ |
54 } else { \ | 56 } else { \ |
55 return Api::NewError("%s expects argument '%s' to be of type %s.", \ | 57 return Api::NewError("%s expects argument '%s' to be of type %s.", \ |
56 CURRENT_FUNC, #dart_handle, #type); \ | 58 CURRENT_FUNC, #dart_handle, #type); \ |
57 } \ | 59 } \ |
58 } while (0) | 60 } while (0) |
59 | 61 |
60 | 62 |
| 63 #define RETURN_NULL_ERROR(parameter) \ |
| 64 return Api::NewError("%s expects argument '%s' to be non-null.", \ |
| 65 CURRENT_FUNC, #parameter); |
| 66 |
| 67 |
| 68 // Takes a vm internal name and makes it suitable for external user. |
| 69 // |
| 70 // Examples: |
| 71 // |
| 72 // Internal getter and setter prefices are removed: |
| 73 // |
| 74 // get:foo -> foo |
| 75 // set:foo -> foo |
| 76 // |
| 77 // Private name mangling is removed, possibly twice: |
| 78 // |
| 79 // _ReceivePortImpl@6be832b -> _ReceivePortImpl |
| 80 // _ReceivePortImpl@6be832b._internal@6be832b -> +ReceivePortImpl._internal |
| 81 // |
| 82 // The trailing . on the default constructor name is dropped: |
| 83 // |
| 84 // List. -> List |
| 85 // |
| 86 // And so forth: |
| 87 // |
| 88 // get:foo@6be832b -> foo |
| 89 // _MyClass@6b3832b. -> _MyClass |
| 90 // _MyClass@6b3832b.named -> _MyClass.named |
| 91 // |
| 92 static RawString* IdentifierPrettyName(Isolate* isolate, const String& name) { |
| 93 intptr_t len = name.Length(); |
| 94 intptr_t start = 0; |
| 95 intptr_t at_pos = len; // Position of '@' in the name. |
| 96 intptr_t dot_pos = len; // Position of '.' in the name. |
| 97 |
| 98 for (int i = 0; i < name.Length(); i++) { |
| 99 if (name.CharAt(i) == ':') { |
| 100 ASSERT(start == 0); |
| 101 start = i + 1; |
| 102 } else if (name.CharAt(i) == '@') { |
| 103 ASSERT(at_pos == len); |
| 104 at_pos = i; |
| 105 } else if (name.CharAt(i) == '.') { |
| 106 dot_pos = i; |
| 107 break; |
| 108 } |
| 109 } |
| 110 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos); |
| 111 if (start == 0 && limit == len) { |
| 112 // This name is fine as it is. |
| 113 return name.raw(); |
| 114 } |
| 115 |
| 116 String& result = String::Handle(isolate); |
| 117 result = String::SubString(name, start, (limit - start)); |
| 118 |
| 119 // Look for a second '@' now to correctly handle names like |
| 120 // "_ReceivePortImpl@6be832b._internal@6be832b". |
| 121 at_pos = len; |
| 122 for (int i = dot_pos; i < name.Length(); i++) { |
| 123 if (name.CharAt(i) == '@') { |
| 124 ASSERT(at_pos == len); |
| 125 at_pos = i; |
| 126 } |
| 127 } |
| 128 |
| 129 intptr_t suffix_len = at_pos - dot_pos; |
| 130 if (suffix_len <= 1) { |
| 131 // The constructor name is of length 0 or 1. That means that |
| 132 // either this isn't a constructor or that this is an unnamed |
| 133 // constructor. In either case, we're done. |
| 134 return result.raw(); |
| 135 } |
| 136 |
| 137 const String& suffix = |
| 138 String::Handle(isolate, String::SubString(name, dot_pos, suffix_len)); |
| 139 return String::Concat(result, suffix); |
| 140 } |
| 141 |
| 142 |
61 // Return error if isolate is in an inconsistent state. | 143 // Return error if isolate is in an inconsistent state. |
62 // Return NULL when no error condition exists. | 144 // Return NULL when no error condition exists. |
63 // | 145 // |
64 // TODO(turnidge): Make this function return an error handle directly | 146 // TODO(turnidge): Make this function return an error handle directly |
65 // rather than returning an error string. The current behavior can | 147 // rather than returning an error string. The current behavior can |
66 // cause compilation errors to appear to be api errors. | 148 // cause compilation errors to appear to be api errors. |
67 const char* CheckIsolateState(Isolate* isolate, bool generating_snapshot) { | 149 const char* CheckIsolateState(Isolate* isolate, bool generating_snapshot) { |
68 bool success = true; | 150 bool success = true; |
69 if (!ClassFinalizer::AllClassesFinalized()) { | 151 if (!ClassFinalizer::AllClassesFinalized()) { |
70 success = (generating_snapshot) ? | 152 success = (generating_snapshot) ? |
(...skipping 30 matching lines...) Expand all Loading... |
101 ApiLocalScope* scope = state->top_scope(); | 183 ApiLocalScope* scope = state->top_scope(); |
102 ASSERT(scope != NULL); | 184 ASSERT(scope != NULL); |
103 LocalHandles* local_handles = scope->local_handles(); | 185 LocalHandles* local_handles = scope->local_handles(); |
104 ASSERT(local_handles != NULL); | 186 ASSERT(local_handles != NULL); |
105 LocalHandle* ref = local_handles->AllocateHandle(); | 187 LocalHandle* ref = local_handles->AllocateHandle(); |
106 ref->set_raw(raw); | 188 ref->set_raw(raw); |
107 return reinterpret_cast<Dart_Handle>(ref); | 189 return reinterpret_cast<Dart_Handle>(ref); |
108 } | 190 } |
109 | 191 |
110 RawObject* Api::UnwrapHandle(Dart_Handle object) { | 192 RawObject* Api::UnwrapHandle(Dart_Handle object) { |
111 #ifdef DEBUG | 193 #if defined(DEBUG) |
112 Isolate* isolate = Isolate::Current(); | 194 Isolate* isolate = Isolate::Current(); |
113 ASSERT(isolate != NULL); | 195 ASSERT(isolate != NULL); |
114 ApiState* state = isolate->api_state(); | 196 ApiState* state = isolate->api_state(); |
115 ASSERT(state != NULL); | 197 ASSERT(state != NULL); |
116 ASSERT(state->IsValidPrologueWeakPersistentHandle(object) || | 198 ASSERT(state->IsValidPrologueWeakPersistentHandle(object) || |
117 state->IsValidWeakPersistentHandle(object) || | 199 state->IsValidWeakPersistentHandle(object) || |
118 state->IsValidPersistentHandle(object) || | 200 state->IsValidPersistentHandle(object) || |
119 state->IsValidLocalHandle(object)); | 201 state->IsValidLocalHandle(object)); |
120 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 && | 202 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 && |
121 PersistentHandle::raw_offset() == 0 && | 203 PersistentHandle::raw_offset() == 0 && |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 | 650 |
569 DART_EXPORT Dart_Handle Dart_NewWeakReferenceSet(Dart_Handle* keys, | 651 DART_EXPORT Dart_Handle Dart_NewWeakReferenceSet(Dart_Handle* keys, |
570 intptr_t num_keys, | 652 intptr_t num_keys, |
571 Dart_Handle* values, | 653 Dart_Handle* values, |
572 intptr_t num_values) { | 654 intptr_t num_values) { |
573 Isolate* isolate = Isolate::Current(); | 655 Isolate* isolate = Isolate::Current(); |
574 CHECK_ISOLATE(isolate); | 656 CHECK_ISOLATE(isolate); |
575 ApiState* state = isolate->api_state(); | 657 ApiState* state = isolate->api_state(); |
576 ASSERT(state != NULL); | 658 ASSERT(state != NULL); |
577 if (keys == NULL) { | 659 if (keys == NULL) { |
578 return Api::NewError("%s expects argument 'keys' to be non-null.", | 660 RETURN_NULL_ERROR(keys); |
579 CURRENT_FUNC); | |
580 } | 661 } |
581 if (num_keys <= 0) { | 662 if (num_keys <= 0) { |
582 return Api::NewError( | 663 return Api::NewError( |
583 "%s expects argument 'num_keys' to be greater than 0.", | 664 "%s expects argument 'num_keys' to be greater than 0.", |
584 CURRENT_FUNC); | 665 CURRENT_FUNC); |
585 } | 666 } |
586 if (values == NULL) { | 667 if (values == NULL) { |
587 return Api::NewError("%s expects argument 'values' to be non-null.", | 668 RETURN_NULL_ERROR(values); |
588 CURRENT_FUNC); | |
589 } | 669 } |
590 if (num_values <= 0) { | 670 if (num_values <= 0) { |
591 return Api::NewError( | 671 return Api::NewError( |
592 "%s expects argument 'num_values' to be greater than 0.", | 672 "%s expects argument 'num_values' to be greater than 0.", |
593 CURRENT_FUNC); | 673 CURRENT_FUNC); |
594 } | 674 } |
595 | 675 |
596 WeakReference* reference = new WeakReference(keys, num_keys, | 676 WeakReference* reference = new WeakReference(keys, num_keys, |
597 values, num_values); | 677 values, num_values); |
598 state->DelayWeakReference(reference); | 678 state->DelayWeakReference(reference); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 callbacks.Remove(callback); | 743 callbacks.Remove(callback); |
664 return Api::Success(isolate); | 744 return Api::Success(isolate); |
665 } | 745 } |
666 | 746 |
667 | 747 |
668 DART_EXPORT Dart_Handle Dart_HeapProfile(Dart_HeapProfileWriteCallback callback, | 748 DART_EXPORT Dart_Handle Dart_HeapProfile(Dart_HeapProfileWriteCallback callback, |
669 void* stream) { | 749 void* stream) { |
670 Isolate* isolate = Isolate::Current(); | 750 Isolate* isolate = Isolate::Current(); |
671 CHECK_ISOLATE(isolate); | 751 CHECK_ISOLATE(isolate); |
672 if (callback == NULL) { | 752 if (callback == NULL) { |
673 return Api::NewError("%s expects argument 'callback' to be non-null.", | 753 RETURN_NULL_ERROR(callback); |
674 CURRENT_FUNC); | |
675 } | 754 } |
676 isolate->heap()->Profile(callback, stream); | 755 isolate->heap()->Profile(callback, stream); |
677 return Api::Success(isolate); | 756 return Api::Success(isolate); |
678 } | 757 } |
679 | 758 |
680 // --- Initialization and Globals --- | 759 // --- Initialization and Globals --- |
681 | 760 |
682 | 761 |
683 DART_EXPORT bool Dart_Initialize(Dart_IsolateCreateCallback create, | 762 DART_EXPORT bool Dart_Initialize(Dart_IsolateCreateCallback create, |
684 Dart_IsolateInterruptCallback interrupt, | 763 Dart_IsolateInterruptCallback interrupt, |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 return reinterpret_cast<uint8_t*>(new_ptr); | 886 return reinterpret_cast<uint8_t*>(new_ptr); |
808 } | 887 } |
809 | 888 |
810 | 889 |
811 DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t** buffer, | 890 DART_EXPORT Dart_Handle Dart_CreateSnapshot(uint8_t** buffer, |
812 intptr_t* size) { | 891 intptr_t* size) { |
813 Isolate* isolate = Isolate::Current(); | 892 Isolate* isolate = Isolate::Current(); |
814 DARTSCOPE(isolate); | 893 DARTSCOPE(isolate); |
815 TIMERSCOPE(time_creating_snapshot); | 894 TIMERSCOPE(time_creating_snapshot); |
816 if (buffer == NULL) { | 895 if (buffer == NULL) { |
817 return Api::NewError("%s expects argument 'buffer' to be non-null.", | 896 RETURN_NULL_ERROR(buffer); |
818 CURRENT_FUNC); | |
819 } | 897 } |
820 if (size == NULL) { | 898 if (size == NULL) { |
821 return Api::NewError("%s expects argument 'size' to be non-null.", | 899 RETURN_NULL_ERROR(size); |
822 CURRENT_FUNC); | |
823 } | 900 } |
824 const char* msg = CheckIsolateState(isolate, | 901 const char* msg = CheckIsolateState(isolate, |
825 ClassFinalizer::kGeneratingSnapshot); | 902 ClassFinalizer::kGeneratingSnapshot); |
826 if (msg != NULL) { | 903 if (msg != NULL) { |
827 return Api::NewError(msg); | 904 return Api::NewError(msg); |
828 } | 905 } |
829 // Since this is only a snapshot the root library should not be set. | 906 // Since this is only a snapshot the root library should not be set. |
830 isolate->object_store()->set_root_library(Library::Handle(isolate)); | 907 isolate->object_store()->set_root_library(Library::Handle(isolate)); |
831 SnapshotWriter writer(Snapshot::kFull, buffer, ApiReallocate); | 908 SnapshotWriter writer(Snapshot::kFull, buffer, ApiReallocate); |
832 writer.WriteFullSnapshot(); | 909 writer.WriteFullSnapshot(); |
833 *size = writer.BytesWritten(); | 910 *size = writer.BytesWritten(); |
834 return Api::Success(isolate); | 911 return Api::Success(isolate); |
835 } | 912 } |
836 | 913 |
837 | 914 |
838 DART_EXPORT Dart_Handle Dart_CreateScriptSnapshot(uint8_t** buffer, | 915 DART_EXPORT Dart_Handle Dart_CreateScriptSnapshot(uint8_t** buffer, |
839 intptr_t* size) { | 916 intptr_t* size) { |
840 Isolate* isolate = Isolate::Current(); | 917 Isolate* isolate = Isolate::Current(); |
841 DARTSCOPE(isolate); | 918 DARTSCOPE(isolate); |
842 TIMERSCOPE(time_creating_snapshot); | 919 TIMERSCOPE(time_creating_snapshot); |
843 if (buffer == NULL) { | 920 if (buffer == NULL) { |
844 return Api::NewError("%s expects argument 'buffer' to be non-null.", | 921 RETURN_NULL_ERROR(buffer); |
845 CURRENT_FUNC); | |
846 } | 922 } |
847 if (size == NULL) { | 923 if (size == NULL) { |
848 return Api::NewError("%s expects argument 'size' to be non-null.", | 924 RETURN_NULL_ERROR(size); |
849 CURRENT_FUNC); | |
850 } | 925 } |
851 const char* msg = CheckIsolateState(isolate); | 926 const char* msg = CheckIsolateState(isolate); |
852 if (msg != NULL) { | 927 if (msg != NULL) { |
853 return Api::NewError(msg); | 928 return Api::NewError(msg); |
854 } | 929 } |
855 Library& library = | 930 Library& library = |
856 Library::Handle(isolate, isolate->object_store()->root_library()); | 931 Library::Handle(isolate, isolate->object_store()->root_library()); |
857 if (library.IsNull()) { | 932 if (library.IsNull()) { |
858 return | 933 return |
859 Api::NewError("%s expects the isolate to have a script loaded in it.", | 934 Api::NewError("%s expects the isolate to have a script loaded in it.", |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 } | 1558 } |
1484 *len = str_obj.Length(); | 1559 *len = str_obj.Length(); |
1485 return Api::Success(isolate); | 1560 return Api::Success(isolate); |
1486 } | 1561 } |
1487 | 1562 |
1488 | 1563 |
1489 DART_EXPORT Dart_Handle Dart_NewString(const char* str) { | 1564 DART_EXPORT Dart_Handle Dart_NewString(const char* str) { |
1490 Isolate* isolate = Isolate::Current(); | 1565 Isolate* isolate = Isolate::Current(); |
1491 DARTSCOPE(isolate); | 1566 DARTSCOPE(isolate); |
1492 if (str == NULL) { | 1567 if (str == NULL) { |
1493 return Api::NewError("%s expects argument 'str' to be non-null.", | 1568 RETURN_NULL_ERROR(str); |
1494 CURRENT_FUNC); | |
1495 } | 1569 } |
1496 if (!Utf8::IsValid(str)) { | 1570 if (!Utf8::IsValid(str)) { |
1497 return Api::NewError("%s expects argument 'str' to be valid UTF-8.", | 1571 return Api::NewError("%s expects argument 'str' to be valid UTF-8.", |
1498 CURRENT_FUNC); | 1572 CURRENT_FUNC); |
1499 } | 1573 } |
1500 return Api::NewHandle(isolate, String::New(str)); | 1574 return Api::NewHandle(isolate, String::New(str)); |
1501 } | 1575 } |
1502 | 1576 |
1503 | 1577 |
1504 DART_EXPORT Dart_Handle Dart_NewString8(const uint8_t* codepoints, | 1578 DART_EXPORT Dart_Handle Dart_NewString8(const uint8_t* codepoints, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 const String& str = Api::UnwrapStringHandle(isolate, object); | 1611 const String& str = Api::UnwrapStringHandle(isolate, object); |
1538 if (str.IsNull()) { | 1612 if (str.IsNull()) { |
1539 RETURN_TYPE_ERROR(isolate, object, String); | 1613 RETURN_TYPE_ERROR(isolate, object, String); |
1540 } | 1614 } |
1541 if (!str.IsExternal()) { | 1615 if (!str.IsExternal()) { |
1542 return | 1616 return |
1543 Api::NewError("%s expects argument 'object' to be an external String.", | 1617 Api::NewError("%s expects argument 'object' to be an external String.", |
1544 CURRENT_FUNC); | 1618 CURRENT_FUNC); |
1545 } | 1619 } |
1546 if (peer == NULL) { | 1620 if (peer == NULL) { |
1547 return Api::NewError("%s expects argument 'peer' to be non-null.", | 1621 RETURN_NULL_ERROR(peer); |
1548 CURRENT_FUNC); | |
1549 } | 1622 } |
1550 *peer = str.GetPeer(); | 1623 *peer = str.GetPeer(); |
1551 return Api::Success(isolate); | 1624 return Api::Success(isolate); |
1552 } | 1625 } |
1553 | 1626 |
1554 | 1627 |
1555 DART_EXPORT Dart_Handle Dart_NewExternalString8(const uint8_t* codepoints, | 1628 DART_EXPORT Dart_Handle Dart_NewExternalString8(const uint8_t* codepoints, |
1556 intptr_t length, | 1629 intptr_t length, |
1557 void* peer, | 1630 void* peer, |
1558 Dart_PeerFinalizer callback) { | 1631 Dart_PeerFinalizer callback) { |
1559 Isolate* isolate = Isolate::Current(); | 1632 Isolate* isolate = Isolate::Current(); |
1560 DARTSCOPE(isolate); | 1633 DARTSCOPE(isolate); |
1561 if (codepoints == NULL && length != 0) { | 1634 if (codepoints == NULL && length != 0) { |
1562 return Api::NewError("%s expects argument 'codepoints' to be non-null.", | 1635 RETURN_NULL_ERROR(codepoints); |
1563 CURRENT_FUNC); | |
1564 } | 1636 } |
1565 if (length < 0) { | 1637 if (length < 0) { |
1566 return Api::NewError("%s expects argument 'length' to be greater than 0.", | 1638 return Api::NewError("%s expects argument 'length' to be greater than 0.", |
1567 CURRENT_FUNC); | 1639 CURRENT_FUNC); |
1568 } | 1640 } |
1569 return Api::NewHandle( | 1641 return Api::NewHandle( |
1570 isolate, String::NewExternal(codepoints, length, peer, callback)); | 1642 isolate, String::NewExternal(codepoints, length, peer, callback)); |
1571 } | 1643 } |
1572 | 1644 |
1573 | 1645 |
1574 DART_EXPORT Dart_Handle Dart_NewExternalString16(const uint16_t* codepoints, | 1646 DART_EXPORT Dart_Handle Dart_NewExternalString16(const uint16_t* codepoints, |
1575 intptr_t length, | 1647 intptr_t length, |
1576 void* peer, | 1648 void* peer, |
1577 Dart_PeerFinalizer callback) { | 1649 Dart_PeerFinalizer callback) { |
1578 Isolate* isolate = Isolate::Current(); | 1650 Isolate* isolate = Isolate::Current(); |
1579 DARTSCOPE(isolate); | 1651 DARTSCOPE(isolate); |
1580 if (codepoints == NULL && length != 0) { | 1652 if (codepoints == NULL && length != 0) { |
1581 return Api::NewError("%s expects argument 'codepoints' to be non-null.", | 1653 RETURN_NULL_ERROR(codepoints); |
1582 CURRENT_FUNC); | |
1583 } | 1654 } |
1584 if (length < 0) { | 1655 if (length < 0) { |
1585 return Api::NewError("%s expects argument 'length' to be greater than 0.", | 1656 return Api::NewError("%s expects argument 'length' to be greater than 0.", |
1586 CURRENT_FUNC); | 1657 CURRENT_FUNC); |
1587 } | 1658 } |
1588 return Api::NewHandle( | 1659 return Api::NewHandle( |
1589 isolate, String::NewExternal(codepoints, length, peer, callback)); | 1660 isolate, String::NewExternal(codepoints, length, peer, callback)); |
1590 } | 1661 } |
1591 | 1662 |
1592 | 1663 |
1593 DART_EXPORT Dart_Handle Dart_NewExternalString32(const uint32_t* codepoints, | 1664 DART_EXPORT Dart_Handle Dart_NewExternalString32(const uint32_t* codepoints, |
1594 intptr_t length, | 1665 intptr_t length, |
1595 void* peer, | 1666 void* peer, |
1596 Dart_PeerFinalizer callback) { | 1667 Dart_PeerFinalizer callback) { |
1597 Isolate* isolate = Isolate::Current(); | 1668 Isolate* isolate = Isolate::Current(); |
1598 DARTSCOPE(isolate); | 1669 DARTSCOPE(isolate); |
1599 if (codepoints == NULL && length != 0) { | 1670 if (codepoints == NULL && length != 0) { |
1600 return Api::NewError("%s expects argument 'codepoints' to be non-null.", | 1671 RETURN_NULL_ERROR(codepoints); |
1601 CURRENT_FUNC); | |
1602 } | 1672 } |
1603 if (length < 0) { | 1673 if (length < 0) { |
1604 return Api::NewError("%s expects argument 'length' to be greater than 0.", | 1674 return Api::NewError("%s expects argument 'length' to be greater than 0.", |
1605 CURRENT_FUNC); | 1675 CURRENT_FUNC); |
1606 } | 1676 } |
1607 return Api::NewHandle( | 1677 return Api::NewHandle( |
1608 isolate, String::NewExternal(codepoints, length, peer, callback)); | 1678 isolate, String::NewExternal(codepoints, length, peer, callback)); |
1609 } | 1679 } |
1610 | 1680 |
1611 | 1681 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1694 DART_EXPORT Dart_Handle Dart_StringToBytes(Dart_Handle object, | 1764 DART_EXPORT Dart_Handle Dart_StringToBytes(Dart_Handle object, |
1695 const uint8_t** bytes, | 1765 const uint8_t** bytes, |
1696 intptr_t *length) { | 1766 intptr_t *length) { |
1697 Isolate* isolate = Isolate::Current(); | 1767 Isolate* isolate = Isolate::Current(); |
1698 DARTSCOPE(isolate); | 1768 DARTSCOPE(isolate); |
1699 const String& str = Api::UnwrapStringHandle(isolate, object); | 1769 const String& str = Api::UnwrapStringHandle(isolate, object); |
1700 if (str.IsNull()) { | 1770 if (str.IsNull()) { |
1701 RETURN_TYPE_ERROR(isolate, object, String); | 1771 RETURN_TYPE_ERROR(isolate, object, String); |
1702 } | 1772 } |
1703 if (bytes == NULL) { | 1773 if (bytes == NULL) { |
1704 return Api::NewError("%s expects argument 'bytes' to be non-null.", | 1774 RETURN_NULL_ERROR(bytes); |
1705 CURRENT_FUNC); | |
1706 } | 1775 } |
1707 if (length == NULL) { | 1776 if (length == NULL) { |
1708 return Api::NewError("%s expects argument 'length' to be non-null.", | 1777 RETURN_NULL_ERROR(length); |
1709 CURRENT_FUNC); | |
1710 } | 1778 } |
1711 const char* cstring = str.ToCString(); | 1779 const char* cstring = str.ToCString(); |
1712 *length = Utf8::Length(str); | 1780 *length = Utf8::Length(str); |
1713 uint8_t* result = reinterpret_cast<uint8_t*>(Api::Allocate(isolate, *length)); | 1781 uint8_t* result = reinterpret_cast<uint8_t*>(Api::Allocate(isolate, *length)); |
1714 if (result == NULL) { | 1782 if (result == NULL) { |
1715 return Api::NewError("Unable to allocate memory"); | 1783 return Api::NewError("Unable to allocate memory"); |
1716 } | 1784 } |
1717 memmove(result, cstring, *length); | 1785 memmove(result, cstring, *length); |
1718 *bytes = result; | 1786 *bytes = result; |
1719 return Api::Success(isolate); | 1787 return Api::Success(isolate); |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2099 } | 2167 } |
2100 | 2168 |
2101 | 2169 |
2102 DART_EXPORT Dart_Handle Dart_NewExternalByteArray(uint8_t* data, | 2170 DART_EXPORT Dart_Handle Dart_NewExternalByteArray(uint8_t* data, |
2103 intptr_t length, | 2171 intptr_t length, |
2104 void* peer, | 2172 void* peer, |
2105 Dart_PeerFinalizer callback) { | 2173 Dart_PeerFinalizer callback) { |
2106 Isolate* isolate = Isolate::Current(); | 2174 Isolate* isolate = Isolate::Current(); |
2107 DARTSCOPE(isolate); | 2175 DARTSCOPE(isolate); |
2108 if (data == NULL && length != 0) { | 2176 if (data == NULL && length != 0) { |
2109 return Api::NewError("%s expects argument 'data' to be non-null.", | 2177 RETURN_NULL_ERROR(data); |
2110 CURRENT_FUNC); | |
2111 } | 2178 } |
2112 if (length < 0) { | 2179 if (length < 0) { |
2113 return Api::NewError("%s expects argument 'length' to be greater than 0.", | 2180 return Api::NewError("%s expects argument 'length' to be greater than 0.", |
2114 CURRENT_FUNC); | 2181 CURRENT_FUNC); |
2115 } | 2182 } |
2116 return Api::NewHandle( | 2183 return Api::NewHandle( |
2117 isolate, ExternalUint8Array::New(data, length, peer, callback)); | 2184 isolate, ExternalUint8Array::New(data, length, peer, callback)); |
2118 } | 2185 } |
2119 | 2186 |
2120 | 2187 |
2121 DART_EXPORT Dart_Handle Dart_ExternalByteArrayGetPeer(Dart_Handle object, | 2188 DART_EXPORT Dart_Handle Dart_ExternalByteArrayGetPeer(Dart_Handle object, |
2122 void** peer) { | 2189 void** peer) { |
2123 Isolate* isolate = Isolate::Current(); | 2190 Isolate* isolate = Isolate::Current(); |
2124 DARTSCOPE(isolate); | 2191 DARTSCOPE(isolate); |
2125 const ExternalUint8Array& array = | 2192 const ExternalUint8Array& array = |
2126 Api::UnwrapExternalUint8ArrayHandle(isolate, object); | 2193 Api::UnwrapExternalUint8ArrayHandle(isolate, object); |
2127 if (array.IsNull()) { | 2194 if (array.IsNull()) { |
2128 RETURN_TYPE_ERROR(isolate, object, ExternalUint8Array); | 2195 RETURN_TYPE_ERROR(isolate, object, ExternalUint8Array); |
2129 } | 2196 } |
2130 if (peer == NULL) { | 2197 if (peer == NULL) { |
2131 return Api::NewError("%s expects argument 'peer' to be non-null.", | 2198 RETURN_NULL_ERROR(peer); |
2132 CURRENT_FUNC); | |
2133 } | 2199 } |
2134 *peer = array.GetPeer(); | 2200 *peer = array.GetPeer(); |
2135 return Api::Success(isolate); | 2201 return Api::Success(isolate); |
2136 } | 2202 } |
2137 | 2203 |
2138 | 2204 |
2139 template<typename T> | 2205 template<typename T> |
2140 Dart_Handle ByteArrayGetAt(T* value, Dart_Handle array, intptr_t offset) { | 2206 Dart_Handle ByteArrayGetAt(T* value, Dart_Handle array, intptr_t offset) { |
2141 Isolate* isolate = Isolate::Current(); | 2207 Isolate* isolate = Isolate::Current(); |
2142 CHECK_ISOLATE(isolate); | 2208 CHECK_ISOLATE(isolate); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2400 | 2466 |
2401 | 2467 |
2402 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) { | 2468 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) { |
2403 Isolate* isolate = Isolate::Current(); | 2469 Isolate* isolate = Isolate::Current(); |
2404 DARTSCOPE(isolate); | 2470 DARTSCOPE(isolate); |
2405 const Class& cls = Class::Handle( | 2471 const Class& cls = Class::Handle( |
2406 isolate, Api::UnwrapClassHandle(isolate, clazz).raw()); | 2472 isolate, Api::UnwrapClassHandle(isolate, clazz).raw()); |
2407 if (cls.IsNull()) { | 2473 if (cls.IsNull()) { |
2408 RETURN_TYPE_ERROR(isolate, clazz, Class); | 2474 RETURN_TYPE_ERROR(isolate, clazz, Class); |
2409 } | 2475 } |
2410 return Api::NewHandle(isolate, cls.Name()); | 2476 const String& cls_name = String::Handle(isolate, cls.Name()); |
| 2477 return Api::NewHandle(isolate, IdentifierPrettyName(isolate, cls_name)); |
2411 } | 2478 } |
2412 | 2479 |
2413 | 2480 |
2414 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) { | 2481 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) { |
2415 Isolate* isolate = Isolate::Current(); | 2482 Isolate* isolate = Isolate::Current(); |
2416 DARTSCOPE(isolate); | 2483 DARTSCOPE(isolate); |
2417 const Class& cls = Class::Handle( | 2484 const Class& cls = Class::Handle( |
2418 isolate, Api::UnwrapClassHandle(isolate, clazz).raw()); | 2485 isolate, Api::UnwrapClassHandle(isolate, clazz).raw()); |
2419 if (cls.IsNull()) { | 2486 if (cls.IsNull()) { |
2420 RETURN_TYPE_ERROR(isolate, clazz, Class); | 2487 RETURN_TYPE_ERROR(isolate, clazz, Class); |
2421 } | 2488 } |
| 2489 |
| 2490 #if defined(DEBUG) |
| 2491 const Library& lib = Library::Handle(cls.library()); |
| 2492 if (lib.IsNull()) { |
| 2493 ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); |
| 2494 } |
| 2495 #endif |
| 2496 |
2422 return Api::NewHandle(isolate, cls.library()); | 2497 return Api::NewHandle(isolate, cls.library()); |
2423 } | 2498 } |
2424 | 2499 |
2425 | 2500 |
2426 DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz) { | 2501 DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz) { |
2427 Isolate* isolate = Isolate::Current(); | 2502 Isolate* isolate = Isolate::Current(); |
2428 DARTSCOPE(isolate); | 2503 DARTSCOPE(isolate); |
2429 const Class& cls = Class::Handle( | 2504 const Class& cls = Class::Handle( |
2430 isolate, Api::UnwrapClassHandle(isolate, clazz).raw()); | 2505 isolate, Api::UnwrapClassHandle(isolate, clazz).raw()); |
2431 if (cls.IsNull()) { | 2506 if (cls.IsNull()) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2490 if (interface_type.HasResolvedTypeClass()) { | 2565 if (interface_type.HasResolvedTypeClass()) { |
2491 return Api::NewHandle(isolate, interface_type.type_class()); | 2566 return Api::NewHandle(isolate, interface_type.type_class()); |
2492 } | 2567 } |
2493 const String& type_name = | 2568 const String& type_name = |
2494 String::Handle(isolate, interface_type.TypeClassName()); | 2569 String::Handle(isolate, interface_type.TypeClassName()); |
2495 return Api::NewError("%s: internal error: found unresolved type class '%s'.", | 2570 return Api::NewError("%s: internal error: found unresolved type class '%s'.", |
2496 CURRENT_FUNC, type_name.ToCString()); | 2571 CURRENT_FUNC, type_name.ToCString()); |
2497 } | 2572 } |
2498 | 2573 |
2499 | 2574 |
| 2575 // --- Function and Variable Reflection --- |
| 2576 |
| 2577 |
| 2578 // Outside of the vm, we expose setter names with a trailing '='. |
| 2579 static bool HasExternalSetterSuffix(const String& name) { |
| 2580 return name.CharAt(name.Length() - 1) == '='; |
| 2581 } |
| 2582 |
| 2583 |
| 2584 static RawString* AddExternalSetterSuffix(const String& name) { |
| 2585 const String& equals = String::Handle(String::NewSymbol("=")); |
| 2586 return String::Concat(name, equals); |
| 2587 } |
| 2588 |
| 2589 |
| 2590 static RawString* RemoveExternalSetterSuffix(const String& name) { |
| 2591 ASSERT(HasExternalSetterSuffix(name)); |
| 2592 return String::SubString(name, 0, name.Length() - 1); |
| 2593 } |
| 2594 |
| 2595 |
| 2596 DART_EXPORT Dart_Handle Dart_GetFunctionNames(Dart_Handle target) { |
| 2597 Isolate* isolate = Isolate::Current(); |
| 2598 DARTSCOPE(isolate); |
| 2599 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
| 2600 if (obj.IsError()) { |
| 2601 return target; |
| 2602 } |
| 2603 |
| 2604 const GrowableObjectArray& names = |
| 2605 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
| 2606 Function& func = Function::Handle(); |
| 2607 String& name = String::Handle(); |
| 2608 |
| 2609 if (obj.IsClass()) { |
| 2610 const Class& cls = Class::Cast(obj); |
| 2611 const Array& func_array = Array::Handle(cls.functions()); |
| 2612 |
| 2613 // Some special types like 'Dynamic' have a null functions list. |
| 2614 if (!func_array.IsNull()) { |
| 2615 for (intptr_t i = 0; i < func_array.Length(); ++i) { |
| 2616 func ^= func_array.At(i); |
| 2617 |
| 2618 // Skip implicit getters and setters. |
| 2619 if (func.kind() == RawFunction::kImplicitGetter || |
| 2620 func.kind() == RawFunction::kImplicitSetter || |
| 2621 func.kind() == RawFunction::kConstImplicitGetter) { |
| 2622 continue; |
| 2623 } |
| 2624 |
| 2625 name = func.name(); |
| 2626 bool is_setter = Field::IsSetterName(name); |
| 2627 name = IdentifierPrettyName(isolate, name); |
| 2628 |
| 2629 if (is_setter) { |
| 2630 name = AddExternalSetterSuffix(name); |
| 2631 } |
| 2632 names.Add(name); |
| 2633 } |
| 2634 } |
| 2635 } else if (obj.IsLibrary()) { |
| 2636 const Library& lib = Library::Cast(obj); |
| 2637 DictionaryIterator it(lib); |
| 2638 Object& obj = Object::Handle(); |
| 2639 while (it.HasNext()) { |
| 2640 obj = it.GetNext(); |
| 2641 if (obj.IsFunction()) { |
| 2642 func ^= obj.raw(); |
| 2643 name = func.name(); |
| 2644 bool is_setter = Field::IsSetterName(name); |
| 2645 name = IdentifierPrettyName(isolate, name); |
| 2646 if (is_setter) { |
| 2647 name = AddExternalSetterSuffix(name); |
| 2648 } |
| 2649 names.Add(name); |
| 2650 } |
| 2651 } |
| 2652 } else { |
| 2653 return Api::NewError( |
| 2654 "%s expects argument 'target' to be a class or library.", |
| 2655 CURRENT_FUNC); |
| 2656 } |
| 2657 return Api::NewHandle(isolate, Array::MakeArray(names)); |
| 2658 } |
| 2659 |
| 2660 |
| 2661 DART_EXPORT Dart_Handle Dart_LookupFunction(Dart_Handle target, |
| 2662 Dart_Handle function_name) { |
| 2663 Isolate* isolate = Isolate::Current(); |
| 2664 DARTSCOPE(isolate); |
| 2665 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
| 2666 if (obj.IsError()) { |
| 2667 return target; |
| 2668 } |
| 2669 const String& func_name = Api::UnwrapStringHandle(isolate, function_name); |
| 2670 if (func_name.IsNull()) { |
| 2671 RETURN_TYPE_ERROR(isolate, function_name, String); |
| 2672 } |
| 2673 |
| 2674 Function& func = Function::Handle(isolate); |
| 2675 String& tmp_name = String::Handle(isolate); |
| 2676 if (obj.IsClass()) { |
| 2677 const Class& cls = Class::Cast(obj); |
| 2678 |
| 2679 // Case 1. Lookup the unmodified function name. |
| 2680 func = cls.LookupFunction(func_name); |
| 2681 |
| 2682 // Case 2. Lookup the function without the external setter suffix |
| 2683 // '='. Make sure to do this check after the regular lookup, so |
| 2684 // that we don't interfere with operator lookups (like ==). |
| 2685 if (func.IsNull() && HasExternalSetterSuffix(func_name)) { |
| 2686 tmp_name = RemoveExternalSetterSuffix(func_name); |
| 2687 tmp_name = Field::SetterName(tmp_name); |
| 2688 func = cls.LookupFunction(tmp_name); |
| 2689 } |
| 2690 |
| 2691 // Case 3. Lookup the funciton with the getter prefix prepended. |
| 2692 if (func.IsNull()) { |
| 2693 tmp_name = Field::GetterName(func_name); |
| 2694 func = cls.LookupFunction(tmp_name); |
| 2695 } |
| 2696 |
| 2697 // Case 4. Lookup the function with a . appended to find the |
| 2698 // unnamed constructor. |
| 2699 if (func.IsNull()) { |
| 2700 const String& dot = String::Handle(String::NewSymbol(".")); |
| 2701 tmp_name = String::Concat(func_name, dot); |
| 2702 func = cls.LookupFunction(tmp_name); |
| 2703 } |
| 2704 } else if (obj.IsLibrary()) { |
| 2705 const Library& lib = Library::Cast(obj); |
| 2706 |
| 2707 // Case 1. Lookup the unmodified function name. |
| 2708 func = lib.LookupFunctionAllowPrivate(func_name); |
| 2709 |
| 2710 // Case 2. Lookup the function without the external setter suffix |
| 2711 // '='. Make sure to do this check after the regular lookup, so |
| 2712 // that we don't interfere with operator lookups (like ==). |
| 2713 if (func.IsNull() && HasExternalSetterSuffix(func_name)) { |
| 2714 tmp_name = RemoveExternalSetterSuffix(func_name); |
| 2715 tmp_name = Field::SetterName(tmp_name); |
| 2716 func = lib.LookupFunctionAllowPrivate(tmp_name); |
| 2717 } |
| 2718 |
| 2719 // Case 3. Lookup the funciton with the getter prefix prepended. |
| 2720 if (func.IsNull()) { |
| 2721 tmp_name = Field::GetterName(func_name); |
| 2722 func = lib.LookupFunctionAllowPrivate(tmp_name); |
| 2723 } |
| 2724 } else { |
| 2725 return Api::NewError( |
| 2726 "%s expects argument 'target' to be a class or library.", |
| 2727 CURRENT_FUNC); |
| 2728 } |
| 2729 |
| 2730 #if defined(DEBUG) |
| 2731 if (!func.IsNull()) { |
| 2732 // We only provide access to a subset of function kinds. |
| 2733 RawFunction::Kind func_kind = func.kind(); |
| 2734 ASSERT(func_kind == RawFunction::kFunction || |
| 2735 func_kind == RawFunction::kGetterFunction || |
| 2736 func_kind == RawFunction::kSetterFunction || |
| 2737 func_kind == RawFunction::kConstructor || |
| 2738 func_kind == RawFunction::kAbstract); |
| 2739 } |
| 2740 #endif |
| 2741 return Api::NewHandle(isolate, func.raw()); |
| 2742 } |
| 2743 |
| 2744 |
| 2745 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { |
| 2746 return Api::ClassId(handle) == kFunction; |
| 2747 } |
| 2748 |
| 2749 |
| 2750 DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) { |
| 2751 Isolate* isolate = Isolate::Current(); |
| 2752 DARTSCOPE(isolate); |
| 2753 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 2754 if (func.IsNull()) { |
| 2755 RETURN_TYPE_ERROR(isolate, function, Function); |
| 2756 } |
| 2757 String& func_name = String::Handle(isolate); |
| 2758 func_name = func.name(); |
| 2759 bool is_setter = Field::IsSetterName(func_name); |
| 2760 func_name = IdentifierPrettyName(isolate, func_name); |
| 2761 if (is_setter) { |
| 2762 func_name = AddExternalSetterSuffix(func_name); |
| 2763 } |
| 2764 return Api::NewHandle(isolate, func_name.raw()); |
| 2765 } |
| 2766 |
| 2767 |
| 2768 DART_EXPORT Dart_Handle Dart_FunctionIsAbstract(Dart_Handle function, |
| 2769 bool* is_abstract) { |
| 2770 Isolate* isolate = Isolate::Current(); |
| 2771 DARTSCOPE(isolate); |
| 2772 if (is_abstract == NULL) { |
| 2773 RETURN_NULL_ERROR(is_abstract); |
| 2774 } |
| 2775 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 2776 if (func.IsNull()) { |
| 2777 RETURN_TYPE_ERROR(isolate, function, Function); |
| 2778 } |
| 2779 *is_abstract = (func.kind() == RawFunction::kAbstract); |
| 2780 return Api::Success(isolate); |
| 2781 } |
| 2782 |
| 2783 |
| 2784 DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, |
| 2785 bool* is_static) { |
| 2786 Isolate* isolate = Isolate::Current(); |
| 2787 DARTSCOPE(isolate); |
| 2788 if (is_static == NULL) { |
| 2789 RETURN_NULL_ERROR(is_static); |
| 2790 } |
| 2791 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 2792 if (func.IsNull()) { |
| 2793 RETURN_TYPE_ERROR(isolate, function, Function); |
| 2794 } |
| 2795 *is_static = func.is_static(); |
| 2796 return Api::Success(isolate); |
| 2797 } |
| 2798 |
| 2799 |
| 2800 DART_EXPORT Dart_Handle Dart_FunctionIsConstructor(Dart_Handle function, |
| 2801 bool* is_constructor) { |
| 2802 Isolate* isolate = Isolate::Current(); |
| 2803 DARTSCOPE(isolate); |
| 2804 if (is_constructor == NULL) { |
| 2805 RETURN_NULL_ERROR(is_constructor); |
| 2806 } |
| 2807 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 2808 if (func.IsNull()) { |
| 2809 RETURN_TYPE_ERROR(isolate, function, Function); |
| 2810 } |
| 2811 *is_constructor = func.kind() == RawFunction::kConstructor; |
| 2812 return Api::Success(isolate); |
| 2813 } |
| 2814 |
| 2815 |
| 2816 DART_EXPORT Dart_Handle Dart_FunctionIsGetter(Dart_Handle function, |
| 2817 bool* is_getter) { |
| 2818 Isolate* isolate = Isolate::Current(); |
| 2819 DARTSCOPE(isolate); |
| 2820 if (is_getter == NULL) { |
| 2821 RETURN_NULL_ERROR(is_getter); |
| 2822 } |
| 2823 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 2824 if (func.IsNull()) { |
| 2825 RETURN_TYPE_ERROR(isolate, function, Function); |
| 2826 } |
| 2827 // TODO(turnidge): It would be nice if I could just use func.kind() |
| 2828 // to check for a getter function here, but unfortunately the only |
| 2829 // way to distinguish abstract getter functions is to use the name |
| 2830 // itself. Consider adding a RawFunction::kAbstractGetter type. |
| 2831 const String& func_name = String::Handle(isolate, func.name()); |
| 2832 *is_getter = Field::IsGetterName(func_name); |
| 2833 |
| 2834 return Api::Success(isolate); |
| 2835 } |
| 2836 |
| 2837 |
| 2838 DART_EXPORT Dart_Handle Dart_FunctionIsSetter(Dart_Handle function, |
| 2839 bool* is_setter) { |
| 2840 Isolate* isolate = Isolate::Current(); |
| 2841 DARTSCOPE(isolate); |
| 2842 if (is_setter == NULL) { |
| 2843 RETURN_NULL_ERROR(is_setter); |
| 2844 } |
| 2845 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 2846 if (func.IsNull()) { |
| 2847 RETURN_TYPE_ERROR(isolate, function, Function); |
| 2848 } |
| 2849 // TODO(turnidge): It would be nice if I could just use func.kind() |
| 2850 // to check for a setter function here, but unfortunately the only |
| 2851 // way to distinguish abstract setter functions is to use the name |
| 2852 // itself. Consider adding a RawFunction::kAbstractSetter type. |
| 2853 const String& func_name = String::Handle(isolate, func.name()); |
| 2854 *is_setter = Field::IsSetterName(func_name); |
| 2855 |
| 2856 return Api::Success(isolate); |
| 2857 } |
| 2858 |
| 2859 |
| 2860 DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) { |
| 2861 Isolate* isolate = Isolate::Current(); |
| 2862 DARTSCOPE(isolate); |
| 2863 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
| 2864 if (obj.IsError()) { |
| 2865 return target; |
| 2866 } |
| 2867 |
| 2868 const GrowableObjectArray& names = |
| 2869 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
| 2870 Field& field = Field::Handle(isolate); |
| 2871 String& name = String::Handle(isolate); |
| 2872 |
| 2873 if (obj.IsClass()) { |
| 2874 const Class& cls = Class::Cast(obj); |
| 2875 const Array& field_array = Array::Handle(cls.fields()); |
| 2876 |
| 2877 // Some special types like 'Dynamic' have a null fields list. |
| 2878 // |
| 2879 // TODO(turnidge): Fix 'Dynamic' so that it does not have a null |
| 2880 // fields list. This will have to wait until the empty array is |
| 2881 // allocated in the vm isolate. |
| 2882 if (!field_array.IsNull()) { |
| 2883 for (intptr_t i = 0; i < field_array.Length(); ++i) { |
| 2884 field ^= field_array.At(i); |
| 2885 name = field.name(); |
| 2886 name = IdentifierPrettyName(isolate, name); |
| 2887 names.Add(name); |
| 2888 } |
| 2889 } |
| 2890 } else if (obj.IsLibrary()) { |
| 2891 const Library& lib = Library::Cast(obj); |
| 2892 DictionaryIterator it(lib); |
| 2893 Object& obj = Object::Handle(isolate); |
| 2894 while (it.HasNext()) { |
| 2895 obj = it.GetNext(); |
| 2896 if (obj.IsField()) { |
| 2897 field ^= obj.raw(); |
| 2898 name = field.name(); |
| 2899 name = IdentifierPrettyName(isolate, name); |
| 2900 names.Add(name); |
| 2901 } |
| 2902 } |
| 2903 } else { |
| 2904 return Api::NewError( |
| 2905 "%s expects argument 'target' to be a class or library.", |
| 2906 CURRENT_FUNC); |
| 2907 } |
| 2908 return Api::NewHandle(isolate, Array::MakeArray(names)); |
| 2909 } |
| 2910 |
| 2911 |
| 2912 DART_EXPORT Dart_Handle Dart_LookupVariable(Dart_Handle target, |
| 2913 Dart_Handle variable_name) { |
| 2914 Isolate* isolate = Isolate::Current(); |
| 2915 DARTSCOPE(isolate); |
| 2916 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
| 2917 if (obj.IsError()) { |
| 2918 return target; |
| 2919 } |
| 2920 const String& var_name = Api::UnwrapStringHandle(isolate, variable_name); |
| 2921 if (var_name.IsNull()) { |
| 2922 RETURN_TYPE_ERROR(isolate, variable_name, String); |
| 2923 } |
| 2924 if (obj.IsClass()) { |
| 2925 const Class& cls = Class::Cast(obj); |
| 2926 return Api::NewHandle(isolate, cls.LookupField(var_name)); |
| 2927 } |
| 2928 if (obj.IsLibrary()) { |
| 2929 const Library& lib = Library::Cast(obj); |
| 2930 return Api::NewHandle(isolate, lib.LookupFieldAllowPrivate(var_name)); |
| 2931 } |
| 2932 return Api::NewError( |
| 2933 "%s expects argument 'target' to be a class or library.", |
| 2934 CURRENT_FUNC); |
| 2935 } |
| 2936 |
| 2937 |
| 2938 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { |
| 2939 return Api::ClassId(handle) == kField; |
| 2940 } |
| 2941 |
| 2942 |
| 2943 DART_EXPORT Dart_Handle Dart_VariableName(Dart_Handle variable) { |
| 2944 Isolate* isolate = Isolate::Current(); |
| 2945 DARTSCOPE(isolate); |
| 2946 const Field& var = Api::UnwrapFieldHandle(isolate, variable); |
| 2947 if (var.IsNull()) { |
| 2948 RETURN_TYPE_ERROR(isolate, variable, Field); |
| 2949 } |
| 2950 const String& var_name = String::Handle(var.name()); |
| 2951 return Api::NewHandle(isolate, IdentifierPrettyName(isolate, var_name)); |
| 2952 } |
| 2953 |
| 2954 |
| 2955 DART_EXPORT Dart_Handle Dart_VariableIsStatic(Dart_Handle variable, |
| 2956 bool* is_static) { |
| 2957 Isolate* isolate = Isolate::Current(); |
| 2958 DARTSCOPE(isolate); |
| 2959 if (is_static == NULL) { |
| 2960 RETURN_NULL_ERROR(is_static); |
| 2961 } |
| 2962 const Field& var = Api::UnwrapFieldHandle(isolate, variable); |
| 2963 if (var.IsNull()) { |
| 2964 RETURN_TYPE_ERROR(isolate, variable, Field); |
| 2965 } |
| 2966 *is_static = var.is_static(); |
| 2967 return Api::Success(isolate); |
| 2968 } |
| 2969 |
| 2970 |
| 2971 DART_EXPORT Dart_Handle Dart_VariableIsFinal(Dart_Handle variable, |
| 2972 bool* is_final) { |
| 2973 Isolate* isolate = Isolate::Current(); |
| 2974 DARTSCOPE(isolate); |
| 2975 if (is_final == NULL) { |
| 2976 RETURN_NULL_ERROR(is_final); |
| 2977 } |
| 2978 const Field& var = Api::UnwrapFieldHandle(isolate, variable); |
| 2979 if (var.IsNull()) { |
| 2980 RETURN_TYPE_ERROR(isolate, variable, Field); |
| 2981 } |
| 2982 *is_final = var.is_final(); |
| 2983 return Api::Success(isolate); |
| 2984 } |
| 2985 |
2500 // --- Constructors, Methods, and Fields --- | 2986 // --- Constructors, Methods, and Fields --- |
2501 | 2987 |
2502 | 2988 |
2503 static RawObject* ResolveConstructor(const char* current_func, | 2989 static RawObject* ResolveConstructor(const char* current_func, |
2504 const Class& cls, | 2990 const Class& cls, |
2505 const String& class_name, | 2991 const String& class_name, |
2506 const String& dotted_name, | 2992 const String& dotted_name, |
2507 int num_args) { | 2993 int num_args) { |
2508 // The constructor must be present in the interface. | 2994 // The constructor must be present in the interface. |
2509 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); | 2995 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); |
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3326 &result); | 3812 &result); |
3327 return result; | 3813 return result; |
3328 } | 3814 } |
3329 | 3815 |
3330 | 3816 |
3331 DART_EXPORT Dart_Handle Dart_LoadScriptFromSnapshot(const uint8_t* buffer) { | 3817 DART_EXPORT Dart_Handle Dart_LoadScriptFromSnapshot(const uint8_t* buffer) { |
3332 Isolate* isolate = Isolate::Current(); | 3818 Isolate* isolate = Isolate::Current(); |
3333 DARTSCOPE(isolate); | 3819 DARTSCOPE(isolate); |
3334 TIMERSCOPE(time_script_loading); | 3820 TIMERSCOPE(time_script_loading); |
3335 if (buffer == NULL) { | 3821 if (buffer == NULL) { |
3336 return Api::NewError("%s expects argument 'buffer' to be non-null.", | 3822 RETURN_NULL_ERROR(buffer); |
3337 CURRENT_FUNC); | |
3338 } | 3823 } |
3339 const Snapshot* snapshot = Snapshot::SetupFromBuffer(buffer); | 3824 const Snapshot* snapshot = Snapshot::SetupFromBuffer(buffer); |
3340 if (!snapshot->IsScriptSnapshot()) { | 3825 if (!snapshot->IsScriptSnapshot()) { |
3341 return Api::NewError("%s expects parameter 'buffer' to be a script type" | 3826 return Api::NewError("%s expects parameter 'buffer' to be a script type" |
3342 " snapshot", CURRENT_FUNC); | 3827 " snapshot", CURRENT_FUNC); |
3343 } | 3828 } |
3344 Library& library = | 3829 Library& library = |
3345 Library::Handle(isolate, isolate->object_store()->root_library()); | 3830 Library::Handle(isolate, isolate->object_store()->root_library()); |
3346 if (!library.IsNull()) { | 3831 if (!library.IsNull()) { |
3347 const String& library_url = String::Handle(isolate, library.url()); | 3832 const String& library_url = String::Handle(isolate, library.url()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3457 RETURN_TYPE_ERROR(isolate, library, Library); | 3942 RETURN_TYPE_ERROR(isolate, library, Library); |
3458 } | 3943 } |
3459 | 3944 |
3460 const GrowableObjectArray& names = | 3945 const GrowableObjectArray& names = |
3461 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | 3946 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
3462 ClassDictionaryIterator it(lib); | 3947 ClassDictionaryIterator it(lib); |
3463 Class& cls = Class::Handle(); | 3948 Class& cls = Class::Handle(); |
3464 String& name = String::Handle(); | 3949 String& name = String::Handle(); |
3465 while (it.HasNext()) { | 3950 while (it.HasNext()) { |
3466 cls = it.GetNextClass(); | 3951 cls = it.GetNextClass(); |
3467 name = cls.Name(); | 3952 // For now we suppress the signature classes of closures. |
3468 names.Add(name); | 3953 // |
| 3954 // TODO(turnidge): Add this to the unit test. |
| 3955 const Function& signature_func = Function::Handle(cls.signature_function()); |
| 3956 if (signature_func.IsNull()) { |
| 3957 name = cls.Name(); |
| 3958 name = IdentifierPrettyName(isolate, name); |
| 3959 names.Add(name); |
| 3960 } |
3469 } | 3961 } |
3470 return Api::NewHandle(isolate, Array::MakeArray(names)); | 3962 return Api::NewHandle(isolate, Array::MakeArray(names)); |
3471 } | 3963 } |
3472 | 3964 |
3473 | 3965 |
3474 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { | 3966 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { |
3475 Isolate* isolate = Isolate::Current(); | 3967 Isolate* isolate = Isolate::Current(); |
3476 DARTSCOPE(isolate); | 3968 DARTSCOPE(isolate); |
3477 const String& url_str = Api::UnwrapStringHandle(isolate, url); | 3969 const String& url_str = Api::UnwrapStringHandle(isolate, url); |
3478 if (url_str.IsNull()) { | 3970 if (url_str.IsNull()) { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3621 *buffer_size = 0; | 4113 *buffer_size = 0; |
3622 } | 4114 } |
3623 } | 4115 } |
3624 | 4116 |
3625 | 4117 |
3626 DART_EXPORT void Dart_InitFlowGraphPrinting(FileWriterFunction function) { | 4118 DART_EXPORT void Dart_InitFlowGraphPrinting(FileWriterFunction function) { |
3627 Dart::set_flow_graph_writer(function); | 4119 Dart::set_flow_graph_writer(function); |
3628 } | 4120 } |
3629 | 4121 |
3630 } // namespace dart | 4122 } // namespace dart |
OLD | NEW |