mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1027528 part 13 - Remove JSString::hasPureChars etc, and refactor callers. r=njn
This commit is contained in:
parent
d7c405117e
commit
2b7ee170f0
@ -161,12 +161,12 @@ AtomHasher::match(const AtomStateEntry &entry, const Lookup &lookup)
|
||||
const Latin1Char *keyChars = key->latin1Chars(lookup.nogc);
|
||||
if (lookup.isLatin1)
|
||||
return mozilla::PodEqual(keyChars, lookup.latin1Chars, lookup.length);
|
||||
return EqualCharsLatin1TwoByte(keyChars, lookup.twoByteChars, lookup.length);
|
||||
return EqualChars(keyChars, lookup.twoByteChars, lookup.length);
|
||||
}
|
||||
|
||||
const jschar *keyChars = key->twoByteChars(lookup.nogc);
|
||||
if (lookup.isLatin1)
|
||||
return EqualCharsLatin1TwoByte(lookup.latin1Chars, keyChars, lookup.length);
|
||||
return EqualChars(lookup.latin1Chars, keyChars, lookup.length);
|
||||
return mozilla::PodEqual(keyChars, lookup.twoByteChars, lookup.length);
|
||||
}
|
||||
|
||||
|
@ -264,6 +264,53 @@ JSCompartment::putWrapper(JSContext *cx, const CrossCompartmentKey &wrapped, con
|
||||
return success;
|
||||
}
|
||||
|
||||
static JSString *
|
||||
CopyStringPure(JSContext *cx, JSString *str)
|
||||
{
|
||||
/*
|
||||
* Directly allocate the copy in the destination compartment, rather than
|
||||
* first flattening it (and possibly allocating in source compartment),
|
||||
* because we don't know whether the flattening will pay off later.
|
||||
*/
|
||||
|
||||
size_t len = str->length();
|
||||
JSString *copy;
|
||||
if (str->isLinear()) {
|
||||
/* Only use AutoStableStringChars if the NoGC allocation fails. */
|
||||
if (str->hasLatin1Chars()) {
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
copy = js_NewStringCopyN<NoGC>(cx, str->asLinear().latin1Chars(nogc), len);
|
||||
} else {
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
copy = js_NewStringCopyN<NoGC>(cx, str->asLinear().twoByteChars(nogc), len);
|
||||
}
|
||||
if (copy)
|
||||
return copy;
|
||||
|
||||
AutoStableStringChars chars(cx);
|
||||
if (!chars.init(cx, str))
|
||||
return nullptr;
|
||||
|
||||
return chars.isLatin1()
|
||||
? js_NewStringCopyN<CanGC>(cx, chars.latin1Range().start().get(), len)
|
||||
: js_NewStringCopyN<CanGC>(cx, chars.twoByteRange().start().get(), len);
|
||||
}
|
||||
|
||||
if (str->hasLatin1Chars()) {
|
||||
ScopedJSFreePtr<Latin1Char> copiedChars;
|
||||
if (!str->asRope().copyLatin1CharsZ(cx, copiedChars))
|
||||
return nullptr;
|
||||
|
||||
return js_NewString<CanGC>(cx, copiedChars.forget(), len);
|
||||
}
|
||||
|
||||
ScopedJSFreePtr<jschar> copiedChars;
|
||||
if (!str->asRope().copyTwoByteCharsZ(cx, copiedChars))
|
||||
return nullptr;
|
||||
|
||||
return js_NewString<CanGC>(cx, copiedChars.forget(), len);
|
||||
}
|
||||
|
||||
bool
|
||||
JSCompartment::wrap(JSContext *cx, JSString **strp)
|
||||
{
|
||||
@ -289,22 +336,8 @@ JSCompartment::wrap(JSContext *cx, JSString **strp)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* No dice. Make a copy, and cache it. Directly allocate the copy in the
|
||||
* destination compartment, rather than first flattening it (and possibly
|
||||
* allocating in source compartment), because we don't know whether the
|
||||
* flattening will pay off later.
|
||||
*/
|
||||
JSString *copy;
|
||||
if (str->hasPureChars()) {
|
||||
copy = js_NewStringCopyN<CanGC>(cx, str->pureChars(), str->length());
|
||||
} else {
|
||||
ScopedJSFreePtr<jschar> copiedChars;
|
||||
if (!str->copyNonPureCharsZ(cx, copiedChars))
|
||||
return false;
|
||||
copy = js_NewString<CanGC>(cx, copiedChars.forget(), str->length());
|
||||
}
|
||||
|
||||
/* No dice. Make a copy, and cache it. */
|
||||
JSString *copy = CopyStringPure(cx, str);
|
||||
if (!copy)
|
||||
return false;
|
||||
if (!putWrapper(cx, CrossCompartmentKey(key), StringValue(copy)))
|
||||
|
@ -1727,14 +1727,14 @@ HasSubstringAt(JSLinearString *text, JSLinearString *pat, size_t start)
|
||||
if (pat->hasLatin1Chars())
|
||||
return PodEqual(textChars, pat->latin1Chars(nogc), patLen);
|
||||
|
||||
return EqualCharsLatin1TwoByte(textChars, pat->twoByteChars(nogc), patLen);
|
||||
return EqualChars(textChars, pat->twoByteChars(nogc), patLen);
|
||||
}
|
||||
|
||||
const jschar *textChars = text->twoByteChars(nogc) + start;
|
||||
if (pat->hasTwoByteChars())
|
||||
return PodEqual(textChars, pat->twoByteChars(nogc), patLen);
|
||||
|
||||
return EqualCharsLatin1TwoByte(pat->latin1Chars(nogc), textChars, patLen);
|
||||
return EqualChars(pat->latin1Chars(nogc), textChars, patLen);
|
||||
}
|
||||
|
||||
/* ES6 20131108 draft 21.1.3.18. */
|
||||
@ -4565,13 +4565,13 @@ js::EqualChars(JSLinearString *str1, JSLinearString *str2)
|
||||
if (str2->hasTwoByteChars())
|
||||
return PodEqual(str1->twoByteChars(nogc), str2->twoByteChars(nogc), len);
|
||||
|
||||
return EqualCharsLatin1TwoByte(str2->latin1Chars(nogc), str1->twoByteChars(nogc), len);
|
||||
return EqualChars(str2->latin1Chars(nogc), str1->twoByteChars(nogc), len);
|
||||
}
|
||||
|
||||
if (str2->hasLatin1Chars())
|
||||
return PodEqual(str1->latin1Chars(nogc), str2->latin1Chars(nogc), len);
|
||||
|
||||
return EqualCharsLatin1TwoByte(str1->latin1Chars(nogc), str2->twoByteChars(nogc), len);
|
||||
return EqualChars(str1->latin1Chars(nogc), str2->twoByteChars(nogc), len);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -4686,7 +4686,7 @@ js::StringEqualsAscii(JSLinearString *str, const char *asciiBytes)
|
||||
AutoCheckCannotGC nogc;
|
||||
return str->hasLatin1Chars()
|
||||
? PodEqual(latin1, str->latin1Chars(nogc), length)
|
||||
: EqualCharsLatin1TwoByte(latin1, str->twoByteChars(nogc), length);
|
||||
: EqualChars(latin1, str->twoByteChars(nogc), length);
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -5338,3 +5338,11 @@ js::PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, const Latin1
|
||||
template size_t
|
||||
js::PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, const jschar *chars,
|
||||
size_t length, uint32_t quote);
|
||||
|
||||
template size_t
|
||||
js::PutEscapedString(char *buffer, size_t bufferSize, const Latin1Char *chars, size_t length,
|
||||
uint32_t quote);
|
||||
|
||||
template size_t
|
||||
js::PutEscapedString(char *buffer, size_t bufferSize, const jschar *chars, size_t length,
|
||||
uint32_t quote);
|
||||
|
@ -249,11 +249,23 @@ js_strdup(js::ThreadSafeContext *cx, const jschar *s);
|
||||
|
||||
namespace js {
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
inline bool
|
||||
EqualCharsLatin1TwoByte(const Latin1Char *s1, const jschar *s2, size_t len)
|
||||
EqualChars(const Char1 *s1, const Char2 *s2, size_t len);
|
||||
|
||||
template <typename Char1>
|
||||
inline bool
|
||||
EqualChars(const Char1 *s1, const Char1 *s2, size_t len)
|
||||
{
|
||||
for (const Latin1Char *s1end = s1 + len; s1 < s1end; s1++, s2++) {
|
||||
if (jschar(*s1) != *s2)
|
||||
return mozilla::PodEqual(s1, s2, len);
|
||||
}
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
inline bool
|
||||
EqualChars(const Char1 *s1, const Char2 *s2, size_t len)
|
||||
{
|
||||
for (const Char1 *s1end = s1 + len; s1 < s1end; s1++, s2++) {
|
||||
if (*s1 != *s2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -356,8 +368,9 @@ PutEscapedString(char *buffer, size_t size, JSLinearString *str, uint32_t quote)
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline size_t
|
||||
PutEscapedString(char *buffer, size_t bufferSize, const jschar *chars, size_t length, uint32_t quote)
|
||||
PutEscapedString(char *buffer, size_t bufferSize, const CharT *chars, size_t length, uint32_t quote)
|
||||
{
|
||||
size_t n = PutEscapedStringImpl(buffer, bufferSize, nullptr, chars, length, quote);
|
||||
|
||||
|
@ -43,51 +43,78 @@ MemoryReportingSundriesThreshold()
|
||||
return 8 * 1024;
|
||||
}
|
||||
|
||||
/* static */ HashNumber
|
||||
InefficientNonFlatteningStringHashPolicy::hash(const Lookup &l)
|
||||
template <typename CharT>
|
||||
static uint32_t
|
||||
HashStringChars(JSString *s)
|
||||
{
|
||||
ScopedJSFreePtr<jschar> ownedChars;
|
||||
const jschar *chars;
|
||||
if (l->hasPureChars()) {
|
||||
chars = l->pureChars();
|
||||
ScopedJSFreePtr<CharT> ownedChars;
|
||||
const CharT *chars;
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
if (s->isLinear()) {
|
||||
chars = s->asLinear().chars<CharT>(nogc);
|
||||
} else {
|
||||
// Slowest hash function evar!
|
||||
if (!l->copyNonPureChars(/* tcx */ nullptr, ownedChars))
|
||||
if (!s->asRope().copyChars<CharT>(/* tcx */ nullptr, ownedChars))
|
||||
MOZ_CRASH("oom");
|
||||
chars = ownedChars;
|
||||
}
|
||||
|
||||
return mozilla::HashString(chars, l->length());
|
||||
return mozilla::HashString(chars, s->length());
|
||||
}
|
||||
|
||||
/* static */ HashNumber
|
||||
InefficientNonFlatteningStringHashPolicy::hash(const Lookup &l)
|
||||
{
|
||||
return l->hasLatin1Chars()
|
||||
? HashStringChars<Latin1Char>(l)
|
||||
: HashStringChars<jschar>(l);
|
||||
}
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
static bool
|
||||
EqualStringsPure(JSString *s1, JSString *s2)
|
||||
{
|
||||
if (s1->length() != s2->length())
|
||||
return false;
|
||||
|
||||
const Char1 *c1;
|
||||
ScopedJSFreePtr<Char1> ownedChars1;
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
if (s1->isLinear()) {
|
||||
c1 = s1->asLinear().chars<Char1>(nogc);
|
||||
} else {
|
||||
if (!s1->asRope().copyChars<Char1>(/* tcx */ nullptr, ownedChars1))
|
||||
MOZ_CRASH("oom");
|
||||
c1 = ownedChars1;
|
||||
}
|
||||
|
||||
const Char2 *c2;
|
||||
ScopedJSFreePtr<Char2> ownedChars2;
|
||||
if (s2->isLinear()) {
|
||||
c2 = s2->asLinear().chars<Char2>(nogc);
|
||||
} else {
|
||||
if (!s2->asRope().copyChars<Char2>(/* tcx */ nullptr, ownedChars2))
|
||||
MOZ_CRASH("oom");
|
||||
c2 = ownedChars2;
|
||||
}
|
||||
|
||||
return EqualChars(c1, c2, s1->length());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
InefficientNonFlatteningStringHashPolicy::match(const JSString *const &k, const Lookup &l)
|
||||
{
|
||||
// We can't use js::EqualStrings, because that flattens our strings.
|
||||
if (k->length() != l->length())
|
||||
return false;
|
||||
|
||||
const jschar *c1;
|
||||
ScopedJSFreePtr<jschar> ownedChars1;
|
||||
if (k->hasPureChars()) {
|
||||
c1 = k->pureChars();
|
||||
} else {
|
||||
if (!k->copyNonPureChars(/* tcx */ nullptr, ownedChars1))
|
||||
MOZ_CRASH("oom");
|
||||
c1 = ownedChars1;
|
||||
JSString *s1 = const_cast<JSString *>(k);
|
||||
if (k->hasLatin1Chars()) {
|
||||
return l->hasLatin1Chars()
|
||||
? EqualStringsPure<Latin1Char, Latin1Char>(s1, l)
|
||||
: EqualStringsPure<Latin1Char, jschar>(s1, l);
|
||||
}
|
||||
|
||||
const jschar *c2;
|
||||
ScopedJSFreePtr<jschar> ownedChars2;
|
||||
if (l->hasPureChars()) {
|
||||
c2 = l->pureChars();
|
||||
} else {
|
||||
if (!l->copyNonPureChars(/* tcx */ nullptr, ownedChars2))
|
||||
MOZ_CRASH("oom");
|
||||
c2 = ownedChars2;
|
||||
}
|
||||
|
||||
return PodEqual(c1, c2, k->length());
|
||||
return l->hasLatin1Chars()
|
||||
? EqualStringsPure<jschar, Latin1Char>(s1, l)
|
||||
: EqualStringsPure<jschar, jschar>(s1, l);
|
||||
}
|
||||
|
||||
/* static */ HashNumber
|
||||
@ -113,6 +140,27 @@ NotableStringInfo::NotableStringInfo()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
static void
|
||||
StoreStringChars(char *buffer, size_t bufferSize, JSString *str)
|
||||
{
|
||||
const CharT* chars;
|
||||
ScopedJSFreePtr<CharT> ownedChars;
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
if (str->isLinear()) {
|
||||
chars = str->asLinear().chars<CharT>(nogc);
|
||||
} else {
|
||||
if (!str->asRope().copyChars<CharT>(/* tcx */ nullptr, ownedChars))
|
||||
MOZ_CRASH("oom");
|
||||
chars = ownedChars;
|
||||
}
|
||||
|
||||
// We might truncate |str| even if it's much shorter than 1024 chars, if
|
||||
// |str| contains unicode chars. Since this is just for a memory reporter,
|
||||
// we don't care.
|
||||
PutEscapedString(buffer, bufferSize, chars, str->length(), /* quote */ 0);
|
||||
}
|
||||
|
||||
NotableStringInfo::NotableStringInfo(JSString *str, const StringInfo &info)
|
||||
: StringInfo(info),
|
||||
length(str->length())
|
||||
@ -123,20 +171,10 @@ NotableStringInfo::NotableStringInfo(JSString *str, const StringInfo &info)
|
||||
MOZ_CRASH("oom");
|
||||
}
|
||||
|
||||
const jschar* chars;
|
||||
ScopedJSFreePtr<jschar> ownedChars;
|
||||
if (str->hasPureChars()) {
|
||||
chars = str->pureChars();
|
||||
} else {
|
||||
if (!str->copyNonPureChars(/* tcx */ nullptr, ownedChars))
|
||||
MOZ_CRASH("oom");
|
||||
chars = ownedChars;
|
||||
}
|
||||
|
||||
// We might truncate |str| even if it's much shorter than 1024 chars, if
|
||||
// |str| contains unicode chars. Since this is just for a memory reporter,
|
||||
// we don't care.
|
||||
PutEscapedString(buffer, bufferSize, chars, str->length(), /* quote */ 0);
|
||||
if (str->hasLatin1Chars())
|
||||
StoreStringChars<Latin1Char>(buffer, bufferSize, str);
|
||||
else
|
||||
StoreStringChars<jschar>(buffer, bufferSize, str);
|
||||
}
|
||||
|
||||
NotableStringInfo::NotableStringInfo(NotableStringInfo &&info)
|
||||
|
@ -170,20 +170,33 @@ AllocChars(ThreadSafeContext *maybecx, size_t length, CharT **chars, size_t *cap
|
||||
}
|
||||
|
||||
bool
|
||||
JSRope::copyNonPureChars(ThreadSafeContext *cx, ScopedJSFreePtr<jschar> &out) const
|
||||
JSRope::copyLatin1CharsZ(ThreadSafeContext *cx, ScopedJSFreePtr<Latin1Char> &out) const
|
||||
{
|
||||
return copyNonPureCharsInternal(cx, out, false);
|
||||
return copyCharsInternal<Latin1Char>(cx, out, true);
|
||||
}
|
||||
|
||||
bool
|
||||
JSRope::copyNonPureCharsZ(ThreadSafeContext *cx, ScopedJSFreePtr<jschar> &out) const
|
||||
JSRope::copyTwoByteCharsZ(ThreadSafeContext *cx, ScopedJSFreePtr<jschar> &out) const
|
||||
{
|
||||
return copyNonPureCharsInternal(cx, out, true);
|
||||
return copyCharsInternal<jschar>(cx, out, true);
|
||||
}
|
||||
|
||||
bool
|
||||
JSRope::copyNonPureCharsInternal(ThreadSafeContext *cx, ScopedJSFreePtr<jschar> &out,
|
||||
bool nullTerminate) const
|
||||
JSRope::copyLatin1Chars(ThreadSafeContext *cx, ScopedJSFreePtr<Latin1Char> &out) const
|
||||
{
|
||||
return copyCharsInternal<Latin1Char>(cx, out, false);
|
||||
}
|
||||
|
||||
bool
|
||||
JSRope::copyTwoByteChars(ThreadSafeContext *cx, ScopedJSFreePtr<jschar> &out) const
|
||||
{
|
||||
return copyCharsInternal<jschar>(cx, out, false);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
bool
|
||||
JSRope::copyCharsInternal(ThreadSafeContext *cx, ScopedJSFreePtr<CharT> &out,
|
||||
bool nullTerminate) const
|
||||
{
|
||||
/*
|
||||
* Perform non-destructive post-order traversal of the rope, splatting
|
||||
@ -192,25 +205,24 @@ JSRope::copyNonPureCharsInternal(ThreadSafeContext *cx, ScopedJSFreePtr<jschar>
|
||||
|
||||
size_t n = length();
|
||||
if (cx)
|
||||
out.reset(cx->pod_malloc<jschar>(n + 1));
|
||||
out.reset(cx->pod_malloc<CharT>(n + 1));
|
||||
else
|
||||
out.reset(js_pod_malloc<jschar>(n + 1));
|
||||
out.reset(js_pod_malloc<CharT>(n + 1));
|
||||
|
||||
if (!out)
|
||||
return false;
|
||||
|
||||
Vector<const JSString *, 8, SystemAllocPolicy> nodeStack;
|
||||
const JSString *str = this;
|
||||
jschar *pos = out;
|
||||
CharT *pos = out;
|
||||
while (true) {
|
||||
if (str->isRope()) {
|
||||
if (!nodeStack.append(str->asRope().rightChild()))
|
||||
return false;
|
||||
str = str->asRope().leftChild();
|
||||
} else {
|
||||
size_t len = str->length();
|
||||
PodCopy(pos, str->asLinear().chars(), len);
|
||||
pos += len;
|
||||
CopyChars(pos, str->asLinear());
|
||||
pos += str->length();
|
||||
if (nodeStack.empty())
|
||||
break;
|
||||
str = nodeStack.popCopy();
|
||||
@ -490,23 +502,6 @@ js::ConcatStrings<CanGC>(ThreadSafeContext *cx, HandleString left, HandleString
|
||||
template JSString *
|
||||
js::ConcatStrings<NoGC>(ThreadSafeContext *cx, JSString *left, JSString *right);
|
||||
|
||||
bool
|
||||
JSDependentString::copyNonPureCharsZ(ThreadSafeContext *cx, ScopedJSFreePtr<jschar> &out) const
|
||||
{
|
||||
JS_ASSERT(JSString::isDependent());
|
||||
|
||||
size_t n = length();
|
||||
jschar *s = cx->pod_malloc<jschar>(n + 1);
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
PodCopy(s, nonInlineChars(), n);
|
||||
s[n] = 0;
|
||||
|
||||
out.reset(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
JSFlatString *
|
||||
JSDependentString::undependInternal(ExclusiveContext *cx)
|
||||
@ -621,14 +616,30 @@ ScopedThreadSafeStringInspector::ensureChars(ThreadSafeContext *cx, const AutoCh
|
||||
latin1Chars_ = linear->latin1Chars(nogc);
|
||||
}
|
||||
} else {
|
||||
if (str_->hasPureChars()) {
|
||||
state_ = TwoByte;
|
||||
twoByteChars_ = str_->pureChars();
|
||||
if (str_->isLinear()) {
|
||||
if (str_->hasLatin1Chars()) {
|
||||
state_ = Latin1;
|
||||
latin1Chars_ = str_->asLinear().latin1Chars(nogc);
|
||||
} else {
|
||||
state_ = TwoByte;
|
||||
twoByteChars_ = str_->asLinear().twoByteChars(nogc);
|
||||
}
|
||||
} else {
|
||||
if (!str_->copyNonPureChars(cx, scopedChars_))
|
||||
return false;
|
||||
state_ = TwoByte;
|
||||
twoByteChars_ = scopedChars_;
|
||||
if (str_->hasLatin1Chars()) {
|
||||
ScopedJSFreePtr<Latin1Char> chars;
|
||||
if (!str_->asRope().copyLatin1Chars(cx, chars))
|
||||
return false;
|
||||
state_ = Latin1;
|
||||
latin1Chars_ = chars;
|
||||
scopedChars_ = chars.forget();
|
||||
} else {
|
||||
ScopedJSFreePtr<jschar> chars;
|
||||
if (!str_->asRope().copyTwoByteChars(cx, chars))
|
||||
return false;
|
||||
state_ = TwoByte;
|
||||
twoByteChars_ = chars;
|
||||
scopedChars_ = chars.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,23 +328,6 @@ class JSString : public js::gc::BarrieredCell<JSString>
|
||||
inline const jschar *getCharsZ(js::ExclusiveContext *cx);
|
||||
inline bool getChar(js::ExclusiveContext *cx, size_t index, jschar *code);
|
||||
|
||||
/*
|
||||
* A string has "pure" chars if it can return a pointer to its chars
|
||||
* infallibly without mutating anything so they are safe to be from off the
|
||||
* main thread. If a string does not have pure chars, the caller can call
|
||||
* copyNonPureChars to allocate a copy of the chars which is also a
|
||||
* non-mutating threadsafe operation. Beware, this is an O(n) operation
|
||||
* (involving a DAG traversal for ropes).
|
||||
*/
|
||||
bool hasPureChars() const { return isLinear(); }
|
||||
bool hasPureCharsZ() const { return isFlat(); }
|
||||
inline const jschar *pureChars() const;
|
||||
inline const jschar *pureCharsZ() const;
|
||||
inline bool copyNonPureChars(js::ThreadSafeContext *cx,
|
||||
js::ScopedJSFreePtr<jschar> &out) const;
|
||||
inline bool copyNonPureCharsZ(js::ThreadSafeContext *cx,
|
||||
js::ScopedJSFreePtr<jschar> &out) const;
|
||||
|
||||
/* Strings have either Latin1 or TwoByte chars. */
|
||||
bool hasLatin1Chars() const {
|
||||
return d.u1.flags & LATIN1_CHARS_BIT;
|
||||
@ -537,11 +520,9 @@ static const bool EnableLatin1Strings = false;
|
||||
|
||||
class JSRope : public JSString
|
||||
{
|
||||
bool copyNonPureCharsInternal(js::ThreadSafeContext *cx,
|
||||
js::ScopedJSFreePtr<jschar> &out,
|
||||
bool nullTerminate) const;
|
||||
bool copyNonPureChars(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const;
|
||||
bool copyNonPureCharsZ(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const;
|
||||
template <typename CharT>
|
||||
bool copyCharsInternal(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<CharT> &out,
|
||||
bool nullTerminate) const;
|
||||
|
||||
enum UsingBarrier { WithIncrementalBarrier, NoBarrier };
|
||||
|
||||
@ -563,6 +544,17 @@ class JSRope : public JSString
|
||||
typename js::MaybeRooted<JSString*, allowGC>::HandleType right,
|
||||
size_t length);
|
||||
|
||||
bool copyLatin1Chars(js::ThreadSafeContext *cx,
|
||||
js::ScopedJSFreePtr<JS::Latin1Char> &out) const;
|
||||
bool copyTwoByteChars(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const;
|
||||
|
||||
bool copyLatin1CharsZ(js::ThreadSafeContext *cx,
|
||||
js::ScopedJSFreePtr<JS::Latin1Char> &out) const;
|
||||
bool copyTwoByteCharsZ(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const;
|
||||
|
||||
template <typename CharT>
|
||||
bool copyChars(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<CharT> &out) const;
|
||||
|
||||
inline JSString *leftChild() const {
|
||||
JS_ASSERT(isRope());
|
||||
return d.s.u2.left;
|
||||
@ -683,8 +675,6 @@ JS_STATIC_ASSERT(sizeof(JSLinearString) == sizeof(JSString));
|
||||
|
||||
class JSDependentString : public JSLinearString
|
||||
{
|
||||
bool copyNonPureCharsZ(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const;
|
||||
|
||||
friend class JSString;
|
||||
JSFlatString *undepend(js::ExclusiveContext *cx);
|
||||
|
||||
@ -1023,7 +1013,7 @@ class ScopedThreadSafeStringInspector
|
||||
{
|
||||
private:
|
||||
JSString *str_;
|
||||
ScopedJSFreePtr<jschar> scopedChars_;
|
||||
ScopedJSFreePtr<void> scopedChars_;
|
||||
union {
|
||||
const jschar *twoByteChars_;
|
||||
const JS::Latin1Char *latin1Chars_;
|
||||
@ -1335,36 +1325,6 @@ JSString::getCharsZ(js::ExclusiveContext *cx)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE const jschar *
|
||||
JSString::pureChars() const
|
||||
{
|
||||
JS_ASSERT(hasPureChars());
|
||||
return asLinear().chars();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE const jschar *
|
||||
JSString::pureCharsZ() const
|
||||
{
|
||||
JS_ASSERT(hasPureCharsZ());
|
||||
return asFlat().charsZ();
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
JSString::copyNonPureChars(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const
|
||||
{
|
||||
JS_ASSERT(!hasPureChars());
|
||||
return asRope().copyNonPureChars(cx, out);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
JSString::copyNonPureCharsZ(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const
|
||||
{
|
||||
JS_ASSERT(!hasPureChars());
|
||||
if (isDependent())
|
||||
return asDependent().copyNonPureCharsZ(cx, out);
|
||||
return asRope().copyNonPureCharsZ(cx, out);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE JSLinearString *
|
||||
JSString::ensureLinear(js::ExclusiveContext *cx)
|
||||
{
|
||||
@ -1419,6 +1379,21 @@ JSLinearString::chars(const JS::AutoCheckCannotGC &nogc) const
|
||||
return rawLatin1Chars();
|
||||
}
|
||||
|
||||
template <>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
JSRope::copyChars<JS::Latin1Char>(js::ThreadSafeContext *cx,
|
||||
js::ScopedJSFreePtr<JS::Latin1Char> &out) const
|
||||
{
|
||||
return copyLatin1Chars(cx, out);
|
||||
}
|
||||
|
||||
template <>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
JSRope::copyChars<jschar>(js::ThreadSafeContext *cx, js::ScopedJSFreePtr<jschar> &out) const
|
||||
{
|
||||
return copyTwoByteChars(cx, out);
|
||||
}
|
||||
|
||||
template<>
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
JSInlineString::lengthFits<JS::Latin1Char>(size_t length)
|
||||
|
Loading…
Reference in New Issue
Block a user