Index: runtime/vm/dart_api_impl.cc |
=================================================================== |
--- runtime/vm/dart_api_impl.cc (revision 25704) |
+++ runtime/vm/dart_api_impl.cc (working copy) |
@@ -2136,6 +2136,23 @@ |
return Api::NewError("Invalid length passed in to access array elements"); \ |
+static Dart_Handle CopyBytes(const TypedData& array, |
+ intptr_t offset, |
+ uint8_t* native_array, |
+ intptr_t length) { |
+ ASSERT(array.IsTypedData()); |
+ ASSERT(array.ElementSizeInBytes() == 1); |
+ if (!Utils::RangeCheck(offset, length, array.Length())) { |
+ return Api::NewError("Invalid length passed in to access list elements"); |
+ } |
+ NoGCScope no_gc; |
+ memmove(native_array, |
+ reinterpret_cast<uint8_t*>(array.DataAddr(offset)), |
+ length); |
+ return Api::Success(); |
+} |
+ |
+ |
DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, |
intptr_t offset, |
uint8_t* native_array, |
@@ -2146,14 +2163,26 @@ |
if (obj.IsTypedData()) { |
const TypedData& array = TypedData::Cast(obj); |
if (array.ElementSizeInBytes() == 1) { |
- if (Utils::RangeCheck(offset, length, array.Length())) { |
- NoGCScope no_gc; |
- memmove(native_array, |
- reinterpret_cast<uint8_t*>(array.DataAddr(offset)), |
- length); |
- return Api::Success(); |
+ return CopyBytes(array, offset, native_array, length); |
+ } |
+ } |
+ if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) { |
+ const Instance& view = Instance::Cast(obj); |
+ if (TypedDataView::ElementSizeInBytes(view) == 1) { |
+ intptr_t view_length = Smi::Value(TypedDataView::Length(view)); |
+ if (!Utils::RangeCheck(offset, length, view_length)) { |
+ return Api::NewError( |
+ "Invalid length passed in to access list elements"); |
} |
- return Api::NewError("Invalid length passed in to access list elements"); |
+ const Instance& data = Instance::Handle(TypedDataView::Data(view)); |
+ intptr_t data_offset = |
+ Smi::Value(TypedDataView::OffsetInBytes(view)) + offset; |
siva
2013/08/01 16:29:31
This data_offset computation can be moved inside t
Florian Schneider
2013/08/02 11:07:33
Done.
|
+ if (data.IsTypedData()) { |
+ const TypedData& array = TypedData::Cast(data); |
+ if (array.ElementSizeInBytes() == 1) { |
+ return CopyBytes(array, data_offset, native_array, length); |
siva
2013/08/01 16:29:31
We end up doing the range check twice in this case
Florian Schneider
2013/08/02 11:07:33
Agree. The second range check is redundant becaus
|
+ } |
+ } |
} |
} |
if (obj.IsArray()) { |
@@ -2193,6 +2222,7 @@ |
const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
args.SetAt(0, instance); // Set up the receiver as the first argument. |
for (int i = 0; i < length; i++) { |
+ HandleScope handle_scope(isolate); |
siva
2013/08/01 16:29:31
Could you use HANDLESCOPE(isolate); here to be con
Florian Schneider
2013/08/02 11:07:33
Done.
|
intobj = Integer::New(offset + i); |
args.SetAt(1, intobj); |
result = DartEntry::InvokeFunction(function, args); |