Index: runtime/vm/dart_api_impl.cc |
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc |
index 6c89434f9f61922d510ada6cc1f1ed48d9258304..9ec2a65095d2f13d5db20f7e7fbbcf5558100df8 100644 |
--- a/runtime/vm/dart_api_impl.cc |
+++ b/runtime/vm/dart_api_impl.cc |
@@ -82,6 +82,26 @@ static RawInstance* GetListInstance(Isolate* isolate, const Object& obj) { |
return Instance::null(); |
} |
+static RawInstance* GetMapInstance(Isolate* isolate, const Object& obj) { |
+ if (obj.IsInstance()) { |
+ const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
+ const Class& map_class = |
+ Class::Handle(core_lib.LookupClass(Symbols::Map())); |
+ ASSERT(!map_class.IsNull()); |
+ const Instance& instance = Instance::Cast(obj); |
+ const Class& obj_class = Class::Handle(isolate, obj.clazz()); |
+ Error& malformed_type_error = Error::Handle(isolate); |
+ if (obj_class.IsSubtypeOf(TypeArguments::Handle(isolate), |
+ map_class, |
+ TypeArguments::Handle(isolate), |
+ &malformed_type_error)) { |
+ ASSERT(malformed_type_error.IsNull()); // Type is a raw Map. |
+ return instance.raw(); |
+ } |
+ } |
+ return Instance::null(); |
+} |
+ |
static bool GetNativeStringArgument(NativeArguments* arguments, |
int arg_index, |
@@ -231,6 +251,40 @@ Heap::Space SpaceForExternal(Isolate* isolate, intptr_t size) { |
} |
+static RawObject* Send0Arg(const Instance& receiver, |
+ const String& selector) { |
+ const intptr_t kNumArgs = 1; |
+ ArgumentsDescriptor args_desc( |
+ Array::Handle(ArgumentsDescriptor::New(kNumArgs))); |
+ const Function& function = Function::Handle( |
+ Resolver::ResolveDynamic(receiver, selector, args_desc)); |
+ if (function.IsNull()) { |
+ return ApiError::New(String::Handle(String::New(""))); |
+ } |
+ const Array& args = Array::Handle(Array::New(kNumArgs)); |
+ args.SetAt(0, receiver); |
+ return DartEntry::InvokeFunction(function, args); |
+} |
+ |
+ |
+static RawObject* Send1Arg(const Instance& receiver, |
+ const String& selector, |
+ const Instance& argument) { |
+ const intptr_t kNumArgs = 2; |
+ ArgumentsDescriptor args_desc( |
+ Array::Handle(ArgumentsDescriptor::New(kNumArgs))); |
+ const Function& function = Function::Handle( |
+ Resolver::ResolveDynamic(receiver, selector, args_desc)); |
+ if (function.IsNull()) { |
+ return ApiError::New(String::Handle(String::New(""))); |
+ } |
+ const Array& args = Array::Handle(Array::New(kNumArgs)); |
+ args.SetAt(0, receiver); |
+ args.SetAt(1, argument); |
+ return DartEntry::InvokeFunction(function, args); |
+} |
+ |
+ |
WeakReferenceSetBuilder* ApiState::NewWeakReferenceSetBuilder() { |
return new WeakReferenceSetBuilder(this); |
} |
@@ -1810,6 +1864,14 @@ DART_EXPORT bool Dart_IsList(Dart_Handle object) { |
} |
+DART_EXPORT bool Dart_IsMap(Dart_Handle object) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
+ return GetMapInstance(isolate, obj) != Instance::null(); |
+} |
+ |
+ |
DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { |
TRACE_API_CALL(CURRENT_FUNC); |
return Api::ClassId(object) == kLibraryCid; |
@@ -2505,25 +2567,14 @@ DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index) { |
return list; |
} else { |
CHECK_CALLBACK_STATE(isolate); |
- |
// Check and handle a dart object that implements the List interface. |
const Instance& instance = |
Instance::Handle(isolate, GetListInstance(isolate, obj)); |
if (!instance.IsNull()) { |
- const int kNumArgs = 2; |
- ArgumentsDescriptor args_desc( |
- Array::Handle(ArgumentsDescriptor::New(kNumArgs))); |
- const Function& function = Function::Handle( |
- isolate, |
- Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc)); |
- if (!function.IsNull()) { |
- const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
- const Integer& indexobj = Integer::Handle(isolate, Integer::New(index)); |
- args.SetAt(0, instance); |
- args.SetAt(1, indexobj); |
- return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, |
- args)); |
- } |
+ return Api::NewHandle(isolate, Send1Arg( |
+ instance, |
+ Symbols::IndexToken(), |
+ Instance::Handle(isolate, Integer::New(index)))); |
} |
return Api::NewError("Object does not implement the 'List' interface"); |
} |
@@ -2902,6 +2953,71 @@ DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list, |
} |
+// --- Maps --- |
+ |
+DART_EXPORT Dart_Handle Dart_MapGetAt(Dart_Handle map, Dart_Handle key) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ CHECK_CALLBACK_STATE(isolate); |
+ const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(map)); |
+ const Instance& instance = |
+ Instance::Handle(isolate, GetMapInstance(isolate, obj)); |
+ if (!instance.IsNull()) { |
+ const Object& key_obj = Object::Handle(Api::UnwrapHandle(key)); |
+ if (!(key_obj.IsInstance() || key_obj.IsNull())) { |
+ return Api::NewError("Key is not an instance"); |
+ } |
+ return Api::NewHandle(isolate, Send1Arg( |
+ instance, |
+ Symbols::IndexToken(), |
+ Instance::Cast(key_obj))); |
+ } |
+ return Api::NewError("Object does not implement the 'Map' interface"); |
+} |
+ |
+ |
+DART_EXPORT Dart_Handle Dart_MapContainsKey(Dart_Handle map, Dart_Handle key) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ CHECK_CALLBACK_STATE(isolate); |
+ const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(map)); |
+ const Instance& instance = |
+ Instance::Handle(isolate, GetMapInstance(isolate, obj)); |
+ if (!instance.IsNull()) { |
+ const Object& key_obj = Object::Handle(Api::UnwrapHandle(key)); |
+ if (!(key_obj.IsInstance() || key_obj.IsNull())) { |
+ return Api::NewError("Key is not an instance"); |
+ } |
+ return Api::NewHandle(isolate, Send1Arg( |
+ instance, |
+ String::Handle(isolate, String::New("containsKey")), |
+ Instance::Cast(key_obj))); |
+ } |
+ return Api::NewError("Object does not implement the 'Map' interface"); |
+} |
+ |
+ |
+DART_EXPORT Dart_Handle Dart_MapKeys(Dart_Handle map) { |
+ Isolate* isolate = Isolate::Current(); |
+ DARTSCOPE(isolate); |
+ CHECK_CALLBACK_STATE(isolate); |
+ Object& obj = Object::Handle(isolate, Api::UnwrapHandle(map)); |
+ Instance& instance = |
+ Instance::Handle(isolate, GetMapInstance(isolate, obj)); |
+ if (!instance.IsNull()) { |
+ const Object& iterator = Object::Handle(Send0Arg( |
+ instance, String::Handle(String::New("get:keys")))); |
+ if (!iterator.IsInstance()) { |
+ return Api::NewHandle(isolate, iterator.raw()); |
+ } |
+ return Api::NewHandle(isolate, Send0Arg( |
+ Instance::Cast(iterator), |
+ String::Handle(String::New("toList")))); |
+ } |
+ return Api::NewError("Object does not implement the 'Map' interface"); |
+} |
+ |
+ |
// --- Typed Data --- |
// Helper method to get the type of a TypedData object. |