? src.temp ? src/biesi.threadsafe ? tests/js/old/gcthreads.js Index: idl/nsIXPConnect.idl =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/idl/nsIXPConnect.idl,v retrieving revision 1.40 diff -u -p -r1.40 nsIXPConnect.idl --- idl/nsIXPConnect.idl 3 Dec 2005 07:42:29 -0000 1.40 +++ idl/nsIXPConnect.idl 2 Feb 2006 10:45:58 -0000 @@ -135,6 +135,10 @@ #define NS_ERROR_XPC_COM_CREATE_FAILED GENERATE_XPC_FAILURE(57) #define NS_ERROR_XPC_IDISPATCH_NOT_ENABLED GENERATE_XPC_FAILURE(58) #endif + +#define NS_ERROR_XPC_BAD_CONVERT_RETURN GENERATE_XPC_FAILURE(59) +#define NS_ERROR_XPC_BAD_CONVERT_OUT GENERATE_XPC_FAILURE(60) + // any new errors here should have an associated entry added in xpc.msg /***************************************************************************/ %} @@ -690,6 +694,17 @@ interface nsIXPConnect : nsISupports void flagSystemFilenamePrefix(in string aFilenamePrefix); /** + * Get a native pointer of type aIID from aJSObject if the object + * is a wrapped native or a wrapped JS object, but never create a + * new wrapper, only use existing ones. + */ + void + getNativeOfJSObject(in JSContextPtr aJSContext, + in JSObjectPtr aJSObj, + in nsIIDRef aIID, + [iid_is(aIID),retval] out nsQIResult result); + + /** * Restore an old prototype for wrapped natives of type * aClassInfo. This should be used only when restoring an old * scope into a state close to where it was prior to Index: idl/xpccomponents.idl =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/idl/xpccomponents.idl,v retrieving revision 1.29 diff -u -p -r1.29 xpccomponents.idl --- idl/xpccomponents.idl 21 Nov 2005 06:30:32 -0000 1.29 +++ idl/xpccomponents.idl 2 Feb 2006 10:45:58 -0000 @@ -182,7 +182,7 @@ interface nsIXPCComponents : nsISupports readonly attribute nsIStackFrame stack; readonly attribute nsIXPCComponents_Results results; readonly attribute nsIComponentManager manager; - readonly attribute nsIXPCComponents_Utils utils; + readonly attribute nsIXPCComponents_Utils utils; readonly attribute nsIXPCComponents_ID ID; readonly attribute nsIXPCComponents_Exception Exception; Index: loader/mozJSComponentLoader.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/loader/mozJSComponentLoader.cpp,v retrieving revision 1.119 diff -u -p -r1.119 mozJSComponentLoader.cpp --- loader/mozJSComponentLoader.cpp 13 Dec 2005 17:55:43 -0000 1.119 +++ loader/mozJSComponentLoader.cpp 2 Feb 2006 10:45:58 -0000 @@ -400,6 +400,26 @@ mozJSComponentLoader::~mozJSComponentLoa sSelf = nsnull; } +static jsuword +GetStackLimit() +{ + // XXX improve me + + jsuword stackLimit; + + int stackDummy; + jsuword currentStackAddr = (jsuword)&stackDummy; + + // We assume here that the stack grows down, and that a stack + // limit of 512k below the current stack addr is ok. If this is + // not the case on some platforms, #ifdef's are needed for those + // platforms. + stackLimit = currentStackAddr + + (0x80000 * JS_STACK_GROWTH_DIRECTION); + + return stackLimit; +} + mozJSComponentLoader* mozJSComponentLoader::sSelf; @@ -426,6 +446,8 @@ mozJSComponentLoader::ReallyInit() if (!mContext) return NS_ERROR_OUT_OF_MEMORY; + ::JS_SetThreadStackLimit(mContext, GetStackLimit()); + uint32 options = JS_GetOptions(mContext); JS_SetOptions(mContext, options | JSOPTION_XML); @@ -589,9 +611,13 @@ mozJSComponentLoader::LoadModule(nsILoca } #ifdef DEBUG_shaver_off - JSString *s = JS_ValueToString(cx, retval); - fprintf(stderr, "mJCL: %s::NSGetModule returned %s\n", - registryLocation, JS_GetStringBytes(s)); + { + JSString *s = JS_ValueToString(cx, retval); + nsCAutoString path; + aComponentFile->GetNativePath(path); + fprintf(stderr, "mJCL: %s::NSGetModule returned %s\n", + path, JS_GetStringBytes(s)); + } #endif JSObject *jsModuleObj; @@ -605,7 +631,10 @@ mozJSComponentLoader::LoadModule(nsILoca if (NS_FAILED(rv)) { /* XXX report error properly */ #ifdef DEBUG - fprintf(stderr, "mJCL: couldn't get nsIModule from jsval\n"); + nsCAutoString path; + aComponentFile->GetNativePath(path); + fprintf(stderr, "mJCL: couldn't get nsIModule from jsval for %s\n", + path); #endif return rv; } @@ -1047,7 +1076,13 @@ mozJSComponentLoader::GlobalForLocation( #ifdef HAVE_PR_MEMMAP PRInt64 fileSize; - aComponent->GetFileSize(&fileSize); + rv = aComponent->GetFileSize(&fileSize); + if (NS_FAILED(rv)) + return rv; + if (LL_IS_ZERO(fileSize)) { + LOG(("File %s is zero bytes long\n", nativePath.get())); + return NS_ERROR_NO_CONTENT; + } PRInt64 maxSize; LL_UI2L(maxSize, PR_UINT32_MAX); Index: loader/mozJSComponentLoader.h =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/loader/mozJSComponentLoader.h,v retrieving revision 1.26 diff -u -p -r1.26 mozJSComponentLoader.h --- loader/mozJSComponentLoader.h 13 Dec 2005 17:55:43 -0000 1.26 +++ loader/mozJSComponentLoader.h 2 Feb 2006 10:45:59 -0000 @@ -143,8 +143,10 @@ class mozJSComponentLoader : public nsIM module = nsnull; if (global) { + JS_BeginRequest(sSelf->mContext); JS_ClearScope(sSelf->mContext, global); JS_RemoveRoot(sSelf->mContext, &global); + JS_EndRequest(sSelf->mContext); } if (location) Index: loader/mozJSSubScriptLoader.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/loader/mozJSSubScriptLoader.cpp,v retrieving revision 1.20 diff -u -p -r1.20 mozJSSubScriptLoader.cpp --- loader/mozJSSubScriptLoader.cpp 9 Dec 2005 18:58:23 -0000 1.20 +++ loader/mozJSSubScriptLoader.cpp 2 Feb 2006 10:45:59 -0000 @@ -77,7 +77,8 @@ ExceptionalErrorReporter (JSContext *cx, if (report && JSREPORT_IS_EXCEPTION (report->flags)) /* if it's already an exception, our job is done. */ return; - + + JS_BeginRequest(cx); ex = JS_NewObject (cx, nsnull, nsnull, nsnull); /* create a jsobject to throw */ if (!ex) @@ -114,6 +115,7 @@ ExceptionalErrorReporter (JSContext *cx, } JS_SetPendingException (cx, OBJECT_TO_JSVAL(ex)); + JS_EndRequest(cx); return; @@ -123,6 +125,7 @@ ExceptionalErrorReporter (JSContext *cx, "mozJSSubScriptLoader: Error occurred while reporting error :/\n") #endif ; + JS_EndRequest(cx); } mozJSSubScriptLoader::mozJSSubScriptLoader() : mSystemPrincipal(nsnull) @@ -196,7 +199,9 @@ mozJSSubScriptLoader::LoadSubScript (con char *url; JSObject *target_obj = nsnull; + JS_BeginRequest(cx); ok = JS_ConvertArguments (cx, argc, argv, "s / o", &url, &target_obj); + JS_EndRequest(cx); if (!ok) { cc->SetExceptionWasThrown (JS_TRUE); @@ -273,6 +278,7 @@ mozJSSubScriptLoader::LoadSubScript (con nsCOMPtr instream; nsCOMPtr serv = do_GetService(kIOServiceCID); + JS_BeginRequest(cx); if (!serv) { errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOSERVICE); @@ -302,8 +308,10 @@ mozJSSubScriptLoader::LoadSubScript (con } buf = new char[len + 1]; - if (!buf) + if (!buf) { + JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; + } buf[len] = '\0'; do { @@ -328,6 +336,7 @@ mozJSSubScriptLoader::LoadSubScript (con rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals); if (NS_FAILED(rv) || !jsPrincipals) { delete[] buf; + JS_EndRequest(cx); return rv; } @@ -339,6 +348,7 @@ mozJSSubScriptLoader::LoadSubScript (con buf, len, url, 1, rval); /* repent for our evil deeds */ JS_SetErrorReporter (cx, er); + JS_EndRequest(cx); cc->SetExceptionWasThrown (!ok); cc->SetReturnValueWasSet (ok); @@ -352,6 +362,7 @@ mozJSSubScriptLoader::LoadSubScript (con delete[] buf; JS_SetPendingException (cx, STRING_TO_JSVAL(errmsg)); + JS_EndRequest(cx); cc->SetExceptionWasThrown (JS_TRUE); return NS_OK; Index: shell/xpcshell.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/shell/xpcshell.cpp,v retrieving revision 1.91 diff -u -p -r1.91 xpcshell.cpp --- shell/xpcshell.cpp 12 Dec 2005 15:08:16 -0000 1.91 +++ shell/xpcshell.cpp 2 Feb 2006 10:46:00 -0000 @@ -63,6 +63,15 @@ #include "nsIJSRuntimeService.h" #include "nsCOMPtr.h" #include "nsIXPCSecurityManager.h" +#include "nsIPrincipal.h" +#include "nsIScriptSecurityManager.h" + +// XXX should not need to use the caps cid +#define NS_SCRIPTSECURITYMANAGER_CID \ +{ 0x7ee2a4c0, 0x4b93, 0x17d3, \ +{ 0xba, 0x18, 0x00, 0x60, 0xb0, 0xf1, 0x99, 0xa2 }} + +static NS_DEFINE_CID(kScriptSecurityManagerCID, NS_SCRIPTSECURITYMANAGER_CID); #ifndef XPCONNECT_STANDALONE #include "nsIScriptSecurityManager.h" @@ -203,6 +212,10 @@ Dump(JSContext *cx, JSObject *obj, uintN char *bytes = JS_GetStringBytes(str); bytes = strdup(bytes); + if (!bytes) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } fputs(bytes, gOutFile); free(bytes); @@ -379,12 +392,18 @@ env_setProperty(JSContext *cx, JSObject const char *name, *value; int rv; + if (!JS_EnterLocalRootScope(cx)) + return JS_FALSE; + idstr = JS_ValueToString(cx, id); valstr = JS_ValueToString(cx, *vp); - if (!idstr || !valstr) + if (!idstr || !valstr) { + JS_LeaveLocalRootScope(cx); return JS_FALSE; + } name = JS_GetStringBytes(idstr); value = JS_GetStringBytes(valstr); + JS_LeaveLocalRootScope(cx); #if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX \ || defined SCO { @@ -600,6 +619,12 @@ ProcessFile(JSContext *cx, JSObject *obj return; } + nsCOMPtr systemPrincipal; + { + nsCOMPtr ssm = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); + if (ssm) + ssm->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); + } /* It's an interactive filehandle; drop into read-eval-print loop. */ lineno = 1; hitEOF = JS_FALSE; @@ -626,8 +651,10 @@ ProcessFile(JSContext *cx, JSObject *obj DoBeginRequest(cx); /* Clear any pending exception from previous failed compiles. */ JS_ClearPendingException(cx); - script = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer, - strlen(buffer), "typein", startline); + script = JS_CompileScriptForPrincipals(cx, obj, + (JSPrincipals *) systemPrincipal.get(), + buffer, strlen(buffer), + "typein", startline); if (script) { JSErrorReporter older; @@ -636,13 +663,17 @@ ProcessFile(JSContext *cx, JSObject *obj if (ok && result != JSVAL_VOID) { /* Suppress error reports from JS_ValueToString(). */ older = JS_SetErrorReporter(cx, NULL); - str = JS_ValueToString(cx, result); - JS_SetErrorReporter(cx, older); - - if (str) - fprintf(gOutFile, "%s\n", JS_GetStringBytes(str)); - else - ok = JS_FALSE; + ok = JS_AddNamedRoot(cx, &result, "script result"); + if (ok) { + str = JS_ValueToString(cx, result); + JS_SetErrorReporter(cx, older); + + if (str) + fprintf(gOutFile, "%s\n", JS_GetStringBytes(str)); + else + ok = JS_FALSE; + JS_RemoveRoot(cx, &result); + } } } JS_DestroyScript(cx, script); @@ -726,12 +757,21 @@ ProcessArgs(JSContext *cx, JSObject *obj * Create arguments early and define it to root it, so it's safe from any * GC calls nested below, and so it is available to -f arguments. */ + DoBeginRequest(cx); argsObj = JS_NewArrayObject(cx, 0, NULL); if (!argsObj) return 1; - if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj), - NULL, NULL, 0)) { + + if (!JS_EnterLocalRootScope(cx)) return 1; + + { + JSBool ok = + JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj), + NULL, NULL, 0); + JS_LeaveLocalRootScope(cx); + if (!ok) + return 1; } length = argc - i; @@ -827,27 +867,311 @@ ProcessArgs(JSContext *cx, JSObject *obj if (filename || isInteractive) Process(cx, obj, filename, forceTTY); + DoEndRequest(cx); return gExitCode; } -/***************************************************************************/ +class FullTrustSecManFactory : public nsIFactory +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIFACTORY -class FullTrustSecMan : public nsIXPCSecurityManager + FullTrustSecManFactory(); + virtual ~FullTrustSecManFactory(); +}; + +class FullTrustSecMan : public nsIScriptSecurityManager { public: NS_DECL_ISUPPORTS NS_DECL_NSIXPCSECURITYMANAGER +#ifndef NS_DECL_NSISCRIPTSECURITYMANAGER +#error EEEK +#endif + NS_DECL_NSISCRIPTSECURITYMANAGER + int HelloWorld; FullTrustSecMan(); +private: + nsCOMPtr mSystemPrincipal; }; -NS_IMPL_ISUPPORTS1(FullTrustSecMan, nsIXPCSecurityManager) +/***************************************************************************/ + +#if 0 +NS_IMPL_QUERY_INTERFACE2_CI(nsDummySystemPrincipal, + nsIPrincipal, + nsISerializable) +NS_IMPL_CI_INTERFACE_GETTER2(nsDummySystemPrincipal, + nsIPrincipal, + nsISerializable) + +NS_IMETHODIMP_(nsrefcnt) +nsDummySystemPrincipal::AddRef() +{ + NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt"); + nsrefcnt count = PR_AtomicIncrement((PRInt32 *)&mJSPrincipals.refcount); + NS_LOG_ADDREF(this, count, "nsDummySystemPrincipal", sizeof(*this)); + return count; +} + +NS_IMETHODIMP_(nsrefcnt) +nsDummySystemPrincipal::Release() +{ + NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release"); + nsrefcnt count = PR_AtomicDecrement((PRInt32 *)&mJSPrincipals.refcount); + NS_LOG_RELEASE(this, count, "nsDummySystemPrincipal"); + if (count == 0) { + NS_DELETEXPCOM(this); + } + + return count; +} + + +/////////////////////////////////////// +// Methods implementing nsIPrincipal // +/////////////////////////////////////// + +NS_IMETHODIMP +nsDummySystemPrincipal::GetPreferences(char** aPrefName, char** aID, + char** aGrantedList, char** aDeniedList) +{ + // The system principal should never be streamed out + *aPrefName = nsnull; + *aID = nsnull; + *aGrantedList = nsnull; + *aDeniedList = nsnull; + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::Equals(nsIPrincipal *other, PRBool *result) +{ + *result = (other == this); + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetHashValue(PRUint32 *result) +{ + *result = NS_PTR_TO_INT32(this); + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::CanEnableCapability(const char *capability, + PRInt16 *result) +{ + // System principal can enable all capabilities. + *result = nsIPrincipal::ENABLE_GRANTED; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::SetCanEnableCapability(const char *capability, + PRInt16 canEnable) +{ + return NS_ERROR_FAILURE; +} + + +NS_IMETHODIMP +nsDummySystemPrincipal::IsCapabilityEnabled(const char *capability, + void *annotation, + PRBool *result) +{ + *result = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::EnableCapability(const char *capability, void **annotation) +{ + *annotation = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::RevertCapability(const char *capability, void **annotation) +{ + *annotation = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::DisableCapability(const char *capability, void **annotation) +{ + // Can't disable the capabilities of the system principal. + // XXX might be handy to be able to do so! + *annotation = nsnull; + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetURI(nsIURI** aURI) +{ + *aURI = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetOrigin(char** aOrigin) +{ + *aOrigin = ToNewCString(NS_LITERAL_CSTRING("[System]")); + return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetCertificateID(char** aID) +{ + *aID = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetCommonName(char** aName) +{ + *aName = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::SetCommonName(const char* aName) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetHasCertificate(PRBool* aResult) +{ + *aResult = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetDomain(nsIURI** aDomain) +{ + *aDomain = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::SetDomain(nsIURI* aDomain) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetSecurityPolicy(void** aSecurityPolicy) +{ + *aSecurityPolicy = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::SetSecurityPolicy(void* aSecurityPolicy) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::GetJSPrincipals(JSContext *cx, JSPrincipals **jsprin) +{ + NS_PRECONDITION(mJSPrincipals.nsIPrincipalPtr, "mJSPrincipals is uninitalized!"); + + JSPRINCIPALS_HOLD(cx, &mJSPrincipals); + *jsprin = &mJSPrincipals; + return NS_OK; +} + + +////////////////////////////////////////// +// Methods implementing nsISerializable // +////////////////////////////////////////// + +NS_IMETHODIMP +nsDummySystemPrincipal::Read(nsIObjectInputStream* aStream) +{ + // no-op: CID is sufficient to identify the mSystemPrincipal singleton + return NS_OK; +} + +NS_IMETHODIMP +nsDummySystemPrincipal::Write(nsIObjectOutputStream* aStream) +{ + // no-op: CID is sufficient to identify the mSystemPrincipal singleton + return NS_OK; +} + +///////////////////////////////////////////// +// Constructor, Destructor, initialization // +///////////////////////////////////////////// + +nsDummySystemPrincipal::nsDummySystemPrincipal() +{ +} + +nsresult +nsDummySystemPrincipal::Init() +{ + return mJSPrincipals.Init(this, "[System Principal]"); +} + +nsDummySystemPrincipal::~nsDummySystemPrincipal(void) +{ +} +#endif + +/***************************************************************************/ +NS_IMPL_ISUPPORTS1(FullTrustSecManFactory, nsIFactory) + +FullTrustSecManFactory::FullTrustSecManFactory() +{ +} + +FullTrustSecManFactory::~FullTrustSecManFactory() +{ +} + + +NS_IMETHODIMP FullTrustSecManFactory::CreateInstance(nsISupports *aOuter, const nsIID & aIID, void **aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + + *aResult = NULL; + FullTrustSecMan *inst = new FullTrustSecMan; + if (!inst) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv = inst->QueryInterface(aIID, aResult); + if (rv != NS_OK) { + // We didn't get the right interface, so clean up + delete inst; + } + + return rv; +} + +NS_IMETHODIMP FullTrustSecManFactory::LockFactory(PRBool lock) +{ + return NS_OK; +} + + +NS_IMPL_ISUPPORTS2(FullTrustSecMan, nsIScriptSecurityManager, nsIXPCSecurityManager) FullTrustSecMan::FullTrustSecMan() { } NS_IMETHODIMP -FullTrustSecMan::CanCreateWrapper(JSContext * aJSContext, const nsIID & aIID, nsISupports *aObj, nsIClassInfo *aClassInfo, void * *aPolicy) +FullTrustSecMan::CanCreateWrapper(JSContext * aJSContext, + const nsIID & aIID, + nsISupports *aObj, + nsIClassInfo *aClassInfo, + void * *aPolicy) { return NS_OK; } @@ -866,11 +1190,220 @@ FullTrustSecMan::CanGetService(JSContext /* void CanAccess (in PRUint32 aAction, in nsIXPCNativeCallContext aCallContext, in JSContextPtr aJSContext, in JSObjectPtr aJSObject, in nsISupports aObj, in nsIClassInfo aClassInfo, in JSVal aName, inout voidPtr aPolicy); */ NS_IMETHODIMP -FullTrustSecMan::CanAccess(PRUint32 aAction, nsIXPCNativeCallContext *aCallContext, JSContext * aJSContext, JSObject * aJSObject, nsISupports *aObj, nsIClassInfo *aClassInfo, jsval aName, void * *aPolicy) +FullTrustSecMan::CanAccess(PRUint32 aAction, + nsIXPCNativeCallContext *aCallContext, + JSContext * aJSContext, + JSObject * aJSObject, + nsISupports *aObj, + nsIClassInfo *aClassInfo, + jsval aName, + void * *aPolicy) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::SecurityCompareURIs(nsIURI* aSourceURI, + nsIURI* aTargetURI, + PRBool* result) +{ + *result = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckPropertyAccess(JSContext* cx, + JSObject* aJSObject, + const char* aClassName, + jsval aProperty, + PRUint32 aAction) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckConnect(JSContext* cx, + nsIURI* aTargetURI, + const char* aClassName, + const char* aPropertyName) { return NS_OK; } +NS_IMETHODIMP +FullTrustSecMan::CheckSameOrigin(JSContext* cx, + nsIURI* aTargetURI) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckSameOriginURI(nsIURI* aSourceURI, + nsIURI* aTargetURI) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckSameOriginPrincipal(nsIPrincipal* aSourcePrincipal, + nsIPrincipal* aTargetPrincipal) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckLoadURIFromScript(JSContext *cx, nsIURI *aURI) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckLoadURI(nsIURI *aSourceURI, nsIURI *aTargetURI, + PRUint32 aFlags) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, + nsIURI *aTargetURI, + PRUint32 aFlags) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckLoadURIStr(const nsACString& aSourceURIStr, const nsACString& aTargetURIStr, + PRUint32 aFlags) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CheckFunctionAccess(JSContext *aCx, void *aFunObj, + void *aTargetObj) +{ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::CanExecuteScripts(JSContext* cx, + nsIPrincipal *aPrincipal, + PRBool *result) +{ + *result = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::GetSubjectPrincipal(nsIPrincipal **result) +{ + return GetSystemPrincipal(result); +} + +NS_IMETHODIMP +FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **result) +{ + if (!mSystemPrincipal) + { +#if 0 + nsDummySystemPrincipal *system = new nsDummySystemPrincipal(); + mSystemPrincipal = system; +#endif + if (!mSystemPrincipal) + return NS_ERROR_OUT_OF_MEMORY; + +#if 0 + nsresult rv = system->Init(); + if (NS_FAILED(rv)) { + mSystemPrincipal = nsnull; + return rv; + } +#endif + } + + NS_ADDREF(*result = mSystemPrincipal); + + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::SubjectPrincipalIsSystem(PRBool* aIsSystem) +{ + *aIsSystem = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::GetCodebasePrincipal(nsIURI *aURI, + nsIPrincipal **result) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +FullTrustSecMan::GetPrincipalFromContext(JSContext *cx, + nsIPrincipal **result) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +FullTrustSecMan::GetObjectPrincipal(JSContext *aCx, JSObject *aObj, + nsIPrincipal **result) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +FullTrustSecMan::IsCapabilityEnabled(const char *capability, + PRBool *result) +{ + *result = PR_TRUE; + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::RequestCapability(nsIPrincipal* aPrincipal, + const char *capability, PRInt16* canEnable) +{ + *canEnable = nsIPrincipal::ENABLE_GRANTED; + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::EnableCapability(const char *capability) +{ + /* do something */ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::RevertCapability(const char *capability) +{ + /* do something */ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::DisableCapability(const char *capability) +{ + /* do something */ + return NS_OK; +} + +NS_IMETHODIMP +FullTrustSecMan::SetCanEnableCapability(nsACString const &,char const *,short) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +FullTrustSecMan::GetCertificatePrincipal(nsACString const &,nsACString const &,nsACString const &,nsISupports *,nsIURI *,nsIPrincipal * *) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + /***************************************************************************/ // #define TEST_InitClassesWithNewWrappedGlobal @@ -976,8 +1509,14 @@ main(int argc, char **argv, char **envp) { nsCOMPtr registrar = do_QueryInterface(servMan); NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); - if (registrar) + if (registrar) { registrar->AutoRegister(nsnull); + nsCOMPtr fullTrustSecManFactory = new FullTrustSecManFactory; + registrar->RegisterFactory(kScriptSecurityManagerCID, + NS_SCRIPTSECURITYMANAGER_CLASSNAME, + NS_SCRIPTSECURITYMANAGER_CONTRACTID, + fullTrustSecManFactory); + } } nsCOMPtr rtsvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); @@ -1012,7 +1551,15 @@ main(int argc, char **argv, char **envp) // just to shut it up. Also, note that even though our secman will allow // anything, we set the flags to '0' so it ought never get called anyway. nsCOMPtr secman = - NS_STATIC_CAST(nsIXPCSecurityManager*, new FullTrustSecMan()); + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); + { + PRBool accessGranted = PR_FALSE; + nsCOMPtr ssm = do_QueryInterface(secman); + if (ssm) + ssm->IsCapabilityEnabled("UniversalXPConnect", &accessGranted); + if (!accessGranted) + secman = NS_STATIC_CAST(nsIXPCSecurityManager*, new FullTrustSecMan()); + } xpc->SetSecurityManagerForJSContext(cx, secman, 0); // xpc->SetCollectGarbageOnMainThreadOnly(PR_TRUE); @@ -1083,12 +1630,14 @@ main(int argc, char **argv, char **envp) NS_ASSERTION(glob == nsnull, "bad GetJSObject?"); return 1; } + DoBeginRequest(cx); if (!JS_DefineFunctions(cx, glob, glob_functions)) return 1; envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0); if (!envobj || !JS_SetPrivate(cx, envobj, envp)) return 1; + DoEndRequest(cx); argc--; argv++; @@ -1101,10 +1650,13 @@ main(int argc, char **argv, char **envp) #ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN // test of late call and release (see below) nsCOMPtr bogus; + DoBeginRequest(cx); xpc->WrapJS(cx, glob, NS_GET_IID(nsIJSContextStack), (void**) getter_AddRefs(bogus)); + DoEndRequest(cx); #endif + DoBeginRequest(cx); JS_ClearScope(cx, glob); JS_GC(cx); JSContext *oldcx; Index: src/XPCDispConvert.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/XPCDispConvert.cpp,v retrieving revision 1.11 diff -u -p -r1.11 XPCDispConvert.cpp --- src/XPCDispConvert.cpp 7 May 2005 06:12:54 -0000 1.11 +++ src/XPCDispConvert.cpp 2 Feb 2006 10:46:02 -0000 @@ -318,7 +318,8 @@ JSBool XPCDispConvert::JSToCOM(XPCCallCo (void**)&pUnknown, obj, &NSID_IDISPATCH, - nsnull, + nsnull, + PR_TRUE, &err)) { // Avoid cleaning up garbage Index: src/XPCNativeWrapper.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/XPCNativeWrapper.cpp,v retrieving revision 1.37 diff -u -p -r1.37 XPCNativeWrapper.cpp --- src/XPCNativeWrapper.cpp 9 Dec 2005 19:08:45 -0000 1.37 +++ src/XPCNativeWrapper.cpp 2 Feb 2006 10:46:07 -0000 @@ -757,7 +757,10 @@ XPC_NW_NewResolve(JSContext *cx, JSObjec ccx.SetResolvingWrapper(oldResolvingWrapper); } - if (!::JS_SetReservedSlot(cx, obj, 0, oldFlags)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_SetReservedSlot(cx, obj, 0, oldFlags); + ::JS_EndRequest(cx); + if (!ok) { return JS_FALSE; } @@ -767,7 +770,9 @@ XPC_NW_NewResolve(JSContext *cx, JSObjec if (newObj) { #ifdef DEBUG_XPCNativeWrapper + ::JS_BeginRequest(cx); JSString* strId = ::JS_ValueToString(cx, id); + ::JS_EndRequest(cx); if (strId) { NS_ConvertUTF16toUTF8 propName((PRUnichar*)::JS_GetStringChars(strId), ::JS_GetStringLength(strId)); @@ -862,9 +867,12 @@ XPC_NW_NewResolve(JSContext *cx, JSObjec } } - if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), - ::JS_GetStringLength(str), v, nsnull, nsnull, - attrs)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), v, nsnull, nsnull, + attrs); + ::JS_EndRequest(cx); + if (!ok) { return JS_FALSE; } Index: src/nsXPConnect.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/nsXPConnect.cpp,v retrieving revision 1.80 diff -u -p -r1.80 nsXPConnect.cpp --- src/nsXPConnect.cpp 10 Nov 2005 16:19:42 -0000 1.80 +++ src/nsXPConnect.cpp 2 Feb 2006 10:46:08 -0000 @@ -612,7 +612,7 @@ nsXPConnect::WrapJS(JSContext * aJSConte nsresult rv; if(!XPCConvert::JSObject2NativeInterface(ccx, result, aJSObj, - &aIID, nsnull, &rv)) + &aIID, nsnull, PR_TRUE, &rv)) return rv; return NS_OK; } @@ -638,7 +638,7 @@ nsXPConnect::WrapJSAggregatedToNative(ns nsresult rv; if(!XPCConvert::JSObject2NativeInterface(ccx, result, aJSObj, - &aIID, aOuter, &rv)) + &aIID, aOuter, PR_TRUE, &rv)) return rv; return NS_OK; } @@ -1391,6 +1391,30 @@ nsXPConnect::FlagSystemFilenamePrefix(co return NS_OK; } +/* void getNativeOfJSObject(in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is(aIID),retval] out nsQIResult result); */ +NS_IMETHODIMP +nsXPConnect::GetNativeOfJSObject(JSContext * aJSContext, + JSObject * aJSObj, + const nsIID & aIID, + void * *result) +{ + NS_ASSERTION(aJSContext, "bad param"); + NS_ASSERTION(aJSObj, "bad param"); + NS_ASSERTION(result, "bad param"); + + *result = nsnull; + + XPCCallContext ccx(NATIVE_CALLER, aJSContext); + if(!ccx.IsValid()) + return UnexpectedFailure(NS_ERROR_FAILURE); + + nsresult rv; + if(!XPCConvert::JSObject2NativeInterface(ccx, result, aJSObj, + &aIID, nsnull, PR_FALSE, &rv)) + return rv; + return NS_OK; +} + #ifdef DEBUG /* These are here to be callable from a debugger */ JS_BEGIN_EXTERN_C Index: src/xpc.msg =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpc.msg,v retrieving revision 1.26 diff -u -p -r1.26 xpc.msg --- src/xpc.msg 25 Nov 2005 08:16:38 -0000 1.26 +++ src/xpc.msg 2 Feb 2006 10:46:08 -0000 @@ -169,3 +169,6 @@ XPC_MSG_DEF(NS_ERROR_XPC_COM_INVALID_CLA XPC_MSG_DEF(NS_ERROR_XPC_COM_CREATE_FAILED , "Unable to create an instance of the desired COM class") XPC_MSG_DEF(NS_ERROR_XPC_IDISPATCH_NOT_ENABLED , "IDispatch support is not enabled") #endif + +XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_RETURN , "Could not convert returned value to the type defined by the interface") +XPC_MSG_DEF(NS_ERROR_XPC_BAD_CONVERT_OUT , "Could not convert an out parameter to the type defined by the interface") Index: src/xpccomponents.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpccomponents.cpp,v retrieving revision 1.84 diff -u -p -r1.84 xpccomponents.cpp --- src/xpccomponents.cpp 16 Nov 2005 02:12:21 -0000 1.84 +++ src/xpccomponents.cpp 2 Feb 2006 10:46:10 -0000 @@ -47,6 +47,8 @@ #include "nsIScriptObjectPrincipal.h" #include "nsIDOMWindow.h" +// XXX Need to make a base class. + /***************************************************************************/ // stuff used by all @@ -97,6 +99,105 @@ char * xpc_CheckAccessList(const PRUnich #endif /***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; +#ifdef XPC_USE_SECURITY_CHECKED_COMPONENT + ++count; +#endif + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIScriptableInterfaces) + PUSH_IID(nsIXPCScriptable) +#ifdef XPC_USE_SECURITY_CHECKED_COMPONENT + PUSH_IID(nsISecurityCheckedComponent) +#endif +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_Interfaces::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents_Interfaces::nsXPCComponents_Interfaces() : mManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID)) @@ -125,6 +226,7 @@ NS_IMETHODIMP nsXPCComponents_Interfaces NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Interfaces) NS_INTERFACE_MAP_ENTRY(nsIScriptableInterfaces) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent) #endif @@ -319,7 +421,8 @@ nsXPCComponents_Interfaces::CanSetProper class nsXPCComponents_InterfacesByID : public nsIScriptableInterfacesByID, - public nsIXPCScriptable + public nsIXPCScriptable, + public nsIClassInfo #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT , public nsISecurityCheckedComponent #endif @@ -329,6 +432,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSISCRIPTABLEINTERFACESBYID NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT NS_DECL_NSISECURITYCHECKEDCOMPONENT #endif @@ -341,6 +445,105 @@ private: nsCOMPtr mManager; }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; +#ifdef XPC_USE_SECURITY_CHECKED_COMPONENT + ++count; +#endif + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIScriptableInterfacesByID) + PUSH_IID(nsIXPCScriptable) +#ifdef XPC_USE_SECURITY_CHECKED_COMPONENT + PUSH_IID(nsISecurityCheckedComponent) +#endif +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_InterfacesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} nsXPCComponents_InterfacesByID::nsXPCComponents_InterfacesByID() : mManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID)) @@ -355,6 +558,7 @@ nsXPCComponents_InterfacesByID::~nsXPCCo NS_INTERFACE_MAP_BEGIN(nsXPCComponents_InterfacesByID) NS_INTERFACE_MAP_ENTRY(nsIScriptableInterfacesByID) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent) #endif @@ -559,19 +763,117 @@ nsXPCComponents_InterfacesByID::CanSetPr -class nsXPCComponents_Classes : public nsIXPCComponents_Classes, public nsIXPCScriptable +class nsXPCComponents_Classes : + public nsIXPCComponents_Classes, + public nsIXPCScriptable, + public nsIClassInfo { public: // all the interface method declarations... NS_DECL_ISUPPORTS NS_DECL_NSIXPCCOMPONENTS_CLASSES NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO public: nsXPCComponents_Classes(); virtual ~nsXPCComponents_Classes(); }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCComponents_Classes) + PUSH_IID(nsIXPCScriptable) +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Classes"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents_Classes::nsXPCComponents_Classes() { } @@ -584,6 +886,7 @@ nsXPCComponents_Classes::~nsXPCComponent NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Classes) NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Classes) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Classes) NS_INTERFACE_MAP_END_THREADSAFE @@ -716,19 +1019,117 @@ nsXPCComponents_Classes::NewResolve(nsIX /***************************************************************************/ /***************************************************************************/ -class nsXPCComponents_ClassesByID : public nsIXPCComponents_ClassesByID, public nsIXPCScriptable +class nsXPCComponents_ClassesByID : + public nsIXPCComponents_ClassesByID, + public nsIXPCScriptable, + public nsIClassInfo { public: // all the interface method declarations... NS_DECL_ISUPPORTS NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO public: nsXPCComponents_ClassesByID(); virtual ~nsXPCComponents_ClassesByID(); }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCComponents_ClassesByID) + PUSH_IID(nsIXPCScriptable) +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_ClassesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents_ClassesByID::nsXPCComponents_ClassesByID() { } @@ -741,6 +1142,7 @@ nsXPCComponents_ClassesByID::~nsXPCCompo NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ClassesByID) NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ClassesByID) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ClassesByID) NS_INTERFACE_MAP_END_THREADSAFE @@ -892,19 +1294,117 @@ nsXPCComponents_ClassesByID::NewResolve( // Currently the possible results do not change at runtime, so they are only // cached once (unlike ContractIDs, CLSIDs, and IIDs) -class nsXPCComponents_Results : public nsIXPCComponents_Results, public nsIXPCScriptable +class nsXPCComponents_Results : + public nsIXPCComponents_Results, + public nsIXPCScriptable, + public nsIClassInfo { public: // all the interface method declarations... NS_DECL_ISUPPORTS NS_DECL_NSIXPCCOMPONENTS_RESULTS NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO public: nsXPCComponents_Results(); virtual ~nsXPCComponents_Results(); }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_Results::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCComponents_Results) + PUSH_IID(nsIXPCScriptable) +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_Results::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_Results::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_Results::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_Results::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_Results::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_Results::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_Results::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents_Results::nsXPCComponents_Results() { } @@ -917,6 +1417,7 @@ nsXPCComponents_Results::~nsXPCComponent NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Results) NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Results) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Results) NS_INTERFACE_MAP_END_THREADSAFE @@ -1019,13 +1520,17 @@ nsXPCComponents_Results::NewResolve(nsIX /***************************************************************************/ // JavaScript Constructor for nsIJSID objects (Components.ID) -class nsXPCComponents_ID : public nsIXPCComponents_ID, public nsIXPCScriptable +class nsXPCComponents_ID : + public nsIXPCComponents_ID, + public nsIXPCScriptable, + public nsIClassInfo { public: // all the interface method declarations... NS_DECL_ISUPPORTS NS_DECL_NSIXPCCOMPONENTS_ID NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO public: @@ -1039,6 +1544,100 @@ private: jsval * vp, PRBool *_retval); }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_ID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCComponents_ID) + PUSH_IID(nsIXPCScriptable) +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_ID::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_ID::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_ID::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_ID::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_ID::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_ID::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_ID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents_ID::nsXPCComponents_ID() { } @@ -1051,6 +1650,7 @@ nsXPCComponents_ID::~nsXPCComponents_ID( NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ID) NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ID) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ID) NS_INTERFACE_MAP_END_THREADSAFE @@ -1148,13 +1748,17 @@ nsXPCComponents_ID::HasInstance(nsIXPCon /***************************************************************************/ // JavaScript Constructor for nsIXPCException objects (Components.Exception) -class nsXPCComponents_Exception : public nsIXPCComponents_Exception, public nsIXPCScriptable +class nsXPCComponents_Exception : + public nsIXPCComponents_Exception, + public nsIXPCScriptable, + public nsIClassInfo { public: // all the interface method declarations... NS_DECL_ISUPPORTS NS_DECL_NSIXPCCOMPONENTS_EXCEPTION NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO public: @@ -1168,6 +1772,100 @@ private: jsval * vp, PRBool *_retval); }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCComponents_Exception) + PUSH_IID(nsIXPCScriptable) +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents_Exception::nsXPCComponents_Exception() { } @@ -1180,6 +1878,7 @@ nsXPCComponents_Exception::~nsXPCCompone NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Exception) NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Exception) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Exception) NS_INTERFACE_MAP_END_THREADSAFE @@ -1335,7 +2034,10 @@ nsXPCComponents_Exception::HasInstance(n { 0xb4a95150, 0xe25a, 0x11d3, \ { 0x8f, 0x61, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } } -class nsXPCConstructor : public nsIXPCConstructor, public nsIXPCScriptable +class nsXPCConstructor : + public nsIXPCConstructor, + public nsIXPCScriptable, + public nsIClassInfo { public: NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCCONSTRUCTOR_CID) @@ -1344,6 +2046,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIXPCCONSTRUCTOR NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO public: nsXPCConstructor(); // not implemented @@ -1363,6 +2066,100 @@ private: char* mInitializer; }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCConstructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCConstructor) + PUSH_IID(nsIXPCScriptable) +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCConstructor::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCConstructor::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCConstructor::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCConstructor::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCConstructor::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCConstructor::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCConstructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCConstructor::nsXPCConstructor(nsIJSCID* aClassID, nsIJSIID* aInterfaceID, const char* aInitializer) @@ -1408,6 +2205,7 @@ nsXPCConstructor::GetInitializer(char * NS_INTERFACE_MAP_BEGIN(nsXPCConstructor) NS_INTERFACE_MAP_ENTRY(nsIXPCConstructor) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCConstructor) NS_INTERFACE_MAP_END_THREADSAFE @@ -1511,13 +2309,17 @@ nsXPCConstructor::CallOrConstruct(nsIXPC /*******************************************************/ // JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor) -class nsXPCComponents_Constructor : public nsIXPCComponents_Constructor, public nsIXPCScriptable +class nsXPCComponents_Constructor : + public nsIXPCComponents_Constructor, + public nsIXPCScriptable, + public nsIClassInfo { public: // all the interface method declarations... NS_DECL_ISUPPORTS NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO public: nsXPCComponents_Constructor(); @@ -1530,6 +2332,100 @@ private: jsval * vp, PRBool *_retval); }; +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCComponents_Constructor) + PUSH_IID(nsIXPCScriptable) +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents_Interfaces"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents_Constructor::nsXPCComponents_Constructor() { } @@ -1542,6 +2438,7 @@ nsXPCComponents_Constructor::~nsXPCCompo NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Constructor) NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Constructor) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Constructor) NS_INTERFACE_MAP_END_THREADSAFE @@ -1900,9 +2797,12 @@ nsXPCComponents_Utils::LookupMethod() // method/property is atomized. jsid name_id; - if(!JS_ValueToId(cx, argv[1], &name_id) || - !JS_IdToValue(cx, name_id, &argv[1])) - return NS_ERROR_XPC_BAD_CONVERT_JS; + { + AutoJSRequestWithNoCallContext req(cx); + if(!JS_ValueToId(cx, argv[1], &name_id) || + !JS_IdToValue(cx, name_id, &argv[1])) + return NS_ERROR_XPC_BAD_CONVERT_JS; + } // this will do verification and the method lookup for us XPCCallContext inner_cc(JS_CALLER, cx, obj, nsnull, argv[1]); @@ -1927,13 +2827,17 @@ nsXPCComponents_Utils::LookupMethod() if(!member->GetValue(inner_cc, iface, &funval)) return NS_ERROR_XPC_BAD_CONVERT_JS; - // Make sure the function we're cloning doesn't go away while - // we're cloning it. - AUTO_MARK_JSVAL(inner_cc, funval); - - // clone a function we can use for this object - JSObject* funobj = xpc_CloneJSFunction(inner_cc, JSVAL_TO_OBJECT(funval), - wrapper->GetFlatJSObject()); + JSObject* funobj; + { + // Make sure the function we're cloning doesn't go away while + // we're cloning it. + AUTO_MARK_JSVAL(inner_cc, funval); + AutoJSRequest req(inner_cc); + + // clone a function we can use for this object + funobj = xpc_CloneJSFunction(inner_cc, JSVAL_TO_OBJECT(funval), + wrapper->GetFlatJSObject()); + } if(!funobj) return NS_ERROR_XPC_BAD_CONVERT_JS; @@ -2001,6 +2905,7 @@ nsXPCComponents_Utils::ReportError() if(NS_FAILED(rv) || !argv) return NS_OK; + AutoJSRequestWithNoCallContext req(cx); JSErrorReport* err = JS_ErrorFromException(cx, argv[0]); if(err) { @@ -2531,6 +3436,7 @@ nsXPCComponents_Utils::CanSetProperty(co NS_INTERFACE_MAP_BEGIN(nsXPCComponents) NS_INTERFACE_MAP_ENTRY(nsIXPCComponents) NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent) #endif @@ -2540,6 +3446,105 @@ NS_INTERFACE_MAP_END_THREADSAFE NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents) NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents) +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +nsXPCComponents::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 2; +#ifdef XPC_USE_SECURITY_CHECKED_COMPONENT + ++count; +#endif + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCComponents) + PUSH_IID(nsIXPCScriptable) +#ifdef XPC_USE_SECURITY_CHECKED_COMPONENT + PUSH_IID(nsISecurityCheckedComponent) +#endif +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +nsXPCComponents::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +nsXPCComponents::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +nsXPCComponents::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "XPCComponents"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +nsXPCComponents::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +nsXPCComponents::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +nsXPCComponents::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +nsXPCComponents::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + nsXPCComponents::nsXPCComponents() : mInterfaces(nsnull), mInterfacesByID(nsnull), Index: src/xpcconvert.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcconvert.cpp,v retrieving revision 1.96 diff -u -p -r1.96 xpcconvert.cpp --- src/xpcconvert.cpp 1 Jun 2005 01:21:23 -0000 1.96 +++ src/xpcconvert.cpp 2 Feb 2006 10:46:10 -0000 @@ -993,7 +993,7 @@ XPCConvert::JSData2Native(XPCCallContext } return JSObject2NativeInterface(ccx, (void**)d, obj, iid, - nsnull, pErr); + nsnull, PR_TRUE, pErr); } default: NS_ASSERTION(0, "bad type"); @@ -1131,6 +1131,7 @@ XPCConvert::JSObject2NativeInterface(XPC void** dest, JSObject* src, const nsID* iid, nsISupports* aOuter, + PRBool createNew, nsresult* pErr) { NS_ASSERTION(dest, "bad param"); @@ -1140,7 +1141,7 @@ XPCConvert::JSObject2NativeInterface(XPC JSContext* cx = ccx.GetJSContext(); *dest = nsnull; - if(pErr) + if(pErr) *pErr = NS_ERROR_XPC_BAD_CONVERT_JS; nsISupports* iface; @@ -1184,7 +1185,13 @@ XPCConvert::JSObject2NativeInterface(XPC // else... nsXPCWrappedJS* wrapper; - nsresult rv = nsXPCWrappedJS::GetNewOrUsed(ccx, src, *iid, aOuter, &wrapper); + nsresult rv; + if (createNew) { + rv = nsXPCWrappedJS::GetNewOrUsed(ccx, src, *iid, aOuter, &wrapper); + } else { + rv = nsXPCWrappedJS::GetUsedOnly(ccx, src, *iid, aOuter, &wrapper); + } + if(pErr) *pErr = rv; if(NS_SUCCEEDED(rv) && wrapper) @@ -1218,19 +1225,25 @@ XPCConvert::ConstructException(nsresult static const char format[] = "\'%s\' when calling method: [%s::%s]"; const char * msg = message; char* sz = nsnull; + nsXPIDLString xmsg; + nsCAutoString sxmsg; + nsCOMPtr errorObject = do_QueryInterface(data); + if(errorObject) { + if (NS_SUCCEEDED(errorObject->GetMessage(getter_Copies(xmsg)))) { + CopyUTF16toUTF8(xmsg, sxmsg); + msg = sxmsg.get(); + } + } if(!msg) if(!nsXPCException::NameAndFormatForNSResult(rv, nsnull, &msg) || ! msg) msg = ""; - if(ifaceName && methodName) - sz = JS_smprintf(format, msg, ifaceName, methodName); - else - sz = (char*) msg; // I promise to play nice after casting away const + msg = sz = JS_smprintf(format, msg, ifaceName, methodName); - nsresult res = nsXPCException::NewException(sz, rv, nsnull, data, exceptn); + nsresult res = nsXPCException::NewException(msg, rv, nsnull, data, exceptn); - if(sz && sz != msg) + if(sz) JS_smprintf_free(sz); return res; } Index: src/xpcdebug.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcdebug.cpp,v retrieving revision 1.14 diff -u -p -r1.14 xpcdebug.cpp --- src/xpcdebug.cpp 23 May 2005 21:00:06 -0000 1.14 +++ src/xpcdebug.cpp 2 Feb 2006 10:46:10 -0000 @@ -49,7 +49,9 @@ static const char* JSVAL2String(JSContext* cx, jsval val, JSBool* isString) { const char* value = nsnull; + JS_BeginRequest(cx); JSString* value_str = JS_ValueToString(cx, val); + JS_EndRequest(cx); if(value_str) value = JS_GetStringBytes(value_str); if(value) @@ -89,6 +91,7 @@ static char* FormatJSFrame(JSContext* cx JSScript* script = JS_GetFrameScript(cx, fp); jsbytecode* pc = JS_GetFramePC(cx, fp); + JS_BeginRequest(cx); if(script && pc) { filename = JS_GetScriptFilename(cx, script); @@ -257,6 +260,7 @@ static char* FormatJSFrame(JSContext* cx } out: + JS_EndRequest(cx); if(callProps.array) JS_PutPropertyDescArray(cx, &callProps); if(thisProps.array) @@ -337,6 +341,7 @@ xpc_DumpEvalInJSStackFrame(JSContext* cx return JS_FALSE; } + JS_BeginRequest(cx); JSExceptionState* exceptionState = JS_SaveExceptionState(cx); JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter); @@ -353,6 +358,7 @@ xpc_DumpEvalInJSStackFrame(JSContext* cx puts("eval failed!"); JS_SetErrorReporter(cx, older); JS_RestoreExceptionState(cx, exceptionState); + JS_EndRequest(cx); return JS_TRUE; } Index: src/xpcexception.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcexception.cpp,v retrieving revision 1.30 diff -u -p -r1.30 xpcexception.cpp --- src/xpcexception.cpp 19 Jun 2004 01:19:27 -0000 1.30 +++ src/xpcexception.cpp 2 Feb 2006 10:46:11 -0000 @@ -402,7 +402,7 @@ nsXPCException::NewException(const char { // A little hack... The nsIGenericModule nsIClassInfo scheme relies on there // having been at least one instance made via the factory. Otherwise, the - // shared factory/classinsance object never gets created and our QI getter + // shared factory/classinstance object never gets created and our QI getter // for our instance's pointer to our nsIClassInfo will always return null. // This is bad because it means that wrapped exceptions will never have a // shared prototype. So... We force one to be created via the factory @@ -411,7 +411,7 @@ nsXPCException::NewException(const char { nsCOMPtr e = do_CreateInstance(XPC_EXCEPTION_CONTRACTID); - sEverMadeOneFromFactory = JS_TRUE; + sEverMadeOneFromFactory = !!e; } nsresult rv; Index: src/xpcjsid.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcjsid.cpp,v retrieving revision 1.66 diff -u -p -r1.66 xpcjsid.cpp --- src/xpcjsid.cpp 7 Nov 2004 23:59:26 -0000 1.66 +++ src/xpcjsid.cpp 2 Feb 2006 10:46:13 -0000 @@ -297,23 +297,25 @@ static JSBool gClassObjectsWereInited = NS_DECL_CI_INTERFACE_GETTER(nsJSIID) // Can't make this static. http://bugzilla.mozilla.org/show_bug.cgi?id=81436 nsIClassInfo* NS_CLASSINFO_NAME(nsJSIID); + static const nsModuleComponentInfo CI_nsJSIID = {"JSIID", {0x26ecb8d0, 0x35c9, 0x11d5, { 0x90, 0xb2, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a }}, nsnull, nsnull, nsnull,nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(nsJSIID), GetSharedScriptableHelperForJSIID, - &NS_CLASSINFO_NAME(nsJSIID), 0}; + &NS_CLASSINFO_NAME(nsJSIID), nsIClassInfo::THREADSAFE}; NS_DECL_CI_INTERFACE_GETTER(nsJSCID) // Can't make this static. http://bugzilla.mozilla.org/show_bug.cgi?id=81436 nsIClassInfo* NS_CLASSINFO_NAME(nsJSCID); + static const nsModuleComponentInfo CI_nsJSCID = {"JSCID", {0x9255b5b0, 0x35cf, 0x11d5, { 0x90, 0xb2, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a }}, nsnull, nsnull, nsnull,nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(nsJSCID), nsnull, - &NS_CLASSINFO_NAME(nsJSCID), 0}; + &NS_CLASSINFO_NAME(nsJSCID), nsIClassInfo::THREADSAFE}; JSBool xpc_InitJSxIDClassObjects() { Index: src/xpcjsruntime.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp,v retrieving revision 1.43 diff -u -p -r1.43 xpcjsruntime.cpp --- src/xpcjsruntime.cpp 15 Jun 2005 00:23:32 -0000 1.43 +++ src/xpcjsruntime.cpp 2 Feb 2006 10:46:13 -0000 @@ -224,6 +224,10 @@ DetachedWrappedNativeProtoMarker(JSDHash return JS_DHASH_NEXT; } +#ifdef XPC_TRACK_DEFERRED_RELEASES +#include "nsDataHashtable.h" +#include "nsHashkeys.h" +#endif // static JSBool XPCJSRuntime::GCCallback(JSContext *cx, JSGCStatus status) { @@ -332,6 +336,13 @@ JSBool XPCJSRuntime::GCCallback(JSContex } wrapper = NS_STATIC_CAST(nsXPCWrappedJS*, dyingWrappedJSArray->ElementAt(count-1)); +#ifdef XP_WIN + // Try to detect free'd pointer + NS_ASSERTION((int)wrapper != 0xfeeefeee, "bad pointer!"); + NS_ASSERTION((int)wrapper != 0xfdfdfdfd, "bad pointer!"); + NS_ASSERTION((int)wrapper != 0xdddddddd, "bad pointer!"); + NS_ASSERTION((int)wrapper != 0, "bad pointer!"); +#endif dyingWrappedJSArray->RemoveElementAt(count-1); } NS_RELEASE(wrapper); @@ -541,6 +552,10 @@ JSBool XPCJSRuntime::GCCallback(JSContex { nsVoidArray* array = &self->mNativesToReleaseArray; #ifdef XPC_TRACK_DEFERRED_RELEASES + nsDataHashtable dropped; + JSBool hashtable = dropped.Init(array->Count()); +#endif +#ifdef XPC_TRACK_DEFERRED_RELEASES printf("XPC - Begin deferred Release of %d nsISupports pointers\n", array->Count()); #endif @@ -559,7 +574,30 @@ JSBool XPCJSRuntime::GCCallback(JSContex array->ElementAt(count-1)); array->RemoveElementAt(count-1); } +#ifndef XPC_TRACK_DEFERRED_RELEASES NS_RELEASE(obj); +#else + if (hashtable) + { + PRUint32 rc = 1; + if (dropped.Get(obj, &rc)) + { + NS_ASSERTION(rc, "Releasing already destroyed deferred pointer"); + } +#ifdef XP_WIN + // Try to detect free'd pointer + NS_ASSERTION(*(int*)obj != 0xfeeefeee, "bad pointer!"); + NS_ASSERTION(*(int*)obj != 0xfdfdfdfd, "bad pointer!"); + NS_ASSERTION(*(int*)obj != 0xdddddddd, "bad pointer!"); + NS_ASSERTION(*(int*)obj != 0, "bad pointer!"); +#endif + if (rc) { + nsrefcnt refcnt; + NS_RELEASE2(obj, refcnt); + dropped.Put(obj, refcnt); + } + } +#endif } #ifdef XPC_TRACK_DEFERRED_RELEASES printf("XPC - End deferred Releases\n"); @@ -911,8 +949,10 @@ XPCJSRuntime::SyncXPCContextList(JSConte } // if it is our first context then we need to generate our string ids - if(!mStrIDs[0]) + if(!mStrIDs[0]) { + AutoJSRequestWithNoCallContext req(cur); GenerateStringIDs(cur); + } if(cx && cx == cur) found = xpcc; Index: src/xpcmodule.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcmodule.cpp,v retrieving revision 1.43 diff -u -p -r1.43 xpcmodule.cpp --- src/xpcmodule.cpp 20 Oct 2005 16:39:24 -0000 1.43 +++ src/xpcmodule.cpp 2 Feb 2006 10:46:13 -0000 @@ -88,7 +88,7 @@ static const nsModuleComponentInfo compo {nsnull, NS_XPCEXCEPTION_CID, XPC_EXCEPTION_CONTRACTID, nsXPCExceptionConstructor, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(nsXPCException), nsnull, &NS_CLASSINFO_NAME(nsXPCException)}, {nsnull, NS_JS_RUNTIME_SERVICE_CID, XPC_RUNTIME_CONTRACTID, nsIJSRuntimeServiceConstructor}, {NS_SCRIPTERROR_CLASSNAME, NS_SCRIPTERROR_CID, NS_SCRIPTERROR_CONTRACTID, nsScriptErrorConstructor }, - {nsnull, SCRIPTABLE_INTERFACES_CID, NS_SCRIPTABLE_INTERFACES_CONTRACTID, nsXPCComponents_InterfacesConstructor }, + {nsnull, SCRIPTABLE_INTERFACES_CID, NS_SCRIPTABLE_INTERFACES_CONTRACTID, nsXPCComponents_InterfacesConstructor, 0, 0, 0, 0, 0, 0, nsIClassInfo::THREADSAFE }, {nsnull, XPCVARIANT_CID, XPCVARIANT_CONTRACTID, nsnull, nsnull, nsnull, nsnull, NS_CI_INTERFACE_GETTER_NAME(XPCVariant), nsnull, &NS_CLASSINFO_NAME(XPCVariant)}, {nsnull, NS_XPC_JSCONTEXT_STACK_ITERATOR_CID, XPC_JSCONTEXT_STACK_ITERATOR_CONTRACTID, nsXPCJSContextStackIteratorConstructor } Index: src/xpcprivate.h =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcprivate.h,v retrieving revision 1.172 diff -u -p -r1.172 xpcprivate.h --- src/xpcprivate.h 3 Dec 2005 07:42:29 -0000 1.172 +++ src/xpcprivate.h 2 Feb 2006 10:46:14 -0000 @@ -140,11 +140,13 @@ // Note that one would not normally turn *any* of these on in a non-DEBUG build. +#define DEBUG_xpc_hacker + #if defined(DEBUG_jband) || defined(DEBUG_jst) || defined(DEBUG_dbradley) || defined(DEBUG_shaver_no) || defined(DEBUG_timeless) #define DEBUG_xpc_hacker #endif -#if defined(DEBUG_brendan) || defined(DEBUG_bzbarsky) +#if defined(DEBUG_brendan) || defined(DEBUG_bzbarsky) || defined(DEBUG_jst) #define DEBUG_XPCNativeWrapper 1 #endif @@ -293,7 +295,7 @@ public: {nsAutoMonitor::DestroyMonitor(lock);} XPCAutoLock(XPCLock* lock) -#ifdef DEBUG +#ifdef DEBUG_jband : nsAutoLockBase(lock ? (void*) lock : (void*) this, eAutoMonitor), #else : nsAutoLockBase(lock, eAutoMonitor), @@ -2068,11 +2070,9 @@ private: XPCWrappedNativeTearOffChunk mFirstChunk; JSObject* mNativeWrapper; -#ifdef XPC_CHECK_WRAPPER_THREADSAFETY public: - PRThread* mThread; // Don't want to overload _mOwningThread + PRThread* mThread; static PRThread* gMainThread; -#endif }; /*************************************************************************** @@ -2132,7 +2132,7 @@ public: nsXPTCMiniVariant* params); JSObject* CallQueryInterfaceOnJSObject(XPCCallContext& ccx, - JSObject* jsobj, REFNSIID aIID); + JSObject* jsobj, REFNSIID aIID, nsresult* rv = 0); static nsresult BuildPropertyEnumerator(XPCCallContext& ccx, JSObject* aJSObj, @@ -2232,6 +2232,12 @@ public: REFNSIID aIID, nsISupports* aOuter, nsXPCWrappedJS** wrapper); + static nsresult + GetUsedOnly(XPCCallContext& ccx, + JSObject* aJSObj, + REFNSIID aIID, + nsISupports* aOuter, + nsXPCWrappedJS** wrapperResult); JSObject* GetJSObject() const {return mJSObj;} nsXPCWrappedJSClass* GetClass() const {return mClass;} @@ -2373,6 +2379,7 @@ public: void** dest, JSObject* src, const nsID* iid, nsISupports* aOuter, + PRBool createNew, nsresult* pErr); static JSBool NativeArray2JS(XPCCallContext& ccx, @@ -2794,8 +2801,9 @@ public: mResolvingWrapper = w; return old;} void Cleanup(); + void ReleaseNatives(); - PRBool IsValid() const {return mJSContextStack != nsnull;} + PRBool IsValid() const {return mJSContextStack && mNativesLock;} static PRLock* GetLock() {return gLock;} // Must be called with the threads locked. @@ -2846,6 +2854,9 @@ private: #ifdef XPC_CHECK_WRAPPER_THREADSAFETY JSUint32 mWrappedNativeThreadsafetyReportDepth; #endif + PRThread* mThread; + nsVoidArray mNativesToReleaseArray; + PRLock* mNativesLock; static PRLock* gLock; static XPCPerThreadData* gThreads; @@ -2894,11 +2905,12 @@ private: #ifndef XPCONNECT_STANDALONE #include "nsIScriptSecurityManager.h" -class BackstagePass : public nsIScriptObjectPrincipal, public nsIXPCScriptable +class BackstagePass : public nsIScriptObjectPrincipal, public nsIXPCScriptable, public nsIClassInfo { public: NS_DECL_ISUPPORTS NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO virtual nsIPrincipal* GetPrincipal() { return mPrincipal; @@ -2917,11 +2929,12 @@ private: #else -class BackstagePass : public nsIXPCScriptable +class BackstagePass : public nsIXPCScriptable, public nsIClassInfo { public: NS_DECL_ISUPPORTS NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO BackstagePass() { @@ -2960,7 +2973,8 @@ class nsJSRuntimeServiceImpl : public ns // 'Components' object class nsXPCComponents : public nsIXPCComponents, - public nsIXPCScriptable + public nsIXPCScriptable, + public nsIClassInfo #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT , public nsISecurityCheckedComponent #endif @@ -2969,6 +2983,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIXPCCOMPONENTS NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT NS_DECL_NSISECURITYCHECKEDCOMPONENT @@ -3004,7 +3019,8 @@ private: class nsXPCComponents_Interfaces : public nsIScriptableInterfaces, - public nsIXPCScriptable + public nsIXPCScriptable, + public nsIClassInfo #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT , public nsISecurityCheckedComponent #endif @@ -3014,6 +3030,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSISCRIPTABLEINTERFACES NS_DECL_NSIXPCSCRIPTABLE + NS_DECL_NSICLASSINFO #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT NS_DECL_NSISECURITYCHECKEDCOMPONENT #endif Index: src/xpcruntimesvc.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcruntimesvc.cpp,v retrieving revision 1.18 diff -u -p -r1.18 xpcruntimesvc.cpp --- src/xpcruntimesvc.cpp 12 May 2005 03:55:41 -0000 1.18 +++ src/xpcruntimesvc.cpp 2 Feb 2006 10:46:14 -0000 @@ -41,11 +41,17 @@ #include "xpcprivate.h" +NS_INTERFACE_MAP_BEGIN(BackstagePass) + NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIClassInfo) #ifndef XPCONNECT_STANDALONE -NS_IMPL_THREADSAFE_ISUPPORTS2(BackstagePass, nsIScriptObjectPrincipal, nsIXPCScriptable) -#else -NS_IMPL_THREADSAFE_ISUPPORTS1(BackstagePass, nsIXPCScriptable) + NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal) #endif + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCScriptable) +NS_INTERFACE_MAP_END_THREADSAFE + +NS_IMPL_THREADSAFE_ADDREF(BackstagePass) +NS_IMPL_THREADSAFE_RELEASE(BackstagePass) // The nsIXPCScriptable map declaration that will generate stubs for us... #define XPC_MAP_CLASSNAME BackstagePass @@ -74,6 +80,105 @@ BackstagePass::NewResolve(nsIXPConnectWr return NS_OK; } +/***************************************************************************/ +/* void getInterfaces (out PRUint32 count, [array, size_is (count), retval] + out nsIIDPtr array); */ +NS_IMETHODIMP +BackstagePass::GetInterfaces(PRUint32 *aCount, nsIID * **aArray) +{ + nsresult rv = NS_OK; + PRUint32 count = 1; +#ifndef XPCONNECT_STANDALONE + ++count; +#endif + *aCount = count; + nsIID **array; + *aArray = array = NS_STATIC_CAST(nsIID**, nsMemory::Alloc(count * sizeof(nsIID*))); + if(!array) + return NS_ERROR_OUT_OF_MEMORY; + + PRUint32 index = 0; + nsIID* clone; +#define PUSH_IID(id) \ + clone = NS_STATIC_CAST(nsIID *, nsMemory::Clone(&NS_GET_IID( id ), \ + sizeof(nsIID))); \ + if (!clone) \ + goto oom; \ + array[index++] = clone; + + PUSH_IID(nsIXPCScriptable) +#ifndef XPCONNECT_STANDALONE + PUSH_IID(nsIScriptObjectPrincipal) +#endif +#undef PUSH_IID + + return NS_OK; +oom: + while (index) + nsMemory::Free(array[--index]); + nsMemory::Free(array); + *aArray = nsnull; + return NS_ERROR_OUT_OF_MEMORY; +} + +/* nsISupports getHelperForLanguage (in PRUint32 language); */ +NS_IMETHODIMP +BackstagePass::GetHelperForLanguage(PRUint32 language, + nsISupports **retval) +{ + *retval = nsnull; + return NS_OK; +} + +/* readonly attribute string contractID; */ +NS_IMETHODIMP +BackstagePass::GetContractID(char * *aContractID) +{ + *aContractID = nsnull; + return NS_ERROR_NOT_AVAILABLE; +} + +/* readonly attribute string classDescription; */ +NS_IMETHODIMP +BackstagePass::GetClassDescription(char * *aClassDescription) +{ + static const char classDescription[] = "BackstagePass"; + *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription)); + return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* readonly attribute nsCIDPtr classID; */ +NS_IMETHODIMP +BackstagePass::GetClassID(nsCID * *aClassID) +{ + *aClassID = nsnull; + return NS_OK; +} + +/* readonly attribute PRUint32 implementationLanguage; */ +NS_IMETHODIMP +BackstagePass::GetImplementationLanguage( + PRUint32 *aImplementationLanguage) +{ + *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; +} + +/* readonly attribute PRUint32 flags; */ +NS_IMETHODIMP +BackstagePass::GetFlags(PRUint32 *aFlags) +{ + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +/* [notxpcom] readonly attribute nsCID classIDNoAlloc; */ +NS_IMETHODIMP +BackstagePass::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +{ + return NS_ERROR_NOT_AVAILABLE; +} + /* * This object holds state that we don't want to lose! * @@ -137,7 +242,14 @@ nsJSRuntimeServiceImpl::GetRuntime(JSRun if(!mRuntime) { - mRuntime = JS_NewRuntime(gGCSize); + char *jsrts = PR_GetEnv("JS_RUNTIME_SIZE"); + uint32 size = jsrts ? atoi(jsrts) : 0; + if (size > 1) { + size *= 1024; + } else { + size = gGCSize; + } + mRuntime = JS_NewRuntime(size); if(!mRuntime) return NS_ERROR_OUT_OF_MEMORY; } Index: src/xpcthreadcontext.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcthreadcontext.cpp,v retrieving revision 1.40 diff -u -p -r1.40 xpcthreadcontext.cpp --- src/xpcthreadcontext.cpp 17 Oct 2005 18:47:13 -0000 1.40 +++ src/xpcthreadcontext.cpp 2 Feb 2006 10:46:14 -0000 @@ -134,6 +134,26 @@ static JSClass global_class = { JSCLASS_NO_OPTIONAL_MEMBERS }; +static jsuword +GetStackLimit() +{ + // XXX improve me + + jsuword stackLimit; + + int stackDummy; + jsuword currentStackAddr = (jsuword)&stackDummy; + + // We assume here that the stack grows down, and that a stack + // limit of 512k below the current stack addr is ok. If this is + // not the case on some platforms, #ifdef's are needed for those + // platforms. + stackLimit = currentStackAddr + + (0x80000 * JS_STACK_GROWTH_DIRECTION); + + return stackLimit; +} + /* attribute JSContext safeJSContext; */ NS_IMETHODIMP XPCJSContextStack::GetSafeJSContext(JSContext * *aSafeJSContext) @@ -151,6 +171,7 @@ XPCJSContextStack::GetSafeJSContext(JSCo mSafeJSContext = JS_NewContext(rt, 8192); if(mSafeJSContext) { + ::JS_SetThreadStackLimit(mSafeJSContext, GetStackLimit()); // scoped JS Request AutoJSRequestWithNoCallContext req(mSafeJSContext); JSObject *glob; @@ -362,10 +383,11 @@ XPCPerThreadData::XPCPerThreadData() mExceptionManager(nsnull), mException(nsnull), mExceptionManagerNotAvailable(JS_FALSE), - mAutoRoots(nsnull) + mAutoRoots(nsnull), #ifdef XPC_CHECK_WRAPPER_THREADSAFETY - , mWrappedNativeThreadsafetyReportDepth(0) + mWrappedNativeThreadsafetyReportDepth(0), #endif + mNativesLock(PR_NewLock()) { if(gLock) { @@ -389,9 +411,65 @@ XPCPerThreadData::Cleanup() mCallContext->SystemIsBeingShutDown(); } +void +XPCPerThreadData::ReleaseNatives() +{ + nsVoidArray dyingNatives; + do { + if (!mNativesLock) + break; + PRInt32 count; + { + nsAutoLock lock(mNativesLock); + count = mNativesToReleaseArray.Count(); + if (!count) + break; + + dyingNatives = mNativesToReleaseArray; + if (dyingNatives.Count() != count) + { + NS_ERROR("we're in trouble"); + dyingNatives.Clear(); + void *elt = mNativesToReleaseArray[count - 1]; + dyingNatives.InsertElementAt(elt, 0); + mNativesToReleaseArray.RemoveElementAt(count - 1); + } + } + for (count = dyingNatives.Count(); count > 0; --count) + { + nsISupports *sup = NS_STATIC_CAST(nsISupports*, dyingNatives[count]); + dyingNatives.RemoveElementAt(count - 1); + NS_ASSERTION(sup, + "people should not stick null pointers into" + "a list of objects to be released"); + NS_IF_RELEASE(sup); + } + { + nsAutoLock lock(mNativesLock); + count = mNativesToReleaseArray.Count(); + if (count) + continue; + } + } while (0); + /* XXX this is the last chance to release thread bound + * objects on the right thread, theoretically the proper + * thing to do is to know what objects are left alive and + * not return until we've released all of them. + * + * actually doing this would result in deadlock when some + * thread decides to Join(us) in any case where someone + * manges to leak any object for which we're responsible. + */ +} + XPCPerThreadData::~XPCPerThreadData() { Cleanup(); + if(mNativesLock) + { + PR_DestroyLock(mNativesLock); + mNativesLock = nsnull; + } // Unlink 'this' from the list of threads. if(gLock) Index: src/xpcwrappedjs.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcwrappedjs.cpp,v retrieving revision 1.42 diff -u -p -r1.42 xpcwrappedjs.cpp --- src/xpcwrappedjs.cpp 3 Dec 2005 07:42:29 -0000 1.42 +++ src/xpcwrappedjs.cpp 2 Feb 2006 10:46:14 -0000 @@ -316,6 +316,59 @@ return_wrapper: return NS_OK; } +// static +nsresult +nsXPCWrappedJS::GetUsedOnly(XPCCallContext& ccx, + JSObject* aJSObj, + REFNSIID aIID, + nsISupports* aOuter, + nsXPCWrappedJS** wrapperResult) +{ + JSObject2WrappedJSMap* map; + JSObject* rootJSObj; + nsXPCWrappedJS* root; + nsXPCWrappedJS* wrapper = nsnull; + nsXPCWrappedJSClass *clazz = nsnull; + XPCJSRuntime* rt = ccx.GetRuntime(); + + map = rt->GetWrappedJSMap(); + if(!map) + { + NS_ASSERTION(map,"bad map"); + return NS_ERROR_FAILURE; + } + + nsXPCWrappedJSClass::GetNewOrUsed(ccx, aIID, &clazz); + if(!clazz) + return NS_ERROR_FAILURE; + + // always find the root JSObject + rootJSObj = clazz->GetRootJSObject(ccx, aJSObj); + + NS_RELEASE(clazz); + + if(!rootJSObj) + return NS_ERROR_FAILURE; + + // look for the root wrapper + { // scoped lock + XPCAutoLock lock(rt->GetMapLock()); + root = map->Find(rootJSObj); + } + + if(root) + { + if((nsnull != (wrapper = root->Find(aIID))) || + (nsnull != (wrapper = root->FindInherited(aIID)))) + { + NS_ADDREF(wrapper); + } + } + + *wrapperResult = wrapper; + return NS_OK; +} + nsXPCWrappedJS::nsXPCWrappedJS(XPCCallContext& ccx, JSObject* aJSObj, nsXPCWrappedJSClass* aClass, Index: src/xpcwrappedjsclass.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcwrappedjsclass.cpp,v retrieving revision 1.88 diff -u -p -r1.88 xpcwrappedjsclass.cpp --- src/xpcwrappedjsclass.cpp 3 Dec 2005 07:42:29 -0000 1.88 +++ src/xpcwrappedjsclass.cpp 2 Feb 2006 10:46:15 -0000 @@ -147,8 +147,20 @@ nsXPCWrappedJSClass::GetNewOrUsed(XPCCal ccx.GetXPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info)); if(info) { + // Modified to try to select a scriptable object. + nsCOMPtr info2; PRBool canScript; - if(NS_SUCCEEDED(info->IsScriptable(&canScript)) && canScript && + while (info) { + if(NS_FAILED(info->IsScriptable(&canScript))) + canScript = PR_FALSE; + else if(canScript) + break; + if (NS_FAILED(info->GetParent(getter_AddRefs(info2)))) + info = nsnull; + else + info.swap(info2); + } + if(canScript && nsXPConnect::IsISupportsDescendant(info)) { clazz = new nsXPCWrappedJSClass(ccx, aIID, info); @@ -225,10 +237,83 @@ nsXPCWrappedJSClass::~nsXPCWrappedJSClas NS_IF_RELEASE(mInfo); } +void JS_DLL_CALLBACK +XPC_ScriptErrorReporter(JSContext *cx, + const char *message, + JSErrorReport *report) +{ + nsAutoString fileName, msg; + + if (report) { + fileName.AssignWithConversion(report->filename); + + const PRUnichar *m = NS_REINTERPRET_CAST(const PRUnichar*, + report->ucmessage); + + if (m) { + msg.Assign(m); + } + } + + if (msg.IsEmpty() && message) { + msg.AssignWithConversion(message); + } + + + // Make an nsIScriptError and populate it with information from + // this error. + nsCOMPtr errorObject = + do_CreateInstance("@mozilla.org/scripterror;1"); + + if (!errorObject) + return; + nsresult rv; + + const char *category = "xpconnect wrapped class"; + + if (report) { + PRUint32 column = report->uctokenptr - report->uclinebuf; + + rv = errorObject->Init(msg.get(), fileName.get(), + NS_REINTERPRET_CAST(const PRUnichar*, + report->uclinebuf), + report->lineno, column, report->flags, + category); +#ifdef DEBUG_xpc_hacker + fprintf(stderr, "%s - message: %s\nfile: %s\ncode: %s\nline: %d col: %d flags: %d\n", + category, + NS_ConvertUCS2toUTF8(msg).get(), + NS_ConvertUCS2toUTF8(fileName).get(), + NS_ConvertUCS2toUTF8(NS_REINTERPRET_CAST(const PRUnichar*, + report->uclinebuf)), + report->lineno, + column, + report->flags); +#endif + } else if (message) { + rv = errorObject->Init(msg.get(), nsnull, nsnull, 0, 0, 0, + category); +#ifdef DEBUG_xpc_hacker + fprintf(stderr, "%s - message: %s\n", + category, + NS_ConvertUCS2toUTF8(msg).get()); +#endif + } + + if (NS_SUCCEEDED(rv)) { + nsCOMPtr consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (consoleService) { + consoleService->LogMessage(errorObject); + } + } +} + JSObject* nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(XPCCallContext& ccx, JSObject* jsobj, - REFNSIID aIID) + REFNSIID aIID, + nsresult* aRV) { JSContext* cx = ccx.GetJSContext(); JSObject* id; @@ -237,11 +322,17 @@ nsXPCWrappedJSClass::CallQueryInterfaceO JSBool success = JS_FALSE; jsid funid; jsval fun; + if (aRV) + *aRV = NS_ERROR_FAILURE; // check upfront for the existence of the function property funid = mRuntime->GetStringID(XPCJSRuntime::IDX_QUERY_INTERFACE); - if(!OBJ_GET_PROPERTY(cx, jsobj, funid, &fun) || JSVAL_IS_PRIMITIVE(fun)) + if(!OBJ_GET_PROPERTY(cx, jsobj, funid, &fun) || JSVAL_IS_PRIMITIVE(fun)) { + /* the lack of a QI function is ok */ + if (aRV) + *aRV = NS_OK; return nsnull; + } // protect fun so that we're sure it's alive when we call it AUTO_MARK_JSVAL(ccx, fun); @@ -252,36 +343,72 @@ nsXPCWrappedJSClass::CallQueryInterfaceO // some interfaces in JS and aggregating a trusted object to // implement intentionally (for security) unscriptable interfaces. // We so often ask for nsISupports that we can short-circuit the test... + nsCOMPtr scriptableInfo; if(!aIID.Equals(NS_GET_IID(nsISupports))) { nsCOMPtr info; ccx.GetXPConnect()->GetInfoForIID(&aIID, getter_AddRefs(info)); if(!info) return nsnull; - PRBool canScript; - if(NS_FAILED(info->IsScriptable(&canScript)) || !canScript) - return nsnull; + { + // Modified to try to select a scriptable object. + nsCOMPtr info2; + scriptableInfo = info; + PRBool canScript; + while (scriptableInfo) { + if(NS_FAILED(scriptableInfo->IsScriptable(&canScript))) + canScript = PR_FALSE; + else if(canScript) + break; + if (NS_FAILED(scriptableInfo->GetParent(getter_AddRefs(info2)))) + scriptableInfo = nsnull; + else + scriptableInfo.swap(info2); + } + if(!scriptableInfo) + return nsnull; + if(info == scriptableInfo) + scriptableInfo = nsnull; + } } // OK, it looks like we'll be calling into JS code. + { + AutoScriptEvaluate scriptEval(cx); - AutoScriptEvaluate scriptEval(cx); + // XXX we should install an error reporter that will send reports to + // the JS error console service. + scriptEval.StartEvaluating(); - // XXX we should install an error reporter that will send reports to - // the JS error console service. - scriptEval.StartEvaluating(); + id = xpc_NewIDObject(cx, jsobj, aIID); + if(id) + { + jsval args[1] = {OBJECT_TO_JSVAL(id)}; + success = JS_CallFunctionValue(cx, jsobj, fun, 1, args, &retval); + } - id = xpc_NewIDObject(cx, jsobj, aIID); - if(id) - { - jsval args[1] = {OBJECT_TO_JSVAL(id)}; - success = JS_CallFunctionValue(cx, jsobj, fun, 1, args, &retval); - } + JSErrorReporter er; + er = JS_SetErrorReporter(cx, XPC_ScriptErrorReporter); + + if(success) + success = JS_ValueToObject(cx, retval, &retObj); - if(success) - success = JS_ValueToObject(cx, retval, &retObj); + JS_SetErrorReporter(cx, er); + } - return success ? retObj : nsnull; + if(!success || !retObj) + return nsnull; + if(!scriptableInfo) { + if(aRV) + *aRV = NS_OK; + return retObj; + } + nsIID *scriptableIID; + if(NS_FAILED(scriptableInfo->GetInterfaceIID(&scriptableIID))) + return nsnull; // Does this leak something? like retObj + if(aRV) + *aRV = NS_OK; + return CallQueryInterfaceOnJSObject(ccx, retObj, *scriptableIID); } /***************************************************************************/ @@ -635,8 +762,12 @@ nsXPCWrappedJSClass::DelegatedQueryInter JSObject* nsXPCWrappedJSClass::GetRootJSObject(XPCCallContext& ccx, JSObject* aJSObj) { + nsresult rv = NS_OK; JSObject* result = CallQueryInterfaceOnJSObject(ccx, aJSObj, - NS_GET_IID(nsISupports)); + NS_GET_IID(nsISupports), + &rv); + if (NS_FAILED(rv)) + return nsnull; return result ? result : aJSObj; } @@ -1414,7 +1545,13 @@ pre_call_clean_up: ccx.GetThreadData()->SetException(nsnull); // XXX necessary? #define HANDLE_OUT_CONVERSION_FAILURE \ - {outConversionFailedIndex = i; break;} + { \ + outConversionFailedIndex = i; \ + retval = param.IsRetval() \ + ? NS_ERROR_XPC_BAD_CONVERT_RETURN \ + : NS_ERROR_XPC_BAD_CONVERT_OUT; \ + break; \ + } // convert out args and result // NOTE: this is the total number of native params, not just the args Index: src/xpcwrappednative.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcwrappednative.cpp,v retrieving revision 1.104 diff -u -p -r1.104 xpcwrappednative.cpp --- src/xpcwrappednative.cpp 16 Nov 2005 02:12:21 -0000 1.104 +++ src/xpcwrappednative.cpp 2 Feb 2006 10:46:16 -0000 @@ -899,6 +899,8 @@ XPCWrappedNative::FlatJSObjectFinalized( { #ifdef XP_WIN // Try to detect free'd pointer + NS_ASSERTION(*(int*)obj != 0xfeeefeee, "bad pointer!"); + NS_ASSERTION(*(int*)obj != 0xfdfdfdfd, "bad pointer!"); NS_ASSERTION(*(int*)obj != 0xdddddddd, "bad pointer!"); NS_ASSERTION(*(int*)obj != 0, "bad pointer!"); #endif @@ -929,6 +931,7 @@ XPCWrappedNative::FlatJSObjectFinalized( NS_ASSERTION(mIdentity, "bad pointer!"); #ifdef XP_WIN // Try to detect free'd pointer + NS_ASSERTION(*(int*)mIdentity != 0xfdfdfdfd, "bad pointer!"); NS_ASSERTION(*(int*)mIdentity != 0xdddddddd, "bad pointer!"); NS_ASSERTION(*(int*)mIdentity != 0, "bad pointer!"); #endif @@ -2926,6 +2929,7 @@ void DEBUG_ReportShadowedMembers(XPCNati // Add any classnames to skip to this (null terminated) array... static const char* skipClasses[] = { "Window", + "HTMLInputElement", "HTMLDocument", "HTMLCollection", "Event", @@ -2960,6 +2964,8 @@ void DEBUG_ReportShadowedMembers(XPCNati } if(quit) return; + if(si->GetFlags() & nsIClassInfo::DOM_OBJECT) + return; } const char header[] = Index: src/xpcwrappednativeinfo.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcwrappednativeinfo.cpp,v retrieving revision 1.14 diff -u -p -r1.14 xpcwrappednativeinfo.cpp --- src/xpcwrappednativeinfo.cpp 17 Sep 2005 04:20:51 -0000 1.14 +++ src/xpcwrappednativeinfo.cpp 2 Feb 2006 10:46:16 -0000 @@ -177,8 +177,12 @@ XPCNativeMember::Resolve(XPCCallContext& callback = XPC_WN_GetterSetter; } - JSFunction *fun = JS_NewFunction(cx, callback, argc, flags, nsnull, - iface->GetMemberName(ccx, this)); + JSFunction *fun; + { + AutoJSRequestWithNoCallContext req(cx); + fun = JS_NewFunction(cx, callback, argc, flags, nsnull, + iface->GetMemberName(ccx, this)); + } if(!fun) return JS_FALSE; @@ -186,9 +190,12 @@ XPCNativeMember::Resolve(XPCCallContext& if(!funobj) return JS_FALSE; - if(!JS_SetReservedSlot(ccx, funobj, 0, PRIVATE_TO_JSVAL(iface))|| - !JS_SetReservedSlot(ccx, funobj, 1, PRIVATE_TO_JSVAL(this))) - return JS_FALSE; + { + AutoJSRequestWithNoCallContext req(ccx); + if(!JS_SetReservedSlot(ccx, funobj, 0, PRIVATE_TO_JSVAL(iface))|| + !JS_SetReservedSlot(ccx, funobj, 1, PRIVATE_TO_JSVAL(this))) + return JS_FALSE; + } { // scoped lock XPCAutoLock lock(ccx.GetRuntime()->GetMapLock()); Index: src/xpcwrappednativejsops.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcwrappednativejsops.cpp,v retrieving revision 1.57 diff -u -p -r1.57 xpcwrappednativejsops.cpp --- src/xpcwrappednativejsops.cpp 8 Oct 2005 00:28:45 -0000 1.57 +++ src/xpcwrappednativejsops.cpp 2 Feb 2006 10:46:16 -0000 @@ -44,6 +44,17 @@ #include "xpcprivate.h" #include "XPCNativeWrapper.h" +/* Winerror.h(21313):// MessageId: RPC_E_ATTEMPTED_MULTITHREAD + * Winerror.h(21317):// Attempted to make calls on more than one thread in single threaded mode. + * Winerror.h(21319):#define RPC_E_ATTEMPTED_MULTITHREAD _HRESULT_TYPEDEF_(0x80010102L) + */ +#define NS_ERROR_ATTEMPTED_MULTITHREAD ((nsresult) 0x80010102) +/* Winerror.h(21421):// MessageId: RPC_E_WRONG_THREAD + * Winerror.h(21425):// The application called an interface that was marshalled for a different thread. + * Winerror.h(21427):#define RPC_E_WRONG_THREAD _HRESULT_TYPEDEF_(0x8001010EL) + */ +#define NS_ERROR_WRONG_THREAD ((nsresult) 0x8001010E) + /***************************************************************************/ // All of the exceptions thrown into JS from this file go through here. @@ -55,6 +66,20 @@ static JSBool Throw(uintN errNum, JSCont return JS_FALSE; } +#ifdef XPC_CHECK_WRAPPER_THREADSAFETY +#define THROW_AND_RETURN_IF_THREADUNSAFE(cx, wrapper) \ + PR_BEGIN_MACRO \ + XPCWrappedNativeProto* proto = wrapper->GetProto(); \ + if(proto && \ + !proto->ClassIsThreadSafe() && \ + wrapper->mThread != PR_GetCurrentThread()) \ + return Throw(NS_ERROR_ATTEMPTED_MULTITHREAD, cx); \ + PR_END_MACRO +#else +#define THROW_AND_RETURN_IF_THREADUNSAFE(cx, wrapper) \ + PR_BEGIN_MACRO \ + PR_END_MACRO +#endif // Handy macro used in many callback stub below. #define THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper) \ @@ -63,6 +88,7 @@ static JSBool Throw(uintN errNum, JSCont return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx); \ if(!wrapper->IsValid()) \ return Throw(NS_ERROR_XPC_HAS_BEEN_SHUTDOWN, cx); \ + THROW_AND_RETURN_IF_THREADUNSAFE(cx, wrapper); \ PR_END_MACRO // We rely on the engine only giving us jsval ids that are actually the @@ -741,12 +767,13 @@ GetIdentityObject(JSContext *cx, JSObjec { XPCWrappedNative *wrapper; - if(XPCNativeWrapper::IsNativeWrapper(cx, obj)) + if (XPCNativeWrapper::IsNativeWrapper(cx, obj)) { wrapper = XPCNativeWrapper::GetWrappedNative(cx, obj); - else + } else { wrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); + } - if(!wrapper) { + if (!wrapper) { return nsnull; } Index: src/xpcwrappednativeproto.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcwrappednativeproto.cpp,v retrieving revision 1.14 diff -u -p -r1.14 xpcwrappednativeproto.cpp --- src/xpcwrappednativeproto.cpp 20 May 2005 03:12:21 -0000 1.14 +++ src/xpcwrappednativeproto.cpp 2 Feb 2006 10:46:16 -0000 @@ -117,7 +117,8 @@ XPCWrappedNativeProto::Init( if(ok && JS_IsSystemObject(ccx, parent)) JS_FlagSystemObject(ccx, mJSProtoObject); - DEBUG_ReportShadowedMembers(mSet, nsnull, this); + if(ok) + DEBUG_ReportShadowedMembers(mSet, nsnull, this); return ok; } Index: tests/js/old/threads.js =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/tests/js/old/threads.js,v retrieving revision 1.2 diff -u -p -r1.2 threads.js --- tests/js/old/threads.js 20 Feb 2004 21:34:57 -0000 1.2 +++ tests/js/old/threads.js 2 Feb 2006 10:46:17 -0000 @@ -20,7 +20,7 @@ function threadProc() { // Commented this because I was thinking that the printf impl being called // on so many thread might be contributing to some apparent memory // corruption cases. - // print(" printed from other thread "+this.id+". foo is: "+foo); + print(" printed from other thread "+this.id+". foo is: "+foo); for(n in this.__parent__) /* print(n) */; }