mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 599481 - static string tables should be constant. r=alangpierce
This commit is contained in:
parent
ac27a6ce80
commit
bd21beac91
@ -3,15 +3,38 @@
|
||||
*/
|
||||
|
||||
#include "tests.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
BEGIN_TEST(testIntString_bug515273)
|
||||
{
|
||||
jsvalRoot v(cx);
|
||||
EVAL("'42';", v.addr());
|
||||
|
||||
EVAL("'1';", v.addr());
|
||||
JSString *str = JSVAL_TO_STRING(v.value());
|
||||
const char *bytes = JS_GetStringBytes(str);
|
||||
CHECK(strcmp(bytes, "42") == 0);
|
||||
CHECK(JSString::isStatic(str));
|
||||
CHECK(strcmp(JS_GetStringBytes(str), "1") == 0);
|
||||
|
||||
EVAL("'42';", v.addr());
|
||||
str = JSVAL_TO_STRING(v.value());
|
||||
CHECK(JSString::isStatic(str));
|
||||
CHECK(strcmp(JS_GetStringBytes(str), "42") == 0);
|
||||
|
||||
EVAL("'111';", v.addr());
|
||||
str = JSVAL_TO_STRING(v.value());
|
||||
CHECK(JSString::isStatic(str));
|
||||
CHECK(strcmp(JS_GetStringBytes(str), "111") == 0);
|
||||
|
||||
/* Test other types of static strings. */
|
||||
EVAL("'a';", v.addr());
|
||||
str = JSVAL_TO_STRING(v.value());
|
||||
CHECK(JSString::isStatic(str));
|
||||
CHECK(strcmp(JS_GetStringBytes(str), "a") == 0);
|
||||
|
||||
EVAL("'bc';", v.addr());
|
||||
str = JSVAL_TO_STRING(v.value());
|
||||
CHECK(JSString::isStatic(str));
|
||||
CHECK(strcmp(JS_GetStringBytes(str), "bc") == 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testIntString_bug515273)
|
||||
|
@ -3126,7 +3126,7 @@ static JSFunctionSpec string_methods[] = {
|
||||
#pragma pack(push, 8)
|
||||
#endif
|
||||
|
||||
JSString JSString::unitStringTable[]
|
||||
const JSString JSString::unitStringTable[]
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((aligned (8)))
|
||||
#endif
|
||||
@ -3152,7 +3152,7 @@ __attribute__ ((aligned (8)))
|
||||
|
||||
#define R TO_SMALL_CHAR
|
||||
|
||||
JSString::SmallChar JSString::toSmallChar[] = { R7(0) };
|
||||
const JSString::SmallChar JSString::toSmallChar[] = { R7(0) };
|
||||
|
||||
#undef R
|
||||
|
||||
@ -3165,7 +3165,7 @@ JSString::SmallChar JSString::toSmallChar[] = { R7(0) };
|
||||
'A' - 36))
|
||||
#define R FROM_SMALL_CHAR
|
||||
|
||||
jschar JSString::fromSmallChar[] = { R6(0) };
|
||||
const jschar JSString::fromSmallChar[] = { R6(0) };
|
||||
|
||||
#undef R
|
||||
|
||||
@ -3186,7 +3186,7 @@ jschar JSString::fromSmallChar[] = { R6(0) };
|
||||
#pragma pack(push, 8)
|
||||
#endif
|
||||
|
||||
JSString JSString::length2StringTable[]
|
||||
const JSString JSString::length2StringTable[]
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((aligned (8)))
|
||||
#endif
|
||||
@ -3228,7 +3228,7 @@ JS_STATIC_ASSERT(100 + (1 << 7) + (1 << 4) + (1 << 3) + (1 << 2) == 256);
|
||||
#pragma pack(push, 8)
|
||||
#endif
|
||||
|
||||
JSString JSString::hundredStringTable[]
|
||||
const JSString JSString::hundredStringTable[]
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((aligned (8)))
|
||||
#endif
|
||||
@ -3246,7 +3246,7 @@ __attribute__ ((aligned (8)))
|
||||
TO_SMALL_CHAR(((c) % 10) + '0') : \
|
||||
JSString::hundredStringTable + ((c) - 100))
|
||||
|
||||
JSString *JSString::intStringTable[] = { R8(0) };
|
||||
const JSString *const JSString::intStringTable[] = { R8(0) };
|
||||
|
||||
#undef R
|
||||
|
||||
@ -3491,7 +3491,7 @@ js_NewDependentString(JSContext *cx, JSString *base, size_t start,
|
||||
jschar *chars = base->chars() + start;
|
||||
|
||||
if (length == 1 && *chars < UNIT_STRING_LIMIT)
|
||||
return &JSString::unitStringTable[*chars];
|
||||
return const_cast<JSString *>(&JSString::unitStringTable[*chars]);
|
||||
|
||||
/* Try to avoid long chains of dependent strings. */
|
||||
while (base->isDependent())
|
||||
|
@ -276,6 +276,7 @@ struct JSString {
|
||||
/* Specific flat string initializer and accessor methods. */
|
||||
JS_ALWAYS_INLINE void initFlat(jschar *chars, size_t length) {
|
||||
JS_ASSERT(length <= MAX_LENGTH);
|
||||
JS_ASSERT(!isStatic(this));
|
||||
e.mBase = NULL;
|
||||
e.mCapacity = 0;
|
||||
mLengthAndFlags = (length << FLAGS_LENGTH_SHIFT) | FLAT;
|
||||
@ -284,6 +285,7 @@ struct JSString {
|
||||
|
||||
JS_ALWAYS_INLINE void initFlatMutable(jschar *chars, size_t length, size_t cap) {
|
||||
JS_ASSERT(length <= MAX_LENGTH);
|
||||
JS_ASSERT(!isStatic(this));
|
||||
e.mBase = NULL;
|
||||
e.mCapacity = cap;
|
||||
mLengthAndFlags = (length << FLAGS_LENGTH_SHIFT) | FLAT | MUTABLE;
|
||||
@ -334,6 +336,7 @@ struct JSString {
|
||||
*/
|
||||
inline void flatSetAtomized() {
|
||||
JS_ASSERT(isFlat());
|
||||
JS_ASSERT(!isStatic(this));
|
||||
JS_ATOMIC_SET_MASK((jsword *)&mLengthAndFlags, ATOMIZED);
|
||||
}
|
||||
|
||||
@ -345,7 +348,13 @@ struct JSString {
|
||||
|
||||
inline void flatClearMutable() {
|
||||
JS_ASSERT(isFlat());
|
||||
mLengthAndFlags &= ~MUTABLE;
|
||||
|
||||
/*
|
||||
* We cannot eliminate the flag check before writing to mLengthAndFlags as
|
||||
* static strings may reside in write-protected memory. See bug 599481.
|
||||
*/
|
||||
if (mLengthAndFlags & MUTABLE)
|
||||
mLengthAndFlags &= ~MUTABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -354,6 +363,7 @@ struct JSString {
|
||||
*/
|
||||
inline void initDependent(JSString *bstr, jschar *chars, size_t len) {
|
||||
JS_ASSERT(len <= MAX_LENGTH);
|
||||
JS_ASSERT(!isStatic(this));
|
||||
e.mParent = NULL;
|
||||
mChars = chars;
|
||||
mLengthAndFlags = DEPENDENT | (len << FLAGS_LENGTH_SHIFT);
|
||||
@ -378,6 +388,7 @@ struct JSString {
|
||||
inline void initTopNode(JSString *left, JSString *right, size_t len,
|
||||
JSRopeBufferInfo *buf) {
|
||||
JS_ASSERT(left->length() + right->length() <= MAX_LENGTH);
|
||||
JS_ASSERT(!isStatic(this));
|
||||
mLengthAndFlags = TOP_NODE | (len << FLAGS_LENGTH_SHIFT);
|
||||
mLeft = left;
|
||||
e.mRight = right;
|
||||
@ -517,16 +528,16 @@ struct JSString {
|
||||
|
||||
static const SmallChar INVALID_SMALL_CHAR = -1;
|
||||
|
||||
static jschar fromSmallChar[];
|
||||
static SmallChar toSmallChar[];
|
||||
static JSString unitStringTable[];
|
||||
static JSString length2StringTable[];
|
||||
static JSString hundredStringTable[];
|
||||
static const jschar fromSmallChar[];
|
||||
static const SmallChar toSmallChar[];
|
||||
static const JSString unitStringTable[];
|
||||
static const JSString length2StringTable[];
|
||||
static const JSString hundredStringTable[];
|
||||
/*
|
||||
* Since int strings can be unit strings, length-2 strings, or hundred
|
||||
* strings, we keep a table to map from integer to the correct string.
|
||||
*/
|
||||
static JSString *intStringTable[];
|
||||
static const JSString *const intStringTable[];
|
||||
static const char deflatedIntStringTable[];
|
||||
static const char deflatedUnitStringTable[];
|
||||
static const char deflatedLength2StringTable[];
|
||||
|
@ -46,7 +46,7 @@ inline JSString *
|
||||
JSString::unitString(jschar c)
|
||||
{
|
||||
JS_ASSERT(c < UNIT_STRING_LIMIT);
|
||||
return &unitStringTable[c];
|
||||
return const_cast<JSString *>(&unitStringTable[c]);
|
||||
}
|
||||
|
||||
inline JSString *
|
||||
@ -64,7 +64,8 @@ JSString::length2String(jschar c1, jschar c2)
|
||||
{
|
||||
JS_ASSERT(fitsInSmallChar(c1));
|
||||
JS_ASSERT(fitsInSmallChar(c2));
|
||||
return &length2StringTable[(((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2]];
|
||||
return const_cast<JSString *>
|
||||
(&length2StringTable[(((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2]]);
|
||||
}
|
||||
|
||||
inline JSString *
|
||||
@ -72,7 +73,7 @@ JSString::intString(jsint i)
|
||||
{
|
||||
jsuint u = jsuint(i);
|
||||
JS_ASSERT(u < INT_STRING_LIMIT);
|
||||
return JSString::intStringTable[u];
|
||||
return const_cast<JSString *>(JSString::intStringTable[u]);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
Loading…
Reference in New Issue
Block a user