зеркало из https://github.com/mozilla/gecko-dev.git
Bug 899309 - modify JS::Value and some helper functions to be constexpr-foldable; r=luke
This commit is contained in:
Родитель
84ba23610c
Коммит
b0ca59e796
|
@ -333,6 +333,49 @@ typedef union jsval_layout
|
|||
|
||||
JS_STATIC_ASSERT(sizeof(jsval_layout) == 8);
|
||||
|
||||
/*
|
||||
* For codesize purposes on some platforms, it's important that the
|
||||
* compiler know that JS::Values constructed from constant values can be
|
||||
* folded to constant bit patterns at compile time, rather than
|
||||
* constructed at runtime. Doing this requires a fair amount of C++11
|
||||
* features, which are not supported on all of our compilers. Set up
|
||||
* some defines and helper macros in an attempt to confine the ugliness
|
||||
* here, rather than scattering it all about the file. The important
|
||||
* features are:
|
||||
*
|
||||
* - constexpr;
|
||||
* - defaulted functions;
|
||||
* - C99-style designated initializers.
|
||||
*/
|
||||
#if defined(__clang__)
|
||||
# if __has_feature(cxx_constexpr) && __has_feature(cxx_defaulted_functions)
|
||||
# define JS_VALUE_IS_CONSTEXPR
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
/*
|
||||
* We need 4.5 for defaulted functions, 4.6 for constexpr, 4.7 because 4.6
|
||||
* doesn't understand |(X) { .field = ... }| syntax, and 4.7.3 because
|
||||
* versions prior to that have bugs in the C++ front-end that cause crashes.
|
||||
*/
|
||||
# if MOZ_GCC_VERSION_AT_LEAST(4, 7, 3)
|
||||
# define JS_VALUE_IS_CONSTEXPR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
# define JS_RETURN_LAYOUT_FROM_BITS(BITS) \
|
||||
return (jsval_layout) { .asBits = (BITS) }
|
||||
# define JS_VALUE_CONSTEXPR MOZ_CONSTEXPR
|
||||
# define JS_VALUE_CONSTEXPR_VAR MOZ_CONSTEXPR_VAR
|
||||
#else
|
||||
# define JS_RETURN_LAYOUT_FROM_BITS(BITS) \
|
||||
jsval_layout l; \
|
||||
l.asBits = (BITS); \
|
||||
return l;
|
||||
# define JS_VALUE_CONSTEXPR
|
||||
# define JS_VALUE_CONSTEXPR_VAR const
|
||||
#endif
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
|
||||
/*
|
||||
|
@ -341,12 +384,10 @@ JS_STATIC_ASSERT(sizeof(jsval_layout) == 8);
|
|||
* Thus, all comparisons should explicitly cast operands to uint32_t.
|
||||
*/
|
||||
|
||||
static inline jsval_layout
|
||||
static inline JS_VALUE_CONSTEXPR jsval_layout
|
||||
BUILD_JSVAL(JSValueTag tag, uint32_t payload)
|
||||
{
|
||||
jsval_layout l;
|
||||
l.asBits = (((uint64_t)(uint32_t)tag) << 32) | payload;
|
||||
return l;
|
||||
JS_RETURN_LAYOUT_FROM_BITS((((uint64_t)(uint32_t)tag) << 32) | payload);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -376,13 +417,17 @@ JSVAL_TO_INT32_IMPL(jsval_layout l)
|
|||
return l.s.payload.i32;
|
||||
}
|
||||
|
||||
static inline jsval_layout
|
||||
static inline JS_VALUE_CONSTEXPR jsval_layout
|
||||
INT32_TO_JSVAL_IMPL(int32_t i)
|
||||
{
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
return BUILD_JSVAL(JSVAL_TAG_INT32, i);
|
||||
#else
|
||||
jsval_layout l;
|
||||
l.s.tag = JSVAL_TAG_INT32;
|
||||
l.s.payload.i32 = i;
|
||||
return l;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -569,12 +614,10 @@ JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
|
|||
|
||||
#elif JS_BITS_PER_WORD == 64
|
||||
|
||||
static inline jsval_layout
|
||||
static inline JS_VALUE_CONSTEXPR jsval_layout
|
||||
BUILD_JSVAL(JSValueTag tag, uint64_t payload)
|
||||
{
|
||||
jsval_layout l;
|
||||
l.asBits = (((uint64_t)(uint32_t)tag) << JSVAL_TAG_SHIFT) | payload;
|
||||
return l;
|
||||
JS_RETURN_LAYOUT_FROM_BITS((((uint64_t)(uint32_t)tag) << JSVAL_TAG_SHIFT) | payload);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -604,12 +647,10 @@ JSVAL_TO_INT32_IMPL(jsval_layout l)
|
|||
return (int32_t)l.asBits;
|
||||
}
|
||||
|
||||
static inline jsval_layout
|
||||
static inline JS_VALUE_CONSTEXPR jsval_layout
|
||||
INT32_TO_JSVAL_IMPL(int32_t i32)
|
||||
{
|
||||
jsval_layout l;
|
||||
l.asBits = ((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32;
|
||||
return l;
|
||||
JS_RETURN_LAYOUT_FROM_BITS(((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -812,10 +853,12 @@ JS_CANONICALIZE_NAN(double d)
|
|||
}
|
||||
|
||||
static inline jsval_layout JSVAL_TO_IMPL(JS::Value v);
|
||||
static inline JS::Value IMPL_TO_JSVAL(jsval_layout l);
|
||||
static inline JS_VALUE_CONSTEXPR JS::Value IMPL_TO_JSVAL(jsval_layout l);
|
||||
|
||||
namespace JS {
|
||||
|
||||
static inline JS_VALUE_CONSTEXPR JS::Value UndefinedValue();
|
||||
|
||||
/*
|
||||
* JS::Value is the interface for a single JavaScript Engine value. A few
|
||||
* general notes on JS::Value:
|
||||
|
@ -858,6 +901,10 @@ class Value
|
|||
* N.B. the default constructor leaves Value unitialized. Adding a default
|
||||
* constructor prevents Value from being stored in a union.
|
||||
*/
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
Value() = default;
|
||||
Value(const Value& v) = default;
|
||||
#endif
|
||||
|
||||
/*** Mutators ***/
|
||||
|
||||
|
@ -1162,6 +1209,10 @@ class Value
|
|||
jsval_layout data;
|
||||
|
||||
private:
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
JS_VALUE_CONSTEXPR Value(jsval_layout layout) : data(layout) {}
|
||||
#endif
|
||||
|
||||
void staticAssertions() {
|
||||
JS_STATIC_ASSERT(sizeof(JSValueType) == 1);
|
||||
JS_STATIC_ASSERT(sizeof(JSValueTag) == 4);
|
||||
|
@ -1170,7 +1221,8 @@ class Value
|
|||
}
|
||||
|
||||
friend jsval_layout (::JSVAL_TO_IMPL)(Value);
|
||||
friend Value (::IMPL_TO_JSVAL)(jsval_layout l);
|
||||
friend Value JS_VALUE_CONSTEXPR (::IMPL_TO_JSVAL)(jsval_layout l);
|
||||
friend Value JS_VALUE_CONSTEXPR (JS::UndefinedValue)();
|
||||
};
|
||||
|
||||
inline bool
|
||||
|
@ -1193,12 +1245,16 @@ NullValue()
|
|||
return v;
|
||||
}
|
||||
|
||||
static inline Value
|
||||
static inline JS_VALUE_CONSTEXPR Value
|
||||
UndefinedValue()
|
||||
{
|
||||
Value v;
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
return Value(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0));
|
||||
#else
|
||||
JS::Value v;
|
||||
v.setUndefined();
|
||||
return v;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline Value
|
||||
|
@ -1608,12 +1664,16 @@ JSVAL_TO_IMPL(JS::Value v)
|
|||
return v.data;
|
||||
}
|
||||
|
||||
inline JS::Value
|
||||
inline JS_VALUE_CONSTEXPR JS::Value
|
||||
IMPL_TO_JSVAL(jsval_layout l)
|
||||
{
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
return JS::Value(l);
|
||||
#else
|
||||
JS::Value v;
|
||||
v.data = l;
|
||||
return v;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
@ -1691,7 +1751,7 @@ JSVAL_TO_INT(jsval v)
|
|||
return JSVAL_TO_INT32_IMPL(JSVAL_TO_IMPL(v));
|
||||
}
|
||||
|
||||
static inline jsval
|
||||
static inline JS_VALUE_CONSTEXPR jsval
|
||||
INT_TO_JSVAL(int32_t i)
|
||||
{
|
||||
return IMPL_TO_JSVAL(INT32_TO_JSVAL_IMPL(i));
|
||||
|
@ -1712,7 +1772,7 @@ JSVAL_TO_DOUBLE(jsval v)
|
|||
return l.asDouble;
|
||||
}
|
||||
|
||||
static inline jsval
|
||||
static inline JS_VALUE_CONSTEXPR jsval
|
||||
DOUBLE_TO_JSVAL(double d)
|
||||
{
|
||||
/*
|
||||
|
@ -1721,20 +1781,26 @@ DOUBLE_TO_JSVAL(double d)
|
|||
* return IMPL_TO_JSVAL(DOUBLE_TO_JSVAL_IMPL(d));
|
||||
* because GCC from XCode 3.1.4 miscompiles the above code.
|
||||
*/
|
||||
#if defined(JS_VALUE_IS_CONSTEXPR)
|
||||
return IMPL_TO_JSVAL(MOZ_UNLIKELY(d != d)
|
||||
? (jsval_layout) { .asBits = 0x7FF8000000000000LL }
|
||||
: (jsval_layout) { .asDouble = d });
|
||||
#else
|
||||
jsval_layout l;
|
||||
if (MOZ_UNLIKELY(d != d))
|
||||
l.asBits = 0x7FF8000000000000LL;
|
||||
else
|
||||
l.asDouble = d;
|
||||
return IMPL_TO_JSVAL(l);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline jsval
|
||||
static inline JS_VALUE_CONSTEXPR jsval
|
||||
UINT_TO_JSVAL(uint32_t i)
|
||||
{
|
||||
if (i <= JSVAL_INT_MAX)
|
||||
return INT_TO_JSVAL((int32_t)i);
|
||||
return DOUBLE_TO_JSVAL((double)i);
|
||||
return (i <= JSVAL_INT_MAX
|
||||
? INT_TO_JSVAL((int32_t)i)
|
||||
: DOUBLE_TO_JSVAL((double)i));
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -1830,4 +1896,7 @@ JSVAL_TO_PRIVATE(jsval v)
|
|||
return JSVAL_TO_PRIVATE_PTR_IMPL(JSVAL_TO_IMPL(v));
|
||||
}
|
||||
|
||||
#undef JS_VALUE_IS_CONSTEXPR
|
||||
#undef JS_RETURN_LAYOUT_FROM_BITS
|
||||
|
||||
#endif /* js_Value_h */
|
||||
|
|
Загрузка…
Ссылка в новой задаче