mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 924014 - Do not rely on std::numeric_limits<char16_t> being available; r=Waldo
This commit is contained in:
parent
aa977286d4
commit
738f5fd13e
@ -8,8 +8,8 @@
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/NumericLimits.h"
|
||||
|
||||
#include <limits>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#include "ctypes/Library.h"
|
||||
|
||||
using namespace std;
|
||||
using mozilla::NumericLimits;
|
||||
|
||||
namespace js {
|
||||
namespace ctypes {
|
||||
@ -1423,7 +1424,7 @@ JS_STATIC_ASSERT(sizeof(long long) == 8);
|
||||
JS_STATIC_ASSERT(sizeof(size_t) == sizeof(uintptr_t));
|
||||
JS_STATIC_ASSERT(sizeof(float) == 4);
|
||||
JS_STATIC_ASSERT(sizeof(PRFuncPtr) == sizeof(void*));
|
||||
JS_STATIC_ASSERT(numeric_limits<double>::is_signed);
|
||||
JS_STATIC_ASSERT(NumericLimits<double>::is_signed);
|
||||
|
||||
// Templated helper to convert FromType to TargetType, for the default case
|
||||
// where the trivial POD constructor will do.
|
||||
@ -1488,15 +1489,15 @@ static JS_ALWAYS_INLINE bool IsAlwaysExact()
|
||||
// 2) If FromType is signed, TargetType must also be signed. (Floating point
|
||||
// types are always signed.)
|
||||
// 3) If TargetType is an exact integral type, FromType must be also.
|
||||
if (numeric_limits<TargetType>::digits < numeric_limits<FromType>::digits)
|
||||
if (NumericLimits<TargetType>::digits < NumericLimits<FromType>::digits)
|
||||
return false;
|
||||
|
||||
if (numeric_limits<FromType>::is_signed &&
|
||||
!numeric_limits<TargetType>::is_signed)
|
||||
if (NumericLimits<FromType>::is_signed &&
|
||||
!NumericLimits<TargetType>::is_signed)
|
||||
return false;
|
||||
|
||||
if (!numeric_limits<FromType>::is_exact &&
|
||||
numeric_limits<TargetType>::is_exact)
|
||||
if (!NumericLimits<FromType>::is_exact &&
|
||||
NumericLimits<TargetType>::is_exact)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -1507,7 +1508,7 @@ static JS_ALWAYS_INLINE bool IsAlwaysExact()
|
||||
template<class TargetType, class FromType, bool TargetSigned, bool FromSigned>
|
||||
struct IsExactImpl {
|
||||
static JS_ALWAYS_INLINE bool Test(FromType i, TargetType j) {
|
||||
JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
|
||||
return FromType(j) == i;
|
||||
}
|
||||
};
|
||||
@ -1516,7 +1517,7 @@ struct IsExactImpl {
|
||||
template<class TargetType, class FromType>
|
||||
struct IsExactImpl<TargetType, FromType, false, true> {
|
||||
static JS_ALWAYS_INLINE bool Test(FromType i, TargetType j) {
|
||||
JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
|
||||
return i >= 0 && FromType(j) == i;
|
||||
}
|
||||
};
|
||||
@ -1525,7 +1526,7 @@ struct IsExactImpl<TargetType, FromType, false, true> {
|
||||
template<class TargetType, class FromType>
|
||||
struct IsExactImpl<TargetType, FromType, true, false> {
|
||||
static JS_ALWAYS_INLINE bool Test(FromType i, TargetType j) {
|
||||
JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
|
||||
return TargetType(i) >= 0 && FromType(j) == i;
|
||||
}
|
||||
};
|
||||
@ -1536,7 +1537,7 @@ template<class TargetType, class FromType>
|
||||
static JS_ALWAYS_INLINE bool ConvertExact(FromType i, TargetType* result)
|
||||
{
|
||||
// Require that TargetType is integral, to simplify conversion.
|
||||
JS_STATIC_ASSERT(numeric_limits<TargetType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<TargetType>::is_exact);
|
||||
|
||||
*result = Convert<TargetType>(i);
|
||||
|
||||
@ -1547,8 +1548,8 @@ static JS_ALWAYS_INLINE bool ConvertExact(FromType i, TargetType* result)
|
||||
// Return 'true' if 'i' is exactly representable in 'TargetType'.
|
||||
return IsExactImpl<TargetType,
|
||||
FromType,
|
||||
numeric_limits<TargetType>::is_signed,
|
||||
numeric_limits<FromType>::is_signed>::Test(i, *result);
|
||||
NumericLimits<TargetType>::is_signed,
|
||||
NumericLimits<FromType>::is_signed>::Test(i, *result);
|
||||
}
|
||||
|
||||
// Templated helper to determine if Type 'i' is negative. Default case
|
||||
@ -1572,7 +1573,7 @@ struct IsNegativeImpl<Type, true> {
|
||||
template<class Type>
|
||||
static JS_ALWAYS_INLINE bool IsNegative(Type i)
|
||||
{
|
||||
return IsNegativeImpl<Type, numeric_limits<Type>::is_signed>::Test(i);
|
||||
return IsNegativeImpl<Type, NumericLimits<Type>::is_signed>::Test(i);
|
||||
}
|
||||
|
||||
// Implicitly convert val to bool, allowing bool, int, and double
|
||||
@ -1606,7 +1607,7 @@ template<class IntegerType>
|
||||
static bool
|
||||
jsvalToInteger(JSContext* cx, jsval val, IntegerType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
|
||||
|
||||
if (JSVAL_IS_INT(val)) {
|
||||
// Make sure the integer fits in the alotted precision, and has the right
|
||||
@ -1695,7 +1696,7 @@ template<class FloatType>
|
||||
static bool
|
||||
jsvalToFloat(JSContext *cx, jsval val, FloatType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(!numeric_limits<FloatType>::is_exact);
|
||||
JS_STATIC_ASSERT(!NumericLimits<FloatType>::is_exact);
|
||||
|
||||
// The following casts may silently throw away some bits, but there's
|
||||
// no good way around it. Sternly requiring that the 64-bit double
|
||||
@ -1751,7 +1752,7 @@ template<class IntegerType>
|
||||
static bool
|
||||
StringToInteger(JSContext* cx, JSString* string, IntegerType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
|
||||
|
||||
const jschar* cp = string->getChars(nullptr);
|
||||
if (!cp)
|
||||
@ -1763,7 +1764,7 @@ StringToInteger(JSContext* cx, JSString* string, IntegerType* result)
|
||||
|
||||
IntegerType sign = 1;
|
||||
if (cp[0] == '-') {
|
||||
if (!numeric_limits<IntegerType>::is_signed)
|
||||
if (!NumericLimits<IntegerType>::is_signed)
|
||||
return false;
|
||||
|
||||
sign = -1;
|
||||
@ -1811,7 +1812,7 @@ jsvalToBigInteger(JSContext* cx,
|
||||
bool allowString,
|
||||
IntegerType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
|
||||
|
||||
if (JSVAL_IS_INT(val)) {
|
||||
// Make sure the integer fits in the alotted precision, and has the right
|
||||
@ -1882,7 +1883,7 @@ jsidToBigInteger(JSContext* cx,
|
||||
bool allowString,
|
||||
IntegerType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
|
||||
|
||||
if (JSID_IS_INT(val)) {
|
||||
// Make sure the integer fits in the alotted precision, and has the right
|
||||
@ -1947,7 +1948,7 @@ template<class IntegerType>
|
||||
static bool
|
||||
jsvalToIntegerExplicit(jsval val, IntegerType* result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
|
||||
|
||||
if (JSVAL_IS_DOUBLE(val)) {
|
||||
// Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
|
||||
@ -2028,7 +2029,7 @@ template<class IntegerType, class CharType, size_t N, class AP>
|
||||
void
|
||||
IntegerToString(IntegerType i, int radix, Vector<CharType, N, AP>& result)
|
||||
{
|
||||
JS_STATIC_ASSERT(numeric_limits<IntegerType>::is_exact);
|
||||
JS_STATIC_ASSERT(NumericLimits<IntegerType>::is_exact);
|
||||
|
||||
// The buffer must be big enough for all the bits of IntegerType to fit,
|
||||
// in base-2, including '-'.
|
||||
@ -2112,7 +2113,7 @@ ConvertToJS(JSContext* cx,
|
||||
/* Return an Int64 or UInt64 object - do not convert to a JS number. */ \
|
||||
uint64_t value; \
|
||||
RootedObject proto(cx); \
|
||||
if (!numeric_limits<type>::is_signed) { \
|
||||
if (!NumericLimits<type>::is_signed) { \
|
||||
value = *static_cast<type*>(data); \
|
||||
/* Get ctypes.UInt64.prototype from ctypes.CType.prototype. */ \
|
||||
proto = CType::GetProtoFromType(cx, typeObj, SLOT_UINT64PROTO); \
|
||||
@ -2121,13 +2122,13 @@ ConvertToJS(JSContext* cx,
|
||||
} else { \
|
||||
value = int64_t(*static_cast<type*>(data)); \
|
||||
/* Get ctypes.Int64.prototype from ctypes.CType.prototype. */ \
|
||||
proto = CType::GetProtoFromType(cx, typeObj, SLOT_INT64PROTO); \
|
||||
proto = CType::GetProtoFromType(cx, typeObj, SLOT_INT64PROTO); \
|
||||
if (!proto) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
JSObject* obj = Int64Base::Construct(cx, proto, value, \
|
||||
!numeric_limits<type>::is_signed); \
|
||||
!NumericLimits<type>::is_signed); \
|
||||
if (!obj) \
|
||||
return false; \
|
||||
*result = OBJECT_TO_JSVAL(obj); \
|
||||
@ -2977,7 +2978,7 @@ BuildDataSource(JSContext* cx,
|
||||
#define DEFINE_WRAPPED_INT_TYPE(name, type, ffiType) \
|
||||
case TYPE_##name: \
|
||||
/* Serialize as a wrapped decimal integer. */ \
|
||||
if (!numeric_limits<type>::is_signed) \
|
||||
if (!NumericLimits<type>::is_signed) \
|
||||
AppendString(result, "ctypes.UInt64(\""); \
|
||||
else \
|
||||
AppendString(result, "ctypes.Int64(\""); \
|
||||
|
40
mfbt/NumericLimits.h
Normal file
40
mfbt/NumericLimits.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Compatibility with std::numeric_limits<char16_t>. */
|
||||
|
||||
#ifndef mozilla_NumericLimits_h
|
||||
#define mozilla_NumericLimits_h
|
||||
|
||||
#include "mozilla/Char16.h"
|
||||
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* The NumericLimits class provides a compatibility layer with std::numeric_limits
|
||||
* for char16_t, otherwise it is exactly the same as std::numeric_limits.
|
||||
* Code which does not need std::numeric_limits<char16_t> should avoid using
|
||||
* NumericLimits.
|
||||
*/
|
||||
template<typename T>
|
||||
class NumericLimits : public std::numeric_limits<T>
|
||||
{
|
||||
};
|
||||
|
||||
#ifdef MOZ_CHAR16_IS_NOT_WCHAR
|
||||
template<>
|
||||
class NumericLimits<char16_t> : public std::numeric_limits<uint16_t>
|
||||
{
|
||||
// char16_t and uint16_t numeric limits should be exactly the same.
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_NumericLimits_h */
|
@ -39,6 +39,7 @@ EXPORTS_mozilla_FILES += \
|
||||
MSIntTypes.h \
|
||||
Move.h \
|
||||
NullPtr.h \
|
||||
NumericLimits.h \
|
||||
PodOperations.h \
|
||||
Poison.h \
|
||||
Range.h \
|
||||
|
Loading…
Reference in New Issue
Block a user