50602: Add support in XPConnect for sharing of refcounted string BufferHandles,
in both directions.
72552: Remedy overzealous CHECK_REQUEST placement in jsapi.c, to produce a
minimal-but-complete set of engine entry points that require a Request
for safe execution.
r=brendan, sr=jband, assist=scc,pinkerton
git-svn-id: svn://10.0.0.236/trunk@90483 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
6e92e75066
commit
44326fc42c
Binary file not shown.
@ -89,28 +89,24 @@
|
||||
JS_PUBLIC_API(jsval)
|
||||
JS_GetNaNValue(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(jsval)
|
||||
JS_GetNegativeInfinityValue(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(jsval)
|
||||
JS_GetPositiveInfinityValue(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(jsval)
|
||||
JS_GetEmptyStringValue(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return STRING_TO_JSVAL(cx->runtime->emptyString);
|
||||
}
|
||||
|
||||
@ -599,7 +595,6 @@ JS_TypeOfValue(JSContext *cx, jsval v)
|
||||
JS_PUBLIC_API(const char *)
|
||||
JS_GetTypeName(JSContext *cx, JSType type)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
if ((uintN)type >= (uintN)JSTYPE_LIMIT)
|
||||
return NULL;
|
||||
return js_type_str[type];
|
||||
@ -930,7 +925,6 @@ JS_SetVersion(JSContext *cx, JSVersion version)
|
||||
{
|
||||
JSVersion oldVersion;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
oldVersion = cx->version;
|
||||
if (version == oldVersion)
|
||||
return oldVersion;
|
||||
@ -1423,7 +1417,6 @@ JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetScopeChain(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return cx->fp ? cx->fp->scopeChain : NULL;
|
||||
}
|
||||
|
||||
@ -1495,6 +1488,12 @@ JS_AddRoot(JSContext *cx, void *rp)
|
||||
return js_AddRoot(cx, rp, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name)
|
||||
{
|
||||
return js_AddRootRT(rt, rp, name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveRoot(JSContext *cx, void *rp)
|
||||
{
|
||||
@ -1742,28 +1741,24 @@ JS_IdToValue(JSContext *cx, jsid id, jsval *vp)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_EnumerateStub(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
#if JS_BUG_EAGER_TOSTRING
|
||||
if (type == JSTYPE_STRING)
|
||||
return JS_TRUE;
|
||||
@ -1856,14 +1851,12 @@ bad:
|
||||
JS_PUBLIC_API(JSClass *)
|
||||
JS_GetClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return OBJ_GET_CLASS(cx, obj);
|
||||
}
|
||||
#else
|
||||
JS_PUBLIC_API(JSClass *)
|
||||
JS_GetClass(JSObject *obj)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return LOCKED_OBJ_GET_CLASS(obj);
|
||||
}
|
||||
#endif
|
||||
@ -1893,7 +1886,6 @@ JS_GetPrivate(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
jsval v;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);
|
||||
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
|
||||
if (!JSVAL_IS_INT(v))
|
||||
@ -1904,7 +1896,6 @@ JS_GetPrivate(JSContext *cx, JSObject *obj)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetPrivate(JSContext *cx, JSObject *obj, void *data)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);
|
||||
OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(data));
|
||||
return JS_TRUE;
|
||||
@ -1914,7 +1905,6 @@ JS_PUBLIC_API(void *)
|
||||
JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
|
||||
jsval *argv)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
if (!JS_InstanceOf(cx, obj, clasp, argv))
|
||||
return NULL;
|
||||
return JS_GetPrivate(cx, obj);
|
||||
@ -1947,7 +1937,6 @@ JS_GetParent(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *parent;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
parent = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PARENT));
|
||||
|
||||
/* Beware ref to dead object (we may be called from obj's finalizer). */
|
||||
@ -2495,7 +2484,6 @@ JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_IsArrayObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return OBJ_GET_CLASS(cx, obj) == &js_ArrayClass;
|
||||
}
|
||||
|
||||
@ -3322,7 +3310,6 @@ JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb)
|
||||
{
|
||||
JSBranchCallback oldcb;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
oldcb = cx->branchCallback;
|
||||
cx->branchCallback = cb;
|
||||
return oldcb;
|
||||
@ -3337,7 +3324,6 @@ JS_IsRunning(JSContext *cx)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_IsConstructing(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return cx->fp && cx->fp->constructing;
|
||||
}
|
||||
|
||||
@ -3511,7 +3497,6 @@ JS_ReportError(JSContext *cx, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
va_start(ap, format);
|
||||
js_ReportErrorVA(cx, JSREPORT_ERROR, format, ap);
|
||||
va_end(ap);
|
||||
@ -3523,7 +3508,6 @@ JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
va_start(ap, errorNumber);
|
||||
js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
|
||||
errorNumber, JS_TRUE, ap);
|
||||
@ -3536,7 +3520,6 @@ JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
va_start(ap, errorNumber);
|
||||
js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
|
||||
errorNumber, JS_FALSE, ap);
|
||||
@ -3563,7 +3546,6 @@ JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags,
|
||||
va_list ap;
|
||||
JSBool ok;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
va_start(ap, errorNumber);
|
||||
ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef,
|
||||
errorNumber, JS_TRUE, ap);
|
||||
@ -3579,7 +3561,6 @@ JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags,
|
||||
va_list ap;
|
||||
JSBool ok;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
va_start(ap, errorNumber);
|
||||
ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef,
|
||||
errorNumber, JS_FALSE, ap);
|
||||
@ -3598,7 +3579,6 @@ JS_SetErrorReporter(JSContext *cx, JSErrorReporter er)
|
||||
{
|
||||
JSErrorReporter older;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
older = cx->errorReporter;
|
||||
cx->errorReporter = er;
|
||||
return older;
|
||||
@ -3674,7 +3654,6 @@ JS_ClearRegExpRoots(JSContext *cx)
|
||||
{
|
||||
JSRegExpStatics *res;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
/* No locking required, cx is thread-private and input must be live. */
|
||||
res = &cx->regExpStatics;
|
||||
res->input = NULL;
|
||||
@ -3702,7 +3681,6 @@ JS_GetLocaleCallbacks(JSContext *cx)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_IsExceptionPending(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
#if JS_HAS_EXCEPTIONS
|
||||
return (JSBool) cx->throwing;
|
||||
#else
|
||||
@ -3713,8 +3691,8 @@ JS_IsExceptionPending(JSContext *cx)
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetPendingException(JSContext *cx, jsval *vp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
#if JS_HAS_EXCEPTIONS
|
||||
CHECK_REQUEST(cx);
|
||||
if (!cx->throwing)
|
||||
return JS_FALSE;
|
||||
*vp = cx->exception;
|
||||
@ -3737,7 +3715,6 @@ JS_SetPendingException(JSContext *cx, jsval v)
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ClearPendingException(JSContext *cx)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
#if JS_HAS_EXCEPTIONS
|
||||
cx->throwing = JS_FALSE;
|
||||
#endif
|
||||
|
||||
@ -512,15 +512,18 @@ JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddRoot(JSContext *cx, void *rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRoot(JSContext *cx, void *rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveRoot(JSContext *cx, void *rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveRootRT(JSRuntime *rt, void *rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRoot(JSContext *cx, void *rp, const char *name);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_DumpNamedRoots(JSRuntime *rt,
|
||||
|
||||
@ -373,7 +373,15 @@ js_FinishGC(JSRuntime *rt)
|
||||
JSBool
|
||||
js_AddRoot(JSContext *cx, void *rp, const char *name)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSBool ok = js_AddRootRT(cx->runtime, rp, name);
|
||||
if (!ok)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_AddRootRT(JSRuntime *rt, void *rp, const char *name)
|
||||
{
|
||||
JSBool ok;
|
||||
|
||||
/*
|
||||
@ -389,7 +397,6 @@ js_AddRoot(JSContext *cx, void *rp, const char *name)
|
||||
* of deadlock because the GC doesn't set rt->gcRunning until after it has
|
||||
* waited for all active requests to end.
|
||||
*/
|
||||
rt = cx->runtime;
|
||||
JS_LOCK_GC(rt);
|
||||
#ifdef JS_THREADSAFE
|
||||
JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);
|
||||
@ -401,8 +408,6 @@ js_AddRoot(JSContext *cx, void *rp, const char *name)
|
||||
#endif
|
||||
ok = (JS_HashTableAdd(rt->gcRootsHash, rp, (void *)name) != NULL);
|
||||
JS_UNLOCK_GC(rt);
|
||||
if (!ok)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@ -82,6 +82,9 @@ js_FinishGC(JSRuntime *rt);
|
||||
extern JSBool
|
||||
js_AddRoot(JSContext *cx, void *rp, const char *name);
|
||||
|
||||
extern JSBool
|
||||
js_AddRootRT(JSRuntime *rt, void *rp, const char *name);
|
||||
|
||||
extern JSBool
|
||||
js_RemoveRoot(JSRuntime *rt, void *rp);
|
||||
|
||||
|
||||
@ -172,7 +172,7 @@ interface nsIXPConnectWrappedJS : nsIXPConnectJSObjectHolder
|
||||
|
||||
/**
|
||||
* This is a somewhat special interface. It is available from the global
|
||||
* nsIXPConnect object when native methods have been called. It is only relevent
|
||||
* nsIXPConnect object when native methods have been called. It is only relevant
|
||||
* to the currently called native method on the given JSContext/thread. Holding
|
||||
* a reference past that time (or while other native methods are being called)
|
||||
* will not assure access to this data.
|
||||
|
||||
@ -60,6 +60,7 @@ CPPSRCS = \
|
||||
xpcnativecallcontext.cpp \
|
||||
xpcruntimesvc.cpp \
|
||||
xpcstack.cpp \
|
||||
xpcstring.cpp \
|
||||
xpcthreadcontext.cpp \
|
||||
xpcthrower.cpp \
|
||||
xpcwrappedjs.cpp \
|
||||
|
||||
@ -62,6 +62,7 @@ OBJS= \
|
||||
.\$(OBJDIR)\xpcnativecallcontext.obj \
|
||||
.\$(OBJDIR)\xpcruntimesvc.obj \
|
||||
.\$(OBJDIR)\xpcstack.obj \
|
||||
.\$(OBJDIR)\xpcstring.obj \
|
||||
.\$(OBJDIR)\xpcthreadcontext.obj \
|
||||
.\$(OBJDIR)\xpcthrower.obj \
|
||||
.\$(OBJDIR)\xpcwrappedjs.obj \
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
* Contributor(s):
|
||||
* John Bandhauer <jband@netscape.com>
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
* Mike Shaver <shaver@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
@ -336,11 +337,11 @@ XPCConvert::NativeData2JS(JSContext* cx, jsval* d, const void* s,
|
||||
|
||||
case nsXPTType::T_IID:
|
||||
{
|
||||
nsID* iid = *((nsID**)s);
|
||||
if(!iid)
|
||||
nsID* iid2 = *((nsID**)s);
|
||||
if(!iid2)
|
||||
break;
|
||||
JSObject* obj;
|
||||
if(!(obj = xpc_NewIDObject(cx, scope, *iid)))
|
||||
if(!(obj = xpc_NewIDObject(cx, scope, *iid2)))
|
||||
return JS_FALSE;
|
||||
*d = OBJECT_TO_JSVAL(obj);
|
||||
break;
|
||||
@ -351,28 +352,10 @@ XPCConvert::NativeData2JS(JSContext* cx, jsval* d, const void* s,
|
||||
const nsAReadableString* p = *((const nsAReadableString**)s);
|
||||
if(!p)
|
||||
break;
|
||||
|
||||
PRUint32 length = p->Length();
|
||||
|
||||
jschar* chars = (jschar *)
|
||||
JS_malloc(cx, (length + 1) * sizeof(jschar));
|
||||
if(!chars)
|
||||
return JS_FALSE;
|
||||
JSString *str = XPCStringConvert::ReadableToJSString(cx, *p);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
|
||||
if(length && !CopyUnicodeTo(*p, 0, (PRUnichar*)chars, length))
|
||||
{
|
||||
JS_free(cx, chars);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
chars[length] = 0;
|
||||
|
||||
JSString* str;
|
||||
if(!(str = JS_NewUCString(cx, chars, length)))
|
||||
{
|
||||
JS_free(cx, chars);
|
||||
return JS_FALSE;
|
||||
}
|
||||
*d = STRING_TO_JSVAL(str);
|
||||
break;
|
||||
}
|
||||
@ -440,7 +423,6 @@ XPCConvert::NativeData2JS(JSContext* cx, jsval* d, const void* s,
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
// static
|
||||
JSBool
|
||||
@ -618,8 +600,9 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
|
||||
static const NS_NAMED_LITERAL_STRING(sVoidString, "undefined");
|
||||
|
||||
const PRUnichar* chars;
|
||||
PRUint32 length;
|
||||
JSString* str = nsnull;
|
||||
JSBool isNewString = JS_FALSE;
|
||||
PRUint32 length;
|
||||
|
||||
if(JSVAL_IS_VOID(s))
|
||||
{
|
||||
@ -635,7 +618,7 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
|
||||
}
|
||||
else
|
||||
{
|
||||
JSString* str = JS_ValueToString(cx, s);
|
||||
str = JS_ValueToString(cx, s);
|
||||
if(!str)
|
||||
return JS_FALSE;
|
||||
|
||||
@ -650,6 +633,7 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
|
||||
}
|
||||
else
|
||||
{
|
||||
str = nsnull;
|
||||
chars = sEmptyString.get();
|
||||
}
|
||||
}
|
||||
@ -658,20 +642,27 @@ XPCConvert::JSData2Native(JSContext* cx, void* d, jsval s,
|
||||
|
||||
if(useAllocator)
|
||||
{
|
||||
nsAReadableString* rs;
|
||||
|
||||
// If the underlying JSString may have been created in the
|
||||
// JS_ValueToString call, then we need to make a copied string
|
||||
// to avoid the possibility of the string data being gc'd before
|
||||
// we are done.
|
||||
if(isNewString)
|
||||
rs = new nsString(chars, length);
|
||||
if (str)
|
||||
{
|
||||
XPCReadableJSStringWrapper *wrapper =
|
||||
XPCStringConvert::JSStringToReadable(str);
|
||||
if (!wrapper)
|
||||
return JS_FALSE;
|
||||
|
||||
// Ask for the shared buffer handle, which will root the
|
||||
// string.
|
||||
if (isNewString && ! wrapper->GetSharedBufferHandle())
|
||||
return JS_FALSE;
|
||||
|
||||
*((nsAReadableString**)d) = wrapper;
|
||||
}
|
||||
else
|
||||
rs = new nsLiteralString(chars, length);
|
||||
|
||||
if(!rs)
|
||||
return JS_FALSE;
|
||||
*((nsAReadableString**)d) = rs;
|
||||
{
|
||||
nsAReadableString *rs = new nsString(chars, length);
|
||||
if (!rs)
|
||||
return JS_FALSE;
|
||||
*((nsAReadableString**)d) = rs;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1248,6 +1239,7 @@ XPCConvert::JSErrorToXPCException(JSContext* cx,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
@ -158,10 +158,10 @@ static char* FormatJSFrame(JSContext* cx, JSStackFrame* fp,
|
||||
{
|
||||
for(uint32 k = namedArgCount; k < argCount; k++)
|
||||
{
|
||||
char num[8];
|
||||
JS_snprintf(num, 8, "%d", (int) k);
|
||||
char number[8];
|
||||
JS_snprintf(number, 8, "%d", (int) k);
|
||||
|
||||
if(JS_GetProperty(cx, argsObj, num, &val))
|
||||
if(JS_GetProperty(cx, argsObj, number, &val))
|
||||
{
|
||||
value = JSVAL2String(cx, val, &isString);
|
||||
buf = JS_sprintf_append(buf, "%s%s%s%s",
|
||||
|
||||
@ -383,13 +383,13 @@ nsJSIID::HasInstance(JSContext *cx, JSObject *obj,
|
||||
if(!JSVAL_IS_PRIMITIVE(v))
|
||||
{
|
||||
// we have a JSObject
|
||||
JSObject* obj = JSVAL_TO_OBJECT(v);
|
||||
JSObject* obj2 = JSVAL_TO_OBJECT(v);
|
||||
|
||||
NS_ASSERTION(obj, "when is an object not an object?");
|
||||
NS_ASSERTION(obj2, "when is an object not an object?");
|
||||
|
||||
// is this really a native xpcom object with a wrapper?
|
||||
nsXPCWrappedNative* other_wrapper =
|
||||
nsXPCWrappedNativeClass::GetWrappedNativeOfJSObject(cx,obj);
|
||||
nsXPCWrappedNativeClass::GetWrappedNativeOfJSObject(cx,obj2);
|
||||
|
||||
if(!other_wrapper)
|
||||
return NS_OK;
|
||||
|
||||
@ -225,6 +225,9 @@ XPCJSRuntime::~XPCJSRuntime()
|
||||
printf("deleting XPCJSRuntime with %d live nsXPCWrappedNative (found in wrapper check)\n", (int)LiveWrapperCount);
|
||||
JS_HashTableDestroy(DEBUG_WrappedNativeHashtable);
|
||||
#endif
|
||||
|
||||
// unwire the readable/JSString sharing magic
|
||||
XPCStringConvert::ShutdownDOMStringFinalizer();
|
||||
}
|
||||
|
||||
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
@ -209,8 +209,8 @@ public:
|
||||
static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect,
|
||||
nsIJSRuntimeService* aJSRuntimeService);
|
||||
|
||||
JSRuntime* GetJSRuntime() const {return mJSRuntime;}
|
||||
nsXPConnect* GetXPConnect() const {return mXPConnect;}
|
||||
JSRuntime* GetJSRuntime() const {return mJSRuntime;}
|
||||
nsXPConnect* GetXPConnect() const {return mXPConnect;}
|
||||
|
||||
JSObject2WrappedJSMap* GetWrappedJSMap() const
|
||||
{return mWrappedJSMap;}
|
||||
@ -224,7 +224,7 @@ public:
|
||||
XPCContext* GetXPCContext(JSContext* cx);
|
||||
XPCContext* SyncXPCContextList(JSContext* cx = nsnull);
|
||||
|
||||
|
||||
|
||||
// Mapping of often used strings to jsid atoms that live 'forever'.
|
||||
//
|
||||
// To add a new string: add to this list and to XPCJSRuntime::mStrings
|
||||
@ -1145,7 +1145,7 @@ private:
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
// data convertion
|
||||
// data conversion
|
||||
|
||||
// class here just for static methods
|
||||
class XPCConvert
|
||||
@ -1215,6 +1215,82 @@ public:
|
||||
|
||||
private:
|
||||
XPCConvert(); // not implemented
|
||||
|
||||
};
|
||||
|
||||
// class to export a JSString as an nsAReadableString, including refcounting
|
||||
class XPCReadableJSStringWrapper : public nsLiteralString
|
||||
{
|
||||
public:
|
||||
XPCReadableJSStringWrapper(JSString *str) :
|
||||
nsLiteralString(NS_REINTERPRET_CAST(PRUnichar *,
|
||||
JS_GetStringChars(str)),
|
||||
JS_GetStringLength(str)),
|
||||
mStr(str), mBufferHandle(0), mHandleIsShared(JS_FALSE)
|
||||
{ }
|
||||
|
||||
~XPCReadableJSStringWrapper();
|
||||
|
||||
// buffer-handle accessors
|
||||
const nsBufferHandle<PRUnichar>* GetBufferHandle() const
|
||||
{
|
||||
return BufferHandle(JS_FALSE);
|
||||
}
|
||||
|
||||
const nsSharedBufferHandle<PRUnichar>* GetSharedBufferHandle() const
|
||||
{
|
||||
return BufferHandle(JS_TRUE);
|
||||
}
|
||||
|
||||
protected:
|
||||
struct WrapperBufferHandle :
|
||||
public nsSharedBufferHandleWithAllocator<PRUnichar>
|
||||
{
|
||||
WrapperBufferHandle(XPCReadableJSStringWrapper *outer, JSString *str) :
|
||||
nsSharedBufferHandleWithAllocator<PRUnichar>
|
||||
(NS_CONST_CAST(PRUnichar *, outer->get()),
|
||||
NS_CONST_CAST(PRUnichar *, outer->get() + outer->Length()),
|
||||
mAllocator),
|
||||
mAllocator(str)
|
||||
{ }
|
||||
|
||||
XPCReadableJSStringWrapper *mOuter;
|
||||
|
||||
struct Allocator : nsStringAllocator<PRUnichar>
|
||||
{
|
||||
Allocator(JSString *str) : mStr(OBJECT_TO_JSVAL(str)) { }
|
||||
virtual ~Allocator() { }
|
||||
|
||||
virtual void Deallocate(PRUnichar *) const;
|
||||
|
||||
JSBool RootString();
|
||||
jsval mStr;
|
||||
};
|
||||
|
||||
Allocator mAllocator;
|
||||
};
|
||||
|
||||
const nsSharedBufferHandle<PRUnichar>* BufferHandle(JSBool shared) const;
|
||||
|
||||
JSString *mStr;
|
||||
WrapperBufferHandle *mBufferHandle;
|
||||
JSBool mHandleIsShared;
|
||||
};
|
||||
|
||||
// readable string conversions, static methods only
|
||||
class XPCStringConvert
|
||||
{
|
||||
public:
|
||||
|
||||
static JSString *ReadableToJSString(JSContext *cx,
|
||||
const nsAReadableString &readable);
|
||||
|
||||
static XPCReadableJSStringWrapper *JSStringToReadable(JSString *str);
|
||||
|
||||
static void ShutdownDOMStringFinalizer();
|
||||
|
||||
private:
|
||||
XPCStringConvert(); // not implemented
|
||||
};
|
||||
|
||||
extern JSBool JS_DLL_CALLBACK
|
||||
|
||||
@ -54,7 +54,7 @@ nsJSRuntimeServiceImpl::~nsJSRuntimeServiceImpl() {
|
||||
JS_DestroyRuntime(mRuntime);
|
||||
JS_ShutDown();
|
||||
#ifdef DEBUG_shaver
|
||||
fprintf(stderr, "nJRSI: destroyed runtime %p\n", mRuntime);
|
||||
fprintf(stderr, "nJRSI: destroyed runtime %p\n", (void *)mRuntime);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -98,7 +98,7 @@ nsJSRuntimeServiceImpl::GetRuntime(JSRuntime **runtime)
|
||||
}
|
||||
*runtime = mRuntime;
|
||||
#ifdef DEBUG_shaver
|
||||
fprintf(stderr, "nJRSI: returning %p\n", mRuntime);
|
||||
fprintf(stderr, "nJRSI: returning %p\n", (void *)mRuntime);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
300
mozilla/js/src/xpconnect/src/xpcstring.cpp
Normal file
300
mozilla/js/src/xpconnect/src/xpcstring.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mike Shaver <shaver@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Infrastructure for sharing DOMString data with JSStrings.
|
||||
*
|
||||
* Importing an nsAReadableString into JS:
|
||||
* If possible (GetSharedBufferHandle works) use the external string support in
|
||||
* JS to create a JSString that points to the readable's buffer. We keep a
|
||||
* reference to the buffer handle until the JSString is finalized.
|
||||
*
|
||||
* Exporting a JSString as an nsAReadable:
|
||||
* Wrap the JSString with a root-holding XPCJSReadableStringWrapper, which roots
|
||||
* the string and exposes its buffer via the nsAReadableString interface, as
|
||||
* well as providing refcounting support.
|
||||
*/
|
||||
|
||||
#include "xpcprivate.h"
|
||||
#include "nscore.h"
|
||||
|
||||
/*
|
||||
* We require that STRING_TO_JSVAL(s) != (jsval)s, for tracking rootedness.
|
||||
* When we colonize Mars and change JSVAL_STRING, we'll need to update this
|
||||
* code.
|
||||
*/
|
||||
#if JSVAL_STRING == 0
|
||||
#error "JSVAL_STRING has zero value -- need to fix root management!"
|
||||
#endif
|
||||
|
||||
XPCReadableJSStringWrapper::~XPCReadableJSStringWrapper()
|
||||
{
|
||||
if (mBufferHandle)
|
||||
{
|
||||
if (mHandleIsShared)
|
||||
{
|
||||
mBufferHandle->ReleaseReference();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete mBufferHandle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nsSharedBufferHandle<PRUnichar>*
|
||||
XPCReadableJSStringWrapper::BufferHandle(JSBool shared) const
|
||||
{
|
||||
XPCReadableJSStringWrapper * mutable_this =
|
||||
NS_CONST_CAST(XPCReadableJSStringWrapper *, this);
|
||||
|
||||
if (!mBufferHandle)
|
||||
{
|
||||
mutable_this->mBufferHandle =
|
||||
new WrapperBufferHandle(mutable_this, mStr);
|
||||
|
||||
}
|
||||
|
||||
if (shared && !mHandleIsShared)
|
||||
{
|
||||
mutable_this->mBufferHandle->AcquireReference();
|
||||
mutable_this->mBufferHandle->mAllocator.RootString();
|
||||
mutable_this->mHandleIsShared = JS_TRUE;
|
||||
}
|
||||
|
||||
return mBufferHandle;
|
||||
}
|
||||
|
||||
void
|
||||
XPCReadableJSStringWrapper::WrapperBufferHandle::Allocator::
|
||||
Deallocate(PRUnichar *) const
|
||||
{
|
||||
if (JSVAL_IS_STRING(mStr))
|
||||
{
|
||||
// unroot
|
||||
JSRuntime *rt;
|
||||
nsCOMPtr<nsIJSRuntimeService> rtsvc =
|
||||
nsJSRuntimeServiceImpl::GetSingleton();
|
||||
if (rtsvc && NS_SUCCEEDED(rtsvc->GetRuntime(&rt)))
|
||||
{
|
||||
JS_RemoveRootRT(rt,
|
||||
NS_CONST_CAST(void **,
|
||||
NS_REINTERPRET_CAST(void * const *,
|
||||
&mStr)));
|
||||
Allocator *mutable_this = NS_CONST_CAST(Allocator *, this);
|
||||
// store untagged to indicate that we're not rooted
|
||||
mutable_this->mStr = NS_REINTERPRET_CAST(jsval,
|
||||
JSVAL_TO_STRING(mStr));
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ERROR("Unable to unroot mStr! Prepare for leak or crash!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSBool
|
||||
XPCReadableJSStringWrapper::WrapperBufferHandle::Allocator::RootString()
|
||||
{
|
||||
JSRuntime *rt;
|
||||
nsCOMPtr<nsIJSRuntimeService> rtsvc =
|
||||
nsJSRuntimeServiceImpl::GetSingleton();
|
||||
JSBool ok = rtsvc &&
|
||||
NS_SUCCEEDED(rtsvc->GetRuntime(&rt)) &&
|
||||
JS_AddNamedRootRT(rt,
|
||||
NS_CONST_CAST(void **,
|
||||
NS_REINTERPRET_CAST(void * const *,
|
||||
&mStr)),
|
||||
"WrapperBufferHandle.mAllocator.mStr");
|
||||
if (ok)
|
||||
{
|
||||
// Indicate that we've rooted the string by storing it as a
|
||||
// string-tagged jsval
|
||||
mStr = STRING_TO_JSVAL(NS_REINTERPRET_CAST(jsval, mStr));
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// structure for entry in the DOMStringTable
|
||||
struct SharedStringEntry : public JSDHashEntryHdr {
|
||||
void *key;
|
||||
const nsSharedBufferHandle<PRUnichar> *handle;
|
||||
};
|
||||
|
||||
// table to match JSStrings to their handles at finalization time
|
||||
static JSDHashTable DOMStringTable;
|
||||
static intN DOMStringFinalizerIndex = -1;
|
||||
|
||||
// unref the appropriate handle when the matching string is finalized
|
||||
static void
|
||||
FinalizeDOMString(JSContext *cx, JSString *str)
|
||||
{
|
||||
NS_ASSERTION(DOMStringFinalizerIndex != -1,
|
||||
"XPCConvert: DOM string finalizer called uninitialized!");
|
||||
|
||||
SharedStringEntry *entry =
|
||||
NS_STATIC_CAST(SharedStringEntry *,
|
||||
JS_DHashTableOperate(&DOMStringTable, str,
|
||||
JS_DHASH_LOOKUP));
|
||||
|
||||
// entry might be empty if we ran out of memory adding it to the hash
|
||||
if (JS_DHASH_ENTRY_IS_BUSY(entry))
|
||||
{
|
||||
entry->handle->ReleaseReference();
|
||||
(void) JS_DHashTableOperate(&DOMStringTable, str, JS_DHASH_REMOVE);
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the aforementioned hash table and register our external finalizer
|
||||
static JSBool
|
||||
InitializeDOMStringFinalizer()
|
||||
{
|
||||
if (!JS_DHashTableInit(&DOMStringTable, JS_DHashGetStubOps(), NULL,
|
||||
sizeof(SharedStringEntry), JS_DHASH_MIN_SIZE))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
DOMStringFinalizerIndex =
|
||||
JS_AddExternalStringFinalizer(FinalizeDOMString);
|
||||
|
||||
if (DOMStringFinalizerIndex == -1)
|
||||
{
|
||||
JS_DHashTableFinish(&DOMStringTable);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// cleanup enumerator for the DOMStringTable
|
||||
static JSDHashOperator
|
||||
ReleaseHandleAndRemove(JSDHashTable *table, JSDHashEntryHdr *hdr,
|
||||
uint32 number, void *arg)
|
||||
{
|
||||
SharedStringEntry *entry = NS_STATIC_CAST(SharedStringEntry *, hdr);
|
||||
entry->handle->ReleaseReference();
|
||||
return JS_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
// clean up the finalizer infrastructure, releasing all outstanding handles
|
||||
// static
|
||||
void
|
||||
XPCStringConvert::ShutdownDOMStringFinalizer()
|
||||
{
|
||||
if (DOMStringFinalizerIndex == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// enumerate and release
|
||||
(void)JS_DHashTableEnumerate(&DOMStringTable, ReleaseHandleAndRemove, NULL);
|
||||
|
||||
JS_DHashTableFinish(&DOMStringTable);
|
||||
DOMStringFinalizerIndex =
|
||||
JS_RemoveExternalStringFinalizer(FinalizeDOMString);
|
||||
|
||||
DOMStringFinalizerIndex = -1;
|
||||
}
|
||||
|
||||
// convert a readable to a JSString, sharing if possible and copying otherwise
|
||||
// static
|
||||
JSString *
|
||||
XPCStringConvert::ReadableToJSString(JSContext *cx,
|
||||
const nsAReadableString &readable)
|
||||
{
|
||||
const nsSharedBufferHandle<PRUnichar> *handle;
|
||||
handle = readable.GetSharedBufferHandle();
|
||||
|
||||
JSString *str;
|
||||
if (!handle || NS_REINTERPRET_CAST(int, handle) == 1)
|
||||
{
|
||||
// blech, have to copy.
|
||||
PRUint32 length = readable.Length();
|
||||
jschar *chars = NS_REINTERPRET_CAST(jschar *,
|
||||
JS_malloc(cx, (length + 1) *
|
||||
sizeof(jschar)));
|
||||
if (!chars)
|
||||
return NULL;
|
||||
|
||||
if (length && !CopyUnicodeTo(readable, 0,
|
||||
NS_REINTERPRET_CAST(PRUnichar *, chars),
|
||||
length))
|
||||
{
|
||||
JS_free(cx, chars);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chars[length] = 0;
|
||||
|
||||
str = JS_NewUCString(cx, chars, length);
|
||||
if (!str)
|
||||
JS_free(cx, chars);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
if (DOMStringFinalizerIndex == -1 && !InitializeDOMStringFinalizer())
|
||||
return NULL;
|
||||
|
||||
str = JS_NewExternalString(cx,
|
||||
NS_CONST_CAST(jschar *,
|
||||
NS_REINTERPRET_CAST(const jschar *,
|
||||
handle->DataStart())),
|
||||
handle->DataLength(),
|
||||
DOMStringFinalizerIndex);
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
SharedStringEntry *entry =
|
||||
NS_STATIC_CAST(SharedStringEntry *,
|
||||
JS_DHashTableOperate(&DOMStringTable, str,
|
||||
JS_DHASH_ADD));
|
||||
|
||||
if (!entry)
|
||||
return NULL; // str will be cleaned up by GC
|
||||
|
||||
entry->handle = handle;
|
||||
entry->key = str;
|
||||
handle->AcquireReference();
|
||||
return str;
|
||||
}
|
||||
|
||||
// static
|
||||
XPCReadableJSStringWrapper *
|
||||
XPCStringConvert::JSStringToReadable(JSString *str)
|
||||
{
|
||||
return new XPCReadableJSStringWrapper(str);
|
||||
}
|
||||
@ -59,6 +59,7 @@ CPPSRCS = \
|
||||
xpctest_inout.cpp \
|
||||
xpctest_multiple.cpp \
|
||||
xpctest_out.cpp \
|
||||
xpctest_domstring.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
|
||||
@ -57,6 +57,7 @@ OBJS= \
|
||||
.\$(OBJDIR)\xpctest_inout.obj \
|
||||
.\$(OBJDIR)\xpctest_calljs.obj \
|
||||
.\$(OBJDIR)\xpctest_multiple.obj\
|
||||
.\$(OBJDIR)\xpctest_domstring.obj \
|
||||
$(NULL)
|
||||
|
||||
LINCS=-I$(PUBLIC)\xpconnect -I$(PUBLIC)\xpcom -I$(PUBLIC)\js \
|
||||
|
||||
124
mozilla/js/src/xpconnect/tests/components/xpctest_domstring.cpp
Normal file
124
mozilla/js/src/xpconnect/tests/components/xpctest_domstring.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mike Shaver <shaver@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
#include "xpctest_domstring.h"
|
||||
#include "xpctest_private.h"
|
||||
|
||||
class xpcTestDOMString : public nsIXPCTestDOMString {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIXPCTESTDOMSTRING
|
||||
xpcTestDOMString();
|
||||
virtual ~xpcTestDOMString();
|
||||
private:
|
||||
const nsSharedBufferHandle<PRUnichar> *mHandle;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(xpcTestDOMString, nsIXPCTestDOMString);
|
||||
|
||||
xpcTestDOMString::xpcTestDOMString()
|
||||
: mHandle(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
NS_ADDREF_THIS();
|
||||
}
|
||||
|
||||
xpcTestDOMString::~xpcTestDOMString()
|
||||
{
|
||||
if (mHandle)
|
||||
mHandle->ReleaseReference();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcTestDOMString::HereHaveADOMString(const nsAReadableString &str)
|
||||
{
|
||||
const nsSharedBufferHandle<PRUnichar> *handle;
|
||||
handle = str.GetSharedBufferHandle();
|
||||
if (!handle || int(handle) == 1)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (mHandle)
|
||||
mHandle->ReleaseReference();
|
||||
mHandle = handle;
|
||||
mHandle->AcquireReference();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcTestDOMString::DontKeepThisOne(const nsAReadableString &str)
|
||||
{
|
||||
nsCString c; c.AssignWithConversion(str);
|
||||
fprintf(stderr, "xpcTestDOMString::DontKeepThisOne: \"%s\"\n", c.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcTestDOMString::GiveDOMStringTo(nsIXPCTestDOMString *recv)
|
||||
{
|
||||
NS_NAMED_LITERAL_STRING(myString, "A DOM String, Just For You");
|
||||
return recv->HereHaveADOMString(myString);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcTestDOMString::PassDOMStringThroughTo(const nsAReadableString &str,
|
||||
nsIXPCTestDOMString *recv)
|
||||
{
|
||||
return recv->HereHaveADOMString(str);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpctest::ConstructXPCTestDOMString(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(!aOuter, "no aggregation");
|
||||
xpcTestDOMString *obj = new xpcTestDOMString();
|
||||
if (obj)
|
||||
{
|
||||
rv = obj->QueryInterface(aIID, aResult);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
|
||||
NS_RELEASE(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
*aResult = nsnull;
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -64,7 +64,8 @@ static nsModuleComponentInfo components[] = {
|
||||
{nsnull, NS_XPCTESTCHILD3_CID, "@mozilla.org/js/xpc/test/Child3;1", xpctest::ConstructXPCTestChild3 },
|
||||
{nsnull, NS_XPCTESTCHILD4_CID, "@mozilla.org/js/xpc/test/Child4;1", xpctest::ConstructXPCTestChild4 },
|
||||
{nsnull, NS_XPCTESTCHILD5_CID, "@mozilla.org/js/xpc/test/Child5;1", xpctest::ConstructXPCTestChild5 },
|
||||
{nsnull, NS_ARRAY_CID, "@mozilla.org/js/xpc/test/ArrayTest;1", xpctest::ConstructArrayTest }
|
||||
{nsnull, NS_ARRAY_CID, "@mozilla.org/js/xpc/test/ArrayTest;1", xpctest::ConstructArrayTest },
|
||||
{nsnull, NS_XPCTESTDOMSTRING_CID, "@mozilla.org/js/xpc/test/DOMString;1", xpctest::ConstructXPCTestDOMString }
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("xpconnect test", components)
|
||||
|
||||
@ -144,6 +144,11 @@
|
||||
{ 0x5b9af380, 0x6569, 0x11d3, \
|
||||
{ 0x98, 0x9e, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
|
||||
|
||||
// {DB569F7E-16FB-4BCB-A86C-E08AA7F97666}
|
||||
#define NS_XPCTESTDOMSTRING_CID \
|
||||
{0xdb569f7e, 0x16fb, 0x1bcb, \
|
||||
{ 0xa8, 0x6c, 0xe0, 0x8a, 0xa7, 0xf9, 0x76, 0x66 }}
|
||||
|
||||
// 'namespace' class
|
||||
class xpctest
|
||||
{
|
||||
@ -167,6 +172,7 @@ public:
|
||||
static NS_METHOD ConstructXPCTestChild4(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
static NS_METHOD ConstructXPCTestChild5(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
static NS_METHOD ConstructArrayTest(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
static NS_METHOD ConstructXPCTestDOMString(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
private:
|
||||
xpctest(); // not implemented
|
||||
|
||||
@ -49,6 +49,7 @@ XPIDLSRCS = \
|
||||
xpctest_in.idl \
|
||||
xpctest_inout.idl \
|
||||
xpctest_multiple.idl \
|
||||
xpctest_domstring.idl \
|
||||
xpctest_out.idl \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@ -45,6 +45,7 @@ XPIDLSRCS = \
|
||||
.\xpctest_inout.idl \
|
||||
.\xpctest_multiple.idl \
|
||||
.\xpctest_out.idl \
|
||||
.\xpctest_domstring.idl \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
54
mozilla/js/src/xpconnect/tests/idl/xpctest_domstring.idl
Normal file
54
mozilla/js/src/xpconnect/tests/idl/xpctest_domstring.idl
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mike Shaver <shaver@mozilla.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/**
|
||||
* Interface for testing the DOMString-conversion infrastructure.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(646d0b6b-6872-43b9-aa73-3c6b89ac3080)]
|
||||
interface nsIXPCTestDOMString : nsISupports {
|
||||
// Implementation should ask for the shared buffer interface and hold
|
||||
// a refcount to it.
|
||||
void hereHaveADOMString(in DOMString str);
|
||||
|
||||
// don't hold onto this one
|
||||
void dontKeepThisOne(in DOMString str);
|
||||
|
||||
void giveDOMStringTo(in nsIXPCTestDOMString recv);
|
||||
|
||||
void passDOMStringThroughTo(in DOMString str, in nsIXPCTestDOMString recv);
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user