mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1023778 part 5 - Add AutoStableStringChars class. r=terrence
This commit is contained in:
parent
68114dd79c
commit
9990d4034b
@ -744,6 +744,57 @@ StaticStrings::isStatic(JSAtom *atom)
|
||||
}
|
||||
}
|
||||
|
||||
AutoStableStringChars::~AutoStableStringChars()
|
||||
{
|
||||
if (ownsChars_) {
|
||||
MOZ_ASSERT(state_ == Latin1 || state_ == TwoByte);
|
||||
if (state_ == Latin1)
|
||||
js_free(const_cast<Latin1Char*>(latin1Chars_));
|
||||
else
|
||||
js_free(const_cast<jschar*>(twoByteChars_));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AutoStableStringChars::init()
|
||||
{
|
||||
MOZ_ASSERT(state_ == Uninitialized);
|
||||
|
||||
if (s_->hasLatin1Chars()) {
|
||||
state_ = Latin1;
|
||||
latin1Chars_ = s_->rawLatin1Chars();
|
||||
} else {
|
||||
state_ = TwoByte;
|
||||
twoByteChars_ = s_->rawTwoByteChars();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AutoStableStringChars::initTwoByte(JSContext *cx)
|
||||
{
|
||||
MOZ_ASSERT(state_ == Uninitialized);
|
||||
|
||||
if (s_->hasTwoByteChars()) {
|
||||
state_ = TwoByte;
|
||||
twoByteChars_ = s_->rawTwoByteChars();
|
||||
return true;
|
||||
}
|
||||
|
||||
jschar *chars = cx->pod_malloc<jschar>(s_->length() + 1);
|
||||
if (!chars)
|
||||
return false;
|
||||
|
||||
CopyAndInflateChars(chars, s_->rawLatin1Chars(), s_->length());
|
||||
chars[s_->length()] = 0;
|
||||
|
||||
state_ = TwoByte;
|
||||
ownsChars_ = true;
|
||||
twoByteChars_ = chars;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
JSAtom::dump()
|
||||
|
@ -30,6 +30,7 @@ class JSRope;
|
||||
|
||||
namespace js {
|
||||
|
||||
class AutoStableStringChars;
|
||||
class StaticStrings;
|
||||
class PropertyName;
|
||||
|
||||
@ -584,6 +585,7 @@ JS_STATIC_ASSERT(sizeof(JSRope) == sizeof(JSString));
|
||||
class JSLinearString : public JSString
|
||||
{
|
||||
friend class JSString;
|
||||
friend class js::AutoStableStringChars;
|
||||
|
||||
/* Vacuous and therefore unimplemented. */
|
||||
JSLinearString *ensureLinear(JSContext *cx) MOZ_DELETE;
|
||||
@ -601,6 +603,9 @@ class JSLinearString : public JSString
|
||||
return (void *)d.s.u2.nonInlineCharsTwoByte;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE const JS::Latin1Char *rawLatin1Chars() const;
|
||||
MOZ_ALWAYS_INLINE const jschar *rawTwoByteChars() const;
|
||||
|
||||
public:
|
||||
MOZ_ALWAYS_INLINE
|
||||
const jschar *nonInlineChars() const {
|
||||
@ -635,10 +640,14 @@ class JSLinearString : public JSString
|
||||
const CharT *chars(const JS::AutoCheckCannotGC &nogc) const;
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
const JS::Latin1Char *latin1Chars(const JS::AutoCheckCannotGC &nogc) const;
|
||||
const JS::Latin1Char *latin1Chars(const JS::AutoCheckCannotGC &nogc) const {
|
||||
return rawLatin1Chars();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
const jschar *twoByteChars(const JS::AutoCheckCannotGC &nogc) const;
|
||||
const jschar *twoByteChars(const JS::AutoCheckCannotGC &nogc) const {
|
||||
return rawTwoByteChars();
|
||||
}
|
||||
|
||||
JS::TwoByteChars range() const {
|
||||
JS_ASSERT(JSString::isLinear());
|
||||
@ -1042,6 +1051,56 @@ class ScopedThreadSafeStringInspector
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This class provides safe access to a string's chars across a GC. Once
|
||||
* we allocate strings and chars in the nursery (bug 903519), this class
|
||||
* will have to make a copy of the string's chars if they are allocated
|
||||
* in the nursery, so it's best to avoid using this class unless you really
|
||||
* need it. It's usually more efficient to use the latin1Chars/twoByteChars
|
||||
* JSString methods and often the code can be rewritten so that only indexes
|
||||
* instead of char pointers are used in parts of the code that can GC.
|
||||
*/
|
||||
class MOZ_STACK_CLASS AutoStableStringChars
|
||||
{
|
||||
/* Ensure the string is kept alive while we're using its chars. */
|
||||
Rooted<JSLinearString*> s_;
|
||||
union {
|
||||
const jschar *twoByteChars_;
|
||||
const JS::Latin1Char *latin1Chars_;
|
||||
};
|
||||
enum State { Uninitialized, Latin1, TwoByte };
|
||||
State state_;
|
||||
bool ownsChars_;
|
||||
|
||||
public:
|
||||
AutoStableStringChars(JSContext *cx, JSLinearString *s)
|
||||
: s_(cx, s), state_(Uninitialized), ownsChars_(false)
|
||||
{};
|
||||
~AutoStableStringChars();
|
||||
|
||||
bool init();
|
||||
|
||||
/* Like init(), but Latin1 chars are inflated to TwoByte. */
|
||||
bool initTwoByte(JSContext *cx);
|
||||
|
||||
bool isLatin1() const { return state_ == Latin1; }
|
||||
bool isTwoByte() const { return state_ == TwoByte; }
|
||||
|
||||
const JS::Latin1Char *latin1Chars() const {
|
||||
MOZ_ASSERT(state_ == Latin1);
|
||||
return latin1Chars_;
|
||||
}
|
||||
|
||||
const jschar *twoByteChars() const {
|
||||
MOZ_ASSERT(state_ == TwoByte);
|
||||
return twoByteChars_;
|
||||
}
|
||||
|
||||
private:
|
||||
AutoStableStringChars(const AutoStableStringChars &other) MOZ_DELETE;
|
||||
void operator=(const AutoStableStringChars &other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
class StaticStrings
|
||||
{
|
||||
private:
|
||||
@ -1321,14 +1380,14 @@ template<>
|
||||
MOZ_ALWAYS_INLINE const jschar *
|
||||
JSLinearString::chars(const JS::AutoCheckCannotGC &nogc) const
|
||||
{
|
||||
return twoByteChars(nogc);
|
||||
return rawTwoByteChars();
|
||||
}
|
||||
|
||||
template<>
|
||||
MOZ_ALWAYS_INLINE const JS::Latin1Char *
|
||||
JSLinearString::chars(const JS::AutoCheckCannotGC &nogc) const
|
||||
{
|
||||
return latin1Chars(nogc);
|
||||
return rawLatin1Chars();
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -1382,19 +1441,19 @@ JSLinearString::chars() const
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE const JS::Latin1Char *
|
||||
JSLinearString::latin1Chars(const JS::AutoCheckCannotGC &nogc) const
|
||||
JSLinearString::rawLatin1Chars() const
|
||||
{
|
||||
JS_ASSERT(JSString::isLinear());
|
||||
JS_ASSERT(hasLatin1Chars());
|
||||
return isInline() ? asInline().latin1Chars(nogc) : nonInlineLatin1Chars(nogc);
|
||||
return isInline() ? d.inlineStorageLatin1 : d.s.u2.nonInlineCharsLatin1;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE const jschar *
|
||||
JSLinearString::twoByteChars(const JS::AutoCheckCannotGC &nogc) const
|
||||
JSLinearString::rawTwoByteChars() const
|
||||
{
|
||||
JS_ASSERT(JSString::isLinear());
|
||||
JS_ASSERT(hasTwoByteChars());
|
||||
return isInline() ? asInline().twoByteChars(nogc) : nonInlineTwoByteChars(nogc);
|
||||
return isInline() ? d.inlineStorageTwoByte : d.s.u2.nonInlineCharsTwoByte;
|
||||
}
|
||||
|
||||
inline js::PropertyName *
|
||||
|
Loading…
Reference in New Issue
Block a user