Bug 1037869 - Fix remaining Latin1 string issues. r=terrence

--HG--
extra : rebase_source : b6fc9024f1a6c7eb9169b6c8c906916b4b1c197e
This commit is contained in:
Jan de Mooij 2014-07-14 22:19:36 +02:00
parent ffa2468a1f
commit 41bfd0176b
16 changed files with 98 additions and 226 deletions

View File

@ -370,10 +370,9 @@ AsyncErrorReporter::AsyncErrorReporter(JSRuntime* aRuntime,
const char16_t* m = static_cast<const char16_t*>(aErrorReport->ucmessage);
if (m) {
const char16_t* n = static_cast<const char16_t*>
(js::GetErrorTypeName(aRuntime, aErrorReport->exnType));
if (n) {
mErrorMsg.Assign(n);
JSFlatString* name = js::GetErrorTypeName(aRuntime, aErrorReport->exnType);
if (name) {
AssignJSFlatString(mErrorMsg, name);
mErrorMsg.AppendLiteral(": ");
}
mErrorMsg.Append(m);

View File

@ -365,9 +365,12 @@ InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
const JSClass* clasp = static_cast<const JSClass*>(v.toPrivate());
v = js::GetFunctionNativeReserved(callee, TOSTRING_NAME_RESERVED_SLOT);
JSString* jsname = static_cast<JSString*>(v.toString());
size_t length;
const jschar* name = JS_GetInternedStringCharsAndLength(jsname, &length);
JSString* jsname = v.toString();
nsAutoJSString name;
if (!name.init(cx, jsname)) {
return false;
}
if (js::GetObjectJSClass(&args.thisv().toObject()) != clasp) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
@ -379,7 +382,7 @@ InterfaceObjectToString(JSContext* cx, unsigned argc, JS::Value *vp)
nsString str;
str.AppendLiteral("function ");
str.Append(name, length);
str.Append(name);
str.AppendLiteral("() {");
str.Append('\n');
str.AppendLiteral(" [native code]");

View File

@ -4751,8 +4751,12 @@ AddFieldToArray(JSContext* cx,
*element = OBJECT_TO_JSVAL(fieldObj);
AutoStableStringChars nameChars(cx);
if (!nameChars.initTwoByte(cx, name))
return false;
if (!JS_DefineUCProperty(cx, fieldObj,
name->chars(), name->length(),
nameChars.twoByteChars(), name->length(),
typeObj,
JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT))
return false;

View File

@ -65,24 +65,4 @@ bool checkObjectFields(JSObject *savedCopy, JSObject *obj)
END_TEST(testConservativeGC)
BEGIN_TEST(testDerivedValues)
{
JSString *str = JS_NewStringCopyZ(cx, "once upon a midnight dreary");
JS::Anchor<JSString *> str_anchor(str);
static const jschar expected[] = { 'o', 'n', 'c', 'e' };
const jschar *ch = JS_GetStringCharsZ(cx, str);
str = nullptr;
/* Do a lot of allocation and collection. */
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 1000; j++)
JS_NewStringCopyZ(cx, "as I pondered weak and weary");
JS_GC(rt);
}
CHECK(!memcmp(ch, expected, sizeof(expected)));
return true;
}
END_TEST(testDerivedValues)
#endif /* !defined(JSGC_USE_EXACT_ROOTING) */

View File

@ -10,8 +10,10 @@ BEGIN_TEST(testOOM)
{
JS::RootedValue v(cx, JS::Int32Value(9));
JS::RootedString jsstr(cx, JS::ToString(cx, v));
mozilla::DebugOnly<const jschar *> s = JS_GetStringCharsZ(cx, jsstr);
JS_ASSERT(s[0] == '9' && s[1] == '\0');
jschar ch;
if (!JS_GetStringCharAt(cx, jsstr, 0, &ch))
return false;
JS_ASSERT(ch == '9');
return true;
}

View File

@ -18,9 +18,10 @@ BEGIN_TEST(testUTF8_badUTF8)
static const char badUTF8[] = "...\xC0...";
JSString *str = JS_NewStringCopyZ(cx, badUTF8);
CHECK(str);
const jschar *chars = JS_GetStringCharsZ(cx, str);
CHECK(chars);
CHECK(chars[3] == 0x00C0);
jschar ch;
if (!JS_GetStringCharAt(cx, str, 3, &ch))
return false;
CHECK(ch == 0x00C0);
return true;
}
END_TEST(testUTF8_badUTF8)
@ -30,9 +31,10 @@ BEGIN_TEST(testUTF8_bigUTF8)
static const char bigUTF8[] = "...\xFB\xBF\xBF\xBF\xBF...";
JSString *str = JS_NewStringCopyZ(cx, bigUTF8);
CHECK(str);
const jschar *chars = JS_GetStringCharsZ(cx, str);
CHECK(chars);
CHECK(chars[3] == 0x00FB);
jschar ch;
if (!JS_GetStringCharAt(cx, str, 3, &ch))
return false;
CHECK(ch == 0x00FB);
return true;
}
END_TEST(testUTF8_bigUTF8)

View File

@ -270,19 +270,11 @@ JS_ConvertArgumentsVA(JSContext *cx, const CallArgs &args, const char *format, v
*va_arg(ap, double *) = ToInteger(d);
break;
case 'S':
case 'W':
str = ToString<CanGC>(cx, arg);
if (!str)
return false;
arg.setString(str);
if (c == 'W') {
JSFlatString *flat = str->ensureFlat(cx);
if (!flat)
return false;
*va_arg(ap, const jschar **) = flat->chars();
} else {
*va_arg(ap, JSString **) = str;
}
*va_arg(ap, JSString **) = str;
break;
case 'o':
if (arg.isNullOrUndefined()) {
@ -1021,12 +1013,6 @@ JS::NewAddonId(JSContext *cx, HandleString str)
return static_cast<JSAddonId *>(JS_InternJSString(cx, str));
}
JS_PUBLIC_API(const jschar *)
JS::CharsZOfAddonId(JSAddonId *id)
{
return id->charsZ();
}
JS_PUBLIC_API(JSString *)
JS::StringOfAddonId(JSAddonId *id)
{
@ -5320,50 +5306,18 @@ JS_GetStringLength(JSString *str)
return str->length();
}
JS_PUBLIC_API(bool)
JS_StringIsFlat(JSString *str)
{
return str->isFlat();
}
JS_PUBLIC_API(bool)
JS_StringHasLatin1Chars(JSString *str)
{
return str->hasLatin1Chars();
}
JS_PUBLIC_API(const jschar *)
JS_GetStringCharsZ(JSContext *cx, JSString *str)
{
size_t dummy;
return JS_GetStringCharsZAndLength(cx, str, &dummy);
}
JS_PUBLIC_API(const jschar *)
JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *plength)
{
/*
* Don't require |cx->compartment()| to be |str|'s compartment. We don't need
* it, and it's annoying for callers.
*/
JS_ASSERT(plength);
AssertHeapIsIdleOrStringIsFlat(cx, str);
CHECK_REQUEST(cx);
JSFlatString *flat = str->ensureFlat(cx);
if (!flat)
return nullptr;
*plength = flat->length();
return flat->chars();
}
JS_PUBLIC_API(const jschar *)
JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *plength)
{
JS_ASSERT(plength);
AssertHeapIsIdleOrStringIsFlat(cx, str);
CHECK_REQUEST(cx);
assertSameCompartment(cx, str);
JSLinearString *linear = str->ensureLinear(cx);
if (!linear)
return nullptr;
*plength = linear->length();
return linear->chars();
}
JS_PUBLIC_API(const JS::Latin1Char *)
JS_GetLatin1StringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
size_t *plength)
@ -5437,26 +5391,24 @@ JS_CopyStringChars(JSContext *cx, mozilla::Range<jschar> dest, JSString *str)
return true;
}
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringChars(JSString *str)
JS_PUBLIC_API(const Latin1Char *)
JS_Latin1InternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str)
{
JS_ASSERT(str->isAtom());
JSFlatString *flat = str->ensureFlat(nullptr);
if (!flat)
return nullptr;
return flat->chars();
return flat->latin1Chars(nogc);
}
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringCharsAndLength(JSString *str, size_t *plength)
JS_GetTwoByteInternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str)
{
JS_ASSERT(str->isAtom());
JS_ASSERT(plength);
JSFlatString *flat = str->ensureFlat(nullptr);
if (!flat)
return nullptr;
*plength = flat->length();
return flat->chars();
return flat->twoByteChars(nogc);
}
extern JS_PUBLIC_API(JSFlatString *)
@ -5471,10 +5423,16 @@ JS_FlattenString(JSContext *cx, JSString *str)
return flat;
}
extern JS_PUBLIC_API(const jschar *)
JS_GetFlatStringChars(JSFlatString *str)
extern JS_PUBLIC_API(const Latin1Char *)
JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str)
{
return str->chars();
return str->latin1Chars(nogc);
}
extern JS_PUBLIC_API(const jschar *)
JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str)
{
return str->twoByteChars(nogc);
}
JS_PUBLIC_API(bool)

View File

@ -4142,15 +4142,16 @@ JS_FileEscapedString(FILE *fp, JSString *str, char quote);
* special cases where getting the chars is infallible:
*
* The first case is interned strings, i.e., strings from JS_InternString or
* JSID_TO_STRING(id), using JS_GetInternedStringChars*.
* JSID_TO_STRING(id), using JS_GetLatin1InternedStringChars or
* JS_GetTwoByteInternedStringChars.
*
* The second case is "flat" strings that have been explicitly prepared in a
* fallible context by JS_FlattenString. To catch errors, a separate opaque
* JSFlatString type is returned by JS_FlattenString and expected by
* JS_GetFlatStringChars. Note, though, that this is purely a syntactic
* distinction: the input and output of JS_FlattenString are the same actual
* GC-thing so only one needs to be rooted. If a JSString is known to be flat,
* JS_ASSERT_STRING_IS_FLAT can be used to make a debug-checked cast. Example:
* GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be
* used to make a debug-checked cast. Example:
*
* // in a fallible context
* JSFlatString *fstr = JS_FlattenString(cx, str);
@ -4159,26 +4160,30 @@ JS_FileEscapedString(FILE *fp, JSString *str, char quote);
* JS_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
*
* // in an infallible context, for the same 'str'
* const jschar *chars = JS_GetFlatStringChars(fstr)
* AutoCheckCannotGC nogc;
* const jschar *chars = JS_GetTwoByteFlatStringChars(nogc, fstr)
* JS_ASSERT(chars);
*
* The CharsZ APIs guarantee that the returned array has a null character at
* chars[length]. This can require additional copying so clients should prefer
* APIs without CharsZ if possible. The infallible functions also return
* null-terminated arrays. (There is no additional cost or non-Z alternative
* for the infallible functions, so 'Z' is left out of the identifier.)
* Flat strings and interned strings are always null-terminated, so
* JS_FlattenString can be used to get a null-terminated string.
*
* Additionally, string characters are stored as either Latin1Char (8-bit)
* or jschar (16-bit). Clients can use JS_StringHasLatin1Chars and can then
* call either the Latin1* or TwoByte* functions. Some functions like
* JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte
* strings.
*/
extern JS_PUBLIC_API(size_t)
JS_GetStringLength(JSString *str);
extern JS_PUBLIC_API(bool)
JS_StringIsFlat(JSString *str);
/* Returns true iff the string's characters are stored as Latin1. */
extern JS_PUBLIC_API(bool)
JS_StringHasLatin1Chars(JSString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length);
extern JS_PUBLIC_API(const JS::Latin1Char *)
JS_GetLatin1StringCharsAndLength(JSContext *cx, const JS::AutoCheckCannotGC &nogc, JSString *str,
size_t *length);
@ -4199,23 +4204,20 @@ JS_GetTwoByteExternalStringChars(JSString *str);
extern JS_PUBLIC_API(bool)
JS_CopyStringChars(JSContext *cx, mozilla::Range<jschar> dest, JSString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetInternedStringChars(JSString *str);
extern JS_PUBLIC_API(const JS::Latin1Char *)
JS_GetLatin1InternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetInternedStringCharsAndLength(JSString *str, size_t *length);
extern JS_PUBLIC_API(const jschar *)
JS_GetStringCharsZ(JSContext *cx, JSString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *length);
JS_GetTwoByteInternedStringChars(const JS::AutoCheckCannotGC &nogc, JSString *str);
extern JS_PUBLIC_API(JSFlatString *)
JS_FlattenString(JSContext *cx, JSString *str);
extern JS_PUBLIC_API(const JS::Latin1Char *)
JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str);
extern JS_PUBLIC_API(const jschar *)
JS_GetFlatStringChars(JSFlatString *str);
JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC &nogc, JSFlatString *str);
static MOZ_ALWAYS_INLINE JSFlatString *
JSID_TO_FLAT_STRING(jsid id)
@ -4227,7 +4229,7 @@ JSID_TO_FLAT_STRING(jsid id)
static MOZ_ALWAYS_INLINE JSFlatString *
JS_ASSERT_STRING_IS_FLAT(JSString *str)
{
JS_ASSERT(JS_GetFlatStringChars((JSFlatString *)str));
JS_ASSERT(JS_StringIsFlat(str));
return (JSFlatString *)str;
}
@ -4388,9 +4390,6 @@ namespace JS {
extern JS_PUBLIC_API(JSAddonId *)
NewAddonId(JSContext *cx, JS::HandleString str);
extern JS_PUBLIC_API(const jschar *)
CharsZOfAddonId(JSAddonId *id);
extern JS_PUBLIC_API(JSString *)
StringOfAddonId(JSAddonId *id);

View File

@ -601,8 +601,8 @@ js_GetLocalizedErrorMessage(ExclusiveContext *cx, void *userRef, const char *loc
return errorString;
}
JS_FRIEND_API(const jschar*)
js::GetErrorTypeName(JSRuntime* rt, int16_t exnType)
JS_FRIEND_API(JSFlatString *)
js::GetErrorTypeName(JSRuntime *rt, int16_t exnType)
{
/*
* JSEXN_INTERNALERR returns null to prevent that "InternalError: "
@ -614,7 +614,7 @@ js::GetErrorTypeName(JSRuntime* rt, int16_t exnType)
return nullptr;
}
JSProtoKey key = GetExceptionProtoKey(JSExnType(exnType));
return ClassName(key, rt)->chars();
return ClassName(key, rt);
}
bool
@ -770,6 +770,7 @@ js_ReportUncaughtException(JSContext *cx)
// value is "".
const char *filename_str = "filename";
JSAutoByteString filename;
AutoStableStringChars strChars(cx);
if (!reportp && exnObject && IsDuckTypedErrorObject(cx, exnObject, &filename_str))
{
// Temporary value for pulling properties off of duck-typed objects.
@ -840,8 +841,8 @@ js_ReportUncaughtException(JSContext *cx)
// done for duck-typed error objects.
//
// If only this stuff could get specced one day...
if (JSFlatString *flat = str->ensureFlat(cx))
report.ucmessage = flat->chars();
if (str->ensureFlat(cx) && strChars.initTwoByte(cx, str))
report.ucmessage = strChars.twoByteChars();
}
}

View File

@ -1097,8 +1097,8 @@ CastToJSFreeOp(FreeOp *fop)
* Get an error type name from a JSExnType constant.
* Returns nullptr for invalid arguments and JSEXN_INTERNALERR
*/
extern JS_FRIEND_API(const jschar*)
GetErrorTypeName(JSRuntime* rt, int16_t exnType);
extern JS_FRIEND_API(JSFlatString *)
GetErrorTypeName(JSRuntime *rt, int16_t exnType);
#ifdef JS_DEBUG
extern JS_FRIEND_API(unsigned)

View File

@ -693,7 +693,10 @@ SecurityWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper,
{
if (desc.getter() || desc.setter()) {
JSString *str = IdToString(cx, id);
const jschar *prop = str ? str->getCharsZ(cx) : nullptr;
AutoStableStringChars chars(cx);
const jschar *prop = nullptr;
if (str->ensureFlat(cx) && chars.initTwoByte(cx, str))
prop = chars.twoByteChars();
JS_ReportErrorNumberUC(cx, js_GetErrorMessage, nullptr,
JSMSG_ACCESSOR_DEF_DENIED, prop);
return false;

View File

@ -453,7 +453,7 @@ inline void
JSExternalString::finalize(js::FreeOp *fop)
{
const JSStringFinalizer *fin = externalFinalizer();
fin->finalize(fin, const_cast<jschar *>(nonInlineChars()));
fin->finalize(fin, const_cast<jschar *>(rawTwoByteChars()));
}
#endif /* vm_String_inl_h */

View File

@ -140,18 +140,13 @@ JSString::dump()
bool
JSString::equals(const char *s)
{
const jschar *c = getChars(nullptr);
if (!c) {
JSLinearString *linear = ensureLinear(nullptr);
if (!linear) {
fprintf(stderr, "OOM in JSString::equals!\n");
return false;
}
while (*c && *s) {
if (*c != *s)
return false;
c++;
s++;
}
return *c == *s;
return StringEqualsAscii(linear, s);
}
#endif /* DEBUG */
@ -164,12 +159,12 @@ JSLinearString::debugUnsafeConvertToLatin1()
MOZ_ASSERT(!hasBase());
size_t len = length();
const jschar *twoByteChars = chars();
char *latin1Chars = (char *)twoByteChars;
const jschar *twoByteChars = rawTwoByteChars();
Latin1Char *latin1Chars = (Latin1Char *)twoByteChars;
for (size_t i = 0; i < len; i++) {
MOZ_ASSERT((twoByteChars[i] & 0xff00) == 0);
latin1Chars[i] = char(twoByteChars[i]);
latin1Chars[i] = Latin1Char(twoByteChars[i]);
}
latin1Chars[len] = '\0';

View File

@ -323,13 +323,6 @@ class JSString : public js::gc::BarrieredCell<JSString>
return d.u1.length == 0;
}
/*
* All strings have a fallible operation to get an array of chars.
* getCharsZ additionally ensures the array is null terminated.
*/
inline const jschar *getChars(js::ExclusiveContext *cx);
inline const jschar *getCharsZ(js::ExclusiveContext *cx);
inline bool getChar(js::ExclusiveContext *cx, size_t index, jschar *code);
/* Strings have either Latin1 or TwoByte chars. */
@ -607,13 +600,6 @@ class JSLinearString : public JSString
MOZ_ALWAYS_INLINE const jschar *rawTwoByteChars() const;
public:
MOZ_ALWAYS_INLINE
const jschar *nonInlineChars() const {
JS_ASSERT(!isInline());
JS_ASSERT(hasTwoByteChars());
return d.s.u2.nonInlineCharsTwoByte;
}
template<typename CharT>
MOZ_ALWAYS_INLINE
const CharT *nonInlineChars(const JS::AutoCheckCannotGC &nogc) const;
@ -632,9 +618,6 @@ class JSLinearString : public JSString
return d.s.u2.nonInlineCharsTwoByte;
}
MOZ_ALWAYS_INLINE
const jschar *chars() const;
template<typename CharT>
MOZ_ALWAYS_INLINE
const CharT *chars(const JS::AutoCheckCannotGC &nogc) const;
@ -649,11 +632,6 @@ class JSLinearString : public JSString
return rawTwoByteChars();
}
JS::TwoByteChars range() const {
JS_ASSERT(JSString::isLinear());
return JS::TwoByteChars(chars(), length());
}
mozilla::Range<const JS::Latin1Char> latin1Range(const JS::AutoCheckCannotGC &nogc) const {
JS_ASSERT(JSString::isLinear());
return mozilla::Range<const JS::Latin1Char>(latin1Chars(nogc), length());
@ -693,9 +671,6 @@ class JSDependentString : public JSLinearString
bool isDependent() const MOZ_DELETE;
JSDependentString &asDependent() const MOZ_DELETE;
/* Hide chars(), nonInlineChars() is more efficient. */
const jschar *chars() const MOZ_DELETE;
/* The offset of this string's chars in base->chars(). */
size_t baseOffset() const {
MOZ_ASSERT(JSString::isDependent());
@ -734,12 +709,6 @@ class JSFlatString : public JSLinearString
static inline JSFlatString *new_(js::ThreadSafeContext *cx,
const CharT *chars, size_t length);
MOZ_ALWAYS_INLINE
const jschar *charsZ() const {
JS_ASSERT(JSString::isFlat());
return chars();
}
/*
* Returns true if this string's characters store an unsigned 32-bit
* integer value, initializing *indexp to that value if so. (Thus if
@ -788,9 +757,6 @@ class JSExtensibleString : public JSFlatString
bool isExtensible() const MOZ_DELETE;
JSExtensibleString &asExtensible() const MOZ_DELETE;
/* Hide chars(), nonInlineChars() is more efficient. */
const jschar *chars() const MOZ_DELETE;
public:
MOZ_ALWAYS_INLINE
size_t capacity() const {
@ -823,13 +789,6 @@ class JSInlineString : public JSFlatString
inline void resetLength(size_t length);
MOZ_ALWAYS_INLINE
const jschar *chars() const {
JS_ASSERT(JSString::isInline());
JS_ASSERT(hasTwoByteChars());
return d.inlineStorageTwoByte;
}
MOZ_ALWAYS_INLINE
const JS::Latin1Char *latin1Chars(const JS::AutoCheckCannotGC &nogc) const {
JS_ASSERT(JSString::isInline());
@ -889,9 +848,6 @@ class JSFatInlineString : public JSInlineString
offsetof(JSFatInlineString, d.inlineStorageLatin1)) / sizeof(char));
}
/* Hide chars(), inlineChars() is more efficient. */
const jschar *chars() const MOZ_DELETE;
protected: /* to fool clang into not warning this is unused */
union {
char inlineStorageExtensionLatin1[INLINE_EXTENSION_CHARS_LATIN1];
@ -941,9 +897,6 @@ class JSExternalString : public JSFlatString
bool isExternal() const MOZ_DELETE;
JSExternalString &asExternal() const MOZ_DELETE;
/* Hide chars(), nonInlineChars() is more efficient. */
const jschar *chars() const MOZ_DELETE;
public:
static inline JSExternalString *new_(JSContext *cx, const jschar *chars, size_t length,
const JSStringFinalizer *fin);
@ -1296,16 +1249,6 @@ CopyChars(CharT *dest, const JSLinearString &str);
class JSAddonId : public JSAtom
{};
/* Avoid requiring vm/String-inl.h just to call getChars. */
MOZ_ALWAYS_INLINE const jschar *
JSString::getChars(js::ExclusiveContext *cx)
{
if (JSLinearString *str = ensureLinear(cx))
return str->chars();
return nullptr;
}
MOZ_ALWAYS_INLINE bool
JSString::getChar(js::ExclusiveContext *cx, size_t index, jschar *code)
{
@ -1340,14 +1283,6 @@ JSString::getChar(js::ExclusiveContext *cx, size_t index, jschar *code)
return true;
}
MOZ_ALWAYS_INLINE const jschar *
JSString::getCharsZ(js::ExclusiveContext *cx)
{
if (JSFlatString *str = ensureFlat(cx))
return str->chars();
return nullptr;
}
MOZ_ALWAYS_INLINE JSLinearString *
JSString::ensureLinear(js::ExclusiveContext *cx)
{
@ -1459,14 +1394,6 @@ JSString::setNonInlineChars(const JS::Latin1Char *chars)
d.s.u2.nonInlineCharsLatin1 = chars;
}
MOZ_ALWAYS_INLINE const jschar *
JSLinearString::chars() const
{
JS_ASSERT(JSString::isLinear());
JS_ASSERT(hasTwoByteChars());
return isInline() ? asInline().chars() : nonInlineChars();
}
MOZ_ALWAYS_INLINE const JS::Latin1Char *
JSLinearString::rawLatin1Chars() const
{

View File

@ -84,15 +84,12 @@ Symbol::dump(FILE *fp)
{
if (isWellKnownSymbol()) {
// All the well-known symbol names are ASCII.
const jschar *desc = description_->chars();
size_t len = description_->length();
for (size_t i = 0; i < len; i++)
fputc(char(desc[i]), fp);
description_->dumpCharsNoNewline(fp);
} else if (code_ == SymbolCode::InSymbolRegistry || code_ == SymbolCode::UniqueSymbol) {
fputs(code_ == SymbolCode::InSymbolRegistry ? "Symbol.for(" : "Symbol(", fp);
if (description_)
JSString::dumpChars(description_->chars(), description_->length(), fp);
description_->dumpCharsNoNewline(fp);
else
fputs("undefined", fp);

View File

@ -18,6 +18,7 @@
#include "nsIResProtocolHandler.h"
#include "nsIChromeRegistry.h"
#include "nsIJARURI.h"
#include "nsJSUtils.h"
#include "mozilla/AddonPathService.h"
#include "mozilla/Omnijar.h"
@ -85,7 +86,8 @@ NS_IMETHODIMP
AddonPathService::FindAddonId(const nsAString& path, nsAString& addonIdString)
{
if (JSAddonId* id = Find(path)) {
addonIdString = JS::CharsZOfAddonId(id);
JSFlatString* flat = JS_ASSERT_STRING_IS_FLAT(JS::StringOfAddonId(id));
AssignJSFlatString(addonIdString, flat);
}
return NS_OK;
}