nsresult nsXBLProtoImplField::InstallField(nsIScriptContext* aContext, JSObject* aBoundNode, nsIPrincipal* aPrincipal, nsIURI* aBindingDocURI, PRBool* aDidInstall) const { NS_TIME_FUNCTION_MIN(5); NS_PRECONDITION(aBoundNode, "uh-oh, bound node should NOT be null or bad things will " "happen"); *aDidInstall = PR_FALSE; if (mFieldTextLength == 0) { return NS_OK; } // EvaluateStringWithValue and JS_DefineUCProperty can both trigger GC, so // protect |result| here. nsresult rv; nsCAutoString uriSpec; aBindingDocURI->GetSpec(uriSpec); JSContext* cx = (JSContext*) aContext->GetNativeContext(); NS_ASSERTION(!::JS_IsExceptionPending(cx), "Shouldn't get here when an exception is pending!"); // compile the literal string PRBool undefined; nsCOMPtr<nsIScriptContext> context = aContext; JSAutoRequest ar(cx); jsval result = JSVAL_NULL; rv = context->EvaluateStringWithValue(nsDependentString(mFieldText, mFieldTextLength), aBoundNode, aPrincipal, uriSpec.get(), mLineNumber, JSVERSION_LATEST, (void*) &result, &undefined); if (NS_FAILED(rv)) return rv; if (undefined) { result = JSVAL_VOID; } // Define the evaluated result as a JS property nsDependentString name(mName); if (!::JS_DefineUCProperty(cx, aBoundNode, reinterpret_cast<const jschar*>(mName), name.Length(), result, nsnull, nsnull, mJSAttributes)) { return NS_ERROR_OUT_OF_MEMORY; } *aDidInstall = PR_TRUE; return NS_OK; }
/* * WaitOnWriteThread() is called from a main thread to wait for the worker * thread to finish. However since the same code is used in the worker thread and * main thread, the worker thread can also call WaitOnWriteThread() which is a no-op. */ void StartupCache::WaitOnWriteThread() { NS_ASSERTION(NS_IsMainThread(), "Startup cache should only wait for io thread on main thread"); if (!mWriteThread || mWriteThread == PR_GetCurrentThread()) return; NS_TIME_FUNCTION_MIN(30); PR_JoinThread(mWriteThread); mWriteThread = NULL; }
nsresult nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr, JSObject* aClassObject) { NS_TIME_FUNCTION_MIN(5); NS_PRECONDITION(!IsCompiled(), "Trying to compile an already-compiled method"); NS_PRECONDITION(aClassObject, "Must have class object to compile"); nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod(); // No parameters or body was supplied, so don't install method. if (!uncompiledMethod) { // Early return after which we consider ourselves compiled. mJSMethodObject = nsnull; return NS_OK; } // Don't install method if no name was supplied. if (!mName) { delete uncompiledMethod; // Early return after which we consider ourselves compiled. mJSMethodObject = nsnull; return NS_OK; } // We have a method. // Allocate an array for our arguments. PRInt32 paramCount = uncompiledMethod->GetParameterCount(); char** args = nsnull; if (paramCount > 0) { args = new char*[paramCount]; if (!args) return NS_ERROR_OUT_OF_MEMORY; // Add our parameters to our args array. PRInt32 argPos = 0; for (nsXBLParameter* curr = uncompiledMethod->mParameters; curr; curr = curr->mNext) { args[argPos] = curr->mName; argPos++; } } // Get the body nsDependentString body; PRUnichar *bodyText = uncompiledMethod->mBodyText.GetText(); if (bodyText) body.Rebind(bodyText); // Now that we have a body and args, compile the function // and then define it. NS_ConvertUTF16toUTF8 cname(mName); nsCAutoString functionUri(aClassStr); PRInt32 hash = functionUri.RFindChar('#'); if (hash != kNotFound) { functionUri.Truncate(hash); } JSObject* methodObject = nsnull; nsresult rv = aContext->CompileFunction(aClassObject, cname, paramCount, const_cast<const char**>(args), body, functionUri.get(), uncompiledMethod->mBodyText.GetLineNumber(), JSVERSION_LATEST, true, &methodObject); // Destroy our uncompiled method and delete our arg list. delete uncompiledMethod; delete [] args; if (NS_FAILED(rv)) { SetUncompiledMethod(nsnull); return rv; } mJSMethodObject = methodObject; return NS_OK; }