Index: runtime/vm/dart_api_impl.cc |
=================================================================== |
--- runtime/vm/dart_api_impl.cc (revision 24032) |
+++ runtime/vm/dart_api_impl.cc (working copy) |
@@ -3,6 +3,8 @@ |
// BSD-style license that can be found in the LICENSE file. |
#include "include/dart_api.h" |
+#include "include/dart_mirrors_api.h" |
+#include "include/dart_native_api.h" |
#include "platform/assert.h" |
#include "vm/bigint_operations.h" |
@@ -18,8 +20,8 @@ |
#include "vm/flags.h" |
#include "vm/growable_array.h" |
#include "vm/message.h" |
+#include "vm/message_handler.h" |
#include "vm/native_entry.h" |
-#include "vm/native_message_handler.h" |
#include "vm/object.h" |
#include "vm/object_store.h" |
#include "vm/port.h" |
@@ -51,39 +53,25 @@ |
} |
-#define RETURN_TYPE_ERROR(isolate, dart_handle, type) \ |
- do { \ |
- const Object& tmp = \ |
- Object::Handle(isolate, Api::UnwrapHandle((dart_handle))); \ |
- if (tmp.IsNull()) { \ |
- return Api::NewError("%s expects argument '%s' to be non-null.", \ |
- CURRENT_FUNC, #dart_handle); \ |
- } else if (tmp.IsError()) { \ |
- return dart_handle; \ |
- } else { \ |
- return Api::NewError("%s expects argument '%s' to be of type %s.", \ |
- CURRENT_FUNC, #dart_handle, #type); \ |
- } \ |
- } while (0) |
+static RawInstance* GetListInstance(Isolate* isolate, const Object& obj) { |
+ if (obj.IsInstance()) { |
+ const Instance& instance = Instance::Cast(obj); |
+ const Class& obj_class = Class::Handle(isolate, obj.clazz()); |
+ const Class& list_class = |
+ Class::Handle(isolate, isolate->object_store()->list_class()); |
+ Error& malformed_type_error = Error::Handle(isolate); |
+ if (obj_class.IsSubtypeOf(TypeArguments::Handle(isolate), |
+ list_class, |
+ TypeArguments::Handle(isolate), |
+ &malformed_type_error)) { |
+ ASSERT(malformed_type_error.IsNull()); // Type is a raw List. |
+ return instance.raw(); |
+ } |
+ } |
+ return Instance::null(); |
+} |
-#define RETURN_NULL_ERROR(parameter) \ |
- return Api::NewError("%s expects argument '%s' to be non-null.", \ |
- CURRENT_FUNC, #parameter); |
- |
- |
-#define CHECK_LENGTH(length, max_elements) \ |
- do { \ |
- intptr_t len = (length); \ |
- intptr_t max = (max_elements); \ |
- if (len < 0 || len > max) { \ |
- return Api::NewError( \ |
- "%s expects argument '%s' to be in the range [0..%"Pd"].", \ |
- CURRENT_FUNC, #length, max); \ |
- } \ |
- } while (0) |
- |
- |
Dart_Handle Api::NewHandle(Isolate* isolate, RawObject* raw) { |
LocalHandles* local_handles = Api::TopScope(isolate)->local_handles(); |
ASSERT(local_handles != NULL); |
@@ -92,6 +80,7 @@ |
return reinterpret_cast<Dart_Handle>(ref); |
} |
+ |
RawObject* Api::UnwrapHandle(Dart_Handle object) { |
#if defined(DEBUG) |
Isolate* isolate = Isolate::Current(); |
@@ -108,6 +97,7 @@ |
return (reinterpret_cast<LocalHandle*>(object))->raw(); |
} |
+ |
#define DEFINE_UNWRAP(type) \ |
const type& Api::Unwrap##type##Handle(Isolate* iso, \ |
Dart_Handle dart_handle) { \ |
@@ -267,36 +257,8 @@ |
} |
-// When we want to return a handle to a type to the user, we handle |
-// class-types differently than some other types. |
-static Dart_Handle TypeToHandle(Isolate* isolate, |
- const char* function_name, |
- const AbstractType& type) { |
- if (type.IsMalformed()) { |
- const Error& error = Error::Handle(type.malformed_error()); |
- return Api::NewError("%s: malformed type encountered: %s.", |
- function_name, error.ToErrorCString()); |
- } else if (type.HasResolvedTypeClass()) { |
- const Class& cls = Class::Handle(isolate, type.type_class()); |
-#if defined(DEBUG) |
- const Library& lib = Library::Handle(cls.library()); |
- if (lib.IsNull()) { |
- ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); |
- } |
-#endif |
- return Api::NewHandle(isolate, cls.raw()); |
- } else if (type.IsTypeParameter()) { |
- return Api::NewHandle(isolate, type.raw()); |
- } else { |
- return Api::NewError("%s: unexpected type '%s' encountered.", |
- function_name, type.ToCString()); |
- } |
-} |
- |
- |
// --- Handles --- |
- |
DART_EXPORT bool Dart_IsError(Dart_Handle handle) { |
return RawObject::IsErrorClassId(Api::ClassId(handle)); |
} |
@@ -674,7 +636,6 @@ |
// --- Garbage Collection Callbacks -- |
- |
DART_EXPORT Dart_Handle Dart_AddGcPrologueCallback( |
Dart_GcPrologueCallback callback) { |
Isolate* isolate = Isolate::Current(); |
@@ -737,17 +698,6 @@ |
} |
-DART_EXPORT Dart_Handle Dart_HeapProfile(Dart_FileWriteCallback callback, |
- void* stream) { |
- Isolate* isolate = Isolate::Current(); |
- CHECK_ISOLATE(isolate); |
- if (callback == NULL) { |
- RETURN_NULL_ERROR(callback); |
- } |
- isolate->heap()->Profile(callback, stream); |
- return Api::Success(); |
-} |
- |
// --- Initialization and Globals --- |
DART_EXPORT const char* Dart_VersionString() { |
@@ -787,7 +737,6 @@ |
// --- Isolates --- |
- |
static char* BuildIsolateName(const char* script_uri, |
const char* main) { |
if (script_uri == NULL) { |
@@ -1049,34 +998,6 @@ |
} |
-DART_EXPORT bool Dart_PostIntArray(Dart_Port port_id, |
- intptr_t len, |
- intptr_t* data) { |
- uint8_t* buffer = NULL; |
- ApiMessageWriter writer(&buffer, &allocator); |
- writer.WriteMessage(len, data); |
- |
- // Post the message at the given port. |
- return PortMap::PostMessage(new Message( |
- port_id, Message::kIllegalPort, buffer, writer.BytesWritten(), |
- Message::kNormalPriority)); |
-} |
- |
- |
-DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) { |
- uint8_t* buffer = NULL; |
- ApiMessageWriter writer(&buffer, allocator); |
- bool success = writer.WriteCMessage(message); |
- |
- if (!success) return success; |
- |
- // Post the message at the given port. |
- return PortMap::PostMessage(new Message( |
- port_id, Message::kIllegalPort, buffer, writer.BytesWritten(), |
- Message::kNormalPriority)); |
-} |
- |
- |
DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
@@ -1090,38 +1011,6 @@ |
} |
-DART_EXPORT Dart_Port Dart_NewNativePort(const char* name, |
- Dart_NativeMessageHandler handler, |
- bool handle_concurrently) { |
- if (name == NULL) { |
- name = "<UnnamedNativePort>"; |
- } |
- if (handler == NULL) { |
- OS::PrintErr("%s expects argument 'handler' to be non-null.\n", |
- CURRENT_FUNC); |
- return ILLEGAL_PORT; |
- } |
- // Start the native port without a current isolate. |
- IsolateSaver saver(Isolate::Current()); |
- Isolate::SetCurrent(NULL); |
- |
- NativeMessageHandler* nmh = new NativeMessageHandler(name, handler); |
- Dart_Port port_id = PortMap::CreatePort(nmh); |
- nmh->Run(Dart::thread_pool(), NULL, NULL, 0); |
- return port_id; |
-} |
- |
- |
-DART_EXPORT bool Dart_CloseNativePort(Dart_Port native_port_id) { |
- // Close the native port without a current isolate. |
- IsolateSaver saver(Isolate::Current()); |
- Isolate::SetCurrent(NULL); |
- |
- // TODO(turnidge): Check that the port is native before trying to close. |
- return PortMap::ClosePort(native_port_id); |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
@@ -1164,9 +1053,9 @@ |
return isolate->main_port(); |
} |
+ |
// --- Scopes ---- |
- |
DART_EXPORT void Dart_EnterScope() { |
Isolate* isolate = Isolate::Current(); |
CHECK_ISOLATE(isolate); |
@@ -1209,7 +1098,6 @@ |
// --- Objects ---- |
- |
DART_EXPORT Dart_Handle Dart_Null() { |
Isolate* isolate = Isolate::Current(); |
CHECK_ISOLATE_SCOPE(isolate); |
@@ -1286,9 +1174,6 @@ |
} |
-// --- Instances ---- |
- |
- |
DART_EXPORT bool Dart_IsInstance(Dart_Handle object) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
@@ -1297,34 +1182,118 @@ |
} |
-// TODO(turnidge): Technically, null has a class. Should we allow it? |
-DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) { |
+DART_EXPORT bool Dart_IsNumber(Dart_Handle object) { |
+ return RawObject::IsNumberClassId(Api::ClassId(object)); |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsInteger(Dart_Handle object) { |
+ return RawObject::IsIntegerClassId(Api::ClassId(object)); |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsDouble(Dart_Handle object) { |
+ return Api::ClassId(object) == kDoubleCid; |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) { |
+ return Api::ClassId(object) == kBoolCid; |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsString(Dart_Handle object) { |
+ return RawObject::IsStringClassId(Api::ClassId(object)); |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) { |
+ return RawObject::IsOneByteStringClassId(Api::ClassId(object)); |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) { |
+ return RawObject::IsExternalStringClassId(Api::ClassId(object)); |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsList(Dart_Handle object) { |
+ if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) { |
+ return true; |
+ } |
+ |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
- const Instance& obj = Api::UnwrapInstanceHandle(isolate, instance); |
- if (obj.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, instance, Instance); |
+ const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
+ return GetListInstance(isolate, obj) != Instance::null(); |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { |
+ return Api::ClassId(object) == kLibraryCid; |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
+ return obj.IsClass(); |
+} |
+ |
+ |
+DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
+ if (obj.IsClass()) { |
+ return Class::Cast(obj).is_abstract(); |
} |
- return Api::NewHandle(isolate, obj.clazz()); |
+ return false; |
} |
-// --- Numbers ---- |
+DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { |
+ return Api::ClassId(handle) == kFunctionCid; |
+} |
-DART_EXPORT bool Dart_IsNumber(Dart_Handle object) { |
- return RawObject::IsNumberClassId(Api::ClassId(object)); |
+DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { |
+ return Api::ClassId(handle) == kFieldCid; |
} |
-// --- Integers ---- |
+DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) { |
+ return Api::ClassId(handle) == kTypeParameterCid; |
+} |
-DART_EXPORT bool Dart_IsInteger(Dart_Handle object) { |
- return RawObject::IsIntegerClassId(Api::ClassId(object)); |
+DART_EXPORT bool Dart_IsClosure(Dart_Handle object) { |
+ // We can't use a fast class index check here because there are many |
+ // different signature classes for closures. |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, object); |
+ return (!closure_obj.IsNull() && closure_obj.IsClosure()); |
} |
+// --- Instances ---- |
+ |
+// TODO(turnidge): Technically, null has a class. Should we allow it? |
+DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ const Instance& obj = Api::UnwrapInstanceHandle(isolate, instance); |
+ if (obj.IsNull()) { |
+ RETURN_TYPE_ERROR(isolate, instance, Instance); |
+ } |
+ return Api::NewHandle(isolate, obj.clazz()); |
+} |
+ |
+ |
+// --- Numbers, Integers and Doubles ---- |
+ |
DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer, |
bool* fits) { |
// Fast path for Smis and Mints. |
@@ -1486,9 +1455,29 @@ |
} |
-// --- Booleans ---- |
+DART_EXPORT Dart_Handle Dart_NewDouble(double value) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ CHECK_CALLBACK_STATE(isolate); |
+ return Api::NewHandle(isolate, Double::New(value)); |
+} |
+DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj, |
+ double* value) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ const Double& obj = Api::UnwrapDoubleHandle(isolate, double_obj); |
+ if (obj.IsNull()) { |
+ RETURN_TYPE_ERROR(isolate, double_obj, Double); |
+ } |
+ *value = obj.value(); |
+ return Api::Success(); |
+} |
+ |
+ |
+// --- Booleans ---- |
+ |
DART_EXPORT Dart_Handle Dart_True() { |
Isolate* isolate = Isolate::Current(); |
CHECK_ISOLATE_SCOPE(isolate); |
@@ -1503,11 +1492,6 @@ |
} |
-DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) { |
- return Api::ClassId(object) == kBoolCid; |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_NewBoolean(bool value) { |
Isolate* isolate = Isolate::Current(); |
CHECK_ISOLATE_SCOPE(isolate); |
@@ -1528,48 +1512,9 @@ |
} |
-// --- Doubles --- |
- |
- |
-DART_EXPORT bool Dart_IsDouble(Dart_Handle object) { |
- return Api::ClassId(object) == kDoubleCid; |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_NewDouble(double value) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- CHECK_CALLBACK_STATE(isolate); |
- return Api::NewHandle(isolate, Double::New(value)); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj, |
- double* value) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Double& obj = Api::UnwrapDoubleHandle(isolate, double_obj); |
- if (obj.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, double_obj, Double); |
- } |
- *value = obj.value(); |
- return Api::Success(); |
-} |
- |
- |
// --- Strings --- |
-DART_EXPORT bool Dart_IsString(Dart_Handle object) { |
- return RawObject::IsStringClassId(Api::ClassId(object)); |
-} |
- |
- |
-DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) { |
- return RawObject::IsOneByteStringClassId(Api::ClassId(object)); |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_StringLength(Dart_Handle str, intptr_t* len) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
@@ -1636,11 +1581,6 @@ |
} |
-DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) { |
- return RawObject::IsExternalStringClassId(Api::ClassId(object)); |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_ExternalStringGetPeer(Dart_Handle object, |
void** peer) { |
if (peer == NULL) { |
@@ -1863,38 +1803,6 @@ |
// --- Lists --- |
- |
-static RawInstance* GetListInstance(Isolate* isolate, const Object& obj) { |
- if (obj.IsInstance()) { |
- const Instance& instance = Instance::Cast(obj); |
- const Class& obj_class = Class::Handle(isolate, obj.clazz()); |
- const Class& list_class = |
- Class::Handle(isolate, isolate->object_store()->list_class()); |
- Error& malformed_type_error = Error::Handle(isolate); |
- if (obj_class.IsSubtypeOf(TypeArguments::Handle(isolate), |
- list_class, |
- TypeArguments::Handle(isolate), |
- &malformed_type_error)) { |
- ASSERT(malformed_type_error.IsNull()); // Type is a raw List. |
- return instance.raw(); |
- } |
- } |
- return Instance::null(); |
-} |
- |
- |
-DART_EXPORT bool Dart_IsList(Dart_Handle object) { |
- if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) { |
- return true; |
- } |
- |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
- return GetListInstance(isolate, obj) != Instance::null(); |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_NewList(intptr_t length) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
@@ -2358,7 +2266,6 @@ |
// --- Typed Data --- |
- |
// Helper method to get the type of a TypedData object. |
static Dart_TypedData_Type GetType(intptr_t class_id) { |
Dart_TypedData_Type type; |
@@ -2750,841 +2657,8 @@ |
} |
-// --- Closures --- |
+// --- Invoking Constructors, Methods, and Field accessors --- |
- |
-DART_EXPORT bool Dart_IsClosure(Dart_Handle object) { |
- // We can't use a fast class index check here because there are many |
- // different signature classes for closures. |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, object); |
- return (!closure_obj.IsNull() && closure_obj.IsClosure()); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ClosureFunction(Dart_Handle closure) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure); |
- if (closure_obj.IsNull() || !closure_obj.IsClosure()) { |
- RETURN_TYPE_ERROR(isolate, closure, Instance); |
- } |
- |
- ASSERT(ClassFinalizer::AllClassesFinalized()); |
- |
- RawFunction* rf = Closure::function(closure_obj); |
- return Api::NewHandle(isolate, rf); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, |
- int number_of_arguments, |
- Dart_Handle* arguments) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- CHECK_CALLBACK_STATE(isolate); |
- const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure); |
- if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) { |
- RETURN_TYPE_ERROR(isolate, closure, Instance); |
- } |
- if (number_of_arguments < 0) { |
- return Api::NewError( |
- "%s expects argument 'number_of_arguments' to be non-negative.", |
- CURRENT_FUNC); |
- } |
- ASSERT(ClassFinalizer::AllClassesFinalized()); |
- |
- // Set up arguments to include the closure as the first argument. |
- const Array& args = Array::Handle(isolate, |
- Array::New(number_of_arguments + 1)); |
- Object& obj = Object::Handle(isolate); |
- args.SetAt(0, closure_obj); |
- for (int i = 0; i < number_of_arguments; i++) { |
- obj = Api::UnwrapHandle(arguments[i]); |
- if (!obj.IsNull() && !obj.IsInstance()) { |
- RETURN_TYPE_ERROR(isolate, arguments[i], Instance); |
- } |
- args.SetAt(i + 1, obj); |
- } |
- // Now try to invoke the closure. |
- return Api::NewHandle(isolate, DartEntry::InvokeClosure(args)); |
-} |
- |
- |
-// --- Classes --- |
- |
- |
-DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
- return obj.IsClass(); |
-} |
- |
- |
-DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
- if (obj.IsClass()) { |
- return Class::Cast(obj).is_abstract(); |
- } |
- return false; |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- return Api::NewHandle(isolate, cls.UserVisibleName()); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- |
-#if defined(DEBUG) |
- const Library& lib = Library::Handle(cls.library()); |
- if (lib.IsNull()) { |
- // ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); |
- if (!cls.IsDynamicClass() && !cls.IsVoidClass()) { |
- fprintf(stderr, "NO LIBRARY: %s\n", cls.ToCString()); |
- } |
- } |
-#endif |
- |
- return Api::NewHandle(isolate, cls.library()); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ClassGetInterfaceCount(Dart_Handle clazz, |
- intptr_t* count) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- |
- const Array& interface_types = Array::Handle(isolate, cls.interfaces()); |
- if (interface_types.IsNull()) { |
- *count = 0; |
- } else { |
- *count = interface_types.Length(); |
- } |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ClassGetInterfaceAt(Dart_Handle clazz, |
- intptr_t index) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- |
- // Finalize all classes. |
- Dart_Handle state = Api::CheckIsolateState(isolate); |
- if (::Dart_IsError(state)) { |
- return state; |
- } |
- |
- const Array& interface_types = Array::Handle(isolate, cls.interfaces()); |
- if (index < 0 || index >= interface_types.Length()) { |
- return Api::NewError("%s: argument 'index' out of bounds.", CURRENT_FUNC); |
- } |
- Type& interface_type = Type::Handle(isolate); |
- interface_type ^= interface_types.At(index); |
- if (interface_type.HasResolvedTypeClass()) { |
- return Api::NewHandle(isolate, interface_type.type_class()); |
- } |
- const String& type_name = |
- String::Handle(isolate, interface_type.TypeClassName()); |
- return Api::NewError("%s: internal error: found unresolved type class '%s'.", |
- CURRENT_FUNC, type_name.ToCString()); |
-} |
- |
- |
-DART_EXPORT bool Dart_ClassIsTypedef(Dart_Handle clazz) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- // For now we represent typedefs as non-canonical signature classes. |
- // I anticipate this may change if we make typedefs more general. |
- return cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ClassGetTypedefReferent(Dart_Handle clazz) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- |
- if (!cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()) { |
- const String& cls_name = String::Handle(cls.UserVisibleName()); |
- return Api::NewError("%s: class '%s' is not a typedef class. " |
- "See Dart_ClassIsTypedef.", |
- CURRENT_FUNC, cls_name.ToCString()); |
- } |
- |
- const Function& func = Function::Handle(isolate, cls.signature_function()); |
- return Api::NewHandle(isolate, func.signature_class()); |
-} |
- |
- |
-DART_EXPORT bool Dart_ClassIsFunctionType(Dart_Handle clazz) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- // A class represents a function type when it is a canonical |
- // signature class. |
- return cls.IsCanonicalSignatureClass(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ClassGetFunctionTypeSignature(Dart_Handle clazz) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- if (!cls.IsCanonicalSignatureClass()) { |
- const String& cls_name = String::Handle(cls.UserVisibleName()); |
- return Api::NewError("%s: class '%s' is not a function-type class. " |
- "See Dart_ClassIsFunctionType.", |
- CURRENT_FUNC, cls_name.ToCString()); |
- } |
- return Api::NewHandle(isolate, cls.signature_function()); |
-} |
- |
- |
-// --- Function and Variable Reflection --- |
- |
- |
-// Outside of the vm, we expose setter names with a trailing '='. |
-static bool HasExternalSetterSuffix(const String& name) { |
- return name.CharAt(name.Length() - 1) == '='; |
-} |
- |
- |
-static RawString* RemoveExternalSetterSuffix(const String& name) { |
- ASSERT(HasExternalSetterSuffix(name)); |
- return String::SubString(name, 0, name.Length() - 1); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_GetFunctionNames(Dart_Handle target) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
- if (obj.IsError()) { |
- return target; |
- } |
- |
- const GrowableObjectArray& names = |
- GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
- Function& func = Function::Handle(); |
- String& name = String::Handle(); |
- |
- if (obj.IsClass()) { |
- const Class& cls = Class::Cast(obj); |
- const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate)); |
- if (!error.IsNull()) { |
- return Api::NewHandle(isolate, error.raw()); |
- } |
- const Array& func_array = Array::Handle(cls.functions()); |
- |
- // Some special types like 'dynamic' have a null functions list. |
- if (!func_array.IsNull()) { |
- for (intptr_t i = 0; i < func_array.Length(); ++i) { |
- func ^= func_array.At(i); |
- |
- // Skip implicit getters and setters. |
- if (func.kind() == RawFunction::kImplicitGetter || |
- func.kind() == RawFunction::kImplicitSetter || |
- func.kind() == RawFunction::kConstImplicitGetter || |
- func.kind() == RawFunction::kMethodExtractor) { |
- continue; |
- } |
- |
- name = func.UserVisibleName(); |
- names.Add(name); |
- } |
- } |
- } else if (obj.IsLibrary()) { |
- const Library& lib = Library::Cast(obj); |
- DictionaryIterator it(lib); |
- Object& obj = Object::Handle(); |
- while (it.HasNext()) { |
- obj = it.GetNext(); |
- if (obj.IsFunction()) { |
- func ^= obj.raw(); |
- name = func.UserVisibleName(); |
- names.Add(name); |
- } |
- } |
- } else { |
- return Api::NewError( |
- "%s expects argument 'target' to be a class or library.", |
- CURRENT_FUNC); |
- } |
- return Api::NewHandle(isolate, Array::MakeArray(names)); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_LookupFunction(Dart_Handle target, |
- Dart_Handle function_name) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
- if (obj.IsError()) { |
- return target; |
- } |
- const String& func_name = Api::UnwrapStringHandle(isolate, function_name); |
- if (func_name.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function_name, String); |
- } |
- |
- Function& func = Function::Handle(isolate); |
- String& tmp_name = String::Handle(isolate); |
- if (obj.IsClass()) { |
- const Class& cls = Class::Cast(obj); |
- |
- // Case 1. Lookup the unmodified function name. |
- func = cls.LookupFunctionAllowPrivate(func_name); |
- |
- // Case 2. Lookup the function without the external setter suffix |
- // '='. Make sure to do this check after the regular lookup, so |
- // that we don't interfere with operator lookups (like ==). |
- if (func.IsNull() && HasExternalSetterSuffix(func_name)) { |
- tmp_name = RemoveExternalSetterSuffix(func_name); |
- tmp_name = Field::SetterName(tmp_name); |
- func = cls.LookupFunctionAllowPrivate(tmp_name); |
- } |
- |
- // Case 3. Lookup the funciton with the getter prefix prepended. |
- if (func.IsNull()) { |
- tmp_name = Field::GetterName(func_name); |
- func = cls.LookupFunctionAllowPrivate(tmp_name); |
- } |
- |
- // Case 4. Lookup the function with a . appended to find the |
- // unnamed constructor. |
- if (func.IsNull()) { |
- tmp_name = String::Concat(func_name, Symbols::Dot()); |
- func = cls.LookupFunctionAllowPrivate(tmp_name); |
- } |
- } else if (obj.IsLibrary()) { |
- const Library& lib = Library::Cast(obj); |
- |
- // Case 1. Lookup the unmodified function name. |
- func = lib.LookupFunctionAllowPrivate(func_name); |
- |
- // Case 2. Lookup the function without the external setter suffix |
- // '='. Make sure to do this check after the regular lookup, so |
- // that we don't interfere with operator lookups (like ==). |
- if (func.IsNull() && HasExternalSetterSuffix(func_name)) { |
- tmp_name = RemoveExternalSetterSuffix(func_name); |
- tmp_name = Field::SetterName(tmp_name); |
- func = lib.LookupFunctionAllowPrivate(tmp_name); |
- } |
- |
- // Case 3. Lookup the function with the getter prefix prepended. |
- if (func.IsNull()) { |
- tmp_name = Field::GetterName(func_name); |
- func = lib.LookupFunctionAllowPrivate(tmp_name); |
- } |
- } else { |
- return Api::NewError( |
- "%s expects argument 'target' to be a class or library.", |
- CURRENT_FUNC); |
- } |
- |
-#if defined(DEBUG) |
- if (!func.IsNull()) { |
- // We only provide access to a subset of function kinds. |
- RawFunction::Kind func_kind = func.kind(); |
- ASSERT(func_kind == RawFunction::kRegularFunction || |
- func_kind == RawFunction::kGetterFunction || |
- func_kind == RawFunction::kSetterFunction || |
- func_kind == RawFunction::kConstructor); |
- } |
-#endif |
- return Api::NewHandle(isolate, func.raw()); |
-} |
- |
- |
-DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { |
- return Api::ClassId(handle) == kFunctionCid; |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- return Api::NewHandle(isolate, func.UserVisibleName()); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionOwner(Dart_Handle function) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- if (func.IsNonImplicitClosureFunction()) { |
- RawFunction* parent_function = func.parent_function(); |
- return Api::NewHandle(isolate, parent_function); |
- } |
- const Class& owner = Class::Handle(func.Owner()); |
- ASSERT(!owner.IsNull()); |
- if (owner.IsTopLevel()) { |
- // Top-level functions are implemented as members of a hidden class. We hide |
- // that class here and instead answer the library. |
-#if defined(DEBUG) |
- const Library& lib = Library::Handle(owner.library()); |
- if (lib.IsNull()) { |
- ASSERT(owner.IsDynamicClass() || owner.IsVoidClass()); |
- } |
-#endif |
- return Api::NewHandle(isolate, owner.library()); |
- } else { |
- return Api::NewHandle(isolate, owner.raw()); |
- } |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionIsAbstract(Dart_Handle function, |
- bool* is_abstract) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (is_abstract == NULL) { |
- RETURN_NULL_ERROR(is_abstract); |
- } |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- *is_abstract = func.is_abstract(); |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, |
- bool* is_static) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (is_static == NULL) { |
- RETURN_NULL_ERROR(is_static); |
- } |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- *is_static = func.is_static(); |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionIsConstructor(Dart_Handle function, |
- bool* is_constructor) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (is_constructor == NULL) { |
- RETURN_NULL_ERROR(is_constructor); |
- } |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- *is_constructor = func.kind() == RawFunction::kConstructor; |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionIsGetter(Dart_Handle function, |
- bool* is_getter) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (is_getter == NULL) { |
- RETURN_NULL_ERROR(is_getter); |
- } |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- *is_getter = func.IsGetterFunction(); |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionIsSetter(Dart_Handle function, |
- bool* is_setter) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (is_setter == NULL) { |
- RETURN_NULL_ERROR(is_setter); |
- } |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- *is_setter = (func.kind() == RawFunction::kSetterFunction); |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionReturnType(Dart_Handle function) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- |
- if (func.kind() == RawFunction::kConstructor) { |
- // Special case the return type for constructors. Inside the vm |
- // we mark them as returning dynamic, but for the purposes of |
- // reflection, they return the type of the class being |
- // constructed. |
- return Api::NewHandle(isolate, func.Owner()); |
- } else { |
- const AbstractType& return_type = |
- AbstractType::Handle(isolate, func.result_type()); |
- return TypeToHandle(isolate, "Dart_FunctionReturnType", return_type); |
- } |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionParameterCounts( |
- Dart_Handle function, |
- int64_t* fixed_param_count, |
- int64_t* opt_param_count) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (fixed_param_count == NULL) { |
- RETURN_NULL_ERROR(fixed_param_count); |
- } |
- if (opt_param_count == NULL) { |
- RETURN_NULL_ERROR(opt_param_count); |
- } |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- |
- // We hide implicit parameters, such as a method's receiver. This is |
- // consistent with Invoke or New, which don't expect their callers to |
- // provide them in the argument lists they are handed. |
- *fixed_param_count = func.num_fixed_parameters() - |
- func.NumImplicitParameters(); |
- // TODO(regis): Separately report named and positional optional param counts. |
- *opt_param_count = func.NumOptionalParameters(); |
- |
- ASSERT(*fixed_param_count >= 0); |
- ASSERT(*opt_param_count >= 0); |
- |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_FunctionParameterType(Dart_Handle function, |
- int parameter_index) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
- if (func.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, function, Function); |
- } |
- |
- const intptr_t num_implicit_params = func.NumImplicitParameters(); |
- const intptr_t num_params = func.NumParameters() - num_implicit_params; |
- if (parameter_index < 0 || parameter_index >= num_params) { |
- return Api::NewError( |
- "%s: argument 'parameter_index' out of range. " |
- "Expected 0..%"Pd" but saw %d.", |
- CURRENT_FUNC, num_params, parameter_index); |
- } |
- const AbstractType& param_type = |
- AbstractType::Handle(isolate, func.ParameterTypeAt( |
- num_implicit_params + parameter_index)); |
- return TypeToHandle(isolate, "Dart_FunctionParameterType", param_type); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
- if (obj.IsError()) { |
- return target; |
- } |
- |
- const GrowableObjectArray& names = |
- GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
- Field& field = Field::Handle(isolate); |
- String& name = String::Handle(isolate); |
- |
- if (obj.IsClass()) { |
- const Class& cls = Class::Cast(obj); |
- const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate)); |
- if (!error.IsNull()) { |
- return Api::NewHandle(isolate, error.raw()); |
- } |
- const Array& field_array = Array::Handle(cls.fields()); |
- |
- // Some special types like 'dynamic' have a null fields list. |
- // |
- // TODO(turnidge): Fix 'dynamic' so that it does not have a null |
- // fields list. This will have to wait until the empty array is |
- // allocated in the vm isolate. |
- if (!field_array.IsNull()) { |
- for (intptr_t i = 0; i < field_array.Length(); ++i) { |
- field ^= field_array.At(i); |
- name = field.UserVisibleName(); |
- names.Add(name); |
- } |
- } |
- } else if (obj.IsLibrary()) { |
- const Library& lib = Library::Cast(obj); |
- DictionaryIterator it(lib); |
- Object& obj = Object::Handle(isolate); |
- while (it.HasNext()) { |
- obj = it.GetNext(); |
- if (obj.IsField()) { |
- field ^= obj.raw(); |
- name = field.UserVisibleName(); |
- names.Add(name); |
- } |
- } |
- } else { |
- return Api::NewError( |
- "%s expects argument 'target' to be a class or library.", |
- CURRENT_FUNC); |
- } |
- return Api::NewHandle(isolate, Array::MakeArray(names)); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_LookupVariable(Dart_Handle target, |
- Dart_Handle variable_name) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
- if (obj.IsError()) { |
- return target; |
- } |
- const String& var_name = Api::UnwrapStringHandle(isolate, variable_name); |
- if (var_name.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, variable_name, String); |
- } |
- if (obj.IsClass()) { |
- const Class& cls = Class::Cast(obj); |
- return Api::NewHandle(isolate, cls.LookupField(var_name)); |
- } |
- if (obj.IsLibrary()) { |
- const Library& lib = Library::Cast(obj); |
- return Api::NewHandle(isolate, lib.LookupFieldAllowPrivate(var_name)); |
- } |
- return Api::NewError( |
- "%s expects argument 'target' to be a class or library.", |
- CURRENT_FUNC); |
-} |
- |
- |
-DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { |
- return Api::ClassId(handle) == kFieldCid; |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_VariableName(Dart_Handle variable) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Field& var = Api::UnwrapFieldHandle(isolate, variable); |
- if (var.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, variable, Field); |
- } |
- return Api::NewHandle(isolate, var.UserVisibleName()); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_VariableIsStatic(Dart_Handle variable, |
- bool* is_static) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (is_static == NULL) { |
- RETURN_NULL_ERROR(is_static); |
- } |
- const Field& var = Api::UnwrapFieldHandle(isolate, variable); |
- if (var.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, variable, Field); |
- } |
- *is_static = var.is_static(); |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_VariableIsFinal(Dart_Handle variable, |
- bool* is_final) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- if (is_final == NULL) { |
- RETURN_NULL_ERROR(is_final); |
- } |
- const Field& var = Api::UnwrapFieldHandle(isolate, variable); |
- if (var.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, variable, Field); |
- } |
- *is_final = var.is_final(); |
- return Api::Success(); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_VariableType(Dart_Handle variable) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Field& var = Api::UnwrapFieldHandle(isolate, variable); |
- if (var.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, variable, Field); |
- } |
- |
- const AbstractType& type = AbstractType::Handle(isolate, var.type()); |
- return TypeToHandle(isolate, "Dart_VariableType", type); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_GetTypeVariableNames(Dart_Handle clazz) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- |
- const intptr_t num_type_params = cls.NumTypeParameters(); |
- const TypeArguments& type_params = |
- TypeArguments::Handle(cls.type_parameters()); |
- |
- const GrowableObjectArray& names = |
- GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
- TypeParameter& type_param = TypeParameter::Handle(isolate); |
- String& name = String::Handle(isolate); |
- for (intptr_t i = 0; i < num_type_params; i++) { |
- type_param ^= type_params.TypeAt(i); |
- name = type_param.name(); |
- names.Add(name); |
- } |
- return Api::NewHandle(isolate, Array::MakeArray(names)); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_LookupTypeVariable( |
- Dart_Handle clazz, |
- Dart_Handle type_variable_name) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
- if (cls.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, clazz, Class); |
- } |
- const String& var_name = Api::UnwrapStringHandle(isolate, type_variable_name); |
- if (var_name.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, type_variable_name, String); |
- } |
- |
- const intptr_t num_type_params = cls.NumTypeParameters(); |
- const TypeArguments& type_params = |
- TypeArguments::Handle(cls.type_parameters()); |
- |
- TypeParameter& type_param = TypeParameter::Handle(isolate); |
- String& name = String::Handle(isolate); |
- for (intptr_t i = 0; i < num_type_params; i++) { |
- type_param ^= type_params.TypeAt(i); |
- name = type_param.name(); |
- if (name.Equals(var_name)) { |
- return Api::NewHandle(isolate, type_param.raw()); |
- } |
- } |
- const String& cls_name = String::Handle(cls.UserVisibleName()); |
- return Api::NewError( |
- "%s: Could not find type variable named '%s' for class %s.\n", |
- CURRENT_FUNC, var_name.ToCString(), cls_name.ToCString()); |
-} |
- |
- |
-DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) { |
- return Api::ClassId(handle) == kTypeParameterCid; |
-} |
- |
-DART_EXPORT Dart_Handle Dart_TypeVariableName(Dart_Handle type_variable) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const TypeParameter& type_var = |
- Api::UnwrapTypeParameterHandle(isolate, type_variable); |
- if (type_var.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); |
- } |
- return Api::NewHandle(isolate, type_var.name()); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_TypeVariableOwner(Dart_Handle type_variable) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const TypeParameter& type_var = |
- Api::UnwrapTypeParameterHandle(isolate, type_variable); |
- if (type_var.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); |
- } |
- const Class& owner = Class::Handle(type_var.parameterized_class()); |
- ASSERT(!owner.IsNull() && owner.IsClass()); |
- return Api::NewHandle(isolate, owner.raw()); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_TypeVariableUpperBound(Dart_Handle type_variable) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const TypeParameter& type_var = |
- Api::UnwrapTypeParameterHandle(isolate, type_variable); |
- if (type_var.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); |
- } |
- const AbstractType& bound = AbstractType::Handle(type_var.bound()); |
- return TypeToHandle(isolate, "Dart_TypeVariableUpperBound", bound); |
-} |
- |
- |
-// --- Constructors, Methods, and Fields --- |
- |
- |
static RawObject* ResolveConstructor(const char* current_func, |
const Class& cls, |
const String& class_name, |
@@ -3879,6 +2953,40 @@ |
} |
+DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, |
+ int number_of_arguments, |
+ Dart_Handle* arguments) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ CHECK_CALLBACK_STATE(isolate); |
+ const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure); |
+ if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) { |
+ RETURN_TYPE_ERROR(isolate, closure, Instance); |
+ } |
+ if (number_of_arguments < 0) { |
+ return Api::NewError( |
+ "%s expects argument 'number_of_arguments' to be non-negative.", |
+ CURRENT_FUNC); |
+ } |
+ ASSERT(ClassFinalizer::AllClassesFinalized()); |
+ |
+ // Set up arguments to include the closure as the first argument. |
+ const Array& args = Array::Handle(isolate, |
+ Array::New(number_of_arguments + 1)); |
+ Object& obj = Object::Handle(isolate); |
+ args.SetAt(0, closure_obj); |
+ for (int i = 0; i < number_of_arguments; i++) { |
+ obj = Api::UnwrapHandle(arguments[i]); |
+ if (!obj.IsNull() && !obj.IsInstance()) { |
+ RETURN_TYPE_ERROR(isolate, arguments[i], Instance); |
+ } |
+ args.SetAt(i + 1, obj); |
+ } |
+ // Now try to invoke the closure. |
+ return Api::NewHandle(isolate, DartEntry::InvokeClosure(args)); |
+} |
+ |
+ |
static bool FieldIsUninitialized(Isolate* isolate, const Field& fld) { |
ASSERT(!fld.IsNull()); |
@@ -4156,6 +3264,85 @@ |
} |
+// --- Exceptions ---- |
+ |
+DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { |
+ Isolate* isolate = Isolate::Current(); |
+ CHECK_ISOLATE(isolate); |
+ CHECK_CALLBACK_STATE(isolate); |
+ { |
+ const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); |
+ if (excp.IsNull()) { |
+ RETURN_TYPE_ERROR(isolate, exception, Instance); |
+ } |
+ } |
+ if (isolate->top_exit_frame_info() == 0) { |
+ // There are no dart frames on the stack so it would be illegal to |
+ // throw an exception here. |
+ return Api::NewError("No Dart frames on stack, cannot throw exception"); |
+ } |
+ |
+ // Unwind all the API scopes till the exit frame before throwing an |
+ // exception. |
+ ApiState* state = isolate->api_state(); |
+ ASSERT(state != NULL); |
+ const Instance* saved_exception; |
+ { |
+ NoGCScope no_gc; |
+ RawInstance* raw_exception = |
+ Api::UnwrapInstanceHandle(isolate, exception).raw(); |
+ state->UnwindScopes(isolate->top_exit_frame_info()); |
+ saved_exception = &Instance::Handle(raw_exception); |
+ } |
+ Exceptions::Throw(*saved_exception); |
+ return Api::NewError("Exception was not thrown, internal error"); |
+} |
+ |
+ |
+DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception, |
+ Dart_Handle stacktrace) { |
+ Isolate* isolate = Isolate::Current(); |
+ CHECK_ISOLATE(isolate); |
+ CHECK_CALLBACK_STATE(isolate); |
+ { |
+ const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); |
+ if (excp.IsNull()) { |
+ RETURN_TYPE_ERROR(isolate, exception, Instance); |
+ } |
+ const Instance& stk = Api::UnwrapInstanceHandle(isolate, stacktrace); |
+ if (stk.IsNull()) { |
+ RETURN_TYPE_ERROR(isolate, stacktrace, Instance); |
+ } |
+ } |
+ if (isolate->top_exit_frame_info() == 0) { |
+ // There are no dart frames on the stack so it would be illegal to |
+ // throw an exception here. |
+ return Api::NewError("No Dart frames on stack, cannot throw exception"); |
+ } |
+ |
+ // Unwind all the API scopes till the exit frame before throwing an |
+ // exception. |
+ ApiState* state = isolate->api_state(); |
+ ASSERT(state != NULL); |
+ const Instance* saved_exception; |
+ const Instance* saved_stacktrace; |
+ { |
+ NoGCScope no_gc; |
+ RawInstance* raw_exception = |
+ Api::UnwrapInstanceHandle(isolate, exception).raw(); |
+ RawInstance* raw_stacktrace = |
+ Api::UnwrapInstanceHandle(isolate, stacktrace).raw(); |
+ state->UnwindScopes(isolate->top_exit_frame_info()); |
+ saved_exception = &Instance::Handle(raw_exception); |
+ saved_stacktrace = &Instance::Handle(raw_stacktrace); |
+ } |
+ Exceptions::ReThrow(*saved_exception, *saved_stacktrace); |
+ return Api::NewError("Exception was not re thrown, internal error"); |
+} |
+ |
+ |
+// --- Native fields and functions --- |
+ |
DART_EXPORT Dart_Handle Dart_CreateNativeWrapperClass(Dart_Handle library, |
Dart_Handle name, |
int field_count) { |
@@ -4238,87 +3425,6 @@ |
} |
-// --- Exceptions ---- |
- |
- |
-DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { |
- Isolate* isolate = Isolate::Current(); |
- CHECK_ISOLATE(isolate); |
- CHECK_CALLBACK_STATE(isolate); |
- { |
- const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); |
- if (excp.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, exception, Instance); |
- } |
- } |
- if (isolate->top_exit_frame_info() == 0) { |
- // There are no dart frames on the stack so it would be illegal to |
- // throw an exception here. |
- return Api::NewError("No Dart frames on stack, cannot throw exception"); |
- } |
- |
- // Unwind all the API scopes till the exit frame before throwing an |
- // exception. |
- ApiState* state = isolate->api_state(); |
- ASSERT(state != NULL); |
- const Instance* saved_exception; |
- { |
- NoGCScope no_gc; |
- RawInstance* raw_exception = |
- Api::UnwrapInstanceHandle(isolate, exception).raw(); |
- state->UnwindScopes(isolate->top_exit_frame_info()); |
- saved_exception = &Instance::Handle(raw_exception); |
- } |
- Exceptions::Throw(*saved_exception); |
- return Api::NewError("Exception was not thrown, internal error"); |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception, |
- Dart_Handle stacktrace) { |
- Isolate* isolate = Isolate::Current(); |
- CHECK_ISOLATE(isolate); |
- CHECK_CALLBACK_STATE(isolate); |
- { |
- const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception); |
- if (excp.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, exception, Instance); |
- } |
- const Instance& stk = Api::UnwrapInstanceHandle(isolate, stacktrace); |
- if (stk.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, stacktrace, Instance); |
- } |
- } |
- if (isolate->top_exit_frame_info() == 0) { |
- // There are no dart frames on the stack so it would be illegal to |
- // throw an exception here. |
- return Api::NewError("No Dart frames on stack, cannot throw exception"); |
- } |
- |
- // Unwind all the API scopes till the exit frame before throwing an |
- // exception. |
- ApiState* state = isolate->api_state(); |
- ASSERT(state != NULL); |
- const Instance* saved_exception; |
- const Instance* saved_stacktrace; |
- { |
- NoGCScope no_gc; |
- RawInstance* raw_exception = |
- Api::UnwrapInstanceHandle(isolate, exception).raw(); |
- RawInstance* raw_stacktrace = |
- Api::UnwrapInstanceHandle(isolate, stacktrace).raw(); |
- state->UnwindScopes(isolate->top_exit_frame_info()); |
- saved_exception = &Instance::Handle(raw_exception); |
- saved_stacktrace = &Instance::Handle(raw_stacktrace); |
- } |
- Exceptions::ReThrow(*saved_exception, *saved_stacktrace); |
- return Api::NewError("Exception was not re thrown, internal error"); |
-} |
- |
- |
-// --- Native functions --- |
- |
- |
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, |
int index) { |
NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
@@ -4350,31 +3456,8 @@ |
} |
-// --- Metadata ---- |
- |
-DART_EXPORT Dart_Handle Dart_GetMetadata(Dart_Handle object) { |
- Isolate* isolate = Isolate::Current(); |
- CHECK_ISOLATE(isolate); |
- DARTSCOPE(isolate); |
- const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
- Class& cls = Class::Handle(isolate); |
- if (obj.IsClass()) { |
- cls ^= obj.raw(); |
- } else if (obj.IsFunction()) { |
- cls = Function::Cast(obj).origin(); |
- } else if (obj.IsField()) { |
- cls = Field::Cast(obj).origin(); |
- } else { |
- return Api::NewHandle(isolate, Object::empty_array().raw()); |
- } |
- const Library& lib = Library::Handle(cls.library()); |
- return Api::NewHandle(isolate, lib.GetMetadata(obj)); |
-} |
- |
- |
// --- Scripts and Libraries --- |
- |
DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler( |
Dart_LibraryTagHandler handler) { |
Isolate* isolate = Isolate::Current(); |
@@ -4512,48 +3595,6 @@ |
} |
-static void CompileAll(Isolate* isolate, Dart_Handle* result) { |
- ASSERT(isolate != NULL); |
- const Error& error = Error::Handle(isolate, Library::CompileAll()); |
- if (error.IsNull()) { |
- *result = Api::Success(); |
- } else { |
- *result = Api::NewHandle(isolate, error.raw()); |
- } |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_CompileAll() { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- Dart_Handle result = Api::CheckIsolateState(isolate); |
- if (::Dart_IsError(result)) { |
- return result; |
- } |
- CHECK_CALLBACK_STATE(isolate); |
- CompileAll(isolate, &result); |
- return result; |
-} |
- |
- |
-DART_EXPORT Dart_Handle Dart_CheckFunctionFingerprints() { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- Dart_Handle result = Api::CheckIsolateState(isolate); |
- if (::Dart_IsError(result)) { |
- return result; |
- } |
- CHECK_CALLBACK_STATE(isolate); |
- Library::CheckFunctionFingerprints(); |
- return result; |
-} |
- |
- |
-DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { |
- return Api::ClassId(object) == kLibraryCid; |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, |
Dart_Handle class_name) { |
Isolate* isolate = Isolate::Current(); |
@@ -4578,19 +3619,6 @@ |
} |
-DART_EXPORT Dart_Handle Dart_LibraryName(Dart_Handle library) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
- if (lib.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, library, Library); |
- } |
- const String& name = String::Handle(isolate, lib.name()); |
- ASSERT(!name.IsNull()); |
- return Api::NewHandle(isolate, name.raw()); |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
@@ -4604,38 +3632,6 @@ |
} |
-DART_EXPORT Dart_Handle Dart_LibraryGetClassNames(Dart_Handle library) { |
- Isolate* isolate = Isolate::Current(); |
- DARTSCOPE(isolate); |
- const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
- if (lib.IsNull()) { |
- RETURN_TYPE_ERROR(isolate, library, Library); |
- } |
- |
- const GrowableObjectArray& names = |
- GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); |
- ClassDictionaryIterator it(lib); |
- Class& cls = Class::Handle(); |
- String& name = String::Handle(); |
- while (it.HasNext()) { |
- cls = it.GetNextClass(); |
- if (cls.IsSignatureClass()) { |
- if (!cls.IsCanonicalSignatureClass()) { |
- // This is a typedef. Add it to the list of class names. |
- name = cls.UserVisibleName(); |
- names.Add(name); |
- } else { |
- // Skip canonical signature classes. These are not named. |
- } |
- } else { |
- name = cls.UserVisibleName(); |
- names.Add(name); |
- } |
- } |
- return Api::NewHandle(isolate, Array::MakeArray(names)); |
-} |
- |
- |
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { |
Isolate* isolate = Isolate::Current(); |
DARTSCOPE(isolate); |
@@ -4813,22 +3809,8 @@ |
} |
-// --- Profiling support --- |
- |
-// TODO(7565): Dartium should use the new VM flag "generate_pprof_symbols" for |
-// pprof profiling. Then these symbols should be removed. |
- |
-DART_EXPORT void Dart_InitPprofSupport() { } |
- |
-DART_EXPORT void Dart_GetPprofSymbolInfo(void** buffer, int* buffer_size) { |
- *buffer = NULL; |
- *buffer_size = 0; |
-} |
- |
- |
// --- Peer support --- |
- |
DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) { |
if (peer == NULL) { |
RETURN_NULL_ERROR(peer); |