Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Unified Diff: vm/dart_api_impl.cc

Issue 8417003: Enhance the array access API to deal with any objct that implements the list interface. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | vm/dart_api_impl_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: vm/dart_api_impl.cc
===================================================================
--- vm/dart_api_impl.cc (revision 849)
+++ vm/dart_api_impl.cc (working copy)
@@ -853,7 +853,18 @@
Zone zone; // Setup a VM zone as we are creating some handles.
HandleScope scope; // Setup a VM handle scope.
const Object& obj = Object::Handle(Api::UnwrapHandle(object));
- return obj.IsArray();
+ if (obj.IsArray()) {
+ return true;
+ }
+ // TODO(5526318): Make access to GrowableObjectArray more efficient.
+ if (obj.IsInstance()) {
Mads Ager (google) 2011/10/28 07:50:18 Maybe extract this into an ImplementsListInterface
siva 2011/10/31 20:30:49 Done.
+ Instance& instance = Instance::Handle();
+ instance ^= obj.raw();
+ Isolate* isolate = Isolate::Current();
+ const Type& type = Type::Handle(isolate->object_store()->list_interface());
+ return instance.Is(type);
turnidge 2011/10/27 21:29:46 A thought. Given that all of the other Is*() func
siva 2011/10/31 20:30:49 Regis and I discussed this, he felt that the only
+ }
+ return false;
}
@@ -875,10 +886,93 @@
*len = array_obj.Length();
return Api::Success();
}
- return Api::Error("Object is not an Array");
+ // TODO(5526318): Make access to GrowableObjectArray more efficient.
+ // Now check and handle a dart object that implements the List interface.
+ if (obj.IsInstance()) {
+ Instance& instance = Instance::Handle();
+ instance ^= obj.raw();
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ const Type& type = Type::Handle(isolate->object_store()->list_interface());
+ if (instance.Is(type)) {
+ String& name = String::Handle(String::New("length"));
+ name = Field::GetterName(name);
+ const Function& function = Function::Handle(
+ Resolver::ResolveDynamic(instance, name, 1, 0));
+ if (!function.IsNull()) {
+ GrowableArray<const Object*> args(0);
+ LongJump* base = isolate->long_jump_base();
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ Dart_Handle result;
+ if (setjmp(*jump.Set()) == 0) {
+ const Array& kNoArgumentNames = Array::Handle();
+ const Instance& retval = Instance::Handle(
+ DartEntry::InvokeDynamic(instance,
+ function,
+ args,
+ kNoArgumentNames));
+ result = Api::Success();
+ if (retval.IsSmi() || retval.IsMint()) {
+ Integer& integer = Integer::Handle();
+ integer ^= retval.raw();
+ *len = integer.AsInt64Value();
+ } else if (retval.IsBigint()) {
+ Bigint& bigint = Bigint::Handle();
+ bigint ^= retval.raw();
+ if (BigintOperations::FitsIntoInt64(bigint)) {
+ *len = BigintOperations::ToInt64(bigint);
+ } else {
+ result = Api::Error("Object has an Invalid length");
turnidge 2011/10/27 21:29:46 Is it possible to create a List at the Dart level
siva 2011/10/31 20:30:49 Yes it is possible that an arbitrary List implemen
+ }
+ } else {
+ result = Api::Error("Object has an Invalid length");
turnidge 2011/10/27 21:29:46 Invalid -> "non-integer"?
siva 2011/10/31 20:30:49 Done.
+ }
+ } else {
+ SetupErrorResult(&result);
+ }
+ isolate->set_long_jump_base(base);
+ return result;
+ }
+ }
+ }
+ return Api::Error("Object does not implement the list inteface");
}
+static RawObject* GetArrayAt(const Instance& instance,
+ const Integer& index,
+ const Function& function,
+ Dart_Handle* result) {
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ ASSERT(result != NULL);
+ LongJump* base = isolate->long_jump_base();
Mads Ager (google) 2011/10/28 07:50:18 Maybe a scoped object would be nice for this at so
siva 2011/10/31 20:30:49 Yes Todd had indicated the same thing, he is going
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ if (setjmp(*jump.Set()) == 0) {
+ Instance& retval = Instance::Handle();
+ GrowableArray<const Object*> args(0);
+ args.Add(&index);
+ const Array& kNoArgumentNames = Array::Handle();
+ retval = DartEntry::InvokeDynamic(instance,
+ function,
+ args,
+ kNoArgumentNames);
+ if (retval.IsUnhandledException()) {
+ *result = Api::Error("Invalid implementation of '[]'");
turnidge 2011/10/27 21:29:46 What do you think of a more informative error mess
siva 2011/10/31 20:30:49 Done.
+ } else {
+ *result = Api::Success();
+ }
+ isolate->set_long_jump_base(base);
+ return retval.raw();
+ }
+ SetupErrorResult(result);
+ isolate->set_long_jump_base(base);
+ return Object::null();
+}
+
+
DART_EXPORT Dart_Handle Dart_ArrayGet(Dart_Handle array,
intptr_t offset,
uint8_t* native_array,
@@ -904,7 +998,39 @@
}
return Api::Error("Invalid length passed in to access array elements");
}
- return Api::Error("Object is not an Array");
+ // TODO(5526318): Make access to GrowableObjectArray more efficient.
+ // Now check and handle a dart object that implements the List interface.
+ if (obj.IsInstance()) {
+ Instance& instance = Instance::Handle();
+ instance ^= obj.raw();
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ const Type& type = Type::Handle(isolate->object_store()->list_interface());
+ if (instance.Is(type)) {
+ String& name = String::Handle(String::New("[]"));
turnidge 2011/10/27 21:29:46 An aside: it will be nice when we can start using
siva 2011/10/31 20:30:49 Agree, there is a TODO somewhere in the VM code fo
+ const Function& function = Function::Handle(
+ Resolver::ResolveDynamic(instance, name, 2, 0));
+ if (!function.IsNull()) {
+ Object& element = Object::Handle();
+ Integer& intobj = Integer::Handle();
+ Dart_Handle result;
+ for (int i = 0; i < length; i++) {
+ intobj = Integer::New(offset + i);
+ element = GetArrayAt(instance, intobj, function, &result);
+ if (!Dart_IsValid(result)) {
+ return result; // Error condition.
+ }
+ intobj ^= element.raw();
+ ASSERT(intobj.AsInt64Value() <= 0xff);
+ // TODO(hpayer): value should always be smaller then 0xff. Add error
+ // handling.
+ native_array[i] = static_cast<uint8_t>(intobj.AsInt64Value() & 0xff);
+ }
+ return Api::Success();
+ }
+ }
+ }
+ return Api::Error("Object does not implement the List interface");
}
@@ -921,10 +1047,68 @@
}
return Api::Error("Invalid index passed in to access array element");
}
+ // TODO(5526318): Make access to GrowableObjectArray more efficient.
+ // Now check and handle a dart object that implements the List interface.
+ if (obj.IsInstance()) {
+ Instance& instance = Instance::Handle();
+ instance ^= obj.raw();
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ const Type& type = Type::Handle(isolate->object_store()->list_interface());
+ if (instance.Is(type)) {
+ String& name = String::Handle(String::New("[]"));
+ const Function& function = Function::Handle(
+ Resolver::ResolveDynamic(instance, name, 2, 0));
+ if (!function.IsNull()) {
+ Object& element = Object::Handle();
+ Integer& indexobj = Integer::Handle();
+ Dart_Handle result;
+ indexobj = Integer::New(index);
+ element = GetArrayAt(instance, indexobj, function, &result);
+ if (!Dart_IsValid(result)) {
+ return result; // Error condition.
+ }
+ return Api::NewLocalHandle(element);
+ }
+ }
+ }
return Api::Error("Object is not an Array");
turnidge 2011/10/27 21:29:46 Inconsistent w/ error msg above -> "Object does no
siva 2011/10/31 20:30:49 Done.
}
+static void SetArrayAt(const Instance& instance,
+ const Integer& index,
+ const Object& value,
+ const Function& function,
+ Dart_Handle* result) {
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ ASSERT(result != NULL);
+ LongJump* base = isolate->long_jump_base();
+ LongJump jump;
+ isolate->set_long_jump_base(&jump);
+ if (setjmp(*jump.Set()) == 0) {
+ GrowableArray<const Object*> args(1);
+ args.Add(&index);
+ args.Add(&value);
+ Instance& retval = Instance::Handle();
+ const Array& kNoArgumentNames = Array::Handle();
+ retval = DartEntry::InvokeDynamic(instance,
+ function,
+ args,
+ kNoArgumentNames);
+ if (retval.IsUnhandledException()) {
+ *result = Api::Error("Invalid implementation of '[]='");
turnidge 2011/10/27 21:29:46 Maybe different error msg here?
siva 2011/10/31 20:30:49 Done.
+ } else {
+ *result = Api::Success();
+ }
+ } else {
+ SetupErrorResult(result);
+ }
+ isolate->set_long_jump_base(base);
+}
+
+
DART_EXPORT Dart_Handle Dart_ArraySet(Dart_Handle array,
intptr_t offset,
uint8_t* native_array,
@@ -945,9 +1129,38 @@
}
return Api::Error("Invalid length passed in to set array elements");
}
- return Api::Error("Object is not an Array");
+ // TODO(5526318): Make access to GrowableObjectArray more efficient.
+ // Now check and handle a dart object that implements the List interface.
+ if (obj.IsInstance()) {
+ Instance& instance = Instance::Handle();
+ instance ^= obj.raw();
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ const Type& type = Type::Handle(isolate->object_store()->list_interface());
turnidge 2011/10/27 21:29:46 We are checking whether an object is a list many t
siva 2011/10/31 20:30:49 Done.
+ if (instance.Is(type)) {
+ String& name = String::Handle(String::New("[]="));
+ const Function& function = Function::Handle(
+ Resolver::ResolveDynamic(instance, name, 3, 0));
+ if (!function.IsNull()) {
+ Integer& indexobj = Integer::Handle();
+ Integer& valueobj = Integer::Handle();
+ Dart_Handle result;
+ for (int i = 0; i < length; i++) {
+ indexobj = Integer::New(offset + i);
+ valueobj ^= Integer::New(native_array[i]);
+ SetArrayAt(instance, indexobj, valueobj, function, &result);
+ if (!Dart_IsValid(result)) {
+ return result; // Error condition.
+ }
+ }
+ return Api::Success();
+ }
+ }
+ }
+ return Api::Error("Object does not implement the list interface");
}
+
DART_EXPORT Dart_Handle Dart_ArraySetAt(Dart_Handle array,
intptr_t index,
Dart_Handle value) {
@@ -964,7 +1177,28 @@
}
return Api::Error("Invalid index passed in to set array element");
}
- return Api::Error("Object is not an Array");
+ // TODO(5526318): Make access to GrowableObjectArray more efficient.
+ // Now check and handle a dart object that implements the List interface.
+ if (obj.IsInstance()) {
+ Instance& instance = Instance::Handle();
+ instance ^= obj.raw();
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ const Type& type = Type::Handle(isolate->object_store()->list_interface());
+ if (instance.Is(type)) {
+ String& name = String::Handle(String::New("[]="));
+ const Function& function = Function::Handle(
+ Resolver::ResolveDynamic(instance, name, 3, 0));
+ if (!function.IsNull()) {
+ Dart_Handle result;
+ const Integer& index_obj = Integer::Handle(Integer::New(index));
+ const Object& value_obj = Object::Handle(Api::UnwrapHandle(value));
+ SetArrayAt(instance, index_obj, value_obj, function, &result);
+ return result;
+ }
+ }
+ }
+ return Api::Error("Object does not implement the list interface");
}
« no previous file with comments | « no previous file | vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698