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 |