mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 724810 - storing finalizer in external strings directly. r=luke
--HG-- extra : rebase_source : d3222c685190bbdbe9446628f2f73f2a6f81eb11
This commit is contained in:
parent
fe418cb25f
commit
146c8750f5
@ -1,37 +1,39 @@
|
||||
#include "tests.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
const jschar arr[] = { 'h', 'i', ',', 'd', 'o', 'n', '\'', 't', ' ', 'd', 'e', 'l', 'e', 't', 'e', ' ', 'm', 'e', '\0' };
|
||||
size_t arrlen = sizeof(arr) / sizeof(arr[0]) - 1;
|
||||
void *magic = (void *)0x42;
|
||||
static const jschar arr[] = {
|
||||
'h', 'i', ',', 'd', 'o', 'n', '\'', 't', ' ', 'd', 'e', 'l', 'e', 't', 'e', ' ', 'm', 'e', '\0'
|
||||
};
|
||||
static const size_t arrlen = sizeof(arr) / sizeof(arr[0]) - 1;
|
||||
|
||||
int finalized_noclosure = 0;
|
||||
int finalized_closure = 0;
|
||||
static int finalized1 = 0;
|
||||
static int finalized2 = 0;
|
||||
|
||||
void finalize_str(JSContext *cx, JSString *str)
|
||||
static void
|
||||
finalize_str(const JSStringFinalizer *fin, jschar *chars);
|
||||
|
||||
static const JSStringFinalizer finalizer1 = { finalize_str };
|
||||
static const JSStringFinalizer finalizer2 = { finalize_str };
|
||||
|
||||
static void
|
||||
finalize_str(const JSStringFinalizer *fin, jschar *chars)
|
||||
{
|
||||
size_t len;
|
||||
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &len);
|
||||
if (chars && len == arrlen && js::PodEqual(chars, arr, len)) {
|
||||
void *closure = JS_GetExternalStringClosure(cx, str);
|
||||
if (closure) {
|
||||
if (closure == magic)
|
||||
++finalized_closure;
|
||||
} else {
|
||||
++finalized_noclosure;
|
||||
if (chars && js::PodEqual(const_cast<const jschar *>(chars), arr, arrlen)) {
|
||||
if (fin == &finalizer1) {
|
||||
++finalized1;
|
||||
} else if (fin == &finalizer2) {
|
||||
++finalized2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN_TEST(testExternalStrings)
|
||||
{
|
||||
intN op = JS_AddExternalStringFinalizer(finalize_str);
|
||||
|
||||
const unsigned N = 1000;
|
||||
|
||||
for (unsigned i = 0; i < N; ++i) {
|
||||
CHECK(JS_NewExternalString(cx, arr, arrlen, op));
|
||||
CHECK(JS_NewExternalStringWithClosure(cx, arr, arrlen, op, magic));
|
||||
CHECK(JS_NewExternalString(cx, arr, arrlen, &finalizer1));
|
||||
CHECK(JS_NewExternalString(cx, arr, arrlen, &finalizer2));
|
||||
}
|
||||
|
||||
// clear that newborn root
|
||||
@ -42,8 +44,8 @@ BEGIN_TEST(testExternalStrings)
|
||||
// a generous fudge factor to account for strings rooted by conservative gc
|
||||
const unsigned epsilon = 10;
|
||||
|
||||
CHECK((N - finalized_noclosure) < epsilon);
|
||||
CHECK((N - finalized_closure) < epsilon);
|
||||
CHECK((N - finalized1) < epsilon);
|
||||
CHECK((N - finalized2) < epsilon);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2966,51 +2966,27 @@ JS_FlushCaches(JSContext *cx)
|
||||
{
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(intN)
|
||||
JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer)
|
||||
{
|
||||
return JSExternalString::changeFinalizer(NULL, finalizer);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(intN)
|
||||
JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer)
|
||||
{
|
||||
return JSExternalString::changeFinalizer(finalizer, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSString *)
|
||||
JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length, intN type)
|
||||
JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
|
||||
const JSStringFinalizer *fin)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
JSString *s = JSExternalString::new_(cx, chars, length, type, NULL);
|
||||
JSString *s = JSExternalString::new_(cx, chars, length, fin);
|
||||
Probes::createString(cx, s, length);
|
||||
return s;
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_NewExternalStringWithClosure(JSContext *cx, const jschar *chars, size_t length,
|
||||
intN type, void *closure)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return JSExternalString::new_(cx, chars, length, type, closure);
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_IsExternalString(JSContext *cx, JSString *str)
|
||||
JS_IsExternalString(JSString *str)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
return str->isExternal();
|
||||
}
|
||||
|
||||
extern JS_PUBLIC_API(void *)
|
||||
JS_GetExternalStringClosure(JSContext *cx, JSString *str)
|
||||
extern JS_PUBLIC_API(const JSStringFinalizer *)
|
||||
JS_GetExternalStringFinalizer(JSString *str)
|
||||
{
|
||||
AssertNoGCOrFlatString(cx, str);
|
||||
CHECK_REQUEST(cx);
|
||||
return str->asExternal().externalClosure();
|
||||
return str->asExternal().externalFinalizer();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
@ -1330,11 +1330,13 @@ typedef void
|
||||
(* JSFinalizeOp)(JSContext *cx, JSObject *obj);
|
||||
|
||||
/*
|
||||
* Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinalizer
|
||||
* to extend and reduce the set of string types finalized by the GC.
|
||||
* Finalizes external strings created by JS_NewExternalString.
|
||||
*/
|
||||
typedef void
|
||||
(* JSStringFinalizeOp)(JSContext *cx, JSString *str);
|
||||
typedef struct JSStringFinalizer JSStringFinalizer;
|
||||
|
||||
struct JSStringFinalizer {
|
||||
void (*finalize)(const JSStringFinalizer *fin, jschar *chars);
|
||||
};
|
||||
|
||||
/*
|
||||
* JSClass.checkAccess type: check whether obj[id] may be accessed per mode,
|
||||
@ -3305,70 +3307,27 @@ JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_FlushCaches(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Add a finalizer for external strings created by JS_NewExternalString (see
|
||||
* below) using a type-code returned from this function, and that understands
|
||||
* how to free or release the memory pointed at by JS_GetStringChars(str).
|
||||
*
|
||||
* Return a nonnegative type index if there is room for finalizer in the
|
||||
* global GC finalizers table, else return -1. If the engine is compiled
|
||||
* JS_THREADSAFE and used in a multi-threaded environment, this function must
|
||||
* be invoked on the primordial thread only, at startup -- or else the entire
|
||||
* program must single-thread itself while loading a module that calls this
|
||||
* function.
|
||||
*/
|
||||
extern JS_PUBLIC_API(intN)
|
||||
JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer);
|
||||
|
||||
/*
|
||||
* Remove finalizer from the global GC finalizers table, returning its type
|
||||
* code if found, -1 if not found.
|
||||
*
|
||||
* As with JS_AddExternalStringFinalizer, there is a threading restriction
|
||||
* if you compile the engine JS_THREADSAFE: this function may be called for a
|
||||
* given finalizer pointer on only one thread; different threads may call to
|
||||
* remove distinct finalizers safely.
|
||||
*
|
||||
* You must ensure that all strings with finalizer's type have been collected
|
||||
* before calling this function. Otherwise, string data will be leaked by the
|
||||
* GC, for want of a finalizer to call.
|
||||
*/
|
||||
extern JS_PUBLIC_API(intN)
|
||||
JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer);
|
||||
|
||||
/*
|
||||
* Create a new JSString whose chars member refers to external memory, i.e.,
|
||||
* memory requiring type-specific finalization. The type code must be a
|
||||
* nonnegative return value from JS_AddExternalStringFinalizer.
|
||||
* memory requiring application-specific finalization.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length, intN type);
|
||||
|
||||
/*
|
||||
* Like JS_NewExternalString, except that 'closure' can be retrieved later via
|
||||
* JS_GetExternalStringClosure. This closure data is a black blox to the JS
|
||||
* engine and may be used by the embedding to associate extra data with an
|
||||
* external string. E.g., an embedding may want to associate a pointer to the
|
||||
* object that owns the chars of an external string so that, when this external
|
||||
* string is finalized, the owner object can be deleted.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_NewExternalStringWithClosure(JSContext *cx, const jschar *chars, size_t length,
|
||||
intN type, void *closure);
|
||||
JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
|
||||
const JSStringFinalizer *fin);
|
||||
|
||||
/*
|
||||
* Return whether 'str' was created with JS_NewExternalString or
|
||||
* JS_NewExternalStringWithClosure.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_IsExternalString(JSContext *cx, JSString *str);
|
||||
JS_IsExternalString(JSString *str);
|
||||
|
||||
/*
|
||||
* Return the 'closure' arg passed to JS_NewExternalStringWithClosure or NULL
|
||||
* if the external string was created via JS_NewExternalString.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void *)
|
||||
JS_GetExternalStringClosure(JSContext *cx, JSString *str);
|
||||
extern JS_PUBLIC_API(const JSStringFinalizer *)
|
||||
JS_GetExternalStringFinalizer(JSString *str);
|
||||
|
||||
/*
|
||||
* Set the size of the native stack that should not be exceed. To disable
|
||||
|
@ -229,18 +229,19 @@ JSShortString::initAtOffsetInBuffer(const jschar *chars, size_t length)
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE void
|
||||
JSExternalString::init(const jschar *chars, size_t length, intN type, void *closure)
|
||||
JSExternalString::init(const jschar *chars, size_t length, const JSStringFinalizer *fin)
|
||||
{
|
||||
JS_ASSERT(fin);
|
||||
JS_ASSERT(fin->finalize);
|
||||
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
|
||||
d.u1.chars = chars;
|
||||
d.s.u2.externalType = type;
|
||||
d.s.u3.externalClosure = closure;
|
||||
d.s.u2.externalFinalizer = fin;
|
||||
}
|
||||
|
||||
JS_ALWAYS_INLINE JSExternalString *
|
||||
JSExternalString::new_(JSContext *cx, const jschar *chars, size_t length, intN type, void *closure)
|
||||
JSExternalString::new_(JSContext *cx, const jschar *chars, size_t length,
|
||||
const JSStringFinalizer *fin)
|
||||
{
|
||||
JS_ASSERT(uintN(type) < JSExternalString::TYPE_LIMIT);
|
||||
JS_ASSERT(chars[length] == 0);
|
||||
|
||||
if (!validateLength(cx, length))
|
||||
@ -248,7 +249,7 @@ JSExternalString::new_(JSContext *cx, const jschar *chars, size_t length, intN t
|
||||
JSExternalString *str = js_NewGCExternalString(cx);
|
||||
if (!str)
|
||||
return NULL;
|
||||
str->init(chars, length, type, closure);
|
||||
str->init(chars, length, fin);
|
||||
cx->runtime->updateMallocCounter(cx, (length + 1) * sizeof(jschar));
|
||||
return str;
|
||||
}
|
||||
@ -408,21 +409,14 @@ JSAtom::finalize(JSRuntime *rt)
|
||||
inline void
|
||||
JSExternalString::finalize(JSContext *cx, bool background)
|
||||
{
|
||||
if (JSStringFinalizeOp finalizer = str_finalizers[externalType()])
|
||||
finalizer(cx, this);
|
||||
finalize();
|
||||
}
|
||||
|
||||
inline void
|
||||
JSExternalString::finalize()
|
||||
{
|
||||
JSStringFinalizeOp finalizer = str_finalizers[externalType()];
|
||||
if (finalizer) {
|
||||
/*
|
||||
* Assume that the finalizer for the permanently interned
|
||||
* string knows how to deal with null context.
|
||||
*/
|
||||
finalizer(NULL, this);
|
||||
}
|
||||
const JSStringFinalizer *fin = externalFinalizer();
|
||||
fin->finalize(fin, const_cast<jschar *>(chars()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -371,10 +371,6 @@ JSDependentString::undepend(JSContext *cx)
|
||||
return &this->asFixed();
|
||||
}
|
||||
|
||||
JSStringFinalizeOp JSExternalString::str_finalizers[JSExternalString::TYPE_LIMIT] = {
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
bool
|
||||
JSFlatString::isIndex(uint32_t *indexp) const
|
||||
{
|
||||
|
@ -174,11 +174,10 @@ class JSString : public js::gc::Cell
|
||||
JSLinearString *base; /* JSDependentString */
|
||||
JSString *right; /* JSRope */
|
||||
size_t capacity; /* JSFlatString (extensible) */
|
||||
size_t externalType; /* JSExternalString */
|
||||
const JSStringFinalizer *externalFinalizer;/* JSExternalString */
|
||||
} u2;
|
||||
union {
|
||||
JSString *parent; /* JSRope (temporary) */
|
||||
void *externalClosure; /* JSExternalString */
|
||||
size_t reserved; /* may use for bug 615290 */
|
||||
} u3;
|
||||
} s;
|
||||
@ -628,55 +627,27 @@ class JSShortString : public JSInlineString
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSShortString) == 2 * sizeof(JSString));
|
||||
|
||||
/*
|
||||
* The externalClosure stored in an external string is a black box to the JS
|
||||
* engine; see JS_NewExternalStringWithClosure.
|
||||
*/
|
||||
class JSExternalString : public JSFixedString
|
||||
{
|
||||
static void staticAsserts() {
|
||||
JS_STATIC_ASSERT(TYPE_LIMIT == 8);
|
||||
}
|
||||
|
||||
void init(const jschar *chars, size_t length, intN type, void *closure);
|
||||
void init(const jschar *chars, size_t length, const JSStringFinalizer *fin);
|
||||
|
||||
/* Vacuous and therefore unimplemented. */
|
||||
bool isExternal() const MOZ_DELETE;
|
||||
JSExternalString &asExternal() const MOZ_DELETE;
|
||||
|
||||
public:
|
||||
static inline JSExternalString *new_(JSContext *cx, const jschar *chars,
|
||||
size_t length, intN type, void *closure);
|
||||
static inline JSExternalString *new_(JSContext *cx, const jschar *chars, size_t length,
|
||||
const JSStringFinalizer *fin);
|
||||
|
||||
intN externalType() const {
|
||||
const JSStringFinalizer *externalFinalizer() const {
|
||||
JS_ASSERT(JSString::isExternal());
|
||||
JS_ASSERT(d.s.u2.externalType < TYPE_LIMIT);
|
||||
return intN(d.s.u2.externalType);
|
||||
}
|
||||
|
||||
void *externalClosure() const {
|
||||
JS_ASSERT(JSString::isExternal());
|
||||
return d.s.u3.externalClosure;
|
||||
}
|
||||
|
||||
static const uintN TYPE_LIMIT = 8;
|
||||
static JSStringFinalizeOp str_finalizers[TYPE_LIMIT];
|
||||
|
||||
static intN changeFinalizer(JSStringFinalizeOp oldop,
|
||||
JSStringFinalizeOp newop) {
|
||||
for (uintN i = 0; i < mozilla::ArrayLength(str_finalizers); i++) {
|
||||
if (str_finalizers[i] == oldop) {
|
||||
str_finalizers[i] = newop;
|
||||
return intN(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return d.s.u2.externalFinalizer;
|
||||
}
|
||||
|
||||
/* Only called by the GC for strings with the FINALIZE_EXTERNAL_STRING kind. */
|
||||
|
||||
void finalize(JSContext *cx, bool background);
|
||||
void finalize();
|
||||
inline void finalize(JSContext *cx, bool background);
|
||||
inline void finalize();
|
||||
};
|
||||
|
||||
JS_STATIC_ASSERT(sizeof(JSExternalString) == sizeof(JSString));
|
||||
|
@ -73,8 +73,6 @@ using namespace mozilla;
|
||||
|
||||
#define ILLEGAL_CHAR_RANGE(c) (0!=((c) & 0x80))
|
||||
|
||||
static intN sXPCOMUCStringFinalizerIndex = -1;
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
// static
|
||||
@ -116,38 +114,12 @@ XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface)
|
||||
/***************************************************************************/
|
||||
|
||||
static void
|
||||
FinalizeXPCOMUCString(JSContext *cx, JSString *str)
|
||||
FinalizeXPCOMUCString(const JSStringFinalizer *fin, jschar *chars)
|
||||
{
|
||||
NS_ASSERTION(sXPCOMUCStringFinalizerIndex != -1,
|
||||
"XPCConvert: XPCOM Unicode string finalizer called uninitialized!");
|
||||
|
||||
jschar* buffer = const_cast<jschar *>(JS_GetStringCharsZ(cx, str));
|
||||
NS_ASSERTION(buffer, "How could this OOM if we allocated the memory?");
|
||||
nsMemory::Free(buffer);
|
||||
nsMemory::Free(chars);
|
||||
}
|
||||
|
||||
|
||||
static JSBool
|
||||
AddXPCOMUCStringFinalizer()
|
||||
{
|
||||
|
||||
sXPCOMUCStringFinalizerIndex =
|
||||
JS_AddExternalStringFinalizer(FinalizeXPCOMUCString);
|
||||
|
||||
if (sXPCOMUCStringFinalizerIndex == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//static
|
||||
void
|
||||
XPCConvert::RemoveXPCOMUCStringFinalizer()
|
||||
{
|
||||
JS_RemoveExternalStringFinalizer(FinalizeXPCOMUCString);
|
||||
sXPCOMUCStringFinalizerIndex = -1;
|
||||
}
|
||||
static const JSStringFinalizer sXPCOMUCStringFinalizer = { FinalizeXPCOMUCString };
|
||||
|
||||
// static
|
||||
JSBool
|
||||
@ -319,13 +291,9 @@ XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
if (sXPCOMUCStringFinalizerIndex == -1 &&
|
||||
!AddXPCOMUCStringFinalizer())
|
||||
return false;
|
||||
|
||||
JSString* jsString =
|
||||
JS_NewExternalString(cx, p, len,
|
||||
sXPCOMUCStringFinalizerIndex);
|
||||
&sXPCOMUCStringFinalizer);
|
||||
|
||||
if (!jsString) {
|
||||
nsMemory::Free(p);
|
||||
@ -350,14 +318,10 @@ XPCConvert::NativeData2JS(XPCLazyCallContext& lccx, jsval* d, const void* s,
|
||||
if (!unicodeString)
|
||||
return false;
|
||||
|
||||
if (sXPCOMUCStringFinalizerIndex == -1 &&
|
||||
!AddXPCOMUCStringFinalizer())
|
||||
return false;
|
||||
|
||||
JSString* jsString = JS_NewExternalString(cx,
|
||||
(jschar*)unicodeString,
|
||||
cString->Length(),
|
||||
sXPCOMUCStringFinalizerIndex);
|
||||
&sXPCOMUCStringFinalizer);
|
||||
|
||||
if (!jsString) {
|
||||
nsMemory::Free(unicodeString);
|
||||
|
@ -1179,11 +1179,6 @@ XPCJSRuntime::~XPCJSRuntime()
|
||||
delete mExplicitNativeWrapperMap;
|
||||
}
|
||||
|
||||
// unwire the readable/JSString sharing magic
|
||||
XPCStringConvert::ShutdownDOMStringFinalizer();
|
||||
|
||||
XPCConvert::RemoveXPCOMUCStringFinalizer();
|
||||
|
||||
if (mJSHolders.ops) {
|
||||
JS_DHashTableFinish(&mJSHolders);
|
||||
mJSHolders.ops = nsnull;
|
||||
|
@ -58,22 +58,13 @@
|
||||
static int sDOMStringFinalizerIndex = -1;
|
||||
|
||||
static void
|
||||
DOMStringFinalizer(JSContext *cx, JSString *str)
|
||||
FinalizeDOMString(const JSStringFinalizer *fin, jschar *chars)
|
||||
{
|
||||
jschar *chars = const_cast<jschar *>(JS_GetStringCharsZ(cx, str));
|
||||
NS_ASSERTION(chars, "How could this OOM if we allocated the memory?");
|
||||
nsStringBuffer::FromData(chars)->Release();
|
||||
}
|
||||
|
||||
void
|
||||
XPCStringConvert::ShutdownDOMStringFinalizer()
|
||||
{
|
||||
if (sDOMStringFinalizerIndex == -1)
|
||||
return;
|
||||
static const JSStringFinalizer sDOMStringFinalizer = { FinalizeDOMString };
|
||||
|
||||
JS_RemoveExternalStringFinalizer(DOMStringFinalizer);
|
||||
sDOMStringFinalizerIndex = -1;
|
||||
}
|
||||
|
||||
// convert a readable to a JSString, copying string data
|
||||
// static
|
||||
@ -94,16 +85,9 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
|
||||
if (buf) {
|
||||
// yay, we can share the string's buffer!
|
||||
|
||||
if (sDOMStringFinalizerIndex == -1) {
|
||||
sDOMStringFinalizerIndex =
|
||||
JS_AddExternalStringFinalizer(DOMStringFinalizer);
|
||||
if (sDOMStringFinalizerIndex == -1)
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
|
||||
str = JS_NewExternalString(cx,
|
||||
reinterpret_cast<jschar *>(buf->Data()),
|
||||
length, sDOMStringFinalizerIndex);
|
||||
length, &sDOMStringFinalizer);
|
||||
|
||||
if (str) {
|
||||
*sharedBuffer = buf;
|
||||
|
@ -3343,8 +3343,6 @@ public:
|
||||
JSContext* cx,
|
||||
jsval *jsExceptionPtr);
|
||||
|
||||
static void RemoveXPCOMUCStringFinalizer();
|
||||
|
||||
private:
|
||||
XPCConvert(); // not implemented
|
||||
|
||||
@ -3363,8 +3361,6 @@ public:
|
||||
static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
|
||||
nsStringBuffer** sharedBuffer);
|
||||
|
||||
static void ShutdownDOMStringFinalizer();
|
||||
|
||||
private:
|
||||
XPCStringConvert(); // not implemented
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user