Index: runtime/vm/dart_api_impl.cc |
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc |
index 6835887efe5e63d0e3482e909d7ec35a29312029..9bd5a9896f5a1908ccd9b798d02239f572cfd4f1 100644 |
--- a/runtime/vm/dart_api_impl.cc |
+++ b/runtime/vm/dart_api_impl.cc |
@@ -80,6 +80,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, |
@@ -1789,6 +1809,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; |
@@ -2872,6 +2900,102 @@ 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 intptr_t 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)); |
+ args.SetAt(0, instance); |
+ args.SetAt(1, Object::Handle(isolate, Api::UnwrapHandle(key))); |
+ return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, |
+ args)); |
+ } |
+ } |
+ return Api::NewError("Object does not implement the 'Map' interface"); |
+} |
+ |
+ |
+DART_EXPORT Dart_Handle Dart_MapContainsKey(Dart_Handle map, Dart_Handle key) { |
koda
2014/05/22 23:40:24
These two functions only differ by the method name
rmacnak
2014/05/30 17:23:33
Factored out 0 and 1 argument sends, and used in L
|
+ 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 intptr_t kNumArgs = 2; |
+ ArgumentsDescriptor args_desc( |
+ Array::Handle(ArgumentsDescriptor::New(kNumArgs))); |
+ const Function& function = Function::Handle( |
+ isolate, |
koda
2014/05/22 23:40:24
Indentation.
|
+ Resolver::ResolveDynamic(instance, |
+ String::Handle(String::New("containsKey")), |
+ args_desc)); |
+ if (!function.IsNull()) { |
+ const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
+ args.SetAt(0, instance); |
+ args.SetAt(1, Object::Handle(isolate, Api::UnwrapHandle(key))); |
+ return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, |
+ args)); |
+ } |
+ } |
+ 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 intptr_t kNumArgs = 1; |
+ ArgumentsDescriptor args_desc( |
+ Array::Handle(ArgumentsDescriptor::New(kNumArgs))); |
+ Function& function = Function::Handle( |
+ isolate, |
+ Resolver::ResolveDynamic(instance, |
+ String::Handle(String::New("get:keys")), |
+ args_desc)); |
+ if (!function.IsNull()) { |
+ const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
+ args.SetAt(0, instance); |
+ obj = DartEntry::InvokeFunction(function, args); |
+ if (!obj.IsInstance()) { |
+ return Api::NewHandle(isolate, obj.raw()); |
+ } |
+ instance ^= obj.raw(); |
koda
2014/05/22 23:40:24
To help the reader, please create a new handle (wi
rmacnak
2014/05/30 17:23:33
Intermediate result named iterator.
|
+ function = Resolver::ResolveDynamic(instance, |
+ String::Handle(String::New("toList")), |
+ args_desc); |
+ args.SetAt(0, instance); |
koda
2014/05/23 00:33:05
Consider passing in 'false' as an argument to get
rmacnak
2014/05/30 17:23:33
Not worth another helper to handle the optional pa
|
+ if (!function.IsNull()) { |
+ return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, |
+ args)); |
+ } |
+ } |
+ } |
+ return Api::NewError("Object does not implement the 'Map' interface"); |
+} |
+ |
+ |
// --- Typed Data --- |
// Helper method to get the type of a TypedData object. |