| 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 |