OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "include/dart_mirrors_api.h" |
| 7 #include "include/dart_native_api.h" |
6 | 8 |
7 #include "platform/assert.h" | 9 #include "platform/assert.h" |
8 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
9 #include "vm/class_finalizer.h" | 11 #include "vm/class_finalizer.h" |
10 #include "vm/compiler.h" | 12 #include "vm/compiler.h" |
11 #include "vm/dart.h" | 13 #include "vm/dart.h" |
12 #include "vm/dart_api_impl.h" | 14 #include "vm/dart_api_impl.h" |
13 #include "vm/dart_api_message.h" | 15 #include "vm/dart_api_message.h" |
14 #include "vm/dart_api_state.h" | 16 #include "vm/dart_api_state.h" |
15 #include "vm/dart_entry.h" | 17 #include "vm/dart_entry.h" |
16 #include "vm/debuginfo.h" | 18 #include "vm/debuginfo.h" |
17 #include "vm/exceptions.h" | 19 #include "vm/exceptions.h" |
18 #include "vm/flags.h" | 20 #include "vm/flags.h" |
19 #include "vm/growable_array.h" | 21 #include "vm/growable_array.h" |
20 #include "vm/message.h" | 22 #include "vm/message.h" |
| 23 #include "vm/message_handler.h" |
21 #include "vm/native_entry.h" | 24 #include "vm/native_entry.h" |
22 #include "vm/native_message_handler.h" | |
23 #include "vm/object.h" | 25 #include "vm/object.h" |
24 #include "vm/object_store.h" | 26 #include "vm/object_store.h" |
25 #include "vm/port.h" | 27 #include "vm/port.h" |
26 #include "vm/resolver.h" | 28 #include "vm/resolver.h" |
27 #include "vm/stack_frame.h" | 29 #include "vm/stack_frame.h" |
28 #include "vm/symbols.h" | 30 #include "vm/symbols.h" |
29 #include "vm/timer.h" | 31 #include "vm/timer.h" |
30 #include "vm/unicode.h" | 32 #include "vm/unicode.h" |
31 #include "vm/verifier.h" | 33 #include "vm/verifier.h" |
32 #include "vm/version.h" | 34 #include "vm/version.h" |
(...skipping 11 matching lines...) Expand all Loading... |
44 | 46 |
45 const char* CanonicalFunction(const char* func) { | 47 const char* CanonicalFunction(const char* func) { |
46 if (strncmp(func, "dart::", 6) == 0) { | 48 if (strncmp(func, "dart::", 6) == 0) { |
47 return func + 6; | 49 return func + 6; |
48 } else { | 50 } else { |
49 return func; | 51 return func; |
50 } | 52 } |
51 } | 53 } |
52 | 54 |
53 | 55 |
54 #define RETURN_TYPE_ERROR(isolate, dart_handle, type) \ | 56 static RawInstance* GetListInstance(Isolate* isolate, const Object& obj) { |
55 do { \ | 57 if (obj.IsInstance()) { |
56 const Object& tmp = \ | 58 const Instance& instance = Instance::Cast(obj); |
57 Object::Handle(isolate, Api::UnwrapHandle((dart_handle))); \ | 59 const Class& obj_class = Class::Handle(isolate, obj.clazz()); |
58 if (tmp.IsNull()) { \ | 60 const Class& list_class = |
59 return Api::NewError("%s expects argument '%s' to be non-null.", \ | 61 Class::Handle(isolate, isolate->object_store()->list_class()); |
60 CURRENT_FUNC, #dart_handle); \ | 62 Error& malformed_type_error = Error::Handle(isolate); |
61 } else if (tmp.IsError()) { \ | 63 if (obj_class.IsSubtypeOf(TypeArguments::Handle(isolate), |
62 return dart_handle; \ | 64 list_class, |
63 } else { \ | 65 TypeArguments::Handle(isolate), |
64 return Api::NewError("%s expects argument '%s' to be of type %s.", \ | 66 &malformed_type_error)) { |
65 CURRENT_FUNC, #dart_handle, #type); \ | 67 ASSERT(malformed_type_error.IsNull()); // Type is a raw List. |
66 } \ | 68 return instance.raw(); |
67 } while (0) | 69 } |
68 | 70 } |
69 | 71 return Instance::null(); |
70 #define RETURN_NULL_ERROR(parameter) \ | 72 } |
71 return Api::NewError("%s expects argument '%s' to be non-null.", \ | |
72 CURRENT_FUNC, #parameter); | |
73 | |
74 | |
75 #define CHECK_LENGTH(length, max_elements) \ | |
76 do { \ | |
77 intptr_t len = (length); \ | |
78 intptr_t max = (max_elements); \ | |
79 if (len < 0 || len > max) { \ | |
80 return Api::NewError( \ | |
81 "%s expects argument '%s' to be in the range [0..%"Pd"].", \ | |
82 CURRENT_FUNC, #length, max); \ | |
83 } \ | |
84 } while (0) | |
85 | 73 |
86 | 74 |
87 Dart_Handle Api::NewHandle(Isolate* isolate, RawObject* raw) { | 75 Dart_Handle Api::NewHandle(Isolate* isolate, RawObject* raw) { |
88 LocalHandles* local_handles = Api::TopScope(isolate)->local_handles(); | 76 LocalHandles* local_handles = Api::TopScope(isolate)->local_handles(); |
89 ASSERT(local_handles != NULL); | 77 ASSERT(local_handles != NULL); |
90 LocalHandle* ref = local_handles->AllocateHandle(); | 78 LocalHandle* ref = local_handles->AllocateHandle(); |
91 ref->set_raw(raw); | 79 ref->set_raw(raw); |
92 return reinterpret_cast<Dart_Handle>(ref); | 80 return reinterpret_cast<Dart_Handle>(ref); |
93 } | 81 } |
94 | 82 |
| 83 |
95 RawObject* Api::UnwrapHandle(Dart_Handle object) { | 84 RawObject* Api::UnwrapHandle(Dart_Handle object) { |
96 #if defined(DEBUG) | 85 #if defined(DEBUG) |
97 Isolate* isolate = Isolate::Current(); | 86 Isolate* isolate = Isolate::Current(); |
98 ASSERT(isolate != NULL); | 87 ASSERT(isolate != NULL); |
99 ApiState* state = isolate->api_state(); | 88 ApiState* state = isolate->api_state(); |
100 ASSERT(state != NULL); | 89 ASSERT(state != NULL); |
101 ASSERT(!FLAG_verify_handles || | 90 ASSERT(!FLAG_verify_handles || |
102 state->IsValidLocalHandle(object) || | 91 state->IsValidLocalHandle(object) || |
103 Dart::vm_isolate()->api_state()->IsValidLocalHandle(object)); | 92 Dart::vm_isolate()->api_state()->IsValidLocalHandle(object)); |
104 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 && | 93 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 && |
105 PersistentHandle::raw_offset() == 0 && | 94 PersistentHandle::raw_offset() == 0 && |
106 LocalHandle::raw_offset() == 0); | 95 LocalHandle::raw_offset() == 0); |
107 #endif | 96 #endif |
108 return (reinterpret_cast<LocalHandle*>(object))->raw(); | 97 return (reinterpret_cast<LocalHandle*>(object))->raw(); |
109 } | 98 } |
110 | 99 |
| 100 |
111 #define DEFINE_UNWRAP(type) \ | 101 #define DEFINE_UNWRAP(type) \ |
112 const type& Api::Unwrap##type##Handle(Isolate* iso, \ | 102 const type& Api::Unwrap##type##Handle(Isolate* iso, \ |
113 Dart_Handle dart_handle) { \ | 103 Dart_Handle dart_handle) { \ |
114 const Object& obj = Object::Handle(iso, Api::UnwrapHandle(dart_handle)); \ | 104 const Object& obj = Object::Handle(iso, Api::UnwrapHandle(dart_handle)); \ |
115 if (obj.Is##type()) { \ | 105 if (obj.Is##type()) { \ |
116 return type::Cast(obj); \ | 106 return type::Cast(obj); \ |
117 } \ | 107 } \ |
118 return type::Handle(iso); \ | 108 return type::Handle(iso); \ |
119 } | 109 } |
120 CLASS_LIST_FOR_HANDLES(DEFINE_UNWRAP) | 110 CLASS_LIST_FOR_HANDLES(DEFINE_UNWRAP) |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 reinterpret_cast<RawExternalTwoByteString*>(raw_obj)->ptr(); | 250 reinterpret_cast<RawExternalTwoByteString*>(raw_obj)->ptr(); |
261 ExternalStringData<uint16_t>* data = raw_string->external_data_; | 251 ExternalStringData<uint16_t>* data = raw_string->external_data_; |
262 *peer = data->peer(); | 252 *peer = data->peer(); |
263 return true; | 253 return true; |
264 } | 254 } |
265 } | 255 } |
266 return false; | 256 return false; |
267 } | 257 } |
268 | 258 |
269 | 259 |
270 // When we want to return a handle to a type to the user, we handle | |
271 // class-types differently than some other types. | |
272 static Dart_Handle TypeToHandle(Isolate* isolate, | |
273 const char* function_name, | |
274 const AbstractType& type) { | |
275 if (type.IsMalformed()) { | |
276 const Error& error = Error::Handle(type.malformed_error()); | |
277 return Api::NewError("%s: malformed type encountered: %s.", | |
278 function_name, error.ToErrorCString()); | |
279 } else if (type.HasResolvedTypeClass()) { | |
280 const Class& cls = Class::Handle(isolate, type.type_class()); | |
281 #if defined(DEBUG) | |
282 const Library& lib = Library::Handle(cls.library()); | |
283 if (lib.IsNull()) { | |
284 ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); | |
285 } | |
286 #endif | |
287 return Api::NewHandle(isolate, cls.raw()); | |
288 } else if (type.IsTypeParameter()) { | |
289 return Api::NewHandle(isolate, type.raw()); | |
290 } else { | |
291 return Api::NewError("%s: unexpected type '%s' encountered.", | |
292 function_name, type.ToCString()); | |
293 } | |
294 } | |
295 | |
296 | |
297 // --- Handles --- | 260 // --- Handles --- |
298 | 261 |
299 | |
300 DART_EXPORT bool Dart_IsError(Dart_Handle handle) { | 262 DART_EXPORT bool Dart_IsError(Dart_Handle handle) { |
301 return RawObject::IsErrorClassId(Api::ClassId(handle)); | 263 return RawObject::IsErrorClassId(Api::ClassId(handle)); |
302 } | 264 } |
303 | 265 |
304 | 266 |
305 DART_EXPORT bool Dart_IsApiError(Dart_Handle object) { | 267 DART_EXPORT bool Dart_IsApiError(Dart_Handle object) { |
306 return Api::ClassId(object) == kApiErrorCid; | 268 return Api::ClassId(object) == kApiErrorCid; |
307 } | 269 } |
308 | 270 |
309 | 271 |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 | 629 |
668 WeakReferenceSet* reference_set = new WeakReferenceSet(keys, num_keys, | 630 WeakReferenceSet* reference_set = new WeakReferenceSet(keys, num_keys, |
669 values, num_values); | 631 values, num_values); |
670 state->DelayWeakReferenceSet(reference_set); | 632 state->DelayWeakReferenceSet(reference_set); |
671 return Api::Success(); | 633 return Api::Success(); |
672 } | 634 } |
673 | 635 |
674 | 636 |
675 // --- Garbage Collection Callbacks -- | 637 // --- Garbage Collection Callbacks -- |
676 | 638 |
677 | |
678 DART_EXPORT Dart_Handle Dart_AddGcPrologueCallback( | 639 DART_EXPORT Dart_Handle Dart_AddGcPrologueCallback( |
679 Dart_GcPrologueCallback callback) { | 640 Dart_GcPrologueCallback callback) { |
680 Isolate* isolate = Isolate::Current(); | 641 Isolate* isolate = Isolate::Current(); |
681 CHECK_ISOLATE(isolate); | 642 CHECK_ISOLATE(isolate); |
682 GcPrologueCallbacks& callbacks = isolate->gc_prologue_callbacks(); | 643 GcPrologueCallbacks& callbacks = isolate->gc_prologue_callbacks(); |
683 if (callbacks.Contains(callback)) { | 644 if (callbacks.Contains(callback)) { |
684 return Api::NewError( | 645 return Api::NewError( |
685 "%s permits only one instance of 'callback' to be present in the " | 646 "%s permits only one instance of 'callback' to be present in the " |
686 "prologue callback list.", | 647 "prologue callback list.", |
687 CURRENT_FUNC); | 648 CURRENT_FUNC); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 if (!callbacks.Contains(callback)) { | 691 if (!callbacks.Contains(callback)) { |
731 return Api::NewError( | 692 return Api::NewError( |
732 "%s expects 'callback' to be present in the epilogue callback list.", | 693 "%s expects 'callback' to be present in the epilogue callback list.", |
733 CURRENT_FUNC); | 694 CURRENT_FUNC); |
734 } | 695 } |
735 callbacks.Remove(callback); | 696 callbacks.Remove(callback); |
736 return Api::Success(); | 697 return Api::Success(); |
737 } | 698 } |
738 | 699 |
739 | 700 |
740 DART_EXPORT Dart_Handle Dart_HeapProfile(Dart_FileWriteCallback callback, | |
741 void* stream) { | |
742 Isolate* isolate = Isolate::Current(); | |
743 CHECK_ISOLATE(isolate); | |
744 if (callback == NULL) { | |
745 RETURN_NULL_ERROR(callback); | |
746 } | |
747 isolate->heap()->Profile(callback, stream); | |
748 return Api::Success(); | |
749 } | |
750 | |
751 // --- Initialization and Globals --- | 701 // --- Initialization and Globals --- |
752 | 702 |
753 DART_EXPORT const char* Dart_VersionString() { | 703 DART_EXPORT const char* Dart_VersionString() { |
754 return Version::String(); | 704 return Version::String(); |
755 } | 705 } |
756 | 706 |
757 DART_EXPORT bool Dart_Initialize( | 707 DART_EXPORT bool Dart_Initialize( |
758 Dart_IsolateCreateCallback create, | 708 Dart_IsolateCreateCallback create, |
759 Dart_IsolateInterruptCallback interrupt, | 709 Dart_IsolateInterruptCallback interrupt, |
760 Dart_IsolateUnhandledExceptionCallback unhandled, | 710 Dart_IsolateUnhandledExceptionCallback unhandled, |
(...skipping 19 matching lines...) Expand all Loading... |
780 DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) { | 730 DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) { |
781 if (Flags::Lookup(flag_name) != NULL) { | 731 if (Flags::Lookup(flag_name) != NULL) { |
782 return true; | 732 return true; |
783 } | 733 } |
784 return false; | 734 return false; |
785 } | 735 } |
786 | 736 |
787 | 737 |
788 // --- Isolates --- | 738 // --- Isolates --- |
789 | 739 |
790 | |
791 static char* BuildIsolateName(const char* script_uri, | 740 static char* BuildIsolateName(const char* script_uri, |
792 const char* main) { | 741 const char* main) { |
793 if (script_uri == NULL) { | 742 if (script_uri == NULL) { |
794 // Just use the main as the name. | 743 // Just use the main as the name. |
795 if (main == NULL) { | 744 if (main == NULL) { |
796 return strdup("isolate"); | 745 return strdup("isolate"); |
797 } else { | 746 } else { |
798 return strdup(main); | 747 return strdup(main); |
799 } | 748 } |
800 } | 749 } |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 return isolate->message_handler()->HasLivePorts(); | 991 return isolate->message_handler()->HasLivePorts(); |
1043 } | 992 } |
1044 | 993 |
1045 | 994 |
1046 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { | 995 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
1047 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 996 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
1048 return reinterpret_cast<uint8_t*>(new_ptr); | 997 return reinterpret_cast<uint8_t*>(new_ptr); |
1049 } | 998 } |
1050 | 999 |
1051 | 1000 |
1052 DART_EXPORT bool Dart_PostIntArray(Dart_Port port_id, | |
1053 intptr_t len, | |
1054 intptr_t* data) { | |
1055 uint8_t* buffer = NULL; | |
1056 ApiMessageWriter writer(&buffer, &allocator); | |
1057 writer.WriteMessage(len, data); | |
1058 | |
1059 // Post the message at the given port. | |
1060 return PortMap::PostMessage(new Message( | |
1061 port_id, Message::kIllegalPort, buffer, writer.BytesWritten(), | |
1062 Message::kNormalPriority)); | |
1063 } | |
1064 | |
1065 | |
1066 DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) { | |
1067 uint8_t* buffer = NULL; | |
1068 ApiMessageWriter writer(&buffer, allocator); | |
1069 bool success = writer.WriteCMessage(message); | |
1070 | |
1071 if (!success) return success; | |
1072 | |
1073 // Post the message at the given port. | |
1074 return PortMap::PostMessage(new Message( | |
1075 port_id, Message::kIllegalPort, buffer, writer.BytesWritten(), | |
1076 Message::kNormalPriority)); | |
1077 } | |
1078 | |
1079 | |
1080 DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) { | 1001 DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) { |
1081 Isolate* isolate = Isolate::Current(); | 1002 Isolate* isolate = Isolate::Current(); |
1082 DARTSCOPE(isolate); | 1003 DARTSCOPE(isolate); |
1083 const Object& object = Object::Handle(isolate, Api::UnwrapHandle(handle)); | 1004 const Object& object = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
1084 uint8_t* data = NULL; | 1005 uint8_t* data = NULL; |
1085 MessageWriter writer(&data, &allocator); | 1006 MessageWriter writer(&data, &allocator); |
1086 writer.WriteMessage(object); | 1007 writer.WriteMessage(object); |
1087 intptr_t len = writer.BytesWritten(); | 1008 intptr_t len = writer.BytesWritten(); |
1088 return PortMap::PostMessage(new Message( | 1009 return PortMap::PostMessage(new Message( |
1089 port_id, Message::kIllegalPort, data, len, Message::kNormalPriority)); | 1010 port_id, Message::kIllegalPort, data, len, Message::kNormalPriority)); |
1090 } | 1011 } |
1091 | 1012 |
1092 | 1013 |
1093 DART_EXPORT Dart_Port Dart_NewNativePort(const char* name, | |
1094 Dart_NativeMessageHandler handler, | |
1095 bool handle_concurrently) { | |
1096 if (name == NULL) { | |
1097 name = "<UnnamedNativePort>"; | |
1098 } | |
1099 if (handler == NULL) { | |
1100 OS::PrintErr("%s expects argument 'handler' to be non-null.\n", | |
1101 CURRENT_FUNC); | |
1102 return ILLEGAL_PORT; | |
1103 } | |
1104 // Start the native port without a current isolate. | |
1105 IsolateSaver saver(Isolate::Current()); | |
1106 Isolate::SetCurrent(NULL); | |
1107 | |
1108 NativeMessageHandler* nmh = new NativeMessageHandler(name, handler); | |
1109 Dart_Port port_id = PortMap::CreatePort(nmh); | |
1110 nmh->Run(Dart::thread_pool(), NULL, NULL, 0); | |
1111 return port_id; | |
1112 } | |
1113 | |
1114 | |
1115 DART_EXPORT bool Dart_CloseNativePort(Dart_Port native_port_id) { | |
1116 // Close the native port without a current isolate. | |
1117 IsolateSaver saver(Isolate::Current()); | |
1118 Isolate::SetCurrent(NULL); | |
1119 | |
1120 // TODO(turnidge): Check that the port is native before trying to close. | |
1121 return PortMap::ClosePort(native_port_id); | |
1122 } | |
1123 | |
1124 | |
1125 DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) { | 1014 DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) { |
1126 Isolate* isolate = Isolate::Current(); | 1015 Isolate* isolate = Isolate::Current(); |
1127 DARTSCOPE(isolate); | 1016 DARTSCOPE(isolate); |
1128 CHECK_CALLBACK_STATE(isolate); | 1017 CHECK_CALLBACK_STATE(isolate); |
1129 return Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id)); | 1018 return Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id)); |
1130 } | 1019 } |
1131 | 1020 |
1132 | 1021 |
1133 DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id) { | 1022 DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id) { |
1134 Isolate* isolate = Isolate::Current(); | 1023 Isolate* isolate = Isolate::Current(); |
(...skipping 22 matching lines...) Expand all Loading... |
1157 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); | 1046 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); |
1158 } | 1047 } |
1159 | 1048 |
1160 | 1049 |
1161 DART_EXPORT Dart_Port Dart_GetMainPortId() { | 1050 DART_EXPORT Dart_Port Dart_GetMainPortId() { |
1162 Isolate* isolate = Isolate::Current(); | 1051 Isolate* isolate = Isolate::Current(); |
1163 CHECK_ISOLATE(isolate); | 1052 CHECK_ISOLATE(isolate); |
1164 return isolate->main_port(); | 1053 return isolate->main_port(); |
1165 } | 1054 } |
1166 | 1055 |
| 1056 |
1167 // --- Scopes ---- | 1057 // --- Scopes ---- |
1168 | 1058 |
1169 | |
1170 DART_EXPORT void Dart_EnterScope() { | 1059 DART_EXPORT void Dart_EnterScope() { |
1171 Isolate* isolate = Isolate::Current(); | 1060 Isolate* isolate = Isolate::Current(); |
1172 CHECK_ISOLATE(isolate); | 1061 CHECK_ISOLATE(isolate); |
1173 ApiState* state = isolate->api_state(); | 1062 ApiState* state = isolate->api_state(); |
1174 ASSERT(state != NULL); | 1063 ASSERT(state != NULL); |
1175 ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(), | 1064 ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(), |
1176 isolate->top_exit_frame_info()); | 1065 isolate->top_exit_frame_info()); |
1177 ASSERT(new_scope != NULL); | 1066 ASSERT(new_scope != NULL); |
1178 state->set_top_scope(new_scope); // New scope is now the top scope. | 1067 state->set_top_scope(new_scope); // New scope is now the top scope. |
1179 } | 1068 } |
(...skipping 22 matching lines...) Expand all Loading... |
1202 ApiNativeScope* scope = ApiNativeScope::Current(); | 1091 ApiNativeScope* scope = ApiNativeScope::Current(); |
1203 if (scope == NULL) return NULL; | 1092 if (scope == NULL) return NULL; |
1204 zone = scope->zone(); | 1093 zone = scope->zone(); |
1205 } | 1094 } |
1206 return reinterpret_cast<uint8_t*>(zone->AllocUnsafe(size)); | 1095 return reinterpret_cast<uint8_t*>(zone->AllocUnsafe(size)); |
1207 } | 1096 } |
1208 | 1097 |
1209 | 1098 |
1210 // --- Objects ---- | 1099 // --- Objects ---- |
1211 | 1100 |
1212 | |
1213 DART_EXPORT Dart_Handle Dart_Null() { | 1101 DART_EXPORT Dart_Handle Dart_Null() { |
1214 Isolate* isolate = Isolate::Current(); | 1102 Isolate* isolate = Isolate::Current(); |
1215 CHECK_ISOLATE_SCOPE(isolate); | 1103 CHECK_ISOLATE_SCOPE(isolate); |
1216 return Api::Null(); | 1104 return Api::Null(); |
1217 } | 1105 } |
1218 | 1106 |
1219 | 1107 |
1220 DART_EXPORT bool Dart_IsNull(Dart_Handle object) { | 1108 DART_EXPORT bool Dart_IsNull(Dart_Handle object) { |
1221 return Api::ClassId(object) == kNullCid; | 1109 return Api::ClassId(object) == kNullCid; |
1222 } | 1110 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 TypeArguments::Handle(isolate), | 1167 TypeArguments::Handle(isolate), |
1280 &malformed_type_error); | 1168 &malformed_type_error); |
1281 ASSERT(malformed_type_error.IsNull()); // Type was created from a class. | 1169 ASSERT(malformed_type_error.IsNull()); // Type was created from a class. |
1282 } else { | 1170 } else { |
1283 *value = false; | 1171 *value = false; |
1284 } | 1172 } |
1285 return Api::Success(); | 1173 return Api::Success(); |
1286 } | 1174 } |
1287 | 1175 |
1288 | 1176 |
1289 // --- Instances ---- | |
1290 | |
1291 | |
1292 DART_EXPORT bool Dart_IsInstance(Dart_Handle object) { | 1177 DART_EXPORT bool Dart_IsInstance(Dart_Handle object) { |
1293 Isolate* isolate = Isolate::Current(); | 1178 Isolate* isolate = Isolate::Current(); |
1294 DARTSCOPE(isolate); | 1179 DARTSCOPE(isolate); |
1295 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | 1180 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
1296 return obj.IsInstance(); | 1181 return obj.IsInstance(); |
1297 } | 1182 } |
1298 | 1183 |
1299 | 1184 |
| 1185 DART_EXPORT bool Dart_IsNumber(Dart_Handle object) { |
| 1186 return RawObject::IsNumberClassId(Api::ClassId(object)); |
| 1187 } |
| 1188 |
| 1189 |
| 1190 DART_EXPORT bool Dart_IsInteger(Dart_Handle object) { |
| 1191 return RawObject::IsIntegerClassId(Api::ClassId(object)); |
| 1192 } |
| 1193 |
| 1194 |
| 1195 DART_EXPORT bool Dart_IsDouble(Dart_Handle object) { |
| 1196 return Api::ClassId(object) == kDoubleCid; |
| 1197 } |
| 1198 |
| 1199 |
| 1200 DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) { |
| 1201 return Api::ClassId(object) == kBoolCid; |
| 1202 } |
| 1203 |
| 1204 |
| 1205 DART_EXPORT bool Dart_IsString(Dart_Handle object) { |
| 1206 return RawObject::IsStringClassId(Api::ClassId(object)); |
| 1207 } |
| 1208 |
| 1209 |
| 1210 DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) { |
| 1211 return RawObject::IsOneByteStringClassId(Api::ClassId(object)); |
| 1212 } |
| 1213 |
| 1214 |
| 1215 DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) { |
| 1216 return RawObject::IsExternalStringClassId(Api::ClassId(object)); |
| 1217 } |
| 1218 |
| 1219 |
| 1220 DART_EXPORT bool Dart_IsList(Dart_Handle object) { |
| 1221 if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) { |
| 1222 return true; |
| 1223 } |
| 1224 |
| 1225 Isolate* isolate = Isolate::Current(); |
| 1226 DARTSCOPE(isolate); |
| 1227 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
| 1228 return GetListInstance(isolate, obj) != Instance::null(); |
| 1229 } |
| 1230 |
| 1231 |
| 1232 DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { |
| 1233 return Api::ClassId(object) == kLibraryCid; |
| 1234 } |
| 1235 |
| 1236 |
| 1237 DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { |
| 1238 Isolate* isolate = Isolate::Current(); |
| 1239 DARTSCOPE(isolate); |
| 1240 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
| 1241 return obj.IsClass(); |
| 1242 } |
| 1243 |
| 1244 |
| 1245 DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle) { |
| 1246 Isolate* isolate = Isolate::Current(); |
| 1247 DARTSCOPE(isolate); |
| 1248 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
| 1249 if (obj.IsClass()) { |
| 1250 return Class::Cast(obj).is_abstract(); |
| 1251 } |
| 1252 return false; |
| 1253 } |
| 1254 |
| 1255 |
| 1256 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { |
| 1257 return Api::ClassId(handle) == kFunctionCid; |
| 1258 } |
| 1259 |
| 1260 |
| 1261 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { |
| 1262 return Api::ClassId(handle) == kFieldCid; |
| 1263 } |
| 1264 |
| 1265 |
| 1266 DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) { |
| 1267 return Api::ClassId(handle) == kTypeParameterCid; |
| 1268 } |
| 1269 |
| 1270 |
| 1271 DART_EXPORT bool Dart_IsClosure(Dart_Handle object) { |
| 1272 // We can't use a fast class index check here because there are many |
| 1273 // different signature classes for closures. |
| 1274 Isolate* isolate = Isolate::Current(); |
| 1275 DARTSCOPE(isolate); |
| 1276 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, object); |
| 1277 return (!closure_obj.IsNull() && closure_obj.IsClosure()); |
| 1278 } |
| 1279 |
| 1280 |
| 1281 // --- Instances ---- |
| 1282 |
1300 // TODO(turnidge): Technically, null has a class. Should we allow it? | 1283 // TODO(turnidge): Technically, null has a class. Should we allow it? |
1301 DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) { | 1284 DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) { |
1302 Isolate* isolate = Isolate::Current(); | 1285 Isolate* isolate = Isolate::Current(); |
1303 DARTSCOPE(isolate); | 1286 DARTSCOPE(isolate); |
1304 const Instance& obj = Api::UnwrapInstanceHandle(isolate, instance); | 1287 const Instance& obj = Api::UnwrapInstanceHandle(isolate, instance); |
1305 if (obj.IsNull()) { | 1288 if (obj.IsNull()) { |
1306 RETURN_TYPE_ERROR(isolate, instance, Instance); | 1289 RETURN_TYPE_ERROR(isolate, instance, Instance); |
1307 } | 1290 } |
1308 return Api::NewHandle(isolate, obj.clazz()); | 1291 return Api::NewHandle(isolate, obj.clazz()); |
1309 } | 1292 } |
1310 | 1293 |
1311 | 1294 |
1312 // --- Numbers ---- | 1295 // --- Numbers, Integers and Doubles ---- |
1313 | |
1314 | |
1315 DART_EXPORT bool Dart_IsNumber(Dart_Handle object) { | |
1316 return RawObject::IsNumberClassId(Api::ClassId(object)); | |
1317 } | |
1318 | |
1319 | |
1320 // --- Integers ---- | |
1321 | |
1322 | |
1323 DART_EXPORT bool Dart_IsInteger(Dart_Handle object) { | |
1324 return RawObject::IsIntegerClassId(Api::ClassId(object)); | |
1325 } | |
1326 | |
1327 | 1296 |
1328 DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer, | 1297 DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer, |
1329 bool* fits) { | 1298 bool* fits) { |
1330 // Fast path for Smis and Mints. | 1299 // Fast path for Smis and Mints. |
1331 Isolate* isolate = Isolate::Current(); | 1300 Isolate* isolate = Isolate::Current(); |
1332 CHECK_ISOLATE(isolate); | 1301 CHECK_ISOLATE(isolate); |
1333 intptr_t class_id = Api::ClassId(integer); | 1302 intptr_t class_id = Api::ClassId(integer); |
1334 if (class_id == kSmiCid || class_id == kMintCid) { | 1303 if (class_id == kSmiCid || class_id == kMintCid) { |
1335 *fits = true; | 1304 *fits = true; |
1336 return Api::Success(); | 1305 return Api::Success(); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1479 BigintOperations::NewFromInt64(int_obj.AsInt64Value())); | 1448 BigintOperations::NewFromInt64(int_obj.AsInt64Value())); |
1480 *value = BigintOperations::ToHexCString(bigint, BigintAllocate); | 1449 *value = BigintOperations::ToHexCString(bigint, BigintAllocate); |
1481 } else { | 1450 } else { |
1482 *value = BigintOperations::ToHexCString(Bigint::Cast(int_obj), | 1451 *value = BigintOperations::ToHexCString(Bigint::Cast(int_obj), |
1483 BigintAllocate); | 1452 BigintAllocate); |
1484 } | 1453 } |
1485 return Api::Success(); | 1454 return Api::Success(); |
1486 } | 1455 } |
1487 | 1456 |
1488 | 1457 |
| 1458 DART_EXPORT Dart_Handle Dart_NewDouble(double value) { |
| 1459 Isolate* isolate = Isolate::Current(); |
| 1460 DARTSCOPE(isolate); |
| 1461 CHECK_CALLBACK_STATE(isolate); |
| 1462 return Api::NewHandle(isolate, Double::New(value)); |
| 1463 } |
| 1464 |
| 1465 |
| 1466 DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj, |
| 1467 double* value) { |
| 1468 Isolate* isolate = Isolate::Current(); |
| 1469 DARTSCOPE(isolate); |
| 1470 const Double& obj = Api::UnwrapDoubleHandle(isolate, double_obj); |
| 1471 if (obj.IsNull()) { |
| 1472 RETURN_TYPE_ERROR(isolate, double_obj, Double); |
| 1473 } |
| 1474 *value = obj.value(); |
| 1475 return Api::Success(); |
| 1476 } |
| 1477 |
| 1478 |
1489 // --- Booleans ---- | 1479 // --- Booleans ---- |
1490 | 1480 |
1491 | |
1492 DART_EXPORT Dart_Handle Dart_True() { | 1481 DART_EXPORT Dart_Handle Dart_True() { |
1493 Isolate* isolate = Isolate::Current(); | 1482 Isolate* isolate = Isolate::Current(); |
1494 CHECK_ISOLATE_SCOPE(isolate); | 1483 CHECK_ISOLATE_SCOPE(isolate); |
1495 return Api::True(); | 1484 return Api::True(); |
1496 } | 1485 } |
1497 | 1486 |
1498 | 1487 |
1499 DART_EXPORT Dart_Handle Dart_False() { | 1488 DART_EXPORT Dart_Handle Dart_False() { |
1500 Isolate* isolate = Isolate::Current(); | 1489 Isolate* isolate = Isolate::Current(); |
1501 CHECK_ISOLATE_SCOPE(isolate); | 1490 CHECK_ISOLATE_SCOPE(isolate); |
1502 return Api::False(); | 1491 return Api::False(); |
1503 } | 1492 } |
1504 | 1493 |
1505 | 1494 |
1506 DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) { | |
1507 return Api::ClassId(object) == kBoolCid; | |
1508 } | |
1509 | |
1510 | |
1511 DART_EXPORT Dart_Handle Dart_NewBoolean(bool value) { | 1495 DART_EXPORT Dart_Handle Dart_NewBoolean(bool value) { |
1512 Isolate* isolate = Isolate::Current(); | 1496 Isolate* isolate = Isolate::Current(); |
1513 CHECK_ISOLATE_SCOPE(isolate); | 1497 CHECK_ISOLATE_SCOPE(isolate); |
1514 return value ? Api::True() : Api::False(); | 1498 return value ? Api::True() : Api::False(); |
1515 } | 1499 } |
1516 | 1500 |
1517 | 1501 |
1518 DART_EXPORT Dart_Handle Dart_BooleanValue(Dart_Handle boolean_obj, | 1502 DART_EXPORT Dart_Handle Dart_BooleanValue(Dart_Handle boolean_obj, |
1519 bool* value) { | 1503 bool* value) { |
1520 Isolate* isolate = Isolate::Current(); | 1504 Isolate* isolate = Isolate::Current(); |
1521 DARTSCOPE(isolate); | 1505 DARTSCOPE(isolate); |
1522 const Bool& obj = Api::UnwrapBoolHandle(isolate, boolean_obj); | 1506 const Bool& obj = Api::UnwrapBoolHandle(isolate, boolean_obj); |
1523 if (obj.IsNull()) { | 1507 if (obj.IsNull()) { |
1524 RETURN_TYPE_ERROR(isolate, boolean_obj, Bool); | 1508 RETURN_TYPE_ERROR(isolate, boolean_obj, Bool); |
1525 } | 1509 } |
1526 *value = obj.value(); | 1510 *value = obj.value(); |
1527 return Api::Success(); | 1511 return Api::Success(); |
1528 } | 1512 } |
1529 | 1513 |
1530 | 1514 |
1531 // --- Doubles --- | |
1532 | |
1533 | |
1534 DART_EXPORT bool Dart_IsDouble(Dart_Handle object) { | |
1535 return Api::ClassId(object) == kDoubleCid; | |
1536 } | |
1537 | |
1538 | |
1539 DART_EXPORT Dart_Handle Dart_NewDouble(double value) { | |
1540 Isolate* isolate = Isolate::Current(); | |
1541 DARTSCOPE(isolate); | |
1542 CHECK_CALLBACK_STATE(isolate); | |
1543 return Api::NewHandle(isolate, Double::New(value)); | |
1544 } | |
1545 | |
1546 | |
1547 DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj, | |
1548 double* value) { | |
1549 Isolate* isolate = Isolate::Current(); | |
1550 DARTSCOPE(isolate); | |
1551 const Double& obj = Api::UnwrapDoubleHandle(isolate, double_obj); | |
1552 if (obj.IsNull()) { | |
1553 RETURN_TYPE_ERROR(isolate, double_obj, Double); | |
1554 } | |
1555 *value = obj.value(); | |
1556 return Api::Success(); | |
1557 } | |
1558 | |
1559 | |
1560 // --- Strings --- | 1515 // --- Strings --- |
1561 | 1516 |
1562 | 1517 |
1563 DART_EXPORT bool Dart_IsString(Dart_Handle object) { | |
1564 return RawObject::IsStringClassId(Api::ClassId(object)); | |
1565 } | |
1566 | |
1567 | |
1568 DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) { | |
1569 return RawObject::IsOneByteStringClassId(Api::ClassId(object)); | |
1570 } | |
1571 | |
1572 | |
1573 DART_EXPORT Dart_Handle Dart_StringLength(Dart_Handle str, intptr_t* len) { | 1518 DART_EXPORT Dart_Handle Dart_StringLength(Dart_Handle str, intptr_t* len) { |
1574 Isolate* isolate = Isolate::Current(); | 1519 Isolate* isolate = Isolate::Current(); |
1575 DARTSCOPE(isolate); | 1520 DARTSCOPE(isolate); |
1576 const String& str_obj = Api::UnwrapStringHandle(isolate, str); | 1521 const String& str_obj = Api::UnwrapStringHandle(isolate, str); |
1577 if (str_obj.IsNull()) { | 1522 if (str_obj.IsNull()) { |
1578 RETURN_TYPE_ERROR(isolate, str, String); | 1523 RETURN_TYPE_ERROR(isolate, str, String); |
1579 } | 1524 } |
1580 *len = str_obj.Length(); | 1525 *len = str_obj.Length(); |
1581 return Api::Success(); | 1526 return Api::Success(); |
1582 } | 1527 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 DARTSCOPE(isolate); | 1574 DARTSCOPE(isolate); |
1630 if (utf32_array == NULL && length != 0) { | 1575 if (utf32_array == NULL && length != 0) { |
1631 RETURN_NULL_ERROR(utf32_array); | 1576 RETURN_NULL_ERROR(utf32_array); |
1632 } | 1577 } |
1633 CHECK_LENGTH(length, String::kMaxElements); | 1578 CHECK_LENGTH(length, String::kMaxElements); |
1634 CHECK_CALLBACK_STATE(isolate); | 1579 CHECK_CALLBACK_STATE(isolate); |
1635 return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length)); | 1580 return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length)); |
1636 } | 1581 } |
1637 | 1582 |
1638 | 1583 |
1639 DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) { | |
1640 return RawObject::IsExternalStringClassId(Api::ClassId(object)); | |
1641 } | |
1642 | |
1643 | |
1644 DART_EXPORT Dart_Handle Dart_ExternalStringGetPeer(Dart_Handle object, | 1584 DART_EXPORT Dart_Handle Dart_ExternalStringGetPeer(Dart_Handle object, |
1645 void** peer) { | 1585 void** peer) { |
1646 if (peer == NULL) { | 1586 if (peer == NULL) { |
1647 RETURN_NULL_ERROR(peer); | 1587 RETURN_NULL_ERROR(peer); |
1648 } | 1588 } |
1649 | 1589 |
1650 if (Api::ExternalStringGetPeerHelper(object, peer)) { | 1590 if (Api::ExternalStringGetPeerHelper(object, peer)) { |
1651 return Api::Success(); | 1591 return Api::Success(); |
1652 } | 1592 } |
1653 | 1593 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1856 } | 1796 } |
1857 return Api::Null(); | 1797 return Api::Null(); |
1858 } | 1798 } |
1859 return Api::NewHandle(isolate, | 1799 return Api::NewHandle(isolate, |
1860 str_obj.MakeExternal(array, length, peer, cback)); | 1800 str_obj.MakeExternal(array, length, peer, cback)); |
1861 } | 1801 } |
1862 | 1802 |
1863 | 1803 |
1864 // --- Lists --- | 1804 // --- Lists --- |
1865 | 1805 |
1866 | |
1867 static RawInstance* GetListInstance(Isolate* isolate, const Object& obj) { | |
1868 if (obj.IsInstance()) { | |
1869 const Instance& instance = Instance::Cast(obj); | |
1870 const Class& obj_class = Class::Handle(isolate, obj.clazz()); | |
1871 const Class& list_class = | |
1872 Class::Handle(isolate, isolate->object_store()->list_class()); | |
1873 Error& malformed_type_error = Error::Handle(isolate); | |
1874 if (obj_class.IsSubtypeOf(TypeArguments::Handle(isolate), | |
1875 list_class, | |
1876 TypeArguments::Handle(isolate), | |
1877 &malformed_type_error)) { | |
1878 ASSERT(malformed_type_error.IsNull()); // Type is a raw List. | |
1879 return instance.raw(); | |
1880 } | |
1881 } | |
1882 return Instance::null(); | |
1883 } | |
1884 | |
1885 | |
1886 DART_EXPORT bool Dart_IsList(Dart_Handle object) { | |
1887 if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) { | |
1888 return true; | |
1889 } | |
1890 | |
1891 Isolate* isolate = Isolate::Current(); | |
1892 DARTSCOPE(isolate); | |
1893 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
1894 return GetListInstance(isolate, obj) != Instance::null(); | |
1895 } | |
1896 | |
1897 | |
1898 DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) { | 1806 DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) { |
1899 Isolate* isolate = Isolate::Current(); | 1807 Isolate* isolate = Isolate::Current(); |
1900 DARTSCOPE(isolate); | 1808 DARTSCOPE(isolate); |
1901 CHECK_LENGTH(length, Array::kMaxElements); | 1809 CHECK_LENGTH(length, Array::kMaxElements); |
1902 CHECK_CALLBACK_STATE(isolate); | 1810 CHECK_CALLBACK_STATE(isolate); |
1903 return Api::NewHandle(isolate, Array::New(length)); | 1811 return Api::NewHandle(isolate, Array::New(length)); |
1904 } | 1812 } |
1905 | 1813 |
1906 | 1814 |
1907 #define GET_LIST_LENGTH(isolate, type, obj, len) \ | 1815 #define GET_LIST_LENGTH(isolate, type, obj, len) \ |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2351 } | 2259 } |
2352 return Api::Success(); | 2260 return Api::Success(); |
2353 } | 2261 } |
2354 } | 2262 } |
2355 return Api::NewError("Object does not implement the 'List' interface"); | 2263 return Api::NewError("Object does not implement the 'List' interface"); |
2356 } | 2264 } |
2357 | 2265 |
2358 | 2266 |
2359 // --- Typed Data --- | 2267 // --- Typed Data --- |
2360 | 2268 |
2361 | |
2362 // Helper method to get the type of a TypedData object. | 2269 // Helper method to get the type of a TypedData object. |
2363 static Dart_TypedData_Type GetType(intptr_t class_id) { | 2270 static Dart_TypedData_Type GetType(intptr_t class_id) { |
2364 Dart_TypedData_Type type; | 2271 Dart_TypedData_Type type; |
2365 switch (class_id) { | 2272 switch (class_id) { |
2366 case kByteDataViewCid : | 2273 case kByteDataViewCid : |
2367 type = Dart_TypedData_kByteData; | 2274 type = Dart_TypedData_kByteData; |
2368 break; | 2275 break; |
2369 case kTypedDataInt8ArrayCid : | 2276 case kTypedDataInt8ArrayCid : |
2370 case kTypedDataInt8ArrayViewCid : | 2277 case kTypedDataInt8ArrayViewCid : |
2371 case kExternalTypedDataInt8ArrayCid : | 2278 case kExternalTypedDataInt8ArrayCid : |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2743 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); | 2650 RETURN_TYPE_ERROR(isolate, object, 'TypedData'); |
2744 } | 2651 } |
2745 if (!RawObject::IsExternalTypedDataClassId(class_id)) { | 2652 if (!RawObject::IsExternalTypedDataClassId(class_id)) { |
2746 isolate->DecrementNoGCScopeDepth(); | 2653 isolate->DecrementNoGCScopeDepth(); |
2747 END_NO_CALLBACK_SCOPE(isolate); | 2654 END_NO_CALLBACK_SCOPE(isolate); |
2748 } | 2655 } |
2749 return Api::Success(); | 2656 return Api::Success(); |
2750 } | 2657 } |
2751 | 2658 |
2752 | 2659 |
2753 // --- Closures --- | 2660 // --- Invoking Constructors, Methods, and Field accessors --- |
2754 | |
2755 | |
2756 DART_EXPORT bool Dart_IsClosure(Dart_Handle object) { | |
2757 // We can't use a fast class index check here because there are many | |
2758 // different signature classes for closures. | |
2759 Isolate* isolate = Isolate::Current(); | |
2760 DARTSCOPE(isolate); | |
2761 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, object); | |
2762 return (!closure_obj.IsNull() && closure_obj.IsClosure()); | |
2763 } | |
2764 | |
2765 | |
2766 DART_EXPORT Dart_Handle Dart_ClosureFunction(Dart_Handle closure) { | |
2767 Isolate* isolate = Isolate::Current(); | |
2768 DARTSCOPE(isolate); | |
2769 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure); | |
2770 if (closure_obj.IsNull() || !closure_obj.IsClosure()) { | |
2771 RETURN_TYPE_ERROR(isolate, closure, Instance); | |
2772 } | |
2773 | |
2774 ASSERT(ClassFinalizer::AllClassesFinalized()); | |
2775 | |
2776 RawFunction* rf = Closure::function(closure_obj); | |
2777 return Api::NewHandle(isolate, rf); | |
2778 } | |
2779 | |
2780 | |
2781 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, | |
2782 int number_of_arguments, | |
2783 Dart_Handle* arguments) { | |
2784 Isolate* isolate = Isolate::Current(); | |
2785 DARTSCOPE(isolate); | |
2786 CHECK_CALLBACK_STATE(isolate); | |
2787 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure); | |
2788 if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) { | |
2789 RETURN_TYPE_ERROR(isolate, closure, Instance); | |
2790 } | |
2791 if (number_of_arguments < 0) { | |
2792 return Api::NewError( | |
2793 "%s expects argument 'number_of_arguments' to be non-negative.", | |
2794 CURRENT_FUNC); | |
2795 } | |
2796 ASSERT(ClassFinalizer::AllClassesFinalized()); | |
2797 | |
2798 // Set up arguments to include the closure as the first argument. | |
2799 const Array& args = Array::Handle(isolate, | |
2800 Array::New(number_of_arguments + 1)); | |
2801 Object& obj = Object::Handle(isolate); | |
2802 args.SetAt(0, closure_obj); | |
2803 for (int i = 0; i < number_of_arguments; i++) { | |
2804 obj = Api::UnwrapHandle(arguments[i]); | |
2805 if (!obj.IsNull() && !obj.IsInstance()) { | |
2806 RETURN_TYPE_ERROR(isolate, arguments[i], Instance); | |
2807 } | |
2808 args.SetAt(i + 1, obj); | |
2809 } | |
2810 // Now try to invoke the closure. | |
2811 return Api::NewHandle(isolate, DartEntry::InvokeClosure(args)); | |
2812 } | |
2813 | |
2814 | |
2815 // --- Classes --- | |
2816 | |
2817 | |
2818 DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { | |
2819 Isolate* isolate = Isolate::Current(); | |
2820 DARTSCOPE(isolate); | |
2821 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); | |
2822 return obj.IsClass(); | |
2823 } | |
2824 | |
2825 | |
2826 DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle) { | |
2827 Isolate* isolate = Isolate::Current(); | |
2828 DARTSCOPE(isolate); | |
2829 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); | |
2830 if (obj.IsClass()) { | |
2831 return Class::Cast(obj).is_abstract(); | |
2832 } | |
2833 return false; | |
2834 } | |
2835 | |
2836 | |
2837 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) { | |
2838 Isolate* isolate = Isolate::Current(); | |
2839 DARTSCOPE(isolate); | |
2840 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2841 if (cls.IsNull()) { | |
2842 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2843 } | |
2844 return Api::NewHandle(isolate, cls.UserVisibleName()); | |
2845 } | |
2846 | |
2847 | |
2848 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) { | |
2849 Isolate* isolate = Isolate::Current(); | |
2850 DARTSCOPE(isolate); | |
2851 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2852 if (cls.IsNull()) { | |
2853 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2854 } | |
2855 | |
2856 #if defined(DEBUG) | |
2857 const Library& lib = Library::Handle(cls.library()); | |
2858 if (lib.IsNull()) { | |
2859 // ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); | |
2860 if (!cls.IsDynamicClass() && !cls.IsVoidClass()) { | |
2861 fprintf(stderr, "NO LIBRARY: %s\n", cls.ToCString()); | |
2862 } | |
2863 } | |
2864 #endif | |
2865 | |
2866 return Api::NewHandle(isolate, cls.library()); | |
2867 } | |
2868 | |
2869 | |
2870 DART_EXPORT Dart_Handle Dart_ClassGetInterfaceCount(Dart_Handle clazz, | |
2871 intptr_t* count) { | |
2872 Isolate* isolate = Isolate::Current(); | |
2873 DARTSCOPE(isolate); | |
2874 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2875 if (cls.IsNull()) { | |
2876 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2877 } | |
2878 | |
2879 const Array& interface_types = Array::Handle(isolate, cls.interfaces()); | |
2880 if (interface_types.IsNull()) { | |
2881 *count = 0; | |
2882 } else { | |
2883 *count = interface_types.Length(); | |
2884 } | |
2885 return Api::Success(); | |
2886 } | |
2887 | |
2888 | |
2889 DART_EXPORT Dart_Handle Dart_ClassGetInterfaceAt(Dart_Handle clazz, | |
2890 intptr_t index) { | |
2891 Isolate* isolate = Isolate::Current(); | |
2892 DARTSCOPE(isolate); | |
2893 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2894 if (cls.IsNull()) { | |
2895 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2896 } | |
2897 | |
2898 // Finalize all classes. | |
2899 Dart_Handle state = Api::CheckIsolateState(isolate); | |
2900 if (::Dart_IsError(state)) { | |
2901 return state; | |
2902 } | |
2903 | |
2904 const Array& interface_types = Array::Handle(isolate, cls.interfaces()); | |
2905 if (index < 0 || index >= interface_types.Length()) { | |
2906 return Api::NewError("%s: argument 'index' out of bounds.", CURRENT_FUNC); | |
2907 } | |
2908 Type& interface_type = Type::Handle(isolate); | |
2909 interface_type ^= interface_types.At(index); | |
2910 if (interface_type.HasResolvedTypeClass()) { | |
2911 return Api::NewHandle(isolate, interface_type.type_class()); | |
2912 } | |
2913 const String& type_name = | |
2914 String::Handle(isolate, interface_type.TypeClassName()); | |
2915 return Api::NewError("%s: internal error: found unresolved type class '%s'.", | |
2916 CURRENT_FUNC, type_name.ToCString()); | |
2917 } | |
2918 | |
2919 | |
2920 DART_EXPORT bool Dart_ClassIsTypedef(Dart_Handle clazz) { | |
2921 Isolate* isolate = Isolate::Current(); | |
2922 DARTSCOPE(isolate); | |
2923 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2924 if (cls.IsNull()) { | |
2925 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2926 } | |
2927 // For now we represent typedefs as non-canonical signature classes. | |
2928 // I anticipate this may change if we make typedefs more general. | |
2929 return cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass(); | |
2930 } | |
2931 | |
2932 | |
2933 DART_EXPORT Dart_Handle Dart_ClassGetTypedefReferent(Dart_Handle clazz) { | |
2934 Isolate* isolate = Isolate::Current(); | |
2935 DARTSCOPE(isolate); | |
2936 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2937 if (cls.IsNull()) { | |
2938 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2939 } | |
2940 | |
2941 if (!cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()) { | |
2942 const String& cls_name = String::Handle(cls.UserVisibleName()); | |
2943 return Api::NewError("%s: class '%s' is not a typedef class. " | |
2944 "See Dart_ClassIsTypedef.", | |
2945 CURRENT_FUNC, cls_name.ToCString()); | |
2946 } | |
2947 | |
2948 const Function& func = Function::Handle(isolate, cls.signature_function()); | |
2949 return Api::NewHandle(isolate, func.signature_class()); | |
2950 } | |
2951 | |
2952 | |
2953 DART_EXPORT bool Dart_ClassIsFunctionType(Dart_Handle clazz) { | |
2954 Isolate* isolate = Isolate::Current(); | |
2955 DARTSCOPE(isolate); | |
2956 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2957 if (cls.IsNull()) { | |
2958 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2959 } | |
2960 // A class represents a function type when it is a canonical | |
2961 // signature class. | |
2962 return cls.IsCanonicalSignatureClass(); | |
2963 } | |
2964 | |
2965 | |
2966 DART_EXPORT Dart_Handle Dart_ClassGetFunctionTypeSignature(Dart_Handle clazz) { | |
2967 Isolate* isolate = Isolate::Current(); | |
2968 DARTSCOPE(isolate); | |
2969 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
2970 if (cls.IsNull()) { | |
2971 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
2972 } | |
2973 if (!cls.IsCanonicalSignatureClass()) { | |
2974 const String& cls_name = String::Handle(cls.UserVisibleName()); | |
2975 return Api::NewError("%s: class '%s' is not a function-type class. " | |
2976 "See Dart_ClassIsFunctionType.", | |
2977 CURRENT_FUNC, cls_name.ToCString()); | |
2978 } | |
2979 return Api::NewHandle(isolate, cls.signature_function()); | |
2980 } | |
2981 | |
2982 | |
2983 // --- Function and Variable Reflection --- | |
2984 | |
2985 | |
2986 // Outside of the vm, we expose setter names with a trailing '='. | |
2987 static bool HasExternalSetterSuffix(const String& name) { | |
2988 return name.CharAt(name.Length() - 1) == '='; | |
2989 } | |
2990 | |
2991 | |
2992 static RawString* RemoveExternalSetterSuffix(const String& name) { | |
2993 ASSERT(HasExternalSetterSuffix(name)); | |
2994 return String::SubString(name, 0, name.Length() - 1); | |
2995 } | |
2996 | |
2997 | |
2998 DART_EXPORT Dart_Handle Dart_GetFunctionNames(Dart_Handle target) { | |
2999 Isolate* isolate = Isolate::Current(); | |
3000 DARTSCOPE(isolate); | |
3001 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
3002 if (obj.IsError()) { | |
3003 return target; | |
3004 } | |
3005 | |
3006 const GrowableObjectArray& names = | |
3007 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
3008 Function& func = Function::Handle(); | |
3009 String& name = String::Handle(); | |
3010 | |
3011 if (obj.IsClass()) { | |
3012 const Class& cls = Class::Cast(obj); | |
3013 const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate)); | |
3014 if (!error.IsNull()) { | |
3015 return Api::NewHandle(isolate, error.raw()); | |
3016 } | |
3017 const Array& func_array = Array::Handle(cls.functions()); | |
3018 | |
3019 // Some special types like 'dynamic' have a null functions list. | |
3020 if (!func_array.IsNull()) { | |
3021 for (intptr_t i = 0; i < func_array.Length(); ++i) { | |
3022 func ^= func_array.At(i); | |
3023 | |
3024 // Skip implicit getters and setters. | |
3025 if (func.kind() == RawFunction::kImplicitGetter || | |
3026 func.kind() == RawFunction::kImplicitSetter || | |
3027 func.kind() == RawFunction::kConstImplicitGetter || | |
3028 func.kind() == RawFunction::kMethodExtractor) { | |
3029 continue; | |
3030 } | |
3031 | |
3032 name = func.UserVisibleName(); | |
3033 names.Add(name); | |
3034 } | |
3035 } | |
3036 } else if (obj.IsLibrary()) { | |
3037 const Library& lib = Library::Cast(obj); | |
3038 DictionaryIterator it(lib); | |
3039 Object& obj = Object::Handle(); | |
3040 while (it.HasNext()) { | |
3041 obj = it.GetNext(); | |
3042 if (obj.IsFunction()) { | |
3043 func ^= obj.raw(); | |
3044 name = func.UserVisibleName(); | |
3045 names.Add(name); | |
3046 } | |
3047 } | |
3048 } else { | |
3049 return Api::NewError( | |
3050 "%s expects argument 'target' to be a class or library.", | |
3051 CURRENT_FUNC); | |
3052 } | |
3053 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
3054 } | |
3055 | |
3056 | |
3057 DART_EXPORT Dart_Handle Dart_LookupFunction(Dart_Handle target, | |
3058 Dart_Handle function_name) { | |
3059 Isolate* isolate = Isolate::Current(); | |
3060 DARTSCOPE(isolate); | |
3061 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
3062 if (obj.IsError()) { | |
3063 return target; | |
3064 } | |
3065 const String& func_name = Api::UnwrapStringHandle(isolate, function_name); | |
3066 if (func_name.IsNull()) { | |
3067 RETURN_TYPE_ERROR(isolate, function_name, String); | |
3068 } | |
3069 | |
3070 Function& func = Function::Handle(isolate); | |
3071 String& tmp_name = String::Handle(isolate); | |
3072 if (obj.IsClass()) { | |
3073 const Class& cls = Class::Cast(obj); | |
3074 | |
3075 // Case 1. Lookup the unmodified function name. | |
3076 func = cls.LookupFunctionAllowPrivate(func_name); | |
3077 | |
3078 // Case 2. Lookup the function without the external setter suffix | |
3079 // '='. Make sure to do this check after the regular lookup, so | |
3080 // that we don't interfere with operator lookups (like ==). | |
3081 if (func.IsNull() && HasExternalSetterSuffix(func_name)) { | |
3082 tmp_name = RemoveExternalSetterSuffix(func_name); | |
3083 tmp_name = Field::SetterName(tmp_name); | |
3084 func = cls.LookupFunctionAllowPrivate(tmp_name); | |
3085 } | |
3086 | |
3087 // Case 3. Lookup the funciton with the getter prefix prepended. | |
3088 if (func.IsNull()) { | |
3089 tmp_name = Field::GetterName(func_name); | |
3090 func = cls.LookupFunctionAllowPrivate(tmp_name); | |
3091 } | |
3092 | |
3093 // Case 4. Lookup the function with a . appended to find the | |
3094 // unnamed constructor. | |
3095 if (func.IsNull()) { | |
3096 tmp_name = String::Concat(func_name, Symbols::Dot()); | |
3097 func = cls.LookupFunctionAllowPrivate(tmp_name); | |
3098 } | |
3099 } else if (obj.IsLibrary()) { | |
3100 const Library& lib = Library::Cast(obj); | |
3101 | |
3102 // Case 1. Lookup the unmodified function name. | |
3103 func = lib.LookupFunctionAllowPrivate(func_name); | |
3104 | |
3105 // Case 2. Lookup the function without the external setter suffix | |
3106 // '='. Make sure to do this check after the regular lookup, so | |
3107 // that we don't interfere with operator lookups (like ==). | |
3108 if (func.IsNull() && HasExternalSetterSuffix(func_name)) { | |
3109 tmp_name = RemoveExternalSetterSuffix(func_name); | |
3110 tmp_name = Field::SetterName(tmp_name); | |
3111 func = lib.LookupFunctionAllowPrivate(tmp_name); | |
3112 } | |
3113 | |
3114 // Case 3. Lookup the function with the getter prefix prepended. | |
3115 if (func.IsNull()) { | |
3116 tmp_name = Field::GetterName(func_name); | |
3117 func = lib.LookupFunctionAllowPrivate(tmp_name); | |
3118 } | |
3119 } else { | |
3120 return Api::NewError( | |
3121 "%s expects argument 'target' to be a class or library.", | |
3122 CURRENT_FUNC); | |
3123 } | |
3124 | |
3125 #if defined(DEBUG) | |
3126 if (!func.IsNull()) { | |
3127 // We only provide access to a subset of function kinds. | |
3128 RawFunction::Kind func_kind = func.kind(); | |
3129 ASSERT(func_kind == RawFunction::kRegularFunction || | |
3130 func_kind == RawFunction::kGetterFunction || | |
3131 func_kind == RawFunction::kSetterFunction || | |
3132 func_kind == RawFunction::kConstructor); | |
3133 } | |
3134 #endif | |
3135 return Api::NewHandle(isolate, func.raw()); | |
3136 } | |
3137 | |
3138 | |
3139 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { | |
3140 return Api::ClassId(handle) == kFunctionCid; | |
3141 } | |
3142 | |
3143 | |
3144 DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) { | |
3145 Isolate* isolate = Isolate::Current(); | |
3146 DARTSCOPE(isolate); | |
3147 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3148 if (func.IsNull()) { | |
3149 RETURN_TYPE_ERROR(isolate, function, Function); | |
3150 } | |
3151 return Api::NewHandle(isolate, func.UserVisibleName()); | |
3152 } | |
3153 | |
3154 | |
3155 DART_EXPORT Dart_Handle Dart_FunctionOwner(Dart_Handle function) { | |
3156 Isolate* isolate = Isolate::Current(); | |
3157 DARTSCOPE(isolate); | |
3158 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3159 if (func.IsNull()) { | |
3160 RETURN_TYPE_ERROR(isolate, function, Function); | |
3161 } | |
3162 if (func.IsNonImplicitClosureFunction()) { | |
3163 RawFunction* parent_function = func.parent_function(); | |
3164 return Api::NewHandle(isolate, parent_function); | |
3165 } | |
3166 const Class& owner = Class::Handle(func.Owner()); | |
3167 ASSERT(!owner.IsNull()); | |
3168 if (owner.IsTopLevel()) { | |
3169 // Top-level functions are implemented as members of a hidden class. We hide | |
3170 // that class here and instead answer the library. | |
3171 #if defined(DEBUG) | |
3172 const Library& lib = Library::Handle(owner.library()); | |
3173 if (lib.IsNull()) { | |
3174 ASSERT(owner.IsDynamicClass() || owner.IsVoidClass()); | |
3175 } | |
3176 #endif | |
3177 return Api::NewHandle(isolate, owner.library()); | |
3178 } else { | |
3179 return Api::NewHandle(isolate, owner.raw()); | |
3180 } | |
3181 } | |
3182 | |
3183 | |
3184 DART_EXPORT Dart_Handle Dart_FunctionIsAbstract(Dart_Handle function, | |
3185 bool* is_abstract) { | |
3186 Isolate* isolate = Isolate::Current(); | |
3187 DARTSCOPE(isolate); | |
3188 if (is_abstract == NULL) { | |
3189 RETURN_NULL_ERROR(is_abstract); | |
3190 } | |
3191 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3192 if (func.IsNull()) { | |
3193 RETURN_TYPE_ERROR(isolate, function, Function); | |
3194 } | |
3195 *is_abstract = func.is_abstract(); | |
3196 return Api::Success(); | |
3197 } | |
3198 | |
3199 | |
3200 DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, | |
3201 bool* is_static) { | |
3202 Isolate* isolate = Isolate::Current(); | |
3203 DARTSCOPE(isolate); | |
3204 if (is_static == NULL) { | |
3205 RETURN_NULL_ERROR(is_static); | |
3206 } | |
3207 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3208 if (func.IsNull()) { | |
3209 RETURN_TYPE_ERROR(isolate, function, Function); | |
3210 } | |
3211 *is_static = func.is_static(); | |
3212 return Api::Success(); | |
3213 } | |
3214 | |
3215 | |
3216 DART_EXPORT Dart_Handle Dart_FunctionIsConstructor(Dart_Handle function, | |
3217 bool* is_constructor) { | |
3218 Isolate* isolate = Isolate::Current(); | |
3219 DARTSCOPE(isolate); | |
3220 if (is_constructor == NULL) { | |
3221 RETURN_NULL_ERROR(is_constructor); | |
3222 } | |
3223 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3224 if (func.IsNull()) { | |
3225 RETURN_TYPE_ERROR(isolate, function, Function); | |
3226 } | |
3227 *is_constructor = func.kind() == RawFunction::kConstructor; | |
3228 return Api::Success(); | |
3229 } | |
3230 | |
3231 | |
3232 DART_EXPORT Dart_Handle Dart_FunctionIsGetter(Dart_Handle function, | |
3233 bool* is_getter) { | |
3234 Isolate* isolate = Isolate::Current(); | |
3235 DARTSCOPE(isolate); | |
3236 if (is_getter == NULL) { | |
3237 RETURN_NULL_ERROR(is_getter); | |
3238 } | |
3239 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3240 if (func.IsNull()) { | |
3241 RETURN_TYPE_ERROR(isolate, function, Function); | |
3242 } | |
3243 *is_getter = func.IsGetterFunction(); | |
3244 return Api::Success(); | |
3245 } | |
3246 | |
3247 | |
3248 DART_EXPORT Dart_Handle Dart_FunctionIsSetter(Dart_Handle function, | |
3249 bool* is_setter) { | |
3250 Isolate* isolate = Isolate::Current(); | |
3251 DARTSCOPE(isolate); | |
3252 if (is_setter == NULL) { | |
3253 RETURN_NULL_ERROR(is_setter); | |
3254 } | |
3255 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3256 if (func.IsNull()) { | |
3257 RETURN_TYPE_ERROR(isolate, function, Function); | |
3258 } | |
3259 *is_setter = (func.kind() == RawFunction::kSetterFunction); | |
3260 return Api::Success(); | |
3261 } | |
3262 | |
3263 | |
3264 DART_EXPORT Dart_Handle Dart_FunctionReturnType(Dart_Handle function) { | |
3265 Isolate* isolate = Isolate::Current(); | |
3266 DARTSCOPE(isolate); | |
3267 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3268 if (func.IsNull()) { | |
3269 RETURN_TYPE_ERROR(isolate, function, Function); | |
3270 } | |
3271 | |
3272 if (func.kind() == RawFunction::kConstructor) { | |
3273 // Special case the return type for constructors. Inside the vm | |
3274 // we mark them as returning dynamic, but for the purposes of | |
3275 // reflection, they return the type of the class being | |
3276 // constructed. | |
3277 return Api::NewHandle(isolate, func.Owner()); | |
3278 } else { | |
3279 const AbstractType& return_type = | |
3280 AbstractType::Handle(isolate, func.result_type()); | |
3281 return TypeToHandle(isolate, "Dart_FunctionReturnType", return_type); | |
3282 } | |
3283 } | |
3284 | |
3285 | |
3286 DART_EXPORT Dart_Handle Dart_FunctionParameterCounts( | |
3287 Dart_Handle function, | |
3288 int64_t* fixed_param_count, | |
3289 int64_t* opt_param_count) { | |
3290 Isolate* isolate = Isolate::Current(); | |
3291 DARTSCOPE(isolate); | |
3292 if (fixed_param_count == NULL) { | |
3293 RETURN_NULL_ERROR(fixed_param_count); | |
3294 } | |
3295 if (opt_param_count == NULL) { | |
3296 RETURN_NULL_ERROR(opt_param_count); | |
3297 } | |
3298 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3299 if (func.IsNull()) { | |
3300 RETURN_TYPE_ERROR(isolate, function, Function); | |
3301 } | |
3302 | |
3303 // We hide implicit parameters, such as a method's receiver. This is | |
3304 // consistent with Invoke or New, which don't expect their callers to | |
3305 // provide them in the argument lists they are handed. | |
3306 *fixed_param_count = func.num_fixed_parameters() - | |
3307 func.NumImplicitParameters(); | |
3308 // TODO(regis): Separately report named and positional optional param counts. | |
3309 *opt_param_count = func.NumOptionalParameters(); | |
3310 | |
3311 ASSERT(*fixed_param_count >= 0); | |
3312 ASSERT(*opt_param_count >= 0); | |
3313 | |
3314 return Api::Success(); | |
3315 } | |
3316 | |
3317 | |
3318 DART_EXPORT Dart_Handle Dart_FunctionParameterType(Dart_Handle function, | |
3319 int parameter_index) { | |
3320 Isolate* isolate = Isolate::Current(); | |
3321 DARTSCOPE(isolate); | |
3322 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
3323 if (func.IsNull()) { | |
3324 RETURN_TYPE_ERROR(isolate, function, Function); | |
3325 } | |
3326 | |
3327 const intptr_t num_implicit_params = func.NumImplicitParameters(); | |
3328 const intptr_t num_params = func.NumParameters() - num_implicit_params; | |
3329 if (parameter_index < 0 || parameter_index >= num_params) { | |
3330 return Api::NewError( | |
3331 "%s: argument 'parameter_index' out of range. " | |
3332 "Expected 0..%"Pd" but saw %d.", | |
3333 CURRENT_FUNC, num_params, parameter_index); | |
3334 } | |
3335 const AbstractType& param_type = | |
3336 AbstractType::Handle(isolate, func.ParameterTypeAt( | |
3337 num_implicit_params + parameter_index)); | |
3338 return TypeToHandle(isolate, "Dart_FunctionParameterType", param_type); | |
3339 } | |
3340 | |
3341 | |
3342 DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) { | |
3343 Isolate* isolate = Isolate::Current(); | |
3344 DARTSCOPE(isolate); | |
3345 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
3346 if (obj.IsError()) { | |
3347 return target; | |
3348 } | |
3349 | |
3350 const GrowableObjectArray& names = | |
3351 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
3352 Field& field = Field::Handle(isolate); | |
3353 String& name = String::Handle(isolate); | |
3354 | |
3355 if (obj.IsClass()) { | |
3356 const Class& cls = Class::Cast(obj); | |
3357 const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate)); | |
3358 if (!error.IsNull()) { | |
3359 return Api::NewHandle(isolate, error.raw()); | |
3360 } | |
3361 const Array& field_array = Array::Handle(cls.fields()); | |
3362 | |
3363 // Some special types like 'dynamic' have a null fields list. | |
3364 // | |
3365 // TODO(turnidge): Fix 'dynamic' so that it does not have a null | |
3366 // fields list. This will have to wait until the empty array is | |
3367 // allocated in the vm isolate. | |
3368 if (!field_array.IsNull()) { | |
3369 for (intptr_t i = 0; i < field_array.Length(); ++i) { | |
3370 field ^= field_array.At(i); | |
3371 name = field.UserVisibleName(); | |
3372 names.Add(name); | |
3373 } | |
3374 } | |
3375 } else if (obj.IsLibrary()) { | |
3376 const Library& lib = Library::Cast(obj); | |
3377 DictionaryIterator it(lib); | |
3378 Object& obj = Object::Handle(isolate); | |
3379 while (it.HasNext()) { | |
3380 obj = it.GetNext(); | |
3381 if (obj.IsField()) { | |
3382 field ^= obj.raw(); | |
3383 name = field.UserVisibleName(); | |
3384 names.Add(name); | |
3385 } | |
3386 } | |
3387 } else { | |
3388 return Api::NewError( | |
3389 "%s expects argument 'target' to be a class or library.", | |
3390 CURRENT_FUNC); | |
3391 } | |
3392 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
3393 } | |
3394 | |
3395 | |
3396 DART_EXPORT Dart_Handle Dart_LookupVariable(Dart_Handle target, | |
3397 Dart_Handle variable_name) { | |
3398 Isolate* isolate = Isolate::Current(); | |
3399 DARTSCOPE(isolate); | |
3400 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
3401 if (obj.IsError()) { | |
3402 return target; | |
3403 } | |
3404 const String& var_name = Api::UnwrapStringHandle(isolate, variable_name); | |
3405 if (var_name.IsNull()) { | |
3406 RETURN_TYPE_ERROR(isolate, variable_name, String); | |
3407 } | |
3408 if (obj.IsClass()) { | |
3409 const Class& cls = Class::Cast(obj); | |
3410 return Api::NewHandle(isolate, cls.LookupField(var_name)); | |
3411 } | |
3412 if (obj.IsLibrary()) { | |
3413 const Library& lib = Library::Cast(obj); | |
3414 return Api::NewHandle(isolate, lib.LookupFieldAllowPrivate(var_name)); | |
3415 } | |
3416 return Api::NewError( | |
3417 "%s expects argument 'target' to be a class or library.", | |
3418 CURRENT_FUNC); | |
3419 } | |
3420 | |
3421 | |
3422 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { | |
3423 return Api::ClassId(handle) == kFieldCid; | |
3424 } | |
3425 | |
3426 | |
3427 DART_EXPORT Dart_Handle Dart_VariableName(Dart_Handle variable) { | |
3428 Isolate* isolate = Isolate::Current(); | |
3429 DARTSCOPE(isolate); | |
3430 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
3431 if (var.IsNull()) { | |
3432 RETURN_TYPE_ERROR(isolate, variable, Field); | |
3433 } | |
3434 return Api::NewHandle(isolate, var.UserVisibleName()); | |
3435 } | |
3436 | |
3437 | |
3438 DART_EXPORT Dart_Handle Dart_VariableIsStatic(Dart_Handle variable, | |
3439 bool* is_static) { | |
3440 Isolate* isolate = Isolate::Current(); | |
3441 DARTSCOPE(isolate); | |
3442 if (is_static == NULL) { | |
3443 RETURN_NULL_ERROR(is_static); | |
3444 } | |
3445 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
3446 if (var.IsNull()) { | |
3447 RETURN_TYPE_ERROR(isolate, variable, Field); | |
3448 } | |
3449 *is_static = var.is_static(); | |
3450 return Api::Success(); | |
3451 } | |
3452 | |
3453 | |
3454 DART_EXPORT Dart_Handle Dart_VariableIsFinal(Dart_Handle variable, | |
3455 bool* is_final) { | |
3456 Isolate* isolate = Isolate::Current(); | |
3457 DARTSCOPE(isolate); | |
3458 if (is_final == NULL) { | |
3459 RETURN_NULL_ERROR(is_final); | |
3460 } | |
3461 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
3462 if (var.IsNull()) { | |
3463 RETURN_TYPE_ERROR(isolate, variable, Field); | |
3464 } | |
3465 *is_final = var.is_final(); | |
3466 return Api::Success(); | |
3467 } | |
3468 | |
3469 | |
3470 DART_EXPORT Dart_Handle Dart_VariableType(Dart_Handle variable) { | |
3471 Isolate* isolate = Isolate::Current(); | |
3472 DARTSCOPE(isolate); | |
3473 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
3474 if (var.IsNull()) { | |
3475 RETURN_TYPE_ERROR(isolate, variable, Field); | |
3476 } | |
3477 | |
3478 const AbstractType& type = AbstractType::Handle(isolate, var.type()); | |
3479 return TypeToHandle(isolate, "Dart_VariableType", type); | |
3480 } | |
3481 | |
3482 | |
3483 DART_EXPORT Dart_Handle Dart_GetTypeVariableNames(Dart_Handle clazz) { | |
3484 Isolate* isolate = Isolate::Current(); | |
3485 DARTSCOPE(isolate); | |
3486 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
3487 if (cls.IsNull()) { | |
3488 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
3489 } | |
3490 | |
3491 const intptr_t num_type_params = cls.NumTypeParameters(); | |
3492 const TypeArguments& type_params = | |
3493 TypeArguments::Handle(cls.type_parameters()); | |
3494 | |
3495 const GrowableObjectArray& names = | |
3496 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
3497 TypeParameter& type_param = TypeParameter::Handle(isolate); | |
3498 String& name = String::Handle(isolate); | |
3499 for (intptr_t i = 0; i < num_type_params; i++) { | |
3500 type_param ^= type_params.TypeAt(i); | |
3501 name = type_param.name(); | |
3502 names.Add(name); | |
3503 } | |
3504 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
3505 } | |
3506 | |
3507 | |
3508 DART_EXPORT Dart_Handle Dart_LookupTypeVariable( | |
3509 Dart_Handle clazz, | |
3510 Dart_Handle type_variable_name) { | |
3511 Isolate* isolate = Isolate::Current(); | |
3512 DARTSCOPE(isolate); | |
3513 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); | |
3514 if (cls.IsNull()) { | |
3515 RETURN_TYPE_ERROR(isolate, clazz, Class); | |
3516 } | |
3517 const String& var_name = Api::UnwrapStringHandle(isolate, type_variable_name); | |
3518 if (var_name.IsNull()) { | |
3519 RETURN_TYPE_ERROR(isolate, type_variable_name, String); | |
3520 } | |
3521 | |
3522 const intptr_t num_type_params = cls.NumTypeParameters(); | |
3523 const TypeArguments& type_params = | |
3524 TypeArguments::Handle(cls.type_parameters()); | |
3525 | |
3526 TypeParameter& type_param = TypeParameter::Handle(isolate); | |
3527 String& name = String::Handle(isolate); | |
3528 for (intptr_t i = 0; i < num_type_params; i++) { | |
3529 type_param ^= type_params.TypeAt(i); | |
3530 name = type_param.name(); | |
3531 if (name.Equals(var_name)) { | |
3532 return Api::NewHandle(isolate, type_param.raw()); | |
3533 } | |
3534 } | |
3535 const String& cls_name = String::Handle(cls.UserVisibleName()); | |
3536 return Api::NewError( | |
3537 "%s: Could not find type variable named '%s' for class %s.\n", | |
3538 CURRENT_FUNC, var_name.ToCString(), cls_name.ToCString()); | |
3539 } | |
3540 | |
3541 | |
3542 DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) { | |
3543 return Api::ClassId(handle) == kTypeParameterCid; | |
3544 } | |
3545 | |
3546 DART_EXPORT Dart_Handle Dart_TypeVariableName(Dart_Handle type_variable) { | |
3547 Isolate* isolate = Isolate::Current(); | |
3548 DARTSCOPE(isolate); | |
3549 const TypeParameter& type_var = | |
3550 Api::UnwrapTypeParameterHandle(isolate, type_variable); | |
3551 if (type_var.IsNull()) { | |
3552 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); | |
3553 } | |
3554 return Api::NewHandle(isolate, type_var.name()); | |
3555 } | |
3556 | |
3557 | |
3558 DART_EXPORT Dart_Handle Dart_TypeVariableOwner(Dart_Handle type_variable) { | |
3559 Isolate* isolate = Isolate::Current(); | |
3560 DARTSCOPE(isolate); | |
3561 const TypeParameter& type_var = | |
3562 Api::UnwrapTypeParameterHandle(isolate, type_variable); | |
3563 if (type_var.IsNull()) { | |
3564 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); | |
3565 } | |
3566 const Class& owner = Class::Handle(type_var.parameterized_class()); | |
3567 ASSERT(!owner.IsNull() && owner.IsClass()); | |
3568 return Api::NewHandle(isolate, owner.raw()); | |
3569 } | |
3570 | |
3571 | |
3572 DART_EXPORT Dart_Handle Dart_TypeVariableUpperBound(Dart_Handle type_variable) { | |
3573 Isolate* isolate = Isolate::Current(); | |
3574 DARTSCOPE(isolate); | |
3575 const TypeParameter& type_var = | |
3576 Api::UnwrapTypeParameterHandle(isolate, type_variable); | |
3577 if (type_var.IsNull()) { | |
3578 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); | |
3579 } | |
3580 const AbstractType& bound = AbstractType::Handle(type_var.bound()); | |
3581 return TypeToHandle(isolate, "Dart_TypeVariableUpperBound", bound); | |
3582 } | |
3583 | |
3584 | |
3585 // --- Constructors, Methods, and Fields --- | |
3586 | |
3587 | 2661 |
3588 static RawObject* ResolveConstructor(const char* current_func, | 2662 static RawObject* ResolveConstructor(const char* current_func, |
3589 const Class& cls, | 2663 const Class& cls, |
3590 const String& class_name, | 2664 const String& class_name, |
3591 const String& constr_name, | 2665 const String& constr_name, |
3592 int num_args) { | 2666 int num_args) { |
3593 // The constructor must be present in the interface. | 2667 // The constructor must be present in the interface. |
3594 const Function& constructor = | 2668 const Function& constructor = |
3595 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name)); | 2669 Function::Handle(cls.LookupFunctionAllowPrivate(constr_name)); |
3596 if (constructor.IsNull() || | 2670 if (constructor.IsNull() || |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3872 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); | 2946 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); |
3873 | 2947 |
3874 } else { | 2948 } else { |
3875 return Api::NewError( | 2949 return Api::NewError( |
3876 "%s expects argument 'target' to be an object, class, or library.", | 2950 "%s expects argument 'target' to be an object, class, or library.", |
3877 CURRENT_FUNC); | 2951 CURRENT_FUNC); |
3878 } | 2952 } |
3879 } | 2953 } |
3880 | 2954 |
3881 | 2955 |
| 2956 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, |
| 2957 int number_of_arguments, |
| 2958 Dart_Handle* arguments) { |
| 2959 Isolate* isolate = Isolate::Current(); |
| 2960 DARTSCOPE(isolate); |
| 2961 CHECK_CALLBACK_STATE(isolate); |
| 2962 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure); |
| 2963 if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) { |
| 2964 RETURN_TYPE_ERROR(isolate, closure, Instance); |
| 2965 } |
| 2966 if (number_of_arguments < 0) { |
| 2967 return Api::NewError( |
| 2968 "%s expects argument 'number_of_arguments' to be non-negative.", |
| 2969 CURRENT_FUNC); |
| 2970 } |
| 2971 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 2972 |
| 2973 // Set up arguments to include the closure as the first argument. |
| 2974 const Array& args = Array::Handle(isolate, |
| 2975 Array::New(number_of_arguments + 1)); |
| 2976 Object& obj = Object::Handle(isolate); |
| 2977 args.SetAt(0, closure_obj); |
| 2978 for (int i = 0; i < number_of_arguments; i++) { |
| 2979 obj = Api::UnwrapHandle(arguments[i]); |
| 2980 if (!obj.IsNull() && !obj.IsInstance()) { |
| 2981 RETURN_TYPE_ERROR(isolate, arguments[i], Instance); |
| 2982 } |
| 2983 args.SetAt(i + 1, obj); |
| 2984 } |
| 2985 // Now try to invoke the closure. |
| 2986 return Api::NewHandle(isolate, DartEntry::InvokeClosure(args)); |
| 2987 } |
| 2988 |
| 2989 |
3882 static bool FieldIsUninitialized(Isolate* isolate, const Field& fld) { | 2990 static bool FieldIsUninitialized(Isolate* isolate, const Field& fld) { |
3883 ASSERT(!fld.IsNull()); | 2991 ASSERT(!fld.IsNull()); |
3884 | 2992 |
3885 // Return getter method for uninitialized fields, rather than the | 2993 // Return getter method for uninitialized fields, rather than the |
3886 // field object, since the value in the field object will not be | 2994 // field object, since the value in the field object will not be |
3887 // initialized until the first time the getter is invoked. | 2995 // initialized until the first time the getter is invoked. |
3888 const Instance& value = Instance::Handle(isolate, fld.value()); | 2996 const Instance& value = Instance::Handle(isolate, fld.value()); |
3889 ASSERT(value.raw() != Object::transition_sentinel().raw()); | 2997 ASSERT(value.raw() != Object::transition_sentinel().raw()); |
3890 return value.raw() == Object::sentinel().raw(); | 2998 return value.raw() == Object::sentinel().raw(); |
3891 } | 2999 } |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4149 } else if (obj.IsError()) { | 3257 } else if (obj.IsError()) { |
4150 return container; | 3258 return container; |
4151 } else { | 3259 } else { |
4152 return Api::NewError( | 3260 return Api::NewError( |
4153 "%s expects argument 'container' to be an object, class, or library.", | 3261 "%s expects argument 'container' to be an object, class, or library.", |
4154 CURRENT_FUNC); | 3262 CURRENT_FUNC); |
4155 } | 3263 } |
4156 } | 3264 } |
4157 | 3265 |
4158 | 3266 |
| 3267 // --- Exceptions ---- |
| 3268 |
| 3269 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { |
| 3270 Isolate* isolate = Isolate::Current(); |
| 3271 CHECK_ISOLATE(isolate); |
| 3272 CHECK_CALLBACK_STATE(isolate); |
| 3273 { |
| 3274 const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); |
| 3275 if (excp.IsNull()) { |
| 3276 RETURN_TYPE_ERROR(isolate, exception, Instance); |
| 3277 } |
| 3278 } |
| 3279 if (isolate->top_exit_frame_info() == 0) { |
| 3280 // There are no dart frames on the stack so it would be illegal to |
| 3281 // throw an exception here. |
| 3282 return Api::NewError("No Dart frames on stack, cannot throw exception"); |
| 3283 } |
| 3284 |
| 3285 // Unwind all the API scopes till the exit frame before throwing an |
| 3286 // exception. |
| 3287 ApiState* state = isolate->api_state(); |
| 3288 ASSERT(state != NULL); |
| 3289 const Instance* saved_exception; |
| 3290 { |
| 3291 NoGCScope no_gc; |
| 3292 RawInstance* raw_exception = |
| 3293 Api::UnwrapInstanceHandle(isolate, exception).raw(); |
| 3294 state->UnwindScopes(isolate->top_exit_frame_info()); |
| 3295 saved_exception = &Instance::Handle(raw_exception); |
| 3296 } |
| 3297 Exceptions::Throw(*saved_exception); |
| 3298 return Api::NewError("Exception was not thrown, internal error"); |
| 3299 } |
| 3300 |
| 3301 |
| 3302 DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception, |
| 3303 Dart_Handle stacktrace) { |
| 3304 Isolate* isolate = Isolate::Current(); |
| 3305 CHECK_ISOLATE(isolate); |
| 3306 CHECK_CALLBACK_STATE(isolate); |
| 3307 { |
| 3308 const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); |
| 3309 if (excp.IsNull()) { |
| 3310 RETURN_TYPE_ERROR(isolate, exception, Instance); |
| 3311 } |
| 3312 const Instance& stk = Api::UnwrapInstanceHandle(isolate, stacktrace); |
| 3313 if (stk.IsNull()) { |
| 3314 RETURN_TYPE_ERROR(isolate, stacktrace, Instance); |
| 3315 } |
| 3316 } |
| 3317 if (isolate->top_exit_frame_info() == 0) { |
| 3318 // There are no dart frames on the stack so it would be illegal to |
| 3319 // throw an exception here. |
| 3320 return Api::NewError("No Dart frames on stack, cannot throw exception"); |
| 3321 } |
| 3322 |
| 3323 // Unwind all the API scopes till the exit frame before throwing an |
| 3324 // exception. |
| 3325 ApiState* state = isolate->api_state(); |
| 3326 ASSERT(state != NULL); |
| 3327 const Instance* saved_exception; |
| 3328 const Instance* saved_stacktrace; |
| 3329 { |
| 3330 NoGCScope no_gc; |
| 3331 RawInstance* raw_exception = |
| 3332 Api::UnwrapInstanceHandle(isolate, exception).raw(); |
| 3333 RawInstance* raw_stacktrace = |
| 3334 Api::UnwrapInstanceHandle(isolate, stacktrace).raw(); |
| 3335 state->UnwindScopes(isolate->top_exit_frame_info()); |
| 3336 saved_exception = &Instance::Handle(raw_exception); |
| 3337 saved_stacktrace = &Instance::Handle(raw_stacktrace); |
| 3338 } |
| 3339 Exceptions::ReThrow(*saved_exception, *saved_stacktrace); |
| 3340 return Api::NewError("Exception was not re thrown, internal error"); |
| 3341 } |
| 3342 |
| 3343 |
| 3344 // --- Native fields and functions --- |
| 3345 |
4159 DART_EXPORT Dart_Handle Dart_CreateNativeWrapperClass(Dart_Handle library, | 3346 DART_EXPORT Dart_Handle Dart_CreateNativeWrapperClass(Dart_Handle library, |
4160 Dart_Handle name, | 3347 Dart_Handle name, |
4161 int field_count) { | 3348 int field_count) { |
4162 Isolate* isolate = Isolate::Current(); | 3349 Isolate* isolate = Isolate::Current(); |
4163 DARTSCOPE(isolate); | 3350 DARTSCOPE(isolate); |
4164 const String& cls_name = Api::UnwrapStringHandle(isolate, name); | 3351 const String& cls_name = Api::UnwrapStringHandle(isolate, name); |
4165 if (cls_name.IsNull()) { | 3352 if (cls_name.IsNull()) { |
4166 RETURN_TYPE_ERROR(isolate, name, String); | 3353 RETURN_TYPE_ERROR(isolate, name, String); |
4167 } | 3354 } |
4168 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 3355 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4231 if (!instance.IsValidNativeIndex(index)) { | 3418 if (!instance.IsValidNativeIndex(index)) { |
4232 return Api::NewError( | 3419 return Api::NewError( |
4233 "%s: invalid index %d passed in to set native instance field", | 3420 "%s: invalid index %d passed in to set native instance field", |
4234 CURRENT_FUNC, index); | 3421 CURRENT_FUNC, index); |
4235 } | 3422 } |
4236 instance.SetNativeField(index, value); | 3423 instance.SetNativeField(index, value); |
4237 return Api::Success(); | 3424 return Api::Success(); |
4238 } | 3425 } |
4239 | 3426 |
4240 | 3427 |
4241 // --- Exceptions ---- | |
4242 | |
4243 | |
4244 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { | |
4245 Isolate* isolate = Isolate::Current(); | |
4246 CHECK_ISOLATE(isolate); | |
4247 CHECK_CALLBACK_STATE(isolate); | |
4248 { | |
4249 const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); | |
4250 if (excp.IsNull()) { | |
4251 RETURN_TYPE_ERROR(isolate, exception, Instance); | |
4252 } | |
4253 } | |
4254 if (isolate->top_exit_frame_info() == 0) { | |
4255 // There are no dart frames on the stack so it would be illegal to | |
4256 // throw an exception here. | |
4257 return Api::NewError("No Dart frames on stack, cannot throw exception"); | |
4258 } | |
4259 | |
4260 // Unwind all the API scopes till the exit frame before throwing an | |
4261 // exception. | |
4262 ApiState* state = isolate->api_state(); | |
4263 ASSERT(state != NULL); | |
4264 const Instance* saved_exception; | |
4265 { | |
4266 NoGCScope no_gc; | |
4267 RawInstance* raw_exception = | |
4268 Api::UnwrapInstanceHandle(isolate, exception).raw(); | |
4269 state->UnwindScopes(isolate->top_exit_frame_info()); | |
4270 saved_exception = &Instance::Handle(raw_exception); | |
4271 } | |
4272 Exceptions::Throw(*saved_exception); | |
4273 return Api::NewError("Exception was not thrown, internal error"); | |
4274 } | |
4275 | |
4276 | |
4277 DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception, | |
4278 Dart_Handle stacktrace) { | |
4279 Isolate* isolate = Isolate::Current(); | |
4280 CHECK_ISOLATE(isolate); | |
4281 CHECK_CALLBACK_STATE(isolate); | |
4282 { | |
4283 const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); | |
4284 if (excp.IsNull()) { | |
4285 RETURN_TYPE_ERROR(isolate, exception, Instance); | |
4286 } | |
4287 const Instance& stk = Api::UnwrapInstanceHandle(isolate, stacktrace); | |
4288 if (stk.IsNull()) { | |
4289 RETURN_TYPE_ERROR(isolate, stacktrace, Instance); | |
4290 } | |
4291 } | |
4292 if (isolate->top_exit_frame_info() == 0) { | |
4293 // There are no dart frames on the stack so it would be illegal to | |
4294 // throw an exception here. | |
4295 return Api::NewError("No Dart frames on stack, cannot throw exception"); | |
4296 } | |
4297 | |
4298 // Unwind all the API scopes till the exit frame before throwing an | |
4299 // exception. | |
4300 ApiState* state = isolate->api_state(); | |
4301 ASSERT(state != NULL); | |
4302 const Instance* saved_exception; | |
4303 const Instance* saved_stacktrace; | |
4304 { | |
4305 NoGCScope no_gc; | |
4306 RawInstance* raw_exception = | |
4307 Api::UnwrapInstanceHandle(isolate, exception).raw(); | |
4308 RawInstance* raw_stacktrace = | |
4309 Api::UnwrapInstanceHandle(isolate, stacktrace).raw(); | |
4310 state->UnwindScopes(isolate->top_exit_frame_info()); | |
4311 saved_exception = &Instance::Handle(raw_exception); | |
4312 saved_stacktrace = &Instance::Handle(raw_stacktrace); | |
4313 } | |
4314 Exceptions::ReThrow(*saved_exception, *saved_stacktrace); | |
4315 return Api::NewError("Exception was not re thrown, internal error"); | |
4316 } | |
4317 | |
4318 | |
4319 // --- Native functions --- | |
4320 | |
4321 | |
4322 DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, | 3428 DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, |
4323 int index) { | 3429 int index) { |
4324 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 3430 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
4325 if ((index < 0) || (index >= arguments->NativeArgCount())) { | 3431 if ((index < 0) || (index >= arguments->NativeArgCount())) { |
4326 return Api::NewError( | 3432 return Api::NewError( |
4327 "%s: argument 'index' out of range. Expected 0..%d but saw %d.", | 3433 "%s: argument 'index' out of range. Expected 0..%d but saw %d.", |
4328 CURRENT_FUNC, arguments->NativeArgCount() - 1, index); | 3434 CURRENT_FUNC, arguments->NativeArgCount() - 1, index); |
4329 } | 3435 } |
4330 return Api::NewHandle(arguments->isolate(), arguments->NativeArgAt(index)); | 3436 return Api::NewHandle(arguments->isolate(), arguments->NativeArgAt(index)); |
4331 } | 3437 } |
(...skipping 11 matching lines...) Expand all Loading... |
4343 if (!ret_obj.IsNull() && !ret_obj.IsInstance()) { | 3449 if (!ret_obj.IsNull() && !ret_obj.IsInstance()) { |
4344 FATAL1("Return value check failed: saw '%s' expected a dart Instance.", | 3450 FATAL1("Return value check failed: saw '%s' expected a dart Instance.", |
4345 ret_obj.ToCString()); | 3451 ret_obj.ToCString()); |
4346 } | 3452 } |
4347 NoGCScope no_gc_scope; | 3453 NoGCScope no_gc_scope; |
4348 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 3454 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
4349 arguments->SetReturn(ret_obj); | 3455 arguments->SetReturn(ret_obj); |
4350 } | 3456 } |
4351 | 3457 |
4352 | 3458 |
4353 // --- Metadata ---- | |
4354 | |
4355 DART_EXPORT Dart_Handle Dart_GetMetadata(Dart_Handle object) { | |
4356 Isolate* isolate = Isolate::Current(); | |
4357 CHECK_ISOLATE(isolate); | |
4358 DARTSCOPE(isolate); | |
4359 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
4360 Class& cls = Class::Handle(isolate); | |
4361 if (obj.IsClass()) { | |
4362 cls ^= obj.raw(); | |
4363 } else if (obj.IsFunction()) { | |
4364 cls = Function::Cast(obj).origin(); | |
4365 } else if (obj.IsField()) { | |
4366 cls = Field::Cast(obj).origin(); | |
4367 } else { | |
4368 return Api::NewHandle(isolate, Object::empty_array().raw()); | |
4369 } | |
4370 const Library& lib = Library::Handle(cls.library()); | |
4371 return Api::NewHandle(isolate, lib.GetMetadata(obj)); | |
4372 } | |
4373 | |
4374 | |
4375 // --- Scripts and Libraries --- | 3459 // --- Scripts and Libraries --- |
4376 | 3460 |
4377 | |
4378 DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler( | 3461 DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler( |
4379 Dart_LibraryTagHandler handler) { | 3462 Dart_LibraryTagHandler handler) { |
4380 Isolate* isolate = Isolate::Current(); | 3463 Isolate* isolate = Isolate::Current(); |
4381 CHECK_ISOLATE(isolate); | 3464 CHECK_ISOLATE(isolate); |
4382 isolate->set_library_tag_handler(handler); | 3465 isolate->set_library_tag_handler(handler); |
4383 return Api::Success(); | 3466 return Api::Success(); |
4384 } | 3467 } |
4385 | 3468 |
4386 | 3469 |
4387 // NOTE: Need to pass 'result' as a parameter here in order to avoid | 3470 // NOTE: Need to pass 'result' as a parameter here in order to avoid |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4505 | 3588 |
4506 DART_EXPORT Dart_Handle Dart_RootLibrary() { | 3589 DART_EXPORT Dart_Handle Dart_RootLibrary() { |
4507 Isolate* isolate = Isolate::Current(); | 3590 Isolate* isolate = Isolate::Current(); |
4508 DARTSCOPE(isolate); | 3591 DARTSCOPE(isolate); |
4509 Library& library = | 3592 Library& library = |
4510 Library::Handle(isolate, isolate->object_store()->root_library()); | 3593 Library::Handle(isolate, isolate->object_store()->root_library()); |
4511 return Api::NewHandle(isolate, library.raw()); | 3594 return Api::NewHandle(isolate, library.raw()); |
4512 } | 3595 } |
4513 | 3596 |
4514 | 3597 |
4515 static void CompileAll(Isolate* isolate, Dart_Handle* result) { | |
4516 ASSERT(isolate != NULL); | |
4517 const Error& error = Error::Handle(isolate, Library::CompileAll()); | |
4518 if (error.IsNull()) { | |
4519 *result = Api::Success(); | |
4520 } else { | |
4521 *result = Api::NewHandle(isolate, error.raw()); | |
4522 } | |
4523 } | |
4524 | |
4525 | |
4526 DART_EXPORT Dart_Handle Dart_CompileAll() { | |
4527 Isolate* isolate = Isolate::Current(); | |
4528 DARTSCOPE(isolate); | |
4529 Dart_Handle result = Api::CheckIsolateState(isolate); | |
4530 if (::Dart_IsError(result)) { | |
4531 return result; | |
4532 } | |
4533 CHECK_CALLBACK_STATE(isolate); | |
4534 CompileAll(isolate, &result); | |
4535 return result; | |
4536 } | |
4537 | |
4538 | |
4539 DART_EXPORT Dart_Handle Dart_CheckFunctionFingerprints() { | |
4540 Isolate* isolate = Isolate::Current(); | |
4541 DARTSCOPE(isolate); | |
4542 Dart_Handle result = Api::CheckIsolateState(isolate); | |
4543 if (::Dart_IsError(result)) { | |
4544 return result; | |
4545 } | |
4546 CHECK_CALLBACK_STATE(isolate); | |
4547 Library::CheckFunctionFingerprints(); | |
4548 return result; | |
4549 } | |
4550 | |
4551 | |
4552 DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { | |
4553 return Api::ClassId(object) == kLibraryCid; | |
4554 } | |
4555 | |
4556 | |
4557 DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, | 3598 DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, |
4558 Dart_Handle class_name) { | 3599 Dart_Handle class_name) { |
4559 Isolate* isolate = Isolate::Current(); | 3600 Isolate* isolate = Isolate::Current(); |
4560 DARTSCOPE(isolate); | 3601 DARTSCOPE(isolate); |
4561 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 3602 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
4562 if (lib.IsNull()) { | 3603 if (lib.IsNull()) { |
4563 RETURN_TYPE_ERROR(isolate, library, Library); | 3604 RETURN_TYPE_ERROR(isolate, library, Library); |
4564 } | 3605 } |
4565 const String& cls_name = Api::UnwrapStringHandle(isolate, class_name); | 3606 const String& cls_name = Api::UnwrapStringHandle(isolate, class_name); |
4566 if (cls_name.IsNull()) { | 3607 if (cls_name.IsNull()) { |
4567 RETURN_TYPE_ERROR(isolate, class_name, String); | 3608 RETURN_TYPE_ERROR(isolate, class_name, String); |
4568 } | 3609 } |
4569 const Class& cls = | 3610 const Class& cls = |
4570 Class::Handle(isolate, lib.LookupClassAllowPrivate(cls_name)); | 3611 Class::Handle(isolate, lib.LookupClassAllowPrivate(cls_name)); |
4571 if (cls.IsNull()) { | 3612 if (cls.IsNull()) { |
4572 // TODO(turnidge): Return null or error in this case? | 3613 // TODO(turnidge): Return null or error in this case? |
4573 const String& lib_name = String::Handle(isolate, lib.name()); | 3614 const String& lib_name = String::Handle(isolate, lib.name()); |
4574 return Api::NewError("Class '%s' not found in library '%s'.", | 3615 return Api::NewError("Class '%s' not found in library '%s'.", |
4575 cls_name.ToCString(), lib_name.ToCString()); | 3616 cls_name.ToCString(), lib_name.ToCString()); |
4576 } | 3617 } |
4577 return Api::NewHandle(isolate, cls.raw()); | 3618 return Api::NewHandle(isolate, cls.raw()); |
4578 } | 3619 } |
4579 | 3620 |
4580 | 3621 |
4581 DART_EXPORT Dart_Handle Dart_LibraryName(Dart_Handle library) { | |
4582 Isolate* isolate = Isolate::Current(); | |
4583 DARTSCOPE(isolate); | |
4584 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | |
4585 if (lib.IsNull()) { | |
4586 RETURN_TYPE_ERROR(isolate, library, Library); | |
4587 } | |
4588 const String& name = String::Handle(isolate, lib.name()); | |
4589 ASSERT(!name.IsNull()); | |
4590 return Api::NewHandle(isolate, name.raw()); | |
4591 } | |
4592 | |
4593 | |
4594 DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) { | 3622 DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) { |
4595 Isolate* isolate = Isolate::Current(); | 3623 Isolate* isolate = Isolate::Current(); |
4596 DARTSCOPE(isolate); | 3624 DARTSCOPE(isolate); |
4597 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 3625 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
4598 if (lib.IsNull()) { | 3626 if (lib.IsNull()) { |
4599 RETURN_TYPE_ERROR(isolate, library, Library); | 3627 RETURN_TYPE_ERROR(isolate, library, Library); |
4600 } | 3628 } |
4601 const String& url = String::Handle(isolate, lib.url()); | 3629 const String& url = String::Handle(isolate, lib.url()); |
4602 ASSERT(!url.IsNull()); | 3630 ASSERT(!url.IsNull()); |
4603 return Api::NewHandle(isolate, url.raw()); | 3631 return Api::NewHandle(isolate, url.raw()); |
4604 } | 3632 } |
4605 | 3633 |
4606 | 3634 |
4607 DART_EXPORT Dart_Handle Dart_LibraryGetClassNames(Dart_Handle library) { | |
4608 Isolate* isolate = Isolate::Current(); | |
4609 DARTSCOPE(isolate); | |
4610 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | |
4611 if (lib.IsNull()) { | |
4612 RETURN_TYPE_ERROR(isolate, library, Library); | |
4613 } | |
4614 | |
4615 const GrowableObjectArray& names = | |
4616 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
4617 ClassDictionaryIterator it(lib); | |
4618 Class& cls = Class::Handle(); | |
4619 String& name = String::Handle(); | |
4620 while (it.HasNext()) { | |
4621 cls = it.GetNextClass(); | |
4622 if (cls.IsSignatureClass()) { | |
4623 if (!cls.IsCanonicalSignatureClass()) { | |
4624 // This is a typedef. Add it to the list of class names. | |
4625 name = cls.UserVisibleName(); | |
4626 names.Add(name); | |
4627 } else { | |
4628 // Skip canonical signature classes. These are not named. | |
4629 } | |
4630 } else { | |
4631 name = cls.UserVisibleName(); | |
4632 names.Add(name); | |
4633 } | |
4634 } | |
4635 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
4636 } | |
4637 | |
4638 | |
4639 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { | 3635 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { |
4640 Isolate* isolate = Isolate::Current(); | 3636 Isolate* isolate = Isolate::Current(); |
4641 DARTSCOPE(isolate); | 3637 DARTSCOPE(isolate); |
4642 const String& url_str = Api::UnwrapStringHandle(isolate, url); | 3638 const String& url_str = Api::UnwrapStringHandle(isolate, url); |
4643 if (url_str.IsNull()) { | 3639 if (url_str.IsNull()) { |
4644 RETURN_TYPE_ERROR(isolate, url, String); | 3640 RETURN_TYPE_ERROR(isolate, url, String); |
4645 } | 3641 } |
4646 const Library& library = | 3642 const Library& library = |
4647 Library::Handle(isolate, Library::LookupLibrary(url_str)); | 3643 Library::Handle(isolate, Library::LookupLibrary(url_str)); |
4648 if (library.IsNull()) { | 3644 if (library.IsNull()) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4806 DARTSCOPE(isolate); | 3802 DARTSCOPE(isolate); |
4807 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 3803 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
4808 if (lib.IsNull()) { | 3804 if (lib.IsNull()) { |
4809 RETURN_TYPE_ERROR(isolate, library, Library); | 3805 RETURN_TYPE_ERROR(isolate, library, Library); |
4810 } | 3806 } |
4811 lib.set_native_entry_resolver(resolver); | 3807 lib.set_native_entry_resolver(resolver); |
4812 return Api::Success(); | 3808 return Api::Success(); |
4813 } | 3809 } |
4814 | 3810 |
4815 | 3811 |
4816 // --- Profiling support --- | |
4817 | |
4818 // TODO(7565): Dartium should use the new VM flag "generate_pprof_symbols" for | |
4819 // pprof profiling. Then these symbols should be removed. | |
4820 | |
4821 DART_EXPORT void Dart_InitPprofSupport() { } | |
4822 | |
4823 DART_EXPORT void Dart_GetPprofSymbolInfo(void** buffer, int* buffer_size) { | |
4824 *buffer = NULL; | |
4825 *buffer_size = 0; | |
4826 } | |
4827 | |
4828 | |
4829 // --- Peer support --- | 3812 // --- Peer support --- |
4830 | 3813 |
4831 | |
4832 DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) { | 3814 DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) { |
4833 if (peer == NULL) { | 3815 if (peer == NULL) { |
4834 RETURN_NULL_ERROR(peer); | 3816 RETURN_NULL_ERROR(peer); |
4835 } | 3817 } |
4836 Isolate* isolate = Isolate::Current(); | 3818 Isolate* isolate = Isolate::Current(); |
4837 DARTSCOPE(isolate); | 3819 DARTSCOPE(isolate); |
4838 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | 3820 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
4839 if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) { | 3821 if (obj.IsNull() || obj.IsNumber() || obj.IsBool()) { |
4840 const char* msg = | 3822 const char* msg = |
4841 "%s: argument 'object' cannot be a subtype of Null, num, or bool"; | 3823 "%s: argument 'object' cannot be a subtype of Null, num, or bool"; |
(...skipping 19 matching lines...) Expand all Loading... |
4861 } | 3843 } |
4862 { | 3844 { |
4863 NoGCScope no_gc; | 3845 NoGCScope no_gc; |
4864 RawObject* raw_obj = obj.raw(); | 3846 RawObject* raw_obj = obj.raw(); |
4865 isolate->heap()->SetPeer(raw_obj, peer); | 3847 isolate->heap()->SetPeer(raw_obj, peer); |
4866 } | 3848 } |
4867 return Api::Success(); | 3849 return Api::Success(); |
4868 } | 3850 } |
4869 | 3851 |
4870 } // namespace dart | 3852 } // namespace dart |
OLD | NEW |