diff --git a/js/src/jit/BitSet.h b/js/src/jit/BitSet.h index 01783969269b..c748fc8f1fb9 100644 --- a/js/src/jit/BitSet.h +++ b/js/src/jit/BitSet.h @@ -129,8 +129,7 @@ class BitSet::Iterator if (word_ == numWords) return; - JS_STATIC_ASSERT(sizeof(value_) * 8 == BitSet::BitsPerWord); - index_ = word_ * sizeof(value_) * 8; + index_ = word_ * BitSet::BitsPerWord; value_ = bits[word_]; } diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index ed04c78470f7..c6ea97105fe6 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -490,16 +490,6 @@ exn_toSource(JSContext *cx, unsigned argc, Value *vp) } #endif -/* JSProto_ ordering for exceptions shall match JSEXN_ constants. */ -JS_STATIC_ASSERT(JSEXN_ERR == 0); -JS_STATIC_ASSERT(JSProto_Error + JSEXN_INTERNALERR == JSProto_InternalError); -JS_STATIC_ASSERT(JSProto_Error + JSEXN_EVALERR == JSProto_EvalError); -JS_STATIC_ASSERT(JSProto_Error + JSEXN_RANGEERR == JSProto_RangeError); -JS_STATIC_ASSERT(JSProto_Error + JSEXN_REFERENCEERR == JSProto_ReferenceError); -JS_STATIC_ASSERT(JSProto_Error + JSEXN_SYNTAXERR == JSProto_SyntaxError); -JS_STATIC_ASSERT(JSProto_Error + JSEXN_TYPEERR == JSProto_TypeError); -JS_STATIC_ASSERT(JSProto_Error + JSEXN_URIERR == JSProto_URIError); - /* static */ JSObject * ErrorObject::createProto(JSContext *cx, JSProtoKey key) { diff --git a/js/src/jsexn.h b/js/src/jsexn.h index ff5b3c66ad89..5c9d8f951f24 100644 --- a/js/src/jsexn.h +++ b/js/src/jsexn.h @@ -86,6 +86,19 @@ js_ErrorFromException(JSContext *cx, js::HandleObject obj); extern JSObject * js_CopyErrorObject(JSContext *cx, JS::Handle errobj); +static_assert(JSEXN_ERR == 0 && + JSProto_Error + JSEXN_INTERNALERR == JSProto_InternalError && + JSProto_Error + JSEXN_EVALERR == JSProto_EvalError && + JSProto_Error + JSEXN_RANGEERR == JSProto_RangeError && + JSProto_Error + JSEXN_REFERENCEERR == JSProto_ReferenceError && + JSProto_Error + JSEXN_SYNTAXERR == JSProto_SyntaxError && + JSProto_Error + JSEXN_TYPEERR == JSProto_TypeError && + JSProto_Error + JSEXN_URIERR == JSProto_URIError && + JSEXN_URIERR + 1 == JSEXN_LIMIT, + "GetExceptionProtoKey and ExnTypeFromProtoKey require that " + "each corresponding JSExnType and JSProtoKey value be separated " + "by the same constant value"); + static inline JSProtoKey GetExceptionProtoKey(JSExnType exn) { diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index bec46405fae7..2ce162fc0100 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -542,9 +542,11 @@ num_toSource(JSContext *cx, unsigned argc, Value *vp) } #endif -ToCStringBuf::ToCStringBuf() :dbuf(nullptr) +ToCStringBuf::ToCStringBuf() : dbuf(nullptr) { - JS_STATIC_ASSERT(sbufSize >= DTOSTR_STANDARD_BUFFER_SIZE); + static_assert(sbufSize >= DTOSTR_STANDARD_BUFFER_SIZE, + "builtin space must be large enough to store even the " + "longest string produced by a conversion"); } ToCStringBuf::~ToCStringBuf() diff --git a/js/src/json.cpp b/js/src/json.cpp index 0cba6f473e15..79285164a2b7 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -47,13 +47,15 @@ const Class js::JSONClass = { JS_ConvertStub }; -static inline bool IsQuoteSpecialCharacter(char16_t c) +static inline bool +IsQuoteSpecialCharacter(char16_t c) { - JS_STATIC_ASSERT('\b' < ' '); - JS_STATIC_ASSERT('\f' < ' '); - JS_STATIC_ASSERT('\n' < ' '); - JS_STATIC_ASSERT('\r' < ' '); - JS_STATIC_ASSERT('\t' < ' '); + static_assert('\b' < ' ', "'\\b' must be treated as special below"); + static_assert('\f' < ' ', "'\\f' must be treated as special below"); + static_assert('\n' < ' ', "'\\n' must be treated as special below"); + static_assert('\r' < ' ', "'\\r' must be treated as special below"); + static_assert('\t' < ' ', "'\\t' must be treated as special below"); + return c == '"' || c == '\\' || c < ' '; } diff --git a/js/src/jstypes.h b/js/src/jstypes.h index 456501257ff2..60ad0ae819a4 100644 --- a/js/src/jstypes.h +++ b/js/src/jstypes.h @@ -22,6 +22,7 @@ #define jstypes_h #include "mozilla/Attributes.h" +#include "mozilla/Casting.h" #include "mozilla/Types.h" // jstypes.h is (or should be!) included by every file in SpiderMonkey. @@ -194,8 +195,8 @@ ** MACROS: JS_FUNC_TO_DATA_PTR ** JS_DATA_TO_FUNC_PTR ** DESCRIPTION: -** Macros to convert between function and data pointers assuming that -** they have the same size. Use them like this: +** Macros to convert between function and data pointers of the same +** size. Use them like this: ** ** JSPropertyOp nativeGetter; ** JSObject *scriptedGetter; @@ -206,14 +207,8 @@ ** ***********************************************************************/ -#ifdef __GNUC__ -# define JS_FUNC_TO_DATA_PTR(type, fun) (__extension__ (type) (size_t) (fun)) -# define JS_DATA_TO_FUNC_PTR(type, ptr) (__extension__ (type) (size_t) (ptr)) -#else -/* Use an extra (void *) cast for MSVC. */ -# define JS_FUNC_TO_DATA_PTR(type, fun) ((type) (void *) (fun)) -# define JS_DATA_TO_FUNC_PTR(type, ptr) ((type) (void *) (ptr)) -#endif +#define JS_FUNC_TO_DATA_PTR(type, fun) (mozilla::BitwiseCast(fun)) +#define JS_DATA_TO_FUNC_PTR(type, ptr) (mozilla::BitwiseCast(ptr)) #ifdef __GNUC__ # define JS_EXTENSION __extension__ diff --git a/js/src/jsutil.cpp b/js/src/jsutil.cpp index c6eda2c4812b..b7def9ff5911 100644 --- a/js/src/jsutil.cpp +++ b/js/src/jsutil.cpp @@ -33,12 +33,6 @@ JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations = UINT32_MAX; JS_PUBLIC_DATA(uint32_t) OOM_counter = 0; #endif -/* - * Checks the assumption that JS_FUNC_TO_DATA_PTR and JS_DATA_TO_FUNC_PTR - * macros uses to implement casts between function and data pointers. - */ -JS_STATIC_ASSERT(sizeof(void *) == sizeof(void (*)())); - JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, int ln) { diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp index 53026dae13d3..130008df117e 100644 --- a/js/src/vm/StructuredClone.cpp +++ b/js/src/vm/StructuredClone.cpp @@ -50,6 +50,7 @@ using namespace js; +using mozilla::BitwiseCast; using mozilla::IsNaN; using mozilla::LittleEndian; using mozilla::NativeEndian; @@ -204,7 +205,6 @@ class SCInput { void staticAssertions() { JS_STATIC_ASSERT(sizeof(char16_t) == 2); JS_STATIC_ASSERT(sizeof(uint32_t) == 4); - JS_STATIC_ASSERT(sizeof(double) == 8); } JSContext *cx; @@ -634,38 +634,16 @@ SCOutput::writePair(uint32_t tag, uint32_t data) return write(PairToUInt64(tag, data)); } -static inline uint64_t -ReinterpretDoubleAsUInt64(double d) -{ - union { - double d; - uint64_t u; - } pun; - pun.d = d; - return pun.u; -} - -static inline double -ReinterpretUInt64AsDouble(uint64_t u) -{ - union { - uint64_t u; - double d; - } pun; - pun.u = u; - return pun.d; -} - static inline double ReinterpretPairAsDouble(uint32_t tag, uint32_t data) { - return ReinterpretUInt64AsDouble(PairToUInt64(tag, data)); + return BitwiseCast(PairToUInt64(tag, data)); } bool SCOutput::writeDouble(double d) { - return write(ReinterpretDoubleAsUInt64(CanonicalizeNaN(d))); + return write(BitwiseCast(CanonicalizeNaN(d))); } template @@ -718,7 +696,9 @@ SCOutput::writeBytes(const void *p, size_t nbytes) bool SCOutput::writeChars(const char16_t *p, size_t nchars) { - MOZ_ASSERT(sizeof(char16_t) == sizeof(uint16_t)); + static_assert(sizeof(char16_t) == sizeof(uint16_t), + "required so that treating char16_t[] memory as uint16_t[] " + "memory is permissible"); return writeArray((const uint16_t *) p, nchars); }