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 6c89434f9f61922d510ada6cc1f1ed48d9258304..bb215ab49e11f4c670b812b5c723b50b315dfcd6 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 Object& argument) { |
|
koda
2014/05/30 20:40:23
Instance seems safer.
rmacnak
2014/05/30 21:49:14
Done.
|
| + 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(), |
| + Integer::Handle(isolate, Integer::New(index)))); |
| } |
| return Api::NewError("Object does not implement the 'List' interface"); |
| } |
| @@ -2902,6 +2953,66 @@ 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()) { |
| + return Api::NewHandle(isolate, Send1Arg( |
| + instance, |
| + Symbols::IndexToken(), |
| + Object::Handle(isolate, Api::UnwrapHandle(key)))); |
| + } |
| + 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()) { |
| + return Api::NewHandle(isolate, Send1Arg( |
| + instance, |
| + String::Handle(isolate, String::New("containsKey")), |
| + Object::Handle(isolate, Api::UnwrapHandle(key)))); |
| + } |
| + 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. |