mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
bug 528645 - js_IsAboutToBeFinalized must check for static strings. r=wagnerg
This commit is contained in:
parent
a9a607f1de
commit
ea2c3a7d8a
@ -53,6 +53,7 @@ CPPSRCS = \
|
||||
testDefineGetterSetterNonEnumerable.cpp \
|
||||
testExtendedEq.cpp \
|
||||
testIntString.cpp \
|
||||
testIsAboutToBeFinalized.cpp \
|
||||
testLookup.cpp \
|
||||
testPropCache.cpp \
|
||||
testTrap.cpp \
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
BEGIN_TEST(testIntString_bug515273)
|
||||
{
|
||||
jsval v;
|
||||
EVAL("'42';", &v);
|
||||
jsvalRoot v(cx);
|
||||
EVAL("'42';", v.addr());
|
||||
|
||||
JSString *str = JSVAL_TO_STRING(v);
|
||||
JSString *str = JSVAL_TO_STRING(v.value());
|
||||
const char *bytes = JS_GetStringBytes(str);
|
||||
CHECK(strcmp(bytes, "42") == 0);
|
||||
return true;
|
||||
|
89
js/src/jsapi-tests/testIsAboutToBeFinalized.cpp
Normal file
89
js/src/jsapi-tests/testIsAboutToBeFinalized.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "tests.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
static JSGCCallback oldGCCallback;
|
||||
|
||||
static void **checkPointers;
|
||||
static jsuint checkPointersLength;
|
||||
|
||||
static JSBool
|
||||
TestAboutToBeFinalizedCallback(JSContext *cx, JSGCStatus status)
|
||||
{
|
||||
if (status == JSGC_MARK_END && checkPointers) {
|
||||
for (jsuint i = 0; i != checkPointersLength; ++i) {
|
||||
void *p = checkPointers[i];
|
||||
JS_ASSERT(p);
|
||||
if (JS_IsAboutToBeFinalized(cx, p))
|
||||
checkPointers[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return !oldGCCallback || oldGCCallback(cx, status);
|
||||
}
|
||||
|
||||
BEGIN_TEST(testIsAboutToBeFinalized_bug528645)
|
||||
{
|
||||
jsvalRoot root(cx);
|
||||
|
||||
/*
|
||||
* Check various types of GC things against JS_IsAboutToBeFinalized.
|
||||
* Make sure to include unit and numeric strings to the set.
|
||||
*/
|
||||
EVAL("var x = 1.1; "
|
||||
"[x + 0.1, ''+x, 'a', '42', 'something'.substring(1), "
|
||||
"{}, [], new Function('return 10;'), <xml/>];",
|
||||
root.addr());
|
||||
|
||||
JSObject *array = JSVAL_TO_OBJECT(root.value());
|
||||
JS_ASSERT(JS_IsArrayObject(cx, array));
|
||||
|
||||
JSBool ok = JS_GetArrayLength(cx, array, &checkPointersLength);
|
||||
CHECK(ok);
|
||||
|
||||
void **elems = (void **) malloc(sizeof(void *) * checkPointersLength);
|
||||
CHECK(elems);
|
||||
|
||||
size_t staticStrings = 0;
|
||||
for (jsuint i = 0; i != checkPointersLength; ++i) {
|
||||
jsval v;
|
||||
ok = JS_GetElement(cx, array, i, &v);
|
||||
CHECK(ok);
|
||||
JS_ASSERT(JSVAL_IS_GCTHING(v));
|
||||
JS_ASSERT(!JSVAL_IS_NULL(v));
|
||||
elems[i] = JSVAL_TO_GCTHING(v);
|
||||
if (JSString::isStatic(elems[i]))
|
||||
++staticStrings;
|
||||
}
|
||||
|
||||
oldGCCallback = JS_SetGCCallback(cx, TestAboutToBeFinalizedCallback);
|
||||
checkPointers = elems;
|
||||
JS_GC(cx);
|
||||
|
||||
/*
|
||||
* All GC things are rooted via the root holding the array containing them
|
||||
* and TestAboutToBeFinalizedCallback must keep them as is.
|
||||
*/
|
||||
for (jsuint i = 0; i != checkPointersLength; ++i)
|
||||
CHECK(checkPointers[i]);
|
||||
|
||||
root = JSVAL_NULL;
|
||||
JS_GC(cx);
|
||||
|
||||
/* Everything is unrooted except unit strings. */
|
||||
for (jsuint i = 0; i != checkPointersLength; ++i) {
|
||||
void *p = checkPointers[i];
|
||||
if (p) {
|
||||
CHECK(JSString::isStatic(p));
|
||||
CHECK(staticStrings != 0);
|
||||
--staticStrings;
|
||||
}
|
||||
}
|
||||
CHECK(staticStrings == 0);
|
||||
|
||||
checkPointers = NULL;
|
||||
JS_SetGCCallback(cx, oldGCCallback);
|
||||
free(elems);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testIsAboutToBeFinalized_bug528645)
|
@ -900,6 +900,9 @@ js_IsAboutToBeFinalized(void *thing)
|
||||
JSGCArenaInfo *a;
|
||||
uint32 index, flags;
|
||||
|
||||
if (JSString::isStatic(thing))
|
||||
return false;
|
||||
|
||||
a = THING_TO_ARENA(thing);
|
||||
if (!a->list) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user