| 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 |