- made nsJSCID's createInstance and getService work as attributes using nsIXPCScriptable::call to support security and sevicemanager protocol.

- made xpccontext strings id scheme more generic.
- fixed stupif IID hash function.
- fixed nsIXPCScriptable call and construct to work with the correct function object.
- added gc and dump (using xpclog) to xpcshell.
This commit is contained in:
jband%netscape.com 1999-04-13 04:15:36 +00:00
Родитель 3638cc03ab
Коммит a0a7da258c
15 изменённых файлов: 503 добавлений и 75 удалений

Просмотреть файл

@ -44,8 +44,10 @@ interface nsIJSIID : nsIJSID
[scriptable, uuid(e3a24a60-d651-11d2-9843-006008962422)] [scriptable, uuid(e3a24a60-d651-11d2-9843-006008962422)]
interface nsIJSCID : nsIJSID interface nsIJSCID : nsIJSID
{ {
nsISupports createInstance(); // these are attributes that are made to be called
nsISupports getService(); // as methods from JavaScript only.
readonly attribute nsISupports createInstance;
readonly attribute nsISupports getService;
}; };
/* this goes into the C++ header verbatim. */ /* this goes into the C++ header verbatim. */

Просмотреть файл

@ -81,11 +81,11 @@ class nsIJSCID : public nsIJSID {
public: public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IJSCID_IID) NS_DEFINE_STATIC_IID_ACCESSOR(NS_IJSCID_IID)
/* nsISupports createInstance (); */ /* readonly attribute nsISupports createInstance; */
NS_IMETHOD createInstance(nsISupports **_retval) = 0; NS_IMETHOD GetCreateInstance(nsISupports * *aCreateInstance) = 0;
/* nsISupports getService (); */ /* readonly attribute nsISupports getService; */
NS_IMETHOD getService(nsISupports **_retval) = 0; NS_IMETHOD GetGetService(nsISupports * *aGetService) = 0;
#ifdef XPIDL_JS_STUBS #ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx); static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);

Просмотреть файл

@ -186,12 +186,68 @@ Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return JS_FALSE; return JS_FALSE;
} }
static JSBool
Dump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
int32 depth = 2;
if (argc > 0) {
if (!JS_ValueToInt32(cx, argv[0], &depth))
return JS_FALSE;
}
XPC_DUMP(XPC_GetXPConnect(), depth);
return JS_TRUE;
}
static JSBool
GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSRuntime *rt;
uint32 preBytes;
rt = cx->runtime;
preBytes = rt->gcBytes;
#ifdef GC_MARK_DEBUG
if (argc && JSVAL_IS_STRING(argv[0])) {
char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
FILE *file = fopen(name, "w");
if (!file) {
fprintf(gErrFile, "gc: can't open %s: %s\n", strerror(errno));
return JS_FALSE;
}
js_DumpGCHeap = file;
} else {
js_DumpGCHeap = stdout;
}
#endif
js_ForceGC(cx);
#ifdef GC_MARK_DEBUG
if (js_DumpGCHeap != stdout)
fclose(js_DumpGCHeap);
js_DumpGCHeap = NULL;
#endif
fprintf(gOutFile, "before %lu, after %lu, break %08lx\n",
(unsigned long)preBytes, (unsigned long)rt->gcBytes,
#ifdef XP_UNIX
(unsigned long)sbrk(0)
#else
0
#endif
);
#ifdef JS_GCMETER
js_DumpGCStats(rt, stdout);
#endif
return JS_TRUE;
}
static JSFunctionSpec glob_functions[] = { static JSFunctionSpec glob_functions[] = {
{"print", Print, 0}, {"print", Print, 0},
{"load", Load, 1}, {"load", Load, 1},
{"quit", Quit, 0}, {"quit", Quit, 0},
{"version", Version, 1}, {"version", Version, 1},
{"build", BuildDate, 0}, {"build", BuildDate, 0},
{"dump", Dump, 1},
{"gc", GC, 0},
{0} {0}
}; };

Просмотреть файл

@ -360,7 +360,7 @@ ComponentsScriptable::GetProperty(JSContext *cx, JSObject *obj,
*retval = JS_TRUE; *retval = JS_TRUE;
XPCContext* xpcc = nsXPConnect::GetContext(cx); XPCContext* xpcc = nsXPConnect::GetContext(cx);
if(xpcc && xpcc->GetLastResultStrID() == id) if(xpcc && xpcc->GetStringID(XPCContext::IDX_LAST_RESULT) == id)
{ {
if(JS_NewDoubleValue(cx, (jsdouble) (PRInt32)xpcc->GetLastResult(), vp)) if(JS_NewDoubleValue(cx, (jsdouble) (PRInt32)xpcc->GetLastResult(), vp))
return NS_OK; return NS_OK;

Просмотреть файл

@ -20,6 +20,12 @@
#include "xpcprivate.h" #include "xpcprivate.h"
const char* XPCContext::mStrings[] = {
"constructor", // IDX_CONSTRUCTOR
"toString", // IDX_TO_STRING
"lastResult" // IDX_LAST_RESULT
};
// static // static
XPCContext* XPCContext*
XPCContext::newXPCContext(JSContext* aJSContext, XPCContext::newXPCContext(JSContext* aJSContext,
@ -50,8 +56,7 @@ XPCContext::newXPCContext(JSContext* aJSContext,
xpcc->GetWrappedNativeMap() && xpcc->GetWrappedNativeMap() &&
xpcc->GetWrappedJSClassMap() && xpcc->GetWrappedJSClassMap() &&
xpcc->GetWrappedNativeClassMap() && xpcc->GetWrappedNativeClassMap() &&
xpcc->mConstuctorStrID && xpcc->mStrIDs[0])
xpcc->mToStringStrID)
{ {
return xpcc; return xpcc;
} }
@ -73,15 +78,17 @@ XPCContext::XPCContext(JSContext* aJSContext,
mWrappedNativeMap = Native2WrappedNativeMap::newMap(WrappedNativeMapSize); mWrappedNativeMap = Native2WrappedNativeMap::newMap(WrappedNativeMapSize);
mWrappedJSClassMap = IID2WrappedJSClassMap::newMap(WrappedJSClassMapSize); mWrappedJSClassMap = IID2WrappedJSClassMap::newMap(WrappedJSClassMapSize);
mWrappedNativeClassMap = IID2WrappedNativeClassMap::newMap(WrappedNativeClassMapSize); mWrappedNativeClassMap = IID2WrappedNativeClassMap::newMap(WrappedNativeClassMapSize);
JS_ValueToId(aJSContext, for(uintN i = 0; i < IDX_TOTAL_COUNT; i++)
STRING_TO_JSVAL(JS_InternString(aJSContext, "constructor")), {
&mConstuctorStrID); JS_ValueToId(aJSContext,
JS_ValueToId(aJSContext, STRING_TO_JSVAL(JS_InternString(aJSContext, mStrings[i])),
STRING_TO_JSVAL(JS_InternString(aJSContext, "toString")), &mStrIDs[i]);
&mToStringStrID); if(!mStrIDs[i])
JS_ValueToId(aJSContext, {
STRING_TO_JSVAL(JS_InternString(aJSContext, "lastResult")), mStrIDs[0] = 0;
&mLastResultStrID); break;
}
}
mLastResult = NS_OK; mLastResult = NS_OK;
} }

Просмотреть файл

@ -231,6 +231,357 @@ nsJSIID::toString(char **_retval)
return GetName(_retval); return GetName(_retval);
} }
/***************************************************************************/
/***************************************************************************/
/*
* nsJSCID supports 'createInstance' and 'getService'. These are implemented
* using the (somewhat complex) nsIXPCScriptable scheme so that when called
* they can do security checks (knows in which JSContect is calling) and also
* so that 'getService' can add a fancy FinalizeListener to follow the
* ServiceManager's protocol for releasing a service.
*/
class CIDCreateInstanceScriptable : public nsIXPCScriptable
{
public:
NS_DECL_ISUPPORTS
XPC_DECLARE_IXPCSCRIPTABLE
CIDCreateInstanceScriptable();
virtual ~CIDCreateInstanceScriptable();
};
// {16A43B00-F116-11d2-985A-006008962422}
#define NS_CIDCREATEINSTANCE_IID \
{ 0x16a43b00, 0xf116, 0x11d2, \
{ 0x98, 0x5a, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
class CIDCreateInstance : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_CIDCREATEINSTANCE_IID)
NS_DECL_ISUPPORTS
CIDCreateInstance(nsJSCID* aCID);
virtual ~CIDCreateInstance();
nsJSCID* GetCID() const {return mCID;}
private:
CIDCreateInstance(); // not implemented
static CIDCreateInstanceScriptable* GetScriptable();
nsJSCID* mCID;
};
/**********************************************/
CIDCreateInstanceScriptable::CIDCreateInstanceScriptable()
{
NS_INIT_REFCNT();
NS_ADDREF_THIS();
}
CIDCreateInstanceScriptable::~CIDCreateInstanceScriptable() {}
static NS_DEFINE_IID(kCIDCreateInstanceScriptableIID, NS_IXPCSCRIPTABLE_IID);
NS_IMPL_ISUPPORTS(CIDCreateInstanceScriptable, kCIDCreateInstanceScriptableIID);
XPC_IMPLEMENT_FORWARD_CREATE(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_LOOKUPPROPERTY(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_DEFINEPROPERTY(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_GETPROPERTY(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_SETPROPERTY(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_GETATTRIBUTES(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_SETATTRIBUTES(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_DELETEPROPERTY(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_FORWARD_DEFAULTVALUE(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_FORWARD_ENUMERATE(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_FORWARD_CHECKACCESS(CIDCreateInstanceScriptable);
// XPC_IMPLEMENT_IGNORE_CALL(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_IGNORE_CONSTRUCT(CIDCreateInstanceScriptable);
XPC_IMPLEMENT_FORWARD_FINALIZE(CIDCreateInstanceScriptable);
NS_IMETHODIMP
CIDCreateInstanceScriptable::Call(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv,
jsval *rval,
nsIXPConnectWrappedNative* wrapper,
nsIXPCScriptable* arbitrary,
JSBool* retval)
{
CIDCreateInstance* self;
nsJSCID* cidObj;
nsCID* cid;
PRBool valid;
if(NS_FAILED(wrapper->GetNative((nsISupports**)&self)) ||
!(cidObj = self->GetCID()) ||
NS_FAILED(cidObj->GetValid(&valid)) ||
!valid ||
NS_FAILED(cidObj->GetId(&cid)) ||
!cid)
{
return NS_ERROR_FAILURE;
}
nsISupports* inst;
nsresult rv;
// XXX can do security check here (don't forget to free cid)
// XXX could allow for passing an IID
rv = nsComponentManager::CreateInstance(*cid, NULL,
nsISupports::GetIID(),
(void**) &inst);
nsAllocator::Free(cid);
if(NS_FAILED(rv))
return NS_ERROR_FAILURE;
nsIXPConnectWrappedNative* instWrapper;
rv = XPC_GetXPConnect()->WrapNative(cx, inst, nsISupports::GetIID(),
&instWrapper);
NS_RELEASE(inst);
if(NS_FAILED(rv) || !instWrapper)
return NS_ERROR_FAILURE;
JSObject* instJSObj;
instWrapper->GetJSObject(&instJSObj);
*rval = OBJECT_TO_JSVAL(instJSObj);
*retval = JS_TRUE;
NS_RELEASE(instWrapper);
return NS_OK;
}
/*********************************************/
NS_IMPL_QUERY_INTERFACE_SCRIPTABLE(CIDCreateInstance, GetScriptable())
NS_IMPL_ADDREF(CIDCreateInstance)
NS_IMPL_RELEASE(CIDCreateInstance)
CIDCreateInstance::CIDCreateInstance(nsJSCID *aCID)
: mCID(aCID)
{
NS_PRECONDITION(mCID, "bad cid");
NS_INIT_ISUPPORTS();
NS_ADDREF_THIS();
NS_ADDREF(mCID);
}
CIDCreateInstance::~CIDCreateInstance()
{
if(mCID)
NS_RELEASE(mCID);
}
// static
CIDCreateInstanceScriptable*
CIDCreateInstance::GetScriptable()
{
static CIDCreateInstanceScriptable* scriptable = NULL;
// we leak this singleton
if(!scriptable)
scriptable = new CIDCreateInstanceScriptable();
return scriptable;
}
/***************************************************************************/
class CIDGetServiceScriptable : public nsIXPCScriptable
{
public:
NS_DECL_ISUPPORTS
XPC_DECLARE_IXPCSCRIPTABLE
CIDGetServiceScriptable();
virtual ~CIDGetServiceScriptable();
};
// {C46BC320-F13E-11d2-985A-006008962422}
#define NS_CIDGETSERVICE_IID \
{ 0xc46bc320, 0xf13e, 0x11d2, \
{ 0x98, 0x5a, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
class CIDGetService : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_CIDGETSERVICE_IID)
NS_DECL_ISUPPORTS
CIDGetService(nsJSCID* aCID);
virtual ~CIDGetService();
nsJSCID* GetCID() const {return mCID;}
private:
CIDGetService(); // not implemented
static CIDGetServiceScriptable* CIDGetService::GetScriptable();
nsJSCID* mCID;
};
/**********************************************/
// {23423AA0-F142-11d2-985A-006008962422}
#define NS_SERVICE_RELEASER_IID \
{ 0x23423aa0, 0xf142, 0x11d2, \
{ 0x98, 0x5a, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
class ServiceReleaser : public nsIXPConnectFinalizeListener
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_SERVICE_RELEASER_IID)
NS_DECL_ISUPPORTS
NS_IMETHOD AboutToRelease(nsISupports* aObj);
ServiceReleaser(const nsCID& aCID);
private:
ServiceReleaser(); // not implemented
virtual ~ServiceReleaser();
nsCID mCID;
};
static NS_DEFINE_IID(kServiceReleaserIID, NS_SERVICE_RELEASER_IID);
NS_IMPL_ISUPPORTS(ServiceReleaser, kServiceReleaserIID);
ServiceReleaser::ServiceReleaser(const nsCID& aCID)
: mCID(aCID)
{
NS_INIT_ISUPPORTS();
NS_ADDREF_THIS();
}
ServiceReleaser::~ServiceReleaser() {}
NS_IMETHODIMP
ServiceReleaser::AboutToRelease(nsISupports* aObj)
{
return nsServiceManager::ReleaseService(mCID, aObj, NULL);
}
/**********************************************/
CIDGetServiceScriptable::CIDGetServiceScriptable()
{
NS_INIT_REFCNT();
NS_ADDREF_THIS();
}
CIDGetServiceScriptable::~CIDGetServiceScriptable() {}
static NS_DEFINE_IID(kCIDGetServiceScriptableIID, NS_IXPCSCRIPTABLE_IID);
NS_IMPL_ISUPPORTS(CIDGetServiceScriptable, kCIDGetServiceScriptableIID);
XPC_IMPLEMENT_FORWARD_CREATE(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_LOOKUPPROPERTY(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_DEFINEPROPERTY(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_GETPROPERTY(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_SETPROPERTY(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_GETATTRIBUTES(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_SETATTRIBUTES(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_DELETEPROPERTY(CIDGetServiceScriptable);
XPC_IMPLEMENT_FORWARD_DEFAULTVALUE(CIDGetServiceScriptable);
XPC_IMPLEMENT_FORWARD_ENUMERATE(CIDGetServiceScriptable);
XPC_IMPLEMENT_FORWARD_CHECKACCESS(CIDGetServiceScriptable);
// XPC_IMPLEMENT_IGNORE_CALL(CIDGetServiceScriptable);
XPC_IMPLEMENT_IGNORE_CONSTRUCT(CIDGetServiceScriptable);
XPC_IMPLEMENT_FORWARD_FINALIZE(CIDGetServiceScriptable);
NS_IMETHODIMP
CIDGetServiceScriptable::Call(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv,
jsval *rval,
nsIXPConnectWrappedNative* wrapper,
nsIXPCScriptable* arbitrary,
JSBool* retval)
{
CIDGetService* self;
nsJSCID* cidObj;
nsCID* cid;
PRBool valid;
if(NS_FAILED(wrapper->GetNative((nsISupports**)&self)) ||
!(cidObj = self->GetCID()) ||
NS_FAILED(cidObj->GetValid(&valid)) ||
!valid ||
NS_FAILED(cidObj->GetId(&cid)) ||
!cid)
{
return NS_ERROR_FAILURE;
}
nsISupports* srvc;
nsresult rv;
// XXX can do security check here (don't forget to free cid)
// XXX could allow for passing an IID
rv = nsServiceManager::GetService(*cid, nsISupports::GetIID(),
&srvc, NULL);
if(NS_FAILED(rv))
return NS_ERROR_FAILURE;
nsIXPConnectWrappedNative* srvcWrapper;
rv = XPC_GetXPConnect()->WrapNative(cx, srvc, nsISupports::GetIID(),
&srvcWrapper);
if(NS_FAILED(rv) || !srvcWrapper)
{
nsServiceManager::ReleaseService(*cid, srvc, NULL);
nsAllocator::Free(cid);
return NS_ERROR_FAILURE;
}
// This will eventually release the reference we got from
// nsServiceManager::GetService
ServiceReleaser* releaser = new ServiceReleaser(*cid);
if(NS_FAILED(srvcWrapper->SetFinalizeListener(releaser)))
{
// Failure means that we are using a preexisting wrapper on
// this service that has already setup a listener. So, we just
// release our extra ref and trust the lister that is already in
// place to do the right thing.
NS_RELEASE(srvc);
NS_RELEASE(releaser);
}
nsAllocator::Free(cid);
JSObject* srvcJSObj;
srvcWrapper->GetJSObject(&srvcJSObj);
*rval = OBJECT_TO_JSVAL(srvcJSObj);
*retval = JS_TRUE;
NS_RELEASE(srvcWrapper);
return NS_OK;
}
/*********************************************/
NS_IMPL_QUERY_INTERFACE_SCRIPTABLE(CIDGetService, GetScriptable())
NS_IMPL_ADDREF(CIDGetService)
NS_IMPL_RELEASE(CIDGetService)
CIDGetService::CIDGetService(nsJSCID *aCID)
: mCID(aCID)
{
NS_PRECONDITION(mCID, "bad cid");
NS_INIT_ISUPPORTS();
NS_ADDREF_THIS();
NS_ADDREF(mCID);
}
CIDGetService::~CIDGetService()
{
if(mCID)
NS_RELEASE(mCID);
}
// static
CIDGetServiceScriptable*
CIDGetService::GetScriptable()
{
static CIDGetServiceScriptable* scriptable = NULL;
// we leak this singleton
if(!scriptable)
scriptable = new CIDGetServiceScriptable();
return scriptable;
}
/***************************************************************************/ /***************************************************************************/
// nsJSCID // nsJSCID
@ -255,7 +606,9 @@ NS_IMPL_ADDREF(nsJSCID)
NS_IMPL_RELEASE(nsJSCID) NS_IMPL_RELEASE(nsJSCID)
nsJSCID::nsJSCID() nsJSCID::nsJSCID()
: mID(GetInvalidIID()), mNumber(gNoString), mName(gNoString) : mID(GetInvalidIID()),
mNumber(gNoString),
mName(gNoString)
{ {
NS_INIT_ISUPPORTS(); NS_INIT_ISUPPORTS();
NS_ADDREF_THIS(); NS_ADDREF_THIS();
@ -408,39 +761,26 @@ nsJSCID::toString(char **_retval)
return GetName(_retval); return GetName(_retval);
} }
/* readonly attribute nsISupports createInstance; */
NS_IMETHODIMP NS_IMETHODIMP
nsJSCID::createInstance(nsISupports **_retval) nsJSCID::GetCreateInstance(nsISupports * *aCreateInstance)
{ {
if(!_retval) if(!aCreateInstance)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
*_retval = NULL; *aCreateInstance = new CIDCreateInstance(this);
if(mID.Equals(GetInvalidIID())) return NS_OK;
return NS_ERROR_FAILURE;
return nsComponentManager::CreateInstance(mID, NULL,
nsISupports::GetIID(),
(void**) _retval);
} }
// XXX this does not yet address the issue of using the SM to release /* readonly attribute nsISupports getService; */
// XXX this does not yet address the issue of security protections
// XXX we'll need to make createInstance and getService dynamic to
// support both of these issues
NS_IMETHODIMP NS_IMETHODIMP
nsJSCID::getService(nsISupports **_retval) nsJSCID::GetGetService(nsISupports * *aGetService)
{ {
if(!_retval) if(!aGetService)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
*_retval = NULL; *aGetService = new CIDGetService(this);
if(mID.Equals(GetInvalidIID())) return NS_OK;
return NS_ERROR_FAILURE;
return nsServiceManager::GetService(mID,
nsISupports::GetIID(),
_retval, NULL);
} }
/***************************************************************************/ /***************************************************************************/

Просмотреть файл

@ -29,18 +29,10 @@ hash_root(const void *key)
return ((JSHashNumber) key) >> 2; /* help lame MSVC1.5 on Win16 */ return ((JSHashNumber) key) >> 2; /* help lame MSVC1.5 on Win16 */
} }
// XXX this is just the hacked String hash function, should do better...
JS_STATIC_DLL_CALLBACK(JSHashNumber) JS_STATIC_DLL_CALLBACK(JSHashNumber)
hash_IID(const void *key) hash_IID(const void *key)
{ {
JSHashNumber h; return (JSHashNumber) *((PRUint32*)key);
const PRUint8 *s;
int i;
h = 0;
for (s = (const PRUint8 *)key, i = 0; i < 16; s++, i++)
h = (h >> 28) ^ (h << 4) ^ *s;
return h;
} }
JS_STATIC_DLL_CALLBACK(intN) JS_STATIC_DLL_CALLBACK(intN)

Просмотреть файл

@ -138,9 +138,25 @@ public:
IID2WrappedNativeClassMap* GetWrappedNativeClassMap() const IID2WrappedNativeClassMap* GetWrappedNativeClassMap() const
{return mWrappedNativeClassMap;} {return mWrappedNativeClassMap;}
jsid GetConstructorStrID() const {return mConstuctorStrID;} // To add a new string: add to this list and to XPCContext::mStrings
jsid GetToStringStrID() const {return mToStringStrID;} // at the top of xpccontext.cpp
jsid GetLastResultStrID() const {return mLastResultStrID;} enum {
IDX_CONSTRUCTOR = 0 ,
IDX_TO_STRING ,
IDX_LAST_RESULT ,
IDX_TOTAL_COUNT // just a count of the above
};
jsid GetStringID(uintN index) const
{
NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
return mStrIDs[index];
}
const char* GetStringName(uintN index) const
{
NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
return mStrings[index];
}
nsresult GetLastResult() {return mLastResult;} nsresult GetLastResult() {return mLastResult;}
void SetLastResult(nsresult rc) {mLastResult = rc;} void SetLastResult(nsresult rc) {mLastResult = rc;}
@ -158,6 +174,7 @@ private:
int WrappedJSClassMapSize, int WrappedJSClassMapSize,
int WrappedNativeClassMapSize); int WrappedNativeClassMapSize);
private: private:
static const char* mStrings[IDX_TOTAL_COUNT];
nsXPConnect* mXPConnect; nsXPConnect* mXPConnect;
JSContext* mJSContext; JSContext* mJSContext;
JSObject* mGlobalObj; JSObject* mGlobalObj;
@ -165,9 +182,7 @@ private:
Native2WrappedNativeMap* mWrappedNativeMap; Native2WrappedNativeMap* mWrappedNativeMap;
IID2WrappedJSClassMap* mWrappedJSClassMap; IID2WrappedJSClassMap* mWrappedJSClassMap;
IID2WrappedNativeClassMap* mWrappedNativeClassMap; IID2WrappedNativeClassMap* mWrappedNativeClassMap;
jsid mConstuctorStrID; jsid mStrIDs[IDX_TOTAL_COUNT];
jsid mToStringStrID;
jsid mLastResultStrID;
nsresult mLastResult; nsresult mLastResult;
}; };
@ -678,11 +693,11 @@ public:
/* boolean init (in string idString); */ /* boolean init (in string idString); */
NS_IMETHOD init(const char *idString, PRBool *_retval); NS_IMETHOD init(const char *idString, PRBool *_retval);
/* nsISupports createInstance (); */ /* readonly attribute nsISupports createInstance; */
NS_IMETHOD createInstance(nsISupports **_retval); NS_IMETHOD GetCreateInstance(nsISupports * *aCreateInstance);
/* nsISupports getService (); */ /* readonly attribute nsISupports getService; */
NS_IMETHOD getService(nsISupports **_retval); NS_IMETHOD GetGetService(nsISupports * *aGetService);
/* string toString (); */ /* string toString (); */
NS_IMETHOD toString(char **_retval); NS_IMETHOD toString(char **_retval);

Просмотреть файл

@ -268,16 +268,16 @@ nsXPCWrappedNative::~nsXPCWrappedNative()
map->Remove(this); map->Remove(this);
} }
} }
if(mDynamicScriptable)
NS_RELEASE(mDynamicScriptable);
if(mClass)
NS_RELEASE(mClass);
if(mFinalizeListener) if(mFinalizeListener)
{ {
if(mObj) if(mObj)
mFinalizeListener->AboutToRelease(mObj); mFinalizeListener->AboutToRelease(mObj);
NS_RELEASE(mFinalizeListener); NS_RELEASE(mFinalizeListener);
} }
if(mDynamicScriptable)
NS_RELEASE(mDynamicScriptable);
if(mClass)
NS_RELEASE(mClass);
if(mObj) if(mObj)
NS_RELEASE(mObj); NS_RELEASE(mObj);
} }
@ -378,11 +378,10 @@ nsXPCWrappedNative::GetIID(nsIID** iid)
NS_IMETHODIMP NS_IMETHODIMP
nsXPCWrappedNative::SetFinalizeListener(nsIXPConnectFinalizeListener* aListener) nsXPCWrappedNative::SetFinalizeListener(nsIXPConnectFinalizeListener* aListener)
{ {
/* if the object already has a listener, then we fail */
if(mFinalizeListener && aListener) if(mFinalizeListener && aListener)
{
NS_ASSERTION(0,"tried to set two FinalizeListeners on a wrapper");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
}
if(mFinalizeListener) if(mFinalizeListener)
NS_RELEASE(mFinalizeListener); NS_RELEASE(mFinalizeListener);
mFinalizeListener = aListener; mFinalizeListener = aListener;

Просмотреть файл

@ -237,6 +237,11 @@ WrappedNative_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
return JS_TRUE; return JS_TRUE;
case JSTYPE_FUNCTION: case JSTYPE_FUNCTION:
if(wrapper->GetDynamicScriptable())
{
*vp = OBJECT_TO_JSVAL(obj);
return JS_TRUE;
}
JS_ReportError(cx, "can't convert WrappedNative to function"); JS_ReportError(cx, "can't convert WrappedNative to function");
return JS_FALSE; return JS_FALSE;
@ -246,7 +251,8 @@ WrappedNative_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
nsXPCWrappedNativeClass* clazz = wrapper->GetClass(); nsXPCWrappedNativeClass* clazz = wrapper->GetClass();
NS_ASSERTION(clazz,"wrapper without class"); NS_ASSERTION(clazz,"wrapper without class");
const XPCNativeMemberDescriptor* desc = const XPCNativeMemberDescriptor* desc =
clazz->LookupMemberByID(clazz->GetXPCContext()->GetToStringStrID()); clazz->LookupMemberByID(clazz->GetXPCContext()->
GetStringID(XPCContext::IDX_TO_STRING));
if(desc && desc->IsMethod()) if(desc && desc->IsMethod())
{ {
if(!clazz->CallWrappedMethod(cx, wrapper, desc, if(!clazz->CallWrappedMethod(cx, wrapper, desc,
@ -636,7 +642,6 @@ WrappedNative_CallMethod(JSContext *cx, JSObject *obj,
jsval idval; jsval idval;
nsXPCWrappedNative* wrapper; nsXPCWrappedNative* wrapper;
wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj); wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx, obj);
if(!wrapper) if(!wrapper)
return JS_FALSE; return JS_FALSE;
@ -690,7 +695,7 @@ WrappedNative_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
if(!wrapper) if(!wrapper)
{ {
XPCContext* xpcc = nsXPConnect::GetContext(cx); XPCContext* xpcc = nsXPConnect::GetContext(cx);
if(xpcc && id == xpcc->GetConstructorStrID()) if(xpcc && id == xpcc->GetStringID(XPCContext::IDX_CONSTRUCTOR))
{ {
// silently fail when looking for constructor property // silently fail when looking for constructor property
*vp = JSVAL_VOID; *vp = JSVAL_VOID;
@ -1102,6 +1107,11 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_Call(JSContext *cx, JSObject *obj, WrappedNative_Call(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *rval) uintN argc, jsval *argv, jsval *rval)
{ {
// this is a hack to get the obj of the actual object not the object
// that JS thinks is the 'this' (which it passes as 'obj').
if(!(obj = (JSObject*)argv[-2]))
return JS_FALSE;
nsIXPCScriptable* ds; nsIXPCScriptable* ds;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx,obj); nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx,obj);
if(wrapper && NULL != (ds = wrapper->GetDynamicScriptable())) if(wrapper && NULL != (ds = wrapper->GetDynamicScriptable()))
@ -1121,6 +1131,11 @@ JS_STATIC_DLL_CALLBACK(JSBool)
WrappedNative_Construct(JSContext *cx, JSObject *obj, WrappedNative_Construct(JSContext *cx, JSObject *obj,
uintN argc, jsval *argv, jsval *rval) uintN argc, jsval *argv, jsval *rval)
{ {
// this is a hack to get the obj of the actual object not the object
// that JS thinks is the 'this' (which it passes as 'obj').
if(!(obj = (JSObject*)argv[-2]))
return JS_FALSE;
nsIXPCScriptable* ds; nsIXPCScriptable* ds;
nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx,obj); nsXPCWrappedNative* wrapper = (nsXPCWrappedNative*) JS_GetPrivate(cx,obj);
if(wrapper && NULL != (ds = wrapper->GetDynamicScriptable())) if(wrapper && NULL != (ds = wrapper->GetDynamicScriptable()))

Просмотреть файл

@ -66,7 +66,9 @@ extern "C" PR_IMPLEMENT(nsresult)
NSRegisterSelf(nsISupports* aServMgr , const char* aPath) NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
{ {
nsresult rv; nsresult rv;
printf("registering xpctest\n"); #ifdef DEBUG
printf("*** Register XPConnect test components\n");
#endif
NS_WITH_SERVICE1(nsIComponentManager, compMgr, NS_WITH_SERVICE1(nsIComponentManager, compMgr,
aServMgr, kComponentManagerCID, &rv); aServMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;

Двоичные данные
js/src/xpconnect/typelib/nsISupports.xpt

Двоичный файл не отображается.

Двоичные данные
js/src/xpconnect/typelib/xpccomponents.xpt

Двоичный файл не отображается.

Двоичные данные
js/src/xpconnect/typelib/xpcjsid.xpt

Двоичный файл не отображается.

Двоичные данные
js/src/xpconnect/typelib/xpctest.xpt

Двоичный файл не отображается.