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 "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
10 #include "vm/native_entry.h" | 10 #include "vm/native_entry.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 intptr_t element_size_in_bytes) { | 21 intptr_t element_size_in_bytes) { |
22 if (!Utils::RangeCheck(offset_in_bytes, access_size, length_in_bytes)) { | 22 if (!Utils::RangeCheck(offset_in_bytes, access_size, length_in_bytes)) { |
23 const intptr_t index = | 23 const intptr_t index = |
24 (offset_in_bytes + access_size) / element_size_in_bytes; | 24 (offset_in_bytes + access_size) / element_size_in_bytes; |
25 const intptr_t length = length_in_bytes / element_size_in_bytes; | 25 const intptr_t length = length_in_bytes / element_size_in_bytes; |
26 Exceptions::ThrowRangeError("index", Integer::Handle(Integer::New(index)), | 26 Exceptions::ThrowRangeError("index", Integer::Handle(Integer::New(index)), |
27 0, length); | 27 0, length); |
28 } | 28 } |
29 } | 29 } |
30 | 30 |
31 | |
32 // Checks to see if a length will not result in an OOM error. | 31 // Checks to see if a length will not result in an OOM error. |
33 static void LengthCheck(intptr_t len, intptr_t max) { | 32 static void LengthCheck(intptr_t len, intptr_t max) { |
34 if (len < 0 || len > max) { | 33 if (len < 0 || len > max) { |
35 const String& error = String::Handle(String::NewFormatted( | 34 const String& error = String::Handle(String::NewFormatted( |
36 "Length (%" Pd ") of object must be in range [0..%" Pd "]", len, max)); | 35 "Length (%" Pd ") of object must be in range [0..%" Pd "]", len, max)); |
37 Exceptions::ThrowArgumentError(error); | 36 Exceptions::ThrowArgumentError(error); |
38 } | 37 } |
39 } | 38 } |
40 | 39 |
41 | |
42 DEFINE_NATIVE_ENTRY(TypedData_length, 1) { | 40 DEFINE_NATIVE_ENTRY(TypedData_length, 1) { |
43 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); | 41 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); |
44 if (instance.IsTypedData()) { | 42 if (instance.IsTypedData()) { |
45 const TypedData& array = TypedData::Cast(instance); | 43 const TypedData& array = TypedData::Cast(instance); |
46 return Smi::New(array.Length()); | 44 return Smi::New(array.Length()); |
47 } | 45 } |
48 if (instance.IsExternalTypedData()) { | 46 if (instance.IsExternalTypedData()) { |
49 const ExternalTypedData& array = ExternalTypedData::Cast(instance); | 47 const ExternalTypedData& array = ExternalTypedData::Cast(instance); |
50 return Smi::New(array.Length()); | 48 return Smi::New(array.Length()); |
51 } | 49 } |
52 const String& error = String::Handle(String::NewFormatted( | 50 const String& error = String::Handle(String::NewFormatted( |
53 "Expected a TypedData object but found %s", instance.ToCString())); | 51 "Expected a TypedData object but found %s", instance.ToCString())); |
54 Exceptions::ThrowArgumentError(error); | 52 Exceptions::ThrowArgumentError(error); |
55 return Integer::null(); | 53 return Integer::null(); |
56 } | 54 } |
57 | 55 |
58 | |
59 template <typename DstType, typename SrcType> | 56 template <typename DstType, typename SrcType> |
60 static RawBool* CopyData(const Instance& dst, | 57 static RawBool* CopyData(const Instance& dst, |
61 const Instance& src, | 58 const Instance& src, |
62 const Smi& dst_start, | 59 const Smi& dst_start, |
63 const Smi& src_start, | 60 const Smi& src_start, |
64 const Smi& length, | 61 const Smi& length, |
65 bool clamped) { | 62 bool clamped) { |
66 const DstType& dst_array = DstType::Cast(dst); | 63 const DstType& dst_array = DstType::Cast(dst); |
67 const SrcType& src_array = SrcType::Cast(src); | 64 const SrcType& src_array = SrcType::Cast(src); |
68 const intptr_t dst_offset_in_bytes = dst_start.Value(); | 65 const intptr_t dst_offset_in_bytes = dst_start.Value(); |
69 const intptr_t src_offset_in_bytes = src_start.Value(); | 66 const intptr_t src_offset_in_bytes = src_start.Value(); |
70 const intptr_t length_in_bytes = length.Value(); | 67 const intptr_t length_in_bytes = length.Value(); |
71 ASSERT(Utils::RangeCheck(src_offset_in_bytes, length_in_bytes, | 68 ASSERT(Utils::RangeCheck(src_offset_in_bytes, length_in_bytes, |
72 src_array.LengthInBytes())); | 69 src_array.LengthInBytes())); |
73 ASSERT(Utils::RangeCheck(dst_offset_in_bytes, length_in_bytes, | 70 ASSERT(Utils::RangeCheck(dst_offset_in_bytes, length_in_bytes, |
74 dst_array.LengthInBytes())); | 71 dst_array.LengthInBytes())); |
75 if (clamped) { | 72 if (clamped) { |
76 TypedData::ClampedCopy<DstType, SrcType>(dst_array, dst_offset_in_bytes, | 73 TypedData::ClampedCopy<DstType, SrcType>(dst_array, dst_offset_in_bytes, |
77 src_array, src_offset_in_bytes, | 74 src_array, src_offset_in_bytes, |
78 length_in_bytes); | 75 length_in_bytes); |
79 } else { | 76 } else { |
80 TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes, src_array, | 77 TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes, src_array, |
81 src_offset_in_bytes, length_in_bytes); | 78 src_offset_in_bytes, length_in_bytes); |
82 } | 79 } |
83 return Bool::True().raw(); | 80 return Bool::True().raw(); |
84 } | 81 } |
85 | 82 |
86 | |
87 static bool IsClamped(intptr_t cid) { | 83 static bool IsClamped(intptr_t cid) { |
88 switch (cid) { | 84 switch (cid) { |
89 case kTypedDataUint8ClampedArrayCid: | 85 case kTypedDataUint8ClampedArrayCid: |
90 case kExternalTypedDataUint8ClampedArrayCid: | 86 case kExternalTypedDataUint8ClampedArrayCid: |
91 case kTypedDataUint8ClampedArrayViewCid: | 87 case kTypedDataUint8ClampedArrayViewCid: |
92 return true; | 88 return true; |
93 default: | 89 default: |
94 return false; | 90 return false; |
95 } | 91 } |
96 } | 92 } |
97 | 93 |
98 | |
99 static bool IsUint8(intptr_t cid) { | 94 static bool IsUint8(intptr_t cid) { |
100 switch (cid) { | 95 switch (cid) { |
101 case kTypedDataUint8ClampedArrayCid: | 96 case kTypedDataUint8ClampedArrayCid: |
102 case kExternalTypedDataUint8ClampedArrayCid: | 97 case kExternalTypedDataUint8ClampedArrayCid: |
103 case kTypedDataUint8ClampedArrayViewCid: | 98 case kTypedDataUint8ClampedArrayViewCid: |
104 case kTypedDataUint8ArrayCid: | 99 case kTypedDataUint8ArrayCid: |
105 case kExternalTypedDataUint8ArrayCid: | 100 case kExternalTypedDataUint8ArrayCid: |
106 case kTypedDataUint8ArrayViewCid: | 101 case kTypedDataUint8ArrayViewCid: |
107 return true; | 102 return true; |
108 default: | 103 default: |
109 return false; | 104 return false; |
110 } | 105 } |
111 } | 106 } |
112 | 107 |
113 | |
114 DEFINE_NATIVE_ENTRY(TypedData_setRange, 7) { | 108 DEFINE_NATIVE_ENTRY(TypedData_setRange, 7) { |
115 const Instance& dst = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 109 const Instance& dst = Instance::CheckedHandle(arguments->NativeArgAt(0)); |
116 const Smi& dst_start = Smi::CheckedHandle(arguments->NativeArgAt(1)); | 110 const Smi& dst_start = Smi::CheckedHandle(arguments->NativeArgAt(1)); |
117 const Smi& length = Smi::CheckedHandle(arguments->NativeArgAt(2)); | 111 const Smi& length = Smi::CheckedHandle(arguments->NativeArgAt(2)); |
118 const Instance& src = Instance::CheckedHandle(arguments->NativeArgAt(3)); | 112 const Instance& src = Instance::CheckedHandle(arguments->NativeArgAt(3)); |
119 const Smi& src_start = Smi::CheckedHandle(arguments->NativeArgAt(4)); | 113 const Smi& src_start = Smi::CheckedHandle(arguments->NativeArgAt(4)); |
120 const Smi& to_cid_smi = Smi::CheckedHandle(arguments->NativeArgAt(5)); | 114 const Smi& to_cid_smi = Smi::CheckedHandle(arguments->NativeArgAt(5)); |
121 const Smi& from_cid_smi = Smi::CheckedHandle(arguments->NativeArgAt(6)); | 115 const Smi& from_cid_smi = Smi::CheckedHandle(arguments->NativeArgAt(6)); |
122 | 116 |
123 if (length.Value() < 0) { | 117 if (length.Value() < 0) { |
(...skipping 19 matching lines...) Expand all Loading... |
143 dst, src, dst_start, src_start, length, needs_clamping); | 137 dst, src, dst_start, src_start, length, needs_clamping); |
144 } else if (src.IsExternalTypedData()) { | 138 } else if (src.IsExternalTypedData()) { |
145 return CopyData<ExternalTypedData, ExternalTypedData>( | 139 return CopyData<ExternalTypedData, ExternalTypedData>( |
146 dst, src, dst_start, src_start, length, needs_clamping); | 140 dst, src, dst_start, src_start, length, needs_clamping); |
147 } | 141 } |
148 } | 142 } |
149 UNREACHABLE(); | 143 UNREACHABLE(); |
150 return Bool::False().raw(); | 144 return Bool::False().raw(); |
151 } | 145 } |
152 | 146 |
153 | |
154 // We check the length parameter against a possible maximum length for the | 147 // We check the length parameter against a possible maximum length for the |
155 // array based on available physical addressable memory on the system. The | 148 // array based on available physical addressable memory on the system. The |
156 // maximum possible length is a scaled value of kSmiMax which is set up based | 149 // maximum possible length is a scaled value of kSmiMax which is set up based |
157 // on whether the underlying architecture is 32-bit or 64-bit. | 150 // on whether the underlying architecture is 32-bit or 64-bit. |
158 // Argument 0 is type arguments and is ignored. | 151 // Argument 0 is type arguments and is ignored. |
159 #define TYPED_DATA_NEW(name) \ | 152 #define TYPED_DATA_NEW(name) \ |
160 DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 2) { \ | 153 DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 2) { \ |
161 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); \ | 154 GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); \ |
162 intptr_t cid = kTypedData##name##Cid; \ | 155 intptr_t cid = kTypedData##name##Cid; \ |
163 intptr_t len = length.Value(); \ | 156 intptr_t len = length.Value(); \ |
164 intptr_t max = TypedData::MaxElements(cid); \ | 157 intptr_t max = TypedData::MaxElements(cid); \ |
165 LengthCheck(len, max); \ | 158 LengthCheck(len, max); \ |
166 return TypedData::New(cid, len); \ | 159 return TypedData::New(cid, len); \ |
167 } | 160 } |
168 | 161 |
169 | |
170 #define TYPED_DATA_NEW_NATIVE(name) TYPED_DATA_NEW(name) | 162 #define TYPED_DATA_NEW_NATIVE(name) TYPED_DATA_NEW(name) |
171 | 163 |
172 | |
173 CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE) | 164 CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE) |
174 | 165 |
175 #define TYPED_DATA_GETTER(getter, object, ctor, access_size) \ | 166 #define TYPED_DATA_GETTER(getter, object, ctor, access_size) \ |
176 DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) { \ | 167 DEFINE_NATIVE_ENTRY(TypedData_##getter, 2) { \ |
177 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, \ | 168 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, \ |
178 arguments->NativeArgAt(0)); \ | 169 arguments->NativeArgAt(0)); \ |
179 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, \ | 170 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, \ |
180 arguments->NativeArgAt(1)); \ | 171 arguments->NativeArgAt(1)); \ |
181 if (instance.IsTypedData()) { \ | 172 if (instance.IsTypedData()) { \ |
182 const TypedData& array = TypedData::Cast(instance); \ | 173 const TypedData& array = TypedData::Cast(instance); \ |
183 RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(), \ | 174 RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(), \ |
184 access_size); \ | 175 access_size); \ |
185 return object::ctor(array.getter(offsetInBytes.Value())); \ | 176 return object::ctor(array.getter(offsetInBytes.Value())); \ |
186 } \ | 177 } \ |
187 if (instance.IsExternalTypedData()) { \ | 178 if (instance.IsExternalTypedData()) { \ |
188 const ExternalTypedData& array = ExternalTypedData::Cast(instance); \ | 179 const ExternalTypedData& array = ExternalTypedData::Cast(instance); \ |
189 RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(), \ | 180 RangeCheck(offsetInBytes.Value(), access_size, array.LengthInBytes(), \ |
190 access_size); \ | 181 access_size); \ |
191 return object::ctor(array.getter(offsetInBytes.Value())); \ | 182 return object::ctor(array.getter(offsetInBytes.Value())); \ |
192 } \ | 183 } \ |
193 const String& error = String::Handle(String::NewFormatted( \ | 184 const String& error = String::Handle(String::NewFormatted( \ |
194 "Expected a TypedData object but found %s", instance.ToCString())); \ | 185 "Expected a TypedData object but found %s", instance.ToCString())); \ |
195 Exceptions::ThrowArgumentError(error); \ | 186 Exceptions::ThrowArgumentError(error); \ |
196 return object::null(); \ | 187 return object::null(); \ |
197 } | 188 } |
198 | 189 |
199 | |
200 #define TYPED_DATA_SETTER(setter, object, get_object_value, access_size, \ | 190 #define TYPED_DATA_SETTER(setter, object, get_object_value, access_size, \ |
201 access_type) \ | 191 access_type) \ |
202 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \ | 192 DEFINE_NATIVE_ENTRY(TypedData_##setter, 3) { \ |
203 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, \ | 193 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, \ |
204 arguments->NativeArgAt(0)); \ | 194 arguments->NativeArgAt(0)); \ |
205 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, \ | 195 GET_NON_NULL_NATIVE_ARGUMENT(Smi, offsetInBytes, \ |
206 arguments->NativeArgAt(1)); \ | 196 arguments->NativeArgAt(1)); \ |
207 GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2)); \ | 197 GET_NON_NULL_NATIVE_ARGUMENT(object, value, arguments->NativeArgAt(2)); \ |
208 if (instance.IsTypedData()) { \ | 198 if (instance.IsTypedData()) { \ |
209 const TypedData& array = TypedData::Cast(instance); \ | 199 const TypedData& array = TypedData::Cast(instance); \ |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 NewFromUint64, | 233 NewFromUint64, |
244 AsTruncatedInt64Value, | 234 AsTruncatedInt64Value, |
245 8, | 235 8, |
246 uint64_t) | 236 uint64_t) |
247 TYPED_DATA_NATIVES(Float32, Double, New, value, 4, float) | 237 TYPED_DATA_NATIVES(Float32, Double, New, value, 4, float) |
248 TYPED_DATA_NATIVES(Float64, Double, New, value, 8, double) | 238 TYPED_DATA_NATIVES(Float64, Double, New, value, 8, double) |
249 TYPED_DATA_NATIVES(Float32x4, Float32x4, New, value, 16, simd128_value_t) | 239 TYPED_DATA_NATIVES(Float32x4, Float32x4, New, value, 16, simd128_value_t) |
250 TYPED_DATA_NATIVES(Int32x4, Int32x4, New, value, 16, simd128_value_t) | 240 TYPED_DATA_NATIVES(Int32x4, Int32x4, New, value, 16, simd128_value_t) |
251 TYPED_DATA_NATIVES(Float64x2, Float64x2, New, value, 16, simd128_value_t) | 241 TYPED_DATA_NATIVES(Float64x2, Float64x2, New, value, 16, simd128_value_t) |
252 | 242 |
253 | |
254 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt16, 2) { | 243 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt16, 2) { |
255 GET_NON_NULL_NATIVE_ARGUMENT(Smi, host_value, arguments->NativeArgAt(0)); | 244 GET_NON_NULL_NATIVE_ARGUMENT(Smi, host_value, arguments->NativeArgAt(0)); |
256 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 245 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
257 int16_t value = host_value.Value(); | 246 int16_t value = host_value.Value(); |
258 if (little_endian.value()) { | 247 if (little_endian.value()) { |
259 value = Utils::HostToLittleEndian16(value); | 248 value = Utils::HostToLittleEndian16(value); |
260 } else { | 249 } else { |
261 value = Utils::HostToBigEndian16(value); | 250 value = Utils::HostToBigEndian16(value); |
262 } | 251 } |
263 return Smi::New(value); | 252 return Smi::New(value); |
264 } | 253 } |
265 | 254 |
266 | |
267 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint16, 2) { | 255 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint16, 2) { |
268 GET_NON_NULL_NATIVE_ARGUMENT(Smi, host_value, arguments->NativeArgAt(0)); | 256 GET_NON_NULL_NATIVE_ARGUMENT(Smi, host_value, arguments->NativeArgAt(0)); |
269 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 257 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
270 uint16_t value = host_value.Value(); | 258 uint16_t value = host_value.Value(); |
271 if (little_endian.value()) { | 259 if (little_endian.value()) { |
272 return Smi::New(Utils::HostToLittleEndian16(value)); | 260 return Smi::New(Utils::HostToLittleEndian16(value)); |
273 } | 261 } |
274 return Smi::New(Utils::HostToBigEndian16(value)); | 262 return Smi::New(Utils::HostToBigEndian16(value)); |
275 } | 263 } |
276 | 264 |
277 | |
278 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt32, 2) { | 265 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt32, 2) { |
279 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); | 266 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); |
280 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 267 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
281 ASSERT((host_value.AsInt64Value() >= kMinInt32) || | 268 ASSERT((host_value.AsInt64Value() >= kMinInt32) || |
282 (host_value.AsInt64Value() <= kMaxInt32)); | 269 (host_value.AsInt64Value() <= kMaxInt32)); |
283 int32_t value = static_cast<int32_t>(host_value.AsInt64Value()); | 270 int32_t value = static_cast<int32_t>(host_value.AsInt64Value()); |
284 if (little_endian.value()) { | 271 if (little_endian.value()) { |
285 value = Utils::HostToLittleEndian32(value); | 272 value = Utils::HostToLittleEndian32(value); |
286 } else { | 273 } else { |
287 value = Utils::HostToBigEndian32(value); | 274 value = Utils::HostToBigEndian32(value); |
288 } | 275 } |
289 return Integer::New(value); | 276 return Integer::New(value); |
290 } | 277 } |
291 | 278 |
292 | |
293 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint32, 2) { | 279 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint32, 2) { |
294 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); | 280 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); |
295 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 281 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
296 ASSERT(host_value.AsInt64Value() <= kMaxUint32); | 282 ASSERT(host_value.AsInt64Value() <= kMaxUint32); |
297 uint32_t value = static_cast<uint32_t>(host_value.AsInt64Value()); | 283 uint32_t value = static_cast<uint32_t>(host_value.AsInt64Value()); |
298 if (little_endian.value()) { | 284 if (little_endian.value()) { |
299 value = Utils::HostToLittleEndian32(value); | 285 value = Utils::HostToLittleEndian32(value); |
300 } else { | 286 } else { |
301 value = Utils::HostToBigEndian32(value); | 287 value = Utils::HostToBigEndian32(value); |
302 } | 288 } |
303 return Integer::New(value); | 289 return Integer::New(value); |
304 } | 290 } |
305 | 291 |
306 | |
307 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt64, 2) { | 292 DEFINE_NATIVE_ENTRY(ByteData_ToEndianInt64, 2) { |
308 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); | 293 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); |
309 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 294 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
310 int64_t value = host_value.AsInt64Value(); | 295 int64_t value = host_value.AsInt64Value(); |
311 if (little_endian.value()) { | 296 if (little_endian.value()) { |
312 value = Utils::HostToLittleEndian64(value); | 297 value = Utils::HostToLittleEndian64(value); |
313 } else { | 298 } else { |
314 value = Utils::HostToBigEndian64(value); | 299 value = Utils::HostToBigEndian64(value); |
315 } | 300 } |
316 return Integer::New(value); | 301 return Integer::New(value); |
317 } | 302 } |
318 | 303 |
319 | |
320 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) { | 304 DEFINE_NATIVE_ENTRY(ByteData_ToEndianUint64, 2) { |
321 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); | 305 GET_NON_NULL_NATIVE_ARGUMENT(Integer, host_value, arguments->NativeArgAt(0)); |
322 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 306 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
323 uint64_t value; | 307 uint64_t value; |
324 if (host_value.IsBigint()) { | 308 if (host_value.IsBigint()) { |
325 const Bigint& bigint = Bigint::Cast(host_value); | 309 const Bigint& bigint = Bigint::Cast(host_value); |
326 ASSERT(bigint.FitsIntoUint64()); | 310 ASSERT(bigint.FitsIntoUint64()); |
327 value = bigint.AsUint64Value(); | 311 value = bigint.AsUint64Value(); |
328 } else { | 312 } else { |
329 ASSERT(host_value.IsMint() || host_value.IsSmi()); | 313 ASSERT(host_value.IsMint() || host_value.IsSmi()); |
330 value = host_value.AsInt64Value(); | 314 value = host_value.AsInt64Value(); |
331 } | 315 } |
332 if (little_endian.value()) { | 316 if (little_endian.value()) { |
333 value = Utils::HostToLittleEndian64(value); | 317 value = Utils::HostToLittleEndian64(value); |
334 } else { | 318 } else { |
335 value = Utils::HostToBigEndian64(value); | 319 value = Utils::HostToBigEndian64(value); |
336 } | 320 } |
337 return Integer::NewFromUint64(value); | 321 return Integer::NewFromUint64(value); |
338 } | 322 } |
339 | 323 |
340 | |
341 DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat32, 2) { | 324 DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat32, 2) { |
342 GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0)); | 325 GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0)); |
343 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 326 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
344 float value = host_value.value(); | 327 float value = host_value.value(); |
345 if (little_endian.value()) { | 328 if (little_endian.value()) { |
346 value = | 329 value = |
347 bit_cast<float>(Utils::HostToLittleEndian32(bit_cast<uint32_t>(value))); | 330 bit_cast<float>(Utils::HostToLittleEndian32(bit_cast<uint32_t>(value))); |
348 } else { | 331 } else { |
349 value = | 332 value = |
350 bit_cast<float>(Utils::HostToBigEndian32(bit_cast<uint32_t>(value))); | 333 bit_cast<float>(Utils::HostToBigEndian32(bit_cast<uint32_t>(value))); |
351 } | 334 } |
352 return Double::New(value); | 335 return Double::New(value); |
353 } | 336 } |
354 | 337 |
355 | |
356 DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat64, 2) { | 338 DEFINE_NATIVE_ENTRY(ByteData_ToEndianFloat64, 2) { |
357 GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0)); | 339 GET_NON_NULL_NATIVE_ARGUMENT(Double, host_value, arguments->NativeArgAt(0)); |
358 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); | 340 GET_NON_NULL_NATIVE_ARGUMENT(Bool, little_endian, arguments->NativeArgAt(1)); |
359 double value = host_value.value(); | 341 double value = host_value.value(); |
360 if (little_endian.value()) { | 342 if (little_endian.value()) { |
361 value = bit_cast<double>( | 343 value = bit_cast<double>( |
362 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); | 344 Utils::HostToLittleEndian64(bit_cast<uint64_t>(value))); |
363 } else { | 345 } else { |
364 value = | 346 value = |
365 bit_cast<double>(Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); | 347 bit_cast<double>(Utils::HostToBigEndian64(bit_cast<uint64_t>(value))); |
366 } | 348 } |
367 return Double::New(value); | 349 return Double::New(value); |
368 } | 350 } |
369 | 351 |
370 } // namespace dart | 352 } // namespace dart |
OLD | NEW |