From 1996b83ba57e38ee6015a56e2af95e32f7722e5e Mon Sep 17 00:00:00 2001 From: Lars T Hansen Date: Fri, 4 Mar 2016 14:18:06 +0100 Subject: [PATCH] Bug 1248153 - Do not convert fp to int by cast. r=waldo --HG-- extra : amend_source : 6eea6a7a9bf113efe43822423ad7d0ab542d94c7 extra : histedit_source : 63cd6daa497e79a01b7011bb5fb56e098104d00d --- js/public/Conversions.h | 6 ++ js/src/vm/TypedArrayCommon.h | 144 +++++++++++++++++++++++++++++++---- 2 files changed, 134 insertions(+), 16 deletions(-) diff --git a/js/public/Conversions.h b/js/public/Conversions.h index ac09cc2261ea..8dc16da9b022 100644 --- a/js/public/Conversions.h +++ b/js/public/Conversions.h @@ -556,6 +556,12 @@ ToInt16(double d) return detail::ToIntWidth(d); } +inline uint16_t +ToUint16(double d) +{ + return detail::ToUintWidth(d); +} + /* WEBIDL 4.2.10 */ inline int64_t ToInt64(double d) diff --git a/js/src/vm/TypedArrayCommon.h b/js/src/vm/TypedArrayCommon.h index 71db62c678f5..196e92733cf9 100644 --- a/js/src/vm/TypedArrayCommon.h +++ b/js/src/vm/TypedArrayCommon.h @@ -58,6 +58,118 @@ ValueIsLength(const Value& v, uint32_t* len) return false; } +template +inline To +ConvertNumber(From src); + +template<> +inline int8_t +ConvertNumber(float src) +{ + return JS::ToInt8(src); +} + +template<> +inline uint8_t +ConvertNumber(float src) +{ + return JS::ToUint8(src); +} + +template<> +inline uint8_clamped +ConvertNumber(float src) +{ + return uint8_clamped(src); +} + +template<> +inline int16_t +ConvertNumber(float src) +{ + return JS::ToInt16(src); +} + +template<> +inline uint16_t +ConvertNumber(float src) +{ + return JS::ToUint16(src); +} + +template<> +inline int32_t +ConvertNumber(float src) +{ + return JS::ToInt32(src); +} + +template<> +inline uint32_t +ConvertNumber(float src) +{ + return JS::ToUint32(src); +} + +template<> inline int8_t +ConvertNumber(double src) +{ + return JS::ToInt8(src); +} + +template<> +inline uint8_t +ConvertNumber(double src) +{ + return JS::ToUint8(src); +} + +template<> +inline uint8_clamped +ConvertNumber(double src) +{ + return uint8_clamped(src); +} + +template<> +inline int16_t +ConvertNumber(double src) +{ + return JS::ToInt16(src); +} + +template<> +inline uint16_t +ConvertNumber(double src) +{ + return JS::ToUint16(src); +} + +template<> +inline int32_t +ConvertNumber(double src) +{ + return JS::ToInt32(src); +} + +template<> +inline uint32_t +ConvertNumber(double src) +{ + return JS::ToUint32(src); +} + +template +inline To +ConvertNumber(From src) +{ + static_assert(!mozilla::IsFloatingPoint::value || + (mozilla::IsFloatingPoint::value && mozilla::IsFloatingPoint::value), + "conversion from floating point to int should have been handled by " + "specializations above"); + return To(src); +} + template struct TypeIDOfType; template<> struct TypeIDOfType { static const Scalar::Type id = Scalar::Int8; }; template<> struct TypeIDOfType { static const Scalar::Type id = Scalar::Uint8; }; @@ -196,50 +308,50 @@ class ElementSpecific case Scalar::Int8: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } case Scalar::Uint8: case Scalar::Uint8Clamped: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } case Scalar::Int16: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } case Scalar::Uint16: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } case Scalar::Int32: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } case Scalar::Uint32: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } case Scalar::Float32: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } case Scalar::Float64: { SharedMem src = data.cast(); for (uint32_t i = 0; i < count; ++i) - Ops::store(dest++, T(Ops::load(src++))); + Ops::store(dest++, ConvertNumber(Ops::load(src++))); break; } default: @@ -351,50 +463,50 @@ class ElementSpecific case Scalar::Int8: { int8_t* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } case Scalar::Uint8: case Scalar::Uint8Clamped: { uint8_t* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } case Scalar::Int16: { int16_t* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } case Scalar::Uint16: { uint16_t* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } case Scalar::Int32: { int32_t* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } case Scalar::Uint32: { uint32_t* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } case Scalar::Float32: { float* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } case Scalar::Float64: { double* src = static_cast(data); for (uint32_t i = 0; i < len; ++i) - Ops::store(dest++, T(*src++)); + Ops::store(dest++, ConvertNumber(*src++)); break; } default: