From ce729bb6e9c4efb01ef6b39f3d676a845ba9f032 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Sat, 31 May 2014 10:44:32 +0200 Subject: [PATCH] Bug 1018243 - Use unsigned char instead of char for latin1 strings. r=luke --- js/public/CharacterEncoding.h | 16 ++++++++-------- js/public/TypeDecls.h | 2 ++ js/src/NamespaceImports.h | 1 + js/src/jsfriendapi.h | 4 ++-- js/src/jsstr.cpp | 6 +++--- js/src/jsstr.h | 7 +++++++ js/src/vm/String-inl.h | 4 ++-- js/src/vm/String.cpp | 6 +++--- js/src/vm/String.h | 24 ++++++++++++------------ 9 files changed, 40 insertions(+), 30 deletions(-) diff --git a/js/public/CharacterEncoding.h b/js/public/CharacterEncoding.h index a42b3bb3ea4f..50dcf572efeb 100644 --- a/js/public/CharacterEncoding.h +++ b/js/public/CharacterEncoding.h @@ -25,35 +25,35 @@ namespace JS { * byte is treated as a 2-byte character, and there is no way to pass in a * string containing characters beyond U+00FF. */ -class Latin1Chars : public mozilla::Range +class Latin1Chars : public mozilla::Range { - typedef mozilla::Range Base; + typedef mozilla::Range Base; public: Latin1Chars() : Base() {} - Latin1Chars(char *aBytes, size_t aLength) : Base(reinterpret_cast(aBytes), aLength) {} + Latin1Chars(char *aBytes, size_t aLength) : Base(reinterpret_cast(aBytes), aLength) {} Latin1Chars(const char *aBytes, size_t aLength) - : Base(reinterpret_cast(const_cast(aBytes)), aLength) + : Base(reinterpret_cast(const_cast(aBytes)), aLength) {} }; /* * A Latin1Chars, but with \0 termination for C compatibility. */ -class Latin1CharsZ : public mozilla::RangedPtr +class Latin1CharsZ : public mozilla::RangedPtr { - typedef mozilla::RangedPtr Base; + typedef mozilla::RangedPtr Base; public: Latin1CharsZ() : Base(nullptr, 0) {} Latin1CharsZ(char *aBytes, size_t aLength) - : Base(reinterpret_cast(aBytes), aLength) + : Base(reinterpret_cast(aBytes), aLength) { MOZ_ASSERT(aBytes[aLength] == '\0'); } - Latin1CharsZ(unsigned char *aBytes, size_t aLength) + Latin1CharsZ(Latin1Char *aBytes, size_t aLength) : Base(aBytes, aLength) { MOZ_ASSERT(aBytes[aLength] == '\0'); diff --git a/js/public/TypeDecls.h b/js/public/TypeDecls.h index 6751d66aed4c..0b9b2d3aac48 100644 --- a/js/public/TypeDecls.h +++ b/js/public/TypeDecls.h @@ -34,6 +34,8 @@ typedef char16_t jschar; namespace JS { +typedef unsigned char Latin1Char; + class Value; template class Handle; template class MutableHandle; diff --git a/js/src/NamespaceImports.h b/js/src/NamespaceImports.h index dfaafaa93733..bb90da1f8ae8 100644 --- a/js/src/NamespaceImports.h +++ b/js/src/NamespaceImports.h @@ -66,6 +66,7 @@ using JS::UndefinedValue; using JS::IsPoisonedPtr; +using JS::Latin1Char; using JS::Latin1CharsZ; using JS::ConstTwoByteChars; using JS::TwoByteChars; diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 55971fc0159e..d58146ef7319 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -589,9 +589,9 @@ struct Atom { uint32_t flags; uint32_t length; union { - const char *nonInlineCharsLatin1; + const JS::Latin1Char *nonInlineCharsLatin1; const jschar *nonInlineCharsTwoByte; - char inlineStorageLatin1[1]; + JS::Latin1Char inlineStorageLatin1[1]; jschar inlineStorageTwoByte[1]; }; }; diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 34ff5d3fb11a..98599851bcbc 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -4199,10 +4199,10 @@ js::StringToSource(JSContext *cx, JSString *str) } static bool -EqualCharsLatin1TwoByte(const char *s1, const jschar *s2, size_t len) +EqualCharsLatin1TwoByte(const Latin1Char *s1, const jschar *s2, size_t len) { - for (const char *s1end = s1 + len; s1 < s1end; s1++, s2++) { - if (jschar((unsigned char)*s1) != *s2) + for (const Latin1Char *s1end = s1 + len; s1 < s1end; s1++, s2++) { + if (jschar(*s1) != *s2) return false; } return true; diff --git a/js/src/jsstr.h b/js/src/jsstr.h index 11656c634171..236f3617e1f7 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -262,6 +262,13 @@ CopyAndInflateChars(jschar *dst, const char *src, size_t srclen) dst[i] = (unsigned char) src[i]; } +inline void +CopyAndInflateChars(jschar *dst, const JS::Latin1Char *src, size_t srclen) +{ + for (size_t i = 0; i < srclen; i++) + dst[i] = src[i]; +} + /* * Deflate JS chars to bytes into a buffer. 'bytes' must be large enough for * 'length chars. The buffer is NOT null-terminated. The destination length diff --git a/js/src/vm/String-inl.h b/js/src/vm/String-inl.h index be6c17ce0fb4..92a74400a437 100644 --- a/js/src/vm/String-inl.h +++ b/js/src/vm/String-inl.h @@ -258,7 +258,7 @@ JSInlineString::initTwoByte(size_t length) return d.inlineStorageTwoByte; } -MOZ_ALWAYS_INLINE char * +MOZ_ALWAYS_INLINE JS::Latin1Char * JSInlineString::initLatin1(size_t length) { JS_ASSERT(latin1LengthFits(length)); @@ -276,7 +276,7 @@ JSFatInlineString::initTwoByte(size_t length) return d.inlineStorageTwoByte; } -MOZ_ALWAYS_INLINE char * +MOZ_ALWAYS_INLINE JS::Latin1Char * JSFatInlineString::initLatin1(size_t length) { JS_ASSERT(latin1LengthFits(length)); diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index d65dac96ad24..e09e9e0c5015 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -240,7 +240,7 @@ CopyChars(jschar *dest, const JSLinearString &str) template <> void -CopyChars(char *dest, const JSLinearString &str) +CopyChars(Latin1Char *dest, const JSLinearString &str) { AutoCheckCannotGC nogc; PodCopy(dest, str.latin1Chars(nogc), str.length()); @@ -409,7 +409,7 @@ JSRope::flattenInternal(ExclusiveContext *maybecx) { if (hasTwoByteChars()) return flattenInternal(maybecx); - return flattenInternal(maybecx); + return flattenInternal(maybecx); } JSFlatString * @@ -459,7 +459,7 @@ js::ConcatStrings(ThreadSafeContext *cx, return nullptr; if (isLatin1) { - char *buf = str->initLatin1(wholeLength); + Latin1Char *buf = str->initLatin1(wholeLength); PodCopy(buf, leftInspector.latin1Chars(), leftLen); PodCopy(buf + leftLen, rightInspector.latin1Chars(), rightLen); buf[wholeLength] = 0; diff --git a/js/src/vm/String.h b/js/src/vm/String.h index cd0c38884459..ce95c4a590b5 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -153,12 +153,12 @@ class JSString : public js::gc::BarrieredCell union { union { /* JS(Fat)InlineString */ - char inlineStorageLatin1[NUM_INLINE_CHARS_LATIN1]; + JS::Latin1Char inlineStorageLatin1[NUM_INLINE_CHARS_LATIN1]; jschar inlineStorageTwoByte[NUM_INLINE_CHARS_TWO_BYTE]; }; struct { union { - const char *nonInlineCharsLatin1; /* JSLinearString, except JS(Fat)InlineString */ + const JS::Latin1Char *nonInlineCharsLatin1; /* JSLinearString, except JS(Fat)InlineString */ const jschar *nonInlineCharsTwoByte;/* JSLinearString, except JS(Fat)InlineString */ JSString *left; /* JSRope */ } u2; @@ -611,7 +611,7 @@ class JSLinearString : public JSString const CharT *nonInlineChars(const JS::AutoCheckCannotGC &nogc) const; MOZ_ALWAYS_INLINE - const char *nonInlineLatin1Chars(const JS::AutoCheckCannotGC &nogc) const { + const JS::Latin1Char *nonInlineLatin1Chars(const JS::AutoCheckCannotGC &nogc) const { JS_ASSERT(!isInline()); JS_ASSERT(hasLatin1Chars()); return d.s.u2.nonInlineCharsLatin1; @@ -628,7 +628,7 @@ class JSLinearString : public JSString const jschar *chars() const; MOZ_ALWAYS_INLINE - const char *latin1Chars(const JS::AutoCheckCannotGC &nogc) const; + const JS::Latin1Char *latin1Chars(const JS::AutoCheckCannotGC &nogc) const; MOZ_ALWAYS_INLINE const jschar *twoByteChars(const JS::AutoCheckCannotGC &nogc) const; @@ -767,7 +767,7 @@ class JSInlineString : public JSFlatString static inline JSInlineString *new_(js::ThreadSafeContext *cx); inline jschar *initTwoByte(size_t length); - inline char *initLatin1(size_t length); + inline JS::Latin1Char *initLatin1(size_t length); inline void resetLength(size_t length); @@ -779,7 +779,7 @@ class JSInlineString : public JSFlatString } MOZ_ALWAYS_INLINE - const char *latin1Chars(const JS::AutoCheckCannotGC &nogc) const { + const JS::Latin1Char *latin1Chars(const JS::AutoCheckCannotGC &nogc) const { JS_ASSERT(JSString::isInline()); JS_ASSERT(hasLatin1Chars()); return d.inlineStorageLatin1; @@ -856,7 +856,7 @@ class JSFatInlineString : public JSInlineString -1 /* null terminator */; inline jschar *initTwoByte(size_t length); - inline char *initLatin1(size_t length); + inline JS::Latin1Char *initLatin1(size_t length); static bool latin1LengthFits(size_t length) { return length <= MAX_LENGTH_LATIN1; @@ -960,7 +960,7 @@ class ScopedThreadSafeStringInspector ScopedJSFreePtr scopedChars_; union { const jschar *twoByteChars_; - const char *latin1Chars_; + const JS::Latin1Char *latin1Chars_; }; enum State { Uninitialized, Latin1, TwoByte }; State state_; @@ -980,7 +980,7 @@ class ScopedThreadSafeStringInspector MOZ_ASSERT(state_ == TwoByte); return twoByteChars_; } - const char *latin1Chars() const { + const JS::Latin1Char *latin1Chars() const { MOZ_ASSERT(state_ == Latin1); return latin1Chars_; } @@ -1257,7 +1257,7 @@ JSLinearString::nonInlineChars(const JS::AutoCheckCannotGC &nogc) const } template<> -MOZ_ALWAYS_INLINE const char * +MOZ_ALWAYS_INLINE const JS::Latin1Char * JSLinearString::nonInlineChars(const JS::AutoCheckCannotGC &nogc) const { return nonInlineLatin1Chars(nogc); @@ -1272,7 +1272,7 @@ JSString::setNonInlineChars(const jschar *chars) template<> MOZ_ALWAYS_INLINE void -JSString::setNonInlineChars(const char *chars) +JSString::setNonInlineChars(const JS::Latin1Char *chars) { d.s.u2.nonInlineCharsLatin1 = chars; } @@ -1285,7 +1285,7 @@ JSLinearString::chars() const return isInline() ? asInline().chars() : nonInlineChars(); } -MOZ_ALWAYS_INLINE const char * +MOZ_ALWAYS_INLINE const JS::Latin1Char * JSLinearString::latin1Chars(const JS::AutoCheckCannotGC &nogc) const { JS_ASSERT(JSString::isLinear());