Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "include/dart_mirrors_api.h" | 6 #include "include/dart_mirrors_api.h" |
| 7 #include "include/dart_native_api.h" | 7 #include "include/dart_native_api.h" |
| 8 | 8 |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2129 } \ | 2129 } \ |
| 2130 const Integer& integer = Integer::Cast(element); \ | 2130 const Integer& integer = Integer::Cast(element); \ |
| 2131 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \ | 2131 native_array[i] = static_cast<uint8_t>(integer.AsInt64Value() & 0xff); \ |
| 2132 ASSERT(integer.AsInt64Value() <= 0xff); \ | 2132 ASSERT(integer.AsInt64Value() <= 0xff); \ |
| 2133 } \ | 2133 } \ |
| 2134 return Api::Success(); \ | 2134 return Api::Success(); \ |
| 2135 } \ | 2135 } \ |
| 2136 return Api::NewError("Invalid length passed in to access array elements"); \ | 2136 return Api::NewError("Invalid length passed in to access array elements"); \ |
| 2137 | 2137 |
| 2138 | 2138 |
| 2139 static Dart_Handle CopyBytes(const TypedData& array, | |
| 2140 intptr_t offset, | |
| 2141 uint8_t* native_array, | |
| 2142 intptr_t length) { | |
| 2143 ASSERT(array.IsTypedData()); | |
| 2144 ASSERT(array.ElementSizeInBytes() == 1); | |
| 2145 NoGCScope no_gc; | |
| 2146 memmove(native_array, | |
| 2147 reinterpret_cast<uint8_t*>(array.DataAddr(offset)), | |
| 2148 length); | |
| 2149 return Api::Success(); | |
| 2150 } | |
| 2151 | |
| 2152 | |
| 2139 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, | 2153 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, |
| 2140 intptr_t offset, | 2154 intptr_t offset, |
| 2141 uint8_t* native_array, | 2155 uint8_t* native_array, |
| 2142 intptr_t length) { | 2156 intptr_t length) { |
| 2143 Isolate* isolate = Isolate::Current(); | 2157 Isolate* isolate = Isolate::Current(); |
| 2144 DARTSCOPE(isolate); | 2158 DARTSCOPE(isolate); |
| 2145 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); | 2159 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list)); |
| 2146 if (obj.IsTypedData()) { | 2160 if (obj.IsTypedData()) { |
| 2147 const TypedData& array = TypedData::Cast(obj); | 2161 const TypedData& array = TypedData::Cast(obj); |
| 2148 if (array.ElementSizeInBytes() == 1) { | 2162 if (array.ElementSizeInBytes() == 1) { |
| 2149 if (Utils::RangeCheck(offset, length, array.Length())) { | 2163 if (!Utils::RangeCheck(offset, length, array.Length())) { |
| 2150 NoGCScope no_gc; | 2164 return Api::NewError( |
| 2151 memmove(native_array, | 2165 "Invalid length passed in to access list elements"); |
| 2152 reinterpret_cast<uint8_t*>(array.DataAddr(offset)), | |
| 2153 length); | |
| 2154 return Api::Success(); | |
| 2155 } | 2166 } |
| 2156 return Api::NewError("Invalid length passed in to access list elements"); | 2167 return CopyBytes(array, offset, native_array, length); |
| 2168 } | |
| 2169 } | |
| 2170 if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) { | |
| 2171 const Instance& view = Instance::Cast(obj); | |
| 2172 if (TypedDataView::ElementSizeInBytes(view) == 1) { | |
| 2173 intptr_t view_length = Smi::Value(TypedDataView::Length(view)); | |
| 2174 if (!Utils::RangeCheck(offset, length, view_length)) { | |
| 2175 return Api::NewError( | |
| 2176 "Invalid length passed in to access list elements"); | |
| 2177 } | |
| 2178 const Instance& data = Instance::Handle(TypedDataView::Data(view)); | |
| 2179 if (data.IsTypedData()) { | |
|
Ivan Posva
2013/08/05 03:45:00
How can this ever not be a typed data? I would exp
Florian Schneider
2013/08/05 08:38:09
Not sure: the view constructor takes just a ByteBu
| |
| 2180 const TypedData& array = TypedData::Cast(data); | |
| 2181 if (array.ElementSizeInBytes() == 1) { | |
| 2182 intptr_t data_offset = | |
| 2183 Smi::Value(TypedDataView::OffsetInBytes(view)) + offset; | |
| 2184 // Range check already performed on the view object. | |
| 2185 ASSERT(Utils::RangeCheck(data_offset, length, array.Length())); | |
| 2186 return CopyBytes(array, data_offset, native_array, length); | |
| 2187 } | |
| 2188 } | |
| 2157 } | 2189 } |
| 2158 } | 2190 } |
| 2159 if (obj.IsArray()) { | 2191 if (obj.IsArray()) { |
| 2160 GET_LIST_ELEMENT_AS_BYTES(isolate, | 2192 GET_LIST_ELEMENT_AS_BYTES(isolate, |
| 2161 Array, | 2193 Array, |
| 2162 obj, | 2194 obj, |
| 2163 native_array, | 2195 native_array, |
| 2164 offset, | 2196 offset, |
| 2165 length); | 2197 length); |
| 2166 } | 2198 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2186 Array::Handle(ArgumentsDescriptor::New(kNumArgs))); | 2218 Array::Handle(ArgumentsDescriptor::New(kNumArgs))); |
| 2187 const Function& function = Function::Handle( | 2219 const Function& function = Function::Handle( |
| 2188 isolate, | 2220 isolate, |
| 2189 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc)); | 2221 Resolver::ResolveDynamic(instance, Symbols::IndexToken(), args_desc)); |
| 2190 if (!function.IsNull()) { | 2222 if (!function.IsNull()) { |
| 2191 Object& result = Object::Handle(isolate); | 2223 Object& result = Object::Handle(isolate); |
| 2192 Integer& intobj = Integer::Handle(isolate); | 2224 Integer& intobj = Integer::Handle(isolate); |
| 2193 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); | 2225 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
| 2194 args.SetAt(0, instance); // Set up the receiver as the first argument. | 2226 args.SetAt(0, instance); // Set up the receiver as the first argument. |
| 2195 for (int i = 0; i < length; i++) { | 2227 for (int i = 0; i < length; i++) { |
| 2228 HANDLESCOPE(isolate); | |
| 2196 intobj = Integer::New(offset + i); | 2229 intobj = Integer::New(offset + i); |
| 2197 args.SetAt(1, intobj); | 2230 args.SetAt(1, intobj); |
| 2198 result = DartEntry::InvokeFunction(function, args); | 2231 result = DartEntry::InvokeFunction(function, args); |
| 2199 if (result.IsError()) { | 2232 if (result.IsError()) { |
| 2200 return Api::NewHandle(isolate, result.raw()); | 2233 return Api::NewHandle(isolate, result.raw()); |
| 2201 } | 2234 } |
| 2202 if (!result.IsInteger()) { | 2235 if (!result.IsInteger()) { |
| 2203 return Api::NewError("%s expects the argument 'list' to be " | 2236 return Api::NewError("%s expects the argument 'list' to be " |
| 2204 "a List of int", CURRENT_FUNC); | 2237 "a List of int", CURRENT_FUNC); |
| 2205 } | 2238 } |
| (...skipping 1903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4109 } | 4142 } |
| 4110 { | 4143 { |
| 4111 NoGCScope no_gc; | 4144 NoGCScope no_gc; |
| 4112 RawObject* raw_obj = obj.raw(); | 4145 RawObject* raw_obj = obj.raw(); |
| 4113 isolate->heap()->SetPeer(raw_obj, peer); | 4146 isolate->heap()->SetPeer(raw_obj, peer); |
| 4114 } | 4147 } |
| 4115 return Api::Success(); | 4148 return Api::Success(); |
| 4116 } | 4149 } |
| 4117 | 4150 |
| 4118 } // namespace dart | 4151 } // namespace dart |
| OLD | NEW |