Chromium Code Reviews| 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. |