1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/src/nsXPConnect.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1628 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* High level class and public functions implementation. */ 1.11 + 1.12 +#include "mozilla/Assertions.h" 1.13 +#include "mozilla/Base64.h" 1.14 +#include "mozilla/Likely.h" 1.15 + 1.16 +#include "xpcprivate.h" 1.17 +#include "XPCWrapper.h" 1.18 +#include "jsfriendapi.h" 1.19 +#include "js/OldDebugAPI.h" 1.20 +#include "nsJSEnvironment.h" 1.21 +#include "nsThreadUtils.h" 1.22 +#include "nsDOMJSUtils.h" 1.23 + 1.24 +#include "WrapperFactory.h" 1.25 +#include "AccessCheck.h" 1.26 + 1.27 +#ifdef MOZ_JSDEBUGGER 1.28 +#include "jsdIDebuggerService.h" 1.29 +#endif 1.30 + 1.31 +#include "XPCQuickStubs.h" 1.32 + 1.33 +#include "mozilla/dom/BindingUtils.h" 1.34 +#include "mozilla/dom/Exceptions.h" 1.35 +#include "mozilla/dom/PromiseBinding.h" 1.36 +#include "mozilla/dom/TextDecoderBinding.h" 1.37 +#include "mozilla/dom/TextEncoderBinding.h" 1.38 +#include "mozilla/dom/DOMErrorBinding.h" 1.39 + 1.40 +#include "nsDOMMutationObserver.h" 1.41 +#include "nsICycleCollectorListener.h" 1.42 +#include "nsThread.h" 1.43 +#include "mozilla/XPTInterfaceInfoManager.h" 1.44 +#include "nsIObjectInputStream.h" 1.45 +#include "nsIObjectOutputStream.h" 1.46 + 1.47 +using namespace mozilla; 1.48 +using namespace mozilla::dom; 1.49 +using namespace xpc; 1.50 +using namespace JS; 1.51 + 1.52 +NS_IMPL_ISUPPORTS(nsXPConnect, 1.53 + nsIXPConnect, 1.54 + nsISupportsWeakReference, 1.55 + nsIThreadObserver, 1.56 + nsIJSRuntimeService) 1.57 + 1.58 +nsXPConnect* nsXPConnect::gSelf = nullptr; 1.59 +bool nsXPConnect::gOnceAliveNowDead = false; 1.60 +uint32_t nsXPConnect::gReportAllJSExceptions = 0; 1.61 + 1.62 +bool xpc::gDebugMode = false; 1.63 +bool xpc::gDesiredDebugMode = false; 1.64 + 1.65 +// Global cache of the default script security manager (QI'd to 1.66 +// nsIScriptSecurityManager) 1.67 +nsIScriptSecurityManager *nsXPConnect::gScriptSecurityManager = nullptr; 1.68 + 1.69 +const char XPC_CONTEXT_STACK_CONTRACTID[] = "@mozilla.org/js/xpc/ContextStack;1"; 1.70 +const char XPC_RUNTIME_CONTRACTID[] = "@mozilla.org/js/xpc/RuntimeService;1"; 1.71 +const char XPC_EXCEPTION_CONTRACTID[] = "@mozilla.org/js/xpc/Exception;1"; 1.72 +const char XPC_CONSOLE_CONTRACTID[] = "@mozilla.org/consoleservice;1"; 1.73 +const char XPC_SCRIPT_ERROR_CONTRACTID[] = "@mozilla.org/scripterror;1"; 1.74 +const char XPC_ID_CONTRACTID[] = "@mozilla.org/js/xpc/ID;1"; 1.75 +const char XPC_XPCONNECT_CONTRACTID[] = "@mozilla.org/js/xpc/XPConnect;1"; 1.76 + 1.77 +/***************************************************************************/ 1.78 + 1.79 +nsXPConnect::nsXPConnect() 1.80 + : mRuntime(nullptr), 1.81 + mShuttingDown(false), 1.82 + mEventDepth(0) 1.83 +{ 1.84 + mRuntime = XPCJSRuntime::newXPCJSRuntime(this); 1.85 + 1.86 + char* reportableEnv = PR_GetEnv("MOZ_REPORT_ALL_JS_EXCEPTIONS"); 1.87 + if (reportableEnv && *reportableEnv) 1.88 + gReportAllJSExceptions = 1; 1.89 +} 1.90 + 1.91 +nsXPConnect::~nsXPConnect() 1.92 +{ 1.93 + mRuntime->DeleteSingletonScopes(); 1.94 + mRuntime->DestroyJSContextStack(); 1.95 + 1.96 + // In order to clean up everything properly, we need to GC twice: once now, 1.97 + // to clean anything that can go away on its own (like the Junk Scope, which 1.98 + // we unrooted above), and once after forcing a bunch of shutdown in 1.99 + // XPConnect, to clean the stuff we forcibly disconnected. The forced 1.100 + // shutdown code defaults to leaking in a number of situations, so we can't 1.101 + // get by with only the second GC. :-( 1.102 + JS_GC(mRuntime->Runtime()); 1.103 + 1.104 + mShuttingDown = true; 1.105 + XPCWrappedNativeScope::SystemIsBeingShutDown(); 1.106 + mRuntime->SystemIsBeingShutDown(); 1.107 + 1.108 + // The above causes us to clean up a bunch of XPConnect data structures, 1.109 + // after which point we need to GC to clean everything up. We need to do 1.110 + // this before deleting the XPCJSRuntime, because doing so destroys the 1.111 + // maps that our finalize callback depends on. 1.112 + JS_GC(mRuntime->Runtime()); 1.113 + 1.114 + mDefaultSecurityManager = nullptr; 1.115 + gScriptSecurityManager = nullptr; 1.116 + 1.117 + // shutdown the logging system 1.118 + XPC_LOG_FINISH(); 1.119 + 1.120 + delete mRuntime; 1.121 + 1.122 + gSelf = nullptr; 1.123 + gOnceAliveNowDead = true; 1.124 +} 1.125 + 1.126 +// static 1.127 +void 1.128 +nsXPConnect::InitStatics() 1.129 +{ 1.130 + gSelf = new nsXPConnect(); 1.131 + gOnceAliveNowDead = false; 1.132 + if (!gSelf->mRuntime) { 1.133 + NS_RUNTIMEABORT("Couldn't create XPCJSRuntime."); 1.134 + } 1.135 + 1.136 + // Initial extra ref to keep the singleton alive 1.137 + // balanced by explicit call to ReleaseXPConnectSingleton() 1.138 + NS_ADDREF(gSelf); 1.139 + 1.140 + // Set XPConnect as the main thread observer. 1.141 + if (NS_FAILED(nsThread::SetMainThreadObserver(gSelf))) { 1.142 + MOZ_CRASH(); 1.143 + } 1.144 +} 1.145 + 1.146 +nsXPConnect* 1.147 +nsXPConnect::GetSingleton() 1.148 +{ 1.149 + nsXPConnect* xpc = nsXPConnect::XPConnect(); 1.150 + NS_IF_ADDREF(xpc); 1.151 + return xpc; 1.152 +} 1.153 + 1.154 +// static 1.155 +void 1.156 +nsXPConnect::ReleaseXPConnectSingleton() 1.157 +{ 1.158 + nsXPConnect* xpc = gSelf; 1.159 + if (xpc) { 1.160 + nsThread::SetMainThreadObserver(nullptr); 1.161 + 1.162 + nsrefcnt cnt; 1.163 + NS_RELEASE2(xpc, cnt); 1.164 + } 1.165 +} 1.166 + 1.167 +// static 1.168 +XPCJSRuntime* 1.169 +nsXPConnect::GetRuntimeInstance() 1.170 +{ 1.171 + nsXPConnect* xpc = XPConnect(); 1.172 + return xpc->GetRuntime(); 1.173 +} 1.174 + 1.175 +// static 1.176 +bool 1.177 +nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info) 1.178 +{ 1.179 + bool found = false; 1.180 + if (info) 1.181 + info->HasAncestor(&NS_GET_IID(nsISupports), &found); 1.182 + return found; 1.183 +} 1.184 + 1.185 +void 1.186 +xpc::SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep) 1.187 +{ 1.188 + // It would be nice to assert !DescribeScriptedCaller here, to be sure 1.189 + // that there isn't any script running that could catch the exception. But 1.190 + // the JS engine invokes the error reporter directly if someone reports an 1.191 + // ErrorReport that it doesn't know how to turn into an exception. Arguably 1.192 + // it should just learn how to throw everything. But either way, if the 1.193 + // exception is ending here, it's not going to get propagated to a caller, 1.194 + // so it's up to us to make it known. 1.195 + 1.196 + nsresult rv; 1.197 + 1.198 + /* Use the console service to register the error. */ 1.199 + nsCOMPtr<nsIConsoleService> consoleService = 1.200 + do_GetService(NS_CONSOLESERVICE_CONTRACTID); 1.201 + 1.202 + /* 1.203 + * Make an nsIScriptError, populate it with information from this 1.204 + * error, then log it with the console service. 1.205 + */ 1.206 + nsCOMPtr<nsIScriptError> errorObject = 1.207 + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); 1.208 + 1.209 + if (consoleService && errorObject) { 1.210 + uint32_t column = rep->uctokenptr - rep->uclinebuf; 1.211 + 1.212 + const char16_t* ucmessage = 1.213 + static_cast<const char16_t*>(rep->ucmessage); 1.214 + const char16_t* uclinebuf = 1.215 + static_cast<const char16_t*>(rep->uclinebuf); 1.216 + 1.217 + rv = errorObject->Init( 1.218 + ucmessage ? nsDependentString(ucmessage) : EmptyString(), 1.219 + NS_ConvertASCIItoUTF16(rep->filename), 1.220 + uclinebuf ? nsDependentString(uclinebuf) : EmptyString(), 1.221 + rep->lineno, column, rep->flags, 1.222 + "system javascript"); 1.223 + if (NS_SUCCEEDED(rv)) 1.224 + consoleService->LogMessage(errorObject); 1.225 + } 1.226 + 1.227 + if (nsContentUtils::DOMWindowDumpEnabled()) { 1.228 + fprintf(stderr, "System JS : %s %s:%d - %s\n", 1.229 + JSREPORT_IS_WARNING(rep->flags) ? "WARNING" : "ERROR", 1.230 + rep->filename, rep->lineno, 1.231 + message ? message : "<no message>"); 1.232 + } 1.233 + 1.234 +} 1.235 + 1.236 + 1.237 +/***************************************************************************/ 1.238 + 1.239 + 1.240 +nsresult 1.241 +nsXPConnect::GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info) 1.242 +{ 1.243 + return XPTInterfaceInfoManager::GetSingleton()->GetInfoForIID(aIID, info); 1.244 +} 1.245 + 1.246 +nsresult 1.247 +nsXPConnect::GetInfoForName(const char * name, nsIInterfaceInfo** info) 1.248 +{ 1.249 + nsresult rv = XPTInterfaceInfoManager::GetSingleton()->GetInfoForName(name, info); 1.250 + return NS_FAILED(rv) ? NS_OK : NS_ERROR_NO_INTERFACE; 1.251 +} 1.252 + 1.253 +NS_IMETHODIMP 1.254 +nsXPConnect::GarbageCollect(uint32_t reason) 1.255 +{ 1.256 + GetRuntime()->Collect(reason); 1.257 + return NS_OK; 1.258 +} 1.259 + 1.260 +bool 1.261 +xpc_GCThingIsGrayCCThing(void *thing) 1.262 +{ 1.263 + return AddToCCKind(js::GCThingTraceKind(thing)) && 1.264 + xpc_IsGrayGCThing(thing); 1.265 +} 1.266 + 1.267 +void 1.268 +xpc_MarkInCCGeneration(nsISupports* aVariant, uint32_t aGeneration) 1.269 +{ 1.270 + nsCOMPtr<XPCVariant> variant = do_QueryInterface(aVariant); 1.271 + if (variant) { 1.272 + variant->SetCCGeneration(aGeneration); 1.273 + variant->GetJSVal(); // Unmarks gray JSObject. 1.274 + XPCVariant* weak = variant.get(); 1.275 + variant = nullptr; 1.276 + if (weak->IsPurple()) { 1.277 + weak->RemovePurple(); 1.278 + } 1.279 + } 1.280 +} 1.281 + 1.282 +void 1.283 +xpc_TryUnmarkWrappedGrayObject(nsISupports* aWrappedJS) 1.284 +{ 1.285 + nsCOMPtr<nsIXPConnectWrappedJS> wjs = do_QueryInterface(aWrappedJS); 1.286 + if (wjs) { 1.287 + // Unmarks gray JSObject. 1.288 + static_cast<nsXPCWrappedJS*>(wjs.get())->GetJSObject(); 1.289 + } 1.290 +} 1.291 + 1.292 +/***************************************************************************/ 1.293 +/***************************************************************************/ 1.294 +// nsIXPConnect interface methods... 1.295 + 1.296 +template<typename T> 1.297 +static inline T UnexpectedFailure(T rv) 1.298 +{ 1.299 + NS_ERROR("This is not supposed to fail!"); 1.300 + return rv; 1.301 +} 1.302 + 1.303 +/* void initClasses (in JSContextPtr aJSContext, in JSObjectPtr aGlobalJSObj); */ 1.304 +NS_IMETHODIMP 1.305 +nsXPConnect::InitClasses(JSContext * aJSContext, JSObject * aGlobalJSObj) 1.306 +{ 1.307 + MOZ_ASSERT(aJSContext, "bad param"); 1.308 + MOZ_ASSERT(aGlobalJSObj, "bad param"); 1.309 + RootedObject globalJSObj(aJSContext, aGlobalJSObj); 1.310 + 1.311 + JSAutoCompartment ac(aJSContext, globalJSObj); 1.312 + 1.313 + XPCWrappedNativeScope* scope = 1.314 + XPCWrappedNativeScope::GetNewOrUsed(aJSContext, globalJSObj); 1.315 + 1.316 + if (!scope) 1.317 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.318 + 1.319 + scope->RemoveWrappedNativeProtos(); 1.320 + 1.321 + if (!XPCNativeWrapper::AttachNewConstructorObject(aJSContext, globalJSObj)) 1.322 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.323 + 1.324 + return NS_OK; 1.325 +} 1.326 + 1.327 +#ifdef DEBUG 1.328 +static void 1.329 +VerifyTraceXPCGlobalCalled(JSTracer *trc, void **thingp, JSGCTraceKind kind) 1.330 +{ 1.331 + // We don't do anything here, we only want to verify that TraceXPCGlobal 1.332 + // was called. 1.333 +} 1.334 + 1.335 +struct VerifyTraceXPCGlobalCalledTracer : public JSTracer 1.336 +{ 1.337 + bool ok; 1.338 + 1.339 + VerifyTraceXPCGlobalCalledTracer(JSRuntime *rt) 1.340 + : JSTracer(rt, VerifyTraceXPCGlobalCalled), ok(false) 1.341 + {} 1.342 +}; 1.343 +#endif 1.344 + 1.345 +void 1.346 +xpc::TraceXPCGlobal(JSTracer *trc, JSObject *obj) 1.347 +{ 1.348 +#ifdef DEBUG 1.349 + if (trc->callback == VerifyTraceXPCGlobalCalled) { 1.350 + // We don't do anything here, we only want to verify that TraceXPCGlobal 1.351 + // was called. 1.352 + reinterpret_cast<VerifyTraceXPCGlobalCalledTracer*>(trc)->ok = true; 1.353 + return; 1.354 + } 1.355 +#endif 1.356 + 1.357 + if (js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL) 1.358 + mozilla::dom::TraceProtoAndIfaceCache(trc, obj); 1.359 + 1.360 + // We might be called from a GC during the creation of a global, before we've 1.361 + // been able to set up the compartment private or the XPCWrappedNativeScope, 1.362 + // so we need to null-check those. 1.363 + xpc::CompartmentPrivate* compartmentPrivate = GetCompartmentPrivate(obj); 1.364 + if (compartmentPrivate && compartmentPrivate->scope) 1.365 + compartmentPrivate->scope->TraceInside(trc); 1.366 +} 1.367 + 1.368 +namespace xpc { 1.369 + 1.370 +JSObject* 1.371 +CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal, 1.372 + JS::CompartmentOptions& aOptions) 1.373 +{ 1.374 + MOZ_ASSERT(NS_IsMainThread(), "using a principal off the main thread?"); 1.375 + MOZ_ASSERT(principal); 1.376 + 1.377 + RootedObject global(cx, 1.378 + JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), 1.379 + JS::DontFireOnNewGlobalHook, aOptions)); 1.380 + if (!global) 1.381 + return nullptr; 1.382 + JSAutoCompartment ac(cx, global); 1.383 + 1.384 + // The constructor automatically attaches the scope to the compartment private 1.385 + // of |global|. 1.386 + (void) new XPCWrappedNativeScope(cx, global); 1.387 + 1.388 +#ifdef DEBUG 1.389 + // Verify that the right trace hook is called. Note that this doesn't 1.390 + // work right for wrapped globals, since the tracing situation there is 1.391 + // more complicated. Manual inspection shows that they do the right thing. 1.392 + if (!((const js::Class*)clasp)->ext.isWrappedNative) 1.393 + { 1.394 + VerifyTraceXPCGlobalCalledTracer trc(JS_GetRuntime(cx)); 1.395 + JS_TraceChildren(&trc, global, JSTRACE_OBJECT); 1.396 + MOZ_ASSERT(trc.ok, "Trace hook on global needs to call TraceXPCGlobal for XPConnect compartments."); 1.397 + } 1.398 +#endif 1.399 + 1.400 + if (clasp->flags & JSCLASS_DOM_GLOBAL) { 1.401 + const char* className = clasp->name; 1.402 + AllocateProtoAndIfaceCache(global, 1.403 + (strcmp(className, "Window") == 0 || 1.404 + strcmp(className, "ChromeWindow") == 0) 1.405 + ? ProtoAndIfaceCache::WindowLike 1.406 + : ProtoAndIfaceCache::NonWindowLike); 1.407 + } 1.408 + 1.409 + return global; 1.410 +} 1.411 + 1.412 +bool 1.413 +InitGlobalObject(JSContext* aJSContext, JS::Handle<JSObject*> aGlobal, uint32_t aFlags) 1.414 +{ 1.415 + // Immediately enter the global's compartment, so that everything else we 1.416 + // create ends up there. 1.417 + JSAutoCompartment ac(aJSContext, aGlobal); 1.418 + if (!(aFlags & nsIXPConnect::OMIT_COMPONENTS_OBJECT)) { 1.419 + // XPCCallContext gives us an active request needed to save/restore. 1.420 + if (!GetCompartmentPrivate(aGlobal)->scope->AttachComponentsObject(aJSContext) || 1.421 + !XPCNativeWrapper::AttachNewConstructorObject(aJSContext, aGlobal)) { 1.422 + return UnexpectedFailure(false); 1.423 + } 1.424 + } 1.425 + 1.426 + if (ShouldDiscardSystemSource()) { 1.427 + nsIPrincipal *prin = GetObjectPrincipal(aGlobal); 1.428 + bool isSystem = nsContentUtils::IsSystemPrincipal(prin); 1.429 + if (!isSystem) { 1.430 + short status = prin->GetAppStatus(); 1.431 + isSystem = status == nsIPrincipal::APP_STATUS_PRIVILEGED || 1.432 + status == nsIPrincipal::APP_STATUS_CERTIFIED; 1.433 + } 1.434 + JS::CompartmentOptionsRef(aGlobal).setDiscardSource(isSystem); 1.435 + } 1.436 + 1.437 + // Stuff coming through this path always ends up as a DOM global. 1.438 + MOZ_ASSERT(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL); 1.439 + 1.440 + // Init WebIDL binding constructors wanted on all XPConnect globals. 1.441 + // 1.442 + // XXX Please do not add any additional classes here without the approval of 1.443 + // the XPConnect module owner. 1.444 + if (!PromiseBinding::GetConstructorObject(aJSContext, aGlobal) || 1.445 + !TextDecoderBinding::GetConstructorObject(aJSContext, aGlobal) || 1.446 + !TextEncoderBinding::GetConstructorObject(aJSContext, aGlobal) || 1.447 + !DOMErrorBinding::GetConstructorObject(aJSContext, aGlobal)) { 1.448 + return UnexpectedFailure(false); 1.449 + } 1.450 + 1.451 + if (!(aFlags & nsIXPConnect::DONT_FIRE_ONNEWGLOBALHOOK)) 1.452 + JS_FireOnNewGlobalObject(aJSContext, aGlobal); 1.453 + 1.454 + return true; 1.455 +} 1.456 + 1.457 +} // namespace xpc 1.458 + 1.459 +NS_IMETHODIMP 1.460 +nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext, 1.461 + nsISupports *aCOMObj, 1.462 + nsIPrincipal * aPrincipal, 1.463 + uint32_t aFlags, 1.464 + JS::CompartmentOptions& aOptions, 1.465 + nsIXPConnectJSObjectHolder **_retval) 1.466 +{ 1.467 + MOZ_ASSERT(aJSContext, "bad param"); 1.468 + MOZ_ASSERT(aCOMObj, "bad param"); 1.469 + MOZ_ASSERT(_retval, "bad param"); 1.470 + 1.471 + // We pass null for the 'extra' pointer during global object creation, so 1.472 + // we need to have a principal. 1.473 + MOZ_ASSERT(aPrincipal); 1.474 + 1.475 + // Call into XPCWrappedNative to make a new global object, scope, and global 1.476 + // prototype. 1.477 + xpcObjectHelper helper(aCOMObj); 1.478 + MOZ_ASSERT(helper.GetScriptableFlags() & nsIXPCScriptable::IS_GLOBAL_OBJECT); 1.479 + nsRefPtr<XPCWrappedNative> wrappedGlobal; 1.480 + nsresult rv = 1.481 + XPCWrappedNative::WrapNewGlobal(helper, aPrincipal, 1.482 + aFlags & nsIXPConnect::INIT_JS_STANDARD_CLASSES, 1.483 + aOptions, getter_AddRefs(wrappedGlobal)); 1.484 + NS_ENSURE_SUCCESS(rv, rv); 1.485 + 1.486 + // Grab a copy of the global and enter its compartment. 1.487 + RootedObject global(aJSContext, wrappedGlobal->GetFlatJSObject()); 1.488 + MOZ_ASSERT(!js::GetObjectParent(global)); 1.489 + 1.490 + if (!InitGlobalObject(aJSContext, global, aFlags)) 1.491 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.492 + 1.493 + wrappedGlobal.forget(_retval); 1.494 + return NS_OK; 1.495 +} 1.496 + 1.497 +static nsresult 1.498 +NativeInterface2JSObject(HandleObject aScope, 1.499 + nsISupports *aCOMObj, 1.500 + nsWrapperCache *aCache, 1.501 + const nsIID * aIID, 1.502 + bool aAllowWrapping, 1.503 + MutableHandleValue aVal, 1.504 + nsIXPConnectJSObjectHolder **aHolder) 1.505 +{ 1.506 + AutoJSContext cx; 1.507 + JSAutoCompartment ac(cx, aScope); 1.508 + 1.509 + nsresult rv; 1.510 + xpcObjectHelper helper(aCOMObj, aCache); 1.511 + if (!XPCConvert::NativeInterface2JSObject(aVal, aHolder, helper, aIID, 1.512 + nullptr, aAllowWrapping, &rv)) 1.513 + return rv; 1.514 + 1.515 + MOZ_ASSERT(aAllowWrapping || !xpc::WrapperFactory::IsXrayWrapper(&aVal.toObject()), 1.516 + "Shouldn't be returning a xray wrapper here"); 1.517 + 1.518 + return NS_OK; 1.519 +} 1.520 + 1.521 +/* nsIXPConnectJSObjectHolder wrapNative (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDRef aIID); */ 1.522 +NS_IMETHODIMP 1.523 +nsXPConnect::WrapNative(JSContext * aJSContext, 1.524 + JSObject * aScopeArg, 1.525 + nsISupports *aCOMObj, 1.526 + const nsIID & aIID, 1.527 + nsIXPConnectJSObjectHolder **aHolder) 1.528 +{ 1.529 + MOZ_ASSERT(aHolder, "bad param"); 1.530 + MOZ_ASSERT(aJSContext, "bad param"); 1.531 + MOZ_ASSERT(aScopeArg, "bad param"); 1.532 + MOZ_ASSERT(aCOMObj, "bad param"); 1.533 + 1.534 + RootedObject aScope(aJSContext, aScopeArg); 1.535 + RootedValue v(aJSContext); 1.536 + return NativeInterface2JSObject(aScope, aCOMObj, nullptr, &aIID, 1.537 + true, &v, aHolder); 1.538 +} 1.539 + 1.540 +/* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, out jsval aVal, out nsIXPConnectJSObjectHolder aHolder); */ 1.541 +NS_IMETHODIMP 1.542 +nsXPConnect::WrapNativeToJSVal(JSContext *aJSContext, 1.543 + JSObject *aScopeArg, 1.544 + nsISupports *aCOMObj, 1.545 + nsWrapperCache *aCache, 1.546 + const nsIID *aIID, 1.547 + bool aAllowWrapping, 1.548 + MutableHandleValue aVal) 1.549 +{ 1.550 + MOZ_ASSERT(aJSContext, "bad param"); 1.551 + MOZ_ASSERT(aScopeArg, "bad param"); 1.552 + MOZ_ASSERT(aCOMObj, "bad param"); 1.553 + 1.554 + RootedObject aScope(aJSContext, aScopeArg); 1.555 + return NativeInterface2JSObject(aScope, aCOMObj, aCache, aIID, 1.556 + aAllowWrapping, aVal, nullptr); 1.557 +} 1.558 + 1.559 +/* void wrapJS (in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is (aIID), retval] out nsQIResult result); */ 1.560 +NS_IMETHODIMP 1.561 +nsXPConnect::WrapJS(JSContext * aJSContext, 1.562 + JSObject * aJSObjArg, 1.563 + const nsIID & aIID, 1.564 + void * *result) 1.565 +{ 1.566 + MOZ_ASSERT(aJSContext, "bad param"); 1.567 + MOZ_ASSERT(aJSObjArg, "bad param"); 1.568 + MOZ_ASSERT(result, "bad param"); 1.569 + 1.570 + *result = nullptr; 1.571 + 1.572 + RootedObject aJSObj(aJSContext, aJSObjArg); 1.573 + JSAutoCompartment ac(aJSContext, aJSObj); 1.574 + 1.575 + nsresult rv = NS_ERROR_UNEXPECTED; 1.576 + if (!XPCConvert::JSObject2NativeInterface(result, aJSObj, 1.577 + &aIID, nullptr, &rv)) 1.578 + return rv; 1.579 + return NS_OK; 1.580 +} 1.581 + 1.582 +NS_IMETHODIMP 1.583 +nsXPConnect::JSValToVariant(JSContext *cx, 1.584 + HandleValue aJSVal, 1.585 + nsIVariant **aResult) 1.586 +{ 1.587 + NS_PRECONDITION(aResult, "bad param"); 1.588 + 1.589 + nsRefPtr<XPCVariant> variant = XPCVariant::newVariant(cx, aJSVal); 1.590 + variant.forget(aResult); 1.591 + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); 1.592 + 1.593 + return NS_OK; 1.594 +} 1.595 + 1.596 +/* void wrapJSAggregatedToNative (in nsISupports aOuter, in JSContextPtr aJSContext, in JSObjectPtr aJSObj, in nsIIDRef aIID, [iid_is (aIID), retval] out nsQIResult result); */ 1.597 +NS_IMETHODIMP 1.598 +nsXPConnect::WrapJSAggregatedToNative(nsISupports *aOuter, 1.599 + JSContext *aJSContext, 1.600 + JSObject *aJSObjArg, 1.601 + const nsIID &aIID, 1.602 + void **result) 1.603 +{ 1.604 + MOZ_ASSERT(aOuter, "bad param"); 1.605 + MOZ_ASSERT(aJSContext, "bad param"); 1.606 + MOZ_ASSERT(aJSObjArg, "bad param"); 1.607 + MOZ_ASSERT(result, "bad param"); 1.608 + 1.609 + *result = nullptr; 1.610 + 1.611 + RootedObject aJSObj(aJSContext, aJSObjArg); 1.612 + nsresult rv; 1.613 + if (!XPCConvert::JSObject2NativeInterface(result, aJSObj, 1.614 + &aIID, aOuter, &rv)) 1.615 + return rv; 1.616 + return NS_OK; 1.617 +} 1.618 + 1.619 +/* nsIXPConnectWrappedNative getWrappedNativeOfJSObject (in JSContextPtr aJSContext, in JSObjectPtr aJSObj); */ 1.620 +NS_IMETHODIMP 1.621 +nsXPConnect::GetWrappedNativeOfJSObject(JSContext * aJSContext, 1.622 + JSObject * aJSObjArg, 1.623 + nsIXPConnectWrappedNative **_retval) 1.624 +{ 1.625 + MOZ_ASSERT(aJSContext, "bad param"); 1.626 + MOZ_ASSERT(aJSObjArg, "bad param"); 1.627 + MOZ_ASSERT(_retval, "bad param"); 1.628 + 1.629 + RootedObject aJSObj(aJSContext, aJSObjArg); 1.630 + aJSObj = js::CheckedUnwrap(aJSObj, /* stopAtOuter = */ false); 1.631 + if (!aJSObj || !IS_WN_REFLECTOR(aJSObj)) { 1.632 + *_retval = nullptr; 1.633 + return NS_ERROR_FAILURE; 1.634 + } 1.635 + 1.636 + nsRefPtr<XPCWrappedNative> temp = XPCWrappedNative::Get(aJSObj); 1.637 + temp.forget(_retval); 1.638 + return NS_OK; 1.639 +} 1.640 + 1.641 +/* nsISupports getNativeOfWrapper(in JSContextPtr aJSContext, in JSObjectPtr aJSObj); */ 1.642 +NS_IMETHODIMP_(nsISupports*) 1.643 +nsXPConnect::GetNativeOfWrapper(JSContext *aJSContext, 1.644 + JSObject *aJSObj) 1.645 +{ 1.646 + MOZ_ASSERT(aJSContext, "bad param"); 1.647 + MOZ_ASSERT(aJSObj, "bad param"); 1.648 + 1.649 + aJSObj = js::CheckedUnwrap(aJSObj, /* stopAtOuter = */ false); 1.650 + if (!aJSObj) { 1.651 + JS_ReportError(aJSContext, "Permission denied to get native of security wrapper"); 1.652 + return nullptr; 1.653 + } 1.654 + if (IS_WN_REFLECTOR(aJSObj)) { 1.655 + if (XPCWrappedNative *wn = XPCWrappedNative::Get(aJSObj)) 1.656 + return wn->Native(); 1.657 + return nullptr; 1.658 + } 1.659 + 1.660 + nsCOMPtr<nsISupports> canonical = 1.661 + do_QueryInterface(mozilla::dom::UnwrapDOMObjectToISupports(aJSObj)); 1.662 + return canonical; 1.663 +} 1.664 + 1.665 +/* nsIXPConnectWrappedNative getWrappedNativeOfNativeObject (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDRef aIID); */ 1.666 +NS_IMETHODIMP 1.667 +nsXPConnect::GetWrappedNativeOfNativeObject(JSContext * aJSContext, 1.668 + JSObject * aScopeArg, 1.669 + nsISupports *aCOMObj, 1.670 + const nsIID & aIID, 1.671 + nsIXPConnectWrappedNative **_retval) 1.672 +{ 1.673 + MOZ_ASSERT(aJSContext, "bad param"); 1.674 + MOZ_ASSERT(aScopeArg, "bad param"); 1.675 + MOZ_ASSERT(aCOMObj, "bad param"); 1.676 + MOZ_ASSERT(_retval, "bad param"); 1.677 + 1.678 + *_retval = nullptr; 1.679 + 1.680 + RootedObject aScope(aJSContext, aScopeArg); 1.681 + 1.682 + XPCWrappedNativeScope* scope = GetObjectScope(aScope); 1.683 + if (!scope) 1.684 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.685 + 1.686 + AutoMarkingNativeInterfacePtr iface(aJSContext); 1.687 + iface = XPCNativeInterface::GetNewOrUsed(&aIID); 1.688 + if (!iface) 1.689 + return NS_ERROR_FAILURE; 1.690 + 1.691 + XPCWrappedNative* wrapper; 1.692 + 1.693 + nsresult rv = XPCWrappedNative::GetUsedOnly(aCOMObj, scope, iface, &wrapper); 1.694 + if (NS_FAILED(rv)) 1.695 + return NS_ERROR_FAILURE; 1.696 + *_retval = static_cast<nsIXPConnectWrappedNative*>(wrapper); 1.697 + return NS_OK; 1.698 +} 1.699 + 1.700 +/* void reparentWrappedNativeIfFound (in JSContextPtr aJSContext, 1.701 + * in JSObjectPtr aScope, 1.702 + * in JSObjectPtr aNewParent, 1.703 + * in nsISupports aCOMObj); */ 1.704 +NS_IMETHODIMP 1.705 +nsXPConnect::ReparentWrappedNativeIfFound(JSContext * aJSContext, 1.706 + JSObject * aScopeArg, 1.707 + JSObject * aNewParentArg, 1.708 + nsISupports *aCOMObj) 1.709 +{ 1.710 + RootedObject aScope(aJSContext, aScopeArg); 1.711 + RootedObject aNewParent(aJSContext, aNewParentArg); 1.712 + 1.713 + XPCWrappedNativeScope* scope = GetObjectScope(aScope); 1.714 + XPCWrappedNativeScope* scope2 = GetObjectScope(aNewParent); 1.715 + if (!scope || !scope2) 1.716 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.717 + 1.718 + RootedObject newParent(aJSContext, aNewParent); 1.719 + return XPCWrappedNative:: 1.720 + ReparentWrapperIfFound(scope, scope2, newParent, aCOMObj); 1.721 +} 1.722 + 1.723 +static PLDHashOperator 1.724 +MoveableWrapperFinder(PLDHashTable *table, PLDHashEntryHdr *hdr, 1.725 + uint32_t number, void *arg) 1.726 +{ 1.727 + nsTArray<nsRefPtr<XPCWrappedNative> > *array = 1.728 + static_cast<nsTArray<nsRefPtr<XPCWrappedNative> > *>(arg); 1.729 + XPCWrappedNative *wn = ((Native2WrappedNativeMap::Entry*)hdr)->value; 1.730 + 1.731 + // If a wrapper is expired, then there are no references to it from JS, so 1.732 + // we don't have to move it. 1.733 + if (!wn->IsWrapperExpired()) 1.734 + array->AppendElement(wn); 1.735 + return PL_DHASH_NEXT; 1.736 +} 1.737 + 1.738 +/* void rescueOrphansInScope(in JSContextPtr aJSContext, in JSObjectPtr aScope); */ 1.739 +NS_IMETHODIMP 1.740 +nsXPConnect::RescueOrphansInScope(JSContext *aJSContext, JSObject *aScopeArg) 1.741 +{ 1.742 + RootedObject aScope(aJSContext, aScopeArg); 1.743 + 1.744 + XPCWrappedNativeScope *scope = GetObjectScope(aScope); 1.745 + if (!scope) 1.746 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.747 + 1.748 + // First, look through the old scope and find all of the wrappers that we 1.749 + // might need to rescue. 1.750 + nsTArray<nsRefPtr<XPCWrappedNative> > wrappersToMove; 1.751 + 1.752 + Native2WrappedNativeMap *map = scope->GetWrappedNativeMap(); 1.753 + wrappersToMove.SetCapacity(map->Count()); 1.754 + map->Enumerate(MoveableWrapperFinder, &wrappersToMove); 1.755 + 1.756 + // Now that we have the wrappers, reparent them to the new scope. 1.757 + for (uint32_t i = 0, stop = wrappersToMove.Length(); i < stop; ++i) { 1.758 + nsresult rv = wrappersToMove[i]->RescueOrphans(); 1.759 + NS_ENSURE_SUCCESS(rv, rv); 1.760 + } 1.761 + 1.762 + return NS_OK; 1.763 +} 1.764 + 1.765 +/* void setDefaultSecurityManager (in nsIXPCSecurityManager aManager); */ 1.766 +NS_IMETHODIMP 1.767 +nsXPConnect::SetDefaultSecurityManager(nsIXPCSecurityManager *aManager) 1.768 +{ 1.769 + mDefaultSecurityManager = aManager; 1.770 + 1.771 + nsCOMPtr<nsIScriptSecurityManager> ssm = 1.772 + do_QueryInterface(mDefaultSecurityManager); 1.773 + 1.774 + // Remember the result of the above QI for fast access to the 1.775 + // script securityt manager. 1.776 + gScriptSecurityManager = ssm; 1.777 + 1.778 + return NS_OK; 1.779 +} 1.780 + 1.781 +/* nsIStackFrame createStackFrameLocation (in uint32_t aLanguage, in string aFilename, in string aFunctionName, in int32_t aLineNumber, in nsIStackFrame aCaller); */ 1.782 +NS_IMETHODIMP 1.783 +nsXPConnect::CreateStackFrameLocation(uint32_t aLanguage, 1.784 + const char *aFilename, 1.785 + const char *aFunctionName, 1.786 + int32_t aLineNumber, 1.787 + nsIStackFrame *aCaller, 1.788 + nsIStackFrame **_retval) 1.789 +{ 1.790 + MOZ_ASSERT(_retval, "bad param"); 1.791 + 1.792 + nsCOMPtr<nsIStackFrame> stackFrame = 1.793 + exceptions::CreateStackFrameLocation(aLanguage, 1.794 + aFilename, 1.795 + aFunctionName, 1.796 + aLineNumber, 1.797 + aCaller); 1.798 + stackFrame.forget(_retval); 1.799 + return NS_OK; 1.800 +} 1.801 + 1.802 +/* readonly attribute nsIStackFrame CurrentJSStack; */ 1.803 +NS_IMETHODIMP 1.804 +nsXPConnect::GetCurrentJSStack(nsIStackFrame * *aCurrentJSStack) 1.805 +{ 1.806 + MOZ_ASSERT(aCurrentJSStack, "bad param"); 1.807 + 1.808 + nsCOMPtr<nsIStackFrame> currentStack = dom::GetCurrentJSStack(); 1.809 + currentStack.forget(aCurrentJSStack); 1.810 + 1.811 + return NS_OK; 1.812 +} 1.813 + 1.814 +/* readonly attribute nsIXPCNativeCallContext CurrentNativeCallContext; */ 1.815 +NS_IMETHODIMP 1.816 +nsXPConnect::GetCurrentNativeCallContext(nsAXPCNativeCallContext * *aCurrentNativeCallContext) 1.817 +{ 1.818 + MOZ_ASSERT(aCurrentNativeCallContext, "bad param"); 1.819 + 1.820 + *aCurrentNativeCallContext = XPCJSRuntime::Get()->GetCallContext(); 1.821 + return NS_OK; 1.822 +} 1.823 + 1.824 +/* void setFunctionThisTranslator (in nsIIDRef aIID, in nsIXPCFunctionThisTranslator aTranslator); */ 1.825 +NS_IMETHODIMP 1.826 +nsXPConnect::SetFunctionThisTranslator(const nsIID & aIID, 1.827 + nsIXPCFunctionThisTranslator *aTranslator) 1.828 +{ 1.829 + XPCJSRuntime* rt = GetRuntime(); 1.830 + IID2ThisTranslatorMap* map = rt->GetThisTranslatorMap(); 1.831 + map->Add(aIID, aTranslator); 1.832 + return NS_OK; 1.833 +} 1.834 + 1.835 +NS_IMETHODIMP 1.836 +nsXPConnect::CreateSandbox(JSContext *cx, nsIPrincipal *principal, 1.837 + nsIXPConnectJSObjectHolder **_retval) 1.838 +{ 1.839 + *_retval = nullptr; 1.840 + 1.841 + RootedValue rval(cx); 1.842 + SandboxOptions options; 1.843 + nsresult rv = CreateSandboxObject(cx, &rval, principal, options); 1.844 + MOZ_ASSERT(NS_FAILED(rv) || !JSVAL_IS_PRIMITIVE(rval), 1.845 + "Bad return value from xpc_CreateSandboxObject()!"); 1.846 + 1.847 + if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(rval)) { 1.848 + *_retval = XPCJSObjectHolder::newHolder(JSVAL_TO_OBJECT(rval)); 1.849 + NS_ENSURE_TRUE(*_retval, NS_ERROR_OUT_OF_MEMORY); 1.850 + 1.851 + NS_ADDREF(*_retval); 1.852 + } 1.853 + 1.854 + return rv; 1.855 +} 1.856 + 1.857 +NS_IMETHODIMP 1.858 +nsXPConnect::EvalInSandboxObject(const nsAString& source, const char *filename, 1.859 + JSContext *cx, JSObject *sandboxArg, 1.860 + bool returnStringOnly, MutableHandleValue rval) 1.861 +{ 1.862 + if (!sandboxArg) 1.863 + return NS_ERROR_INVALID_ARG; 1.864 + 1.865 + RootedObject sandbox(cx, sandboxArg); 1.866 + nsCString filenameStr; 1.867 + if (filename) { 1.868 + filenameStr.Assign(filename); 1.869 + } else { 1.870 + filenameStr = NS_LITERAL_CSTRING("x-bogus://XPConnect/Sandbox"); 1.871 + } 1.872 + return EvalInSandbox(cx, sandbox, source, filenameStr, 1, 1.873 + JSVERSION_DEFAULT, returnStringOnly, rval); 1.874 +} 1.875 + 1.876 +/* nsIXPConnectJSObjectHolder getWrappedNativePrototype (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsIClassInfo aClassInfo); */ 1.877 +NS_IMETHODIMP 1.878 +nsXPConnect::GetWrappedNativePrototype(JSContext * aJSContext, 1.879 + JSObject * aScopeArg, 1.880 + nsIClassInfo *aClassInfo, 1.881 + nsIXPConnectJSObjectHolder **_retval) 1.882 +{ 1.883 + RootedObject aScope(aJSContext, aScopeArg); 1.884 + JSAutoCompartment ac(aJSContext, aScope); 1.885 + 1.886 + XPCWrappedNativeScope* scope = GetObjectScope(aScope); 1.887 + if (!scope) 1.888 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.889 + 1.890 + XPCNativeScriptableCreateInfo sciProto; 1.891 + XPCWrappedNative::GatherProtoScriptableCreateInfo(aClassInfo, sciProto); 1.892 + 1.893 + AutoMarkingWrappedNativeProtoPtr proto(aJSContext); 1.894 + proto = XPCWrappedNativeProto::GetNewOrUsed(scope, aClassInfo, &sciProto); 1.895 + if (!proto) 1.896 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.897 + 1.898 + nsIXPConnectJSObjectHolder* holder; 1.899 + *_retval = holder = XPCJSObjectHolder::newHolder(proto->GetJSProtoObject()); 1.900 + if (!holder) 1.901 + return UnexpectedFailure(NS_ERROR_FAILURE); 1.902 + 1.903 + NS_ADDREF(holder); 1.904 + return NS_OK; 1.905 +} 1.906 + 1.907 +/* void debugDump (in short depth); */ 1.908 +NS_IMETHODIMP 1.909 +nsXPConnect::DebugDump(int16_t depth) 1.910 +{ 1.911 +#ifdef DEBUG 1.912 + depth-- ; 1.913 + XPC_LOG_ALWAYS(("nsXPConnect @ %x with mRefCnt = %d", this, mRefCnt.get())); 1.914 + XPC_LOG_INDENT(); 1.915 + XPC_LOG_ALWAYS(("gSelf @ %x", gSelf)); 1.916 + XPC_LOG_ALWAYS(("gOnceAliveNowDead is %d", (int)gOnceAliveNowDead)); 1.917 + XPC_LOG_ALWAYS(("mDefaultSecurityManager @ %x", mDefaultSecurityManager.get())); 1.918 + if (mRuntime) { 1.919 + if (depth) 1.920 + mRuntime->DebugDump(depth); 1.921 + else 1.922 + XPC_LOG_ALWAYS(("XPCJSRuntime @ %x", mRuntime)); 1.923 + } else 1.924 + XPC_LOG_ALWAYS(("mRuntime is null")); 1.925 + XPCWrappedNativeScope::DebugDumpAllScopes(depth); 1.926 + XPC_LOG_OUTDENT(); 1.927 +#endif 1.928 + return NS_OK; 1.929 +} 1.930 + 1.931 +/* void debugDumpObject (in nsISupports aCOMObj, in short depth); */ 1.932 +NS_IMETHODIMP 1.933 +nsXPConnect::DebugDumpObject(nsISupports *p, int16_t depth) 1.934 +{ 1.935 +#ifdef DEBUG 1.936 + if (!depth) 1.937 + return NS_OK; 1.938 + if (!p) { 1.939 + XPC_LOG_ALWAYS(("*** Cound not dump object with NULL address")); 1.940 + return NS_OK; 1.941 + } 1.942 + 1.943 + nsIXPConnect* xpc; 1.944 + nsIXPCWrappedJSClass* wjsc; 1.945 + nsIXPConnectWrappedNative* wn; 1.946 + nsIXPConnectWrappedJS* wjs; 1.947 + 1.948 + if (NS_SUCCEEDED(p->QueryInterface(NS_GET_IID(nsIXPConnect), 1.949 + (void**)&xpc))) { 1.950 + XPC_LOG_ALWAYS(("Dumping a nsIXPConnect...")); 1.951 + xpc->DebugDump(depth); 1.952 + NS_RELEASE(xpc); 1.953 + } else if (NS_SUCCEEDED(p->QueryInterface(NS_GET_IID(nsIXPCWrappedJSClass), 1.954 + (void**)&wjsc))) { 1.955 + XPC_LOG_ALWAYS(("Dumping a nsIXPCWrappedJSClass...")); 1.956 + wjsc->DebugDump(depth); 1.957 + NS_RELEASE(wjsc); 1.958 + } else if (NS_SUCCEEDED(p->QueryInterface(NS_GET_IID(nsIXPConnectWrappedNative), 1.959 + (void**)&wn))) { 1.960 + XPC_LOG_ALWAYS(("Dumping a nsIXPConnectWrappedNative...")); 1.961 + wn->DebugDump(depth); 1.962 + NS_RELEASE(wn); 1.963 + } else if (NS_SUCCEEDED(p->QueryInterface(NS_GET_IID(nsIXPConnectWrappedJS), 1.964 + (void**)&wjs))) { 1.965 + XPC_LOG_ALWAYS(("Dumping a nsIXPConnectWrappedJS...")); 1.966 + wjs->DebugDump(depth); 1.967 + NS_RELEASE(wjs); 1.968 + } else 1.969 + XPC_LOG_ALWAYS(("*** Could not dump the nsISupports @ %x", p)); 1.970 +#endif 1.971 + return NS_OK; 1.972 +} 1.973 + 1.974 +/* void debugDumpJSStack (in bool showArgs, in bool showLocals, in bool showThisProps); */ 1.975 +NS_IMETHODIMP 1.976 +nsXPConnect::DebugDumpJSStack(bool showArgs, 1.977 + bool showLocals, 1.978 + bool showThisProps) 1.979 +{ 1.980 + JSContext* cx = GetCurrentJSContext(); 1.981 + if (!cx) 1.982 + printf("there is no JSContext on the nsIThreadJSContextStack!\n"); 1.983 + else 1.984 + xpc_DumpJSStack(cx, showArgs, showLocals, showThisProps); 1.985 + 1.986 + return NS_OK; 1.987 +} 1.988 + 1.989 +char* 1.990 +nsXPConnect::DebugPrintJSStack(bool showArgs, 1.991 + bool showLocals, 1.992 + bool showThisProps) 1.993 +{ 1.994 + JSContext* cx = GetCurrentJSContext(); 1.995 + if (!cx) 1.996 + printf("there is no JSContext on the nsIThreadJSContextStack!\n"); 1.997 + else 1.998 + return xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps); 1.999 + 1.1000 + return nullptr; 1.1001 +} 1.1002 + 1.1003 +/* void debugDumpEvalInJSStackFrame (in uint32_t aFrameNumber, in string aSourceText); */ 1.1004 +NS_IMETHODIMP 1.1005 +nsXPConnect::DebugDumpEvalInJSStackFrame(uint32_t aFrameNumber, const char *aSourceText) 1.1006 +{ 1.1007 + JSContext* cx = GetCurrentJSContext(); 1.1008 + if (!cx) 1.1009 + printf("there is no JSContext on the nsIThreadJSContextStack!\n"); 1.1010 + else 1.1011 + xpc_DumpEvalInJSStackFrame(cx, aFrameNumber, aSourceText); 1.1012 + 1.1013 + return NS_OK; 1.1014 +} 1.1015 + 1.1016 +/* jsval variantToJS (in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value); */ 1.1017 +NS_IMETHODIMP 1.1018 +nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, nsIVariant* value, 1.1019 + MutableHandleValue _retval) 1.1020 +{ 1.1021 + NS_PRECONDITION(ctx, "bad param"); 1.1022 + NS_PRECONDITION(scopeArg, "bad param"); 1.1023 + NS_PRECONDITION(value, "bad param"); 1.1024 + 1.1025 + RootedObject scope(ctx, scopeArg); 1.1026 + MOZ_ASSERT(js::IsObjectInContextCompartment(scope, ctx)); 1.1027 + 1.1028 + nsresult rv = NS_OK; 1.1029 + if (!XPCVariant::VariantDataToJS(value, &rv, _retval)) { 1.1030 + if (NS_FAILED(rv)) 1.1031 + return rv; 1.1032 + 1.1033 + return NS_ERROR_FAILURE; 1.1034 + } 1.1035 + return NS_OK; 1.1036 +} 1.1037 + 1.1038 +/* nsIVariant JSToVariant (in JSContextPtr ctx, in jsval value); */ 1.1039 +NS_IMETHODIMP 1.1040 +nsXPConnect::JSToVariant(JSContext* ctx, HandleValue value, nsIVariant** _retval) 1.1041 +{ 1.1042 + NS_PRECONDITION(ctx, "bad param"); 1.1043 + NS_PRECONDITION(_retval, "bad param"); 1.1044 + 1.1045 + nsRefPtr<XPCVariant> variant = XPCVariant::newVariant(ctx, value); 1.1046 + variant.forget(_retval); 1.1047 + if (!(*_retval)) 1.1048 + return NS_ERROR_FAILURE; 1.1049 + 1.1050 + return NS_OK; 1.1051 +} 1.1052 + 1.1053 +NS_IMETHODIMP 1.1054 +nsXPConnect::OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait, 1.1055 + uint32_t aRecursionDepth) 1.1056 +{ 1.1057 + // Record this event. 1.1058 + mEventDepth++; 1.1059 + 1.1060 + // Push a null JSContext so that we don't see any script during 1.1061 + // event processing. 1.1062 + MOZ_ASSERT(NS_IsMainThread()); 1.1063 + bool ok = PushJSContextNoScriptContext(nullptr); 1.1064 + NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); 1.1065 + return NS_OK; 1.1066 +} 1.1067 + 1.1068 +NS_IMETHODIMP 1.1069 +nsXPConnect::AfterProcessNextEvent(nsIThreadInternal *aThread, 1.1070 + uint32_t aRecursionDepth, 1.1071 + bool aEventWasProcessed) 1.1072 +{ 1.1073 + // Watch out for unpaired events during observer registration. 1.1074 + if (MOZ_UNLIKELY(mEventDepth == 0)) 1.1075 + return NS_OK; 1.1076 + mEventDepth--; 1.1077 + 1.1078 + // Now that we're back to the event loop, reset the slow script checkpoint. 1.1079 + mRuntime->OnAfterProcessNextEvent(); 1.1080 + 1.1081 + // Call cycle collector occasionally. 1.1082 + MOZ_ASSERT(NS_IsMainThread()); 1.1083 + nsJSContext::MaybePokeCC(); 1.1084 + nsDOMMutationObserver::HandleMutations(); 1.1085 + 1.1086 + PopJSContextNoScriptContext(); 1.1087 + 1.1088 + // If the cx stack is empty, that means we're at the an un-nested event 1.1089 + // loop. This is a good time to make changes to debug mode. 1.1090 + if (XPCJSRuntime::Get()->GetJSContextStack()->Count() == 0) { 1.1091 + MOZ_ASSERT(mEventDepth == 0); 1.1092 + CheckForDebugMode(XPCJSRuntime::Get()->Runtime()); 1.1093 + } 1.1094 + return NS_OK; 1.1095 +} 1.1096 + 1.1097 +NS_IMETHODIMP 1.1098 +nsXPConnect::OnDispatchedEvent(nsIThreadInternal* aThread) 1.1099 +{ 1.1100 + NS_NOTREACHED("Why tell us?"); 1.1101 + return NS_ERROR_UNEXPECTED; 1.1102 +} 1.1103 + 1.1104 +NS_IMETHODIMP 1.1105 +nsXPConnect::SetReportAllJSExceptions(bool newval) 1.1106 +{ 1.1107 + // Ignore if the environment variable was set. 1.1108 + if (gReportAllJSExceptions != 1) 1.1109 + gReportAllJSExceptions = newval ? 2 : 0; 1.1110 + 1.1111 + return NS_OK; 1.1112 +} 1.1113 + 1.1114 +/* attribute JSRuntime runtime; */ 1.1115 +NS_IMETHODIMP 1.1116 +nsXPConnect::GetRuntime(JSRuntime **runtime) 1.1117 +{ 1.1118 + if (!runtime) 1.1119 + return NS_ERROR_NULL_POINTER; 1.1120 + 1.1121 + JSRuntime *rt = GetRuntime()->Runtime(); 1.1122 + JS_AbortIfWrongThread(rt); 1.1123 + *runtime = rt; 1.1124 + return NS_OK; 1.1125 +} 1.1126 + 1.1127 +/* [noscript, notxpcom] void registerGCCallback(in xpcGCCallback func); */ 1.1128 +NS_IMETHODIMP_(void) 1.1129 +nsXPConnect::RegisterGCCallback(xpcGCCallback func) 1.1130 +{ 1.1131 + mRuntime->AddGCCallback(func); 1.1132 +} 1.1133 + 1.1134 +/* [noscript, notxpcom] void unregisterGCCallback(in xpcGCCallback func); */ 1.1135 +NS_IMETHODIMP_(void) 1.1136 +nsXPConnect::UnregisterGCCallback(xpcGCCallback func) 1.1137 +{ 1.1138 + mRuntime->RemoveGCCallback(func); 1.1139 +} 1.1140 + 1.1141 +/* [noscript, notxpcom] void registerContextCallback(in xpcContextCallback func); */ 1.1142 +NS_IMETHODIMP_(void) 1.1143 +nsXPConnect::RegisterContextCallback(xpcContextCallback func) 1.1144 +{ 1.1145 + mRuntime->AddContextCallback(func); 1.1146 +} 1.1147 + 1.1148 +/* [noscript, notxpcom] void unregisterContextCallback(in xpcContextCallback func); */ 1.1149 +NS_IMETHODIMP_(void) 1.1150 +nsXPConnect::UnregisterContextCallback(xpcContextCallback func) 1.1151 +{ 1.1152 + mRuntime->RemoveContextCallback(func); 1.1153 +} 1.1154 + 1.1155 +#ifdef MOZ_JSDEBUGGER 1.1156 +void 1.1157 +nsXPConnect::CheckForDebugMode(JSRuntime *rt) 1.1158 +{ 1.1159 + if (gDebugMode == gDesiredDebugMode) { 1.1160 + return; 1.1161 + } 1.1162 + 1.1163 + // This can happen if a Worker is running, but we don't have the ability to 1.1164 + // debug workers right now, so just return. 1.1165 + if (!NS_IsMainThread()) 1.1166 + MOZ_CRASH(); 1.1167 + 1.1168 + AutoSafeJSContext cx; 1.1169 + JS_SetRuntimeDebugMode(rt, gDesiredDebugMode); 1.1170 + 1.1171 + nsresult rv; 1.1172 + const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1"; 1.1173 + nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv); 1.1174 + if (NS_FAILED(rv)) { 1.1175 + goto fail; 1.1176 + } 1.1177 + 1.1178 + if (!JS_SetDebugModeForAllCompartments(cx, gDesiredDebugMode)) 1.1179 + goto fail; 1.1180 + 1.1181 + if (gDesiredDebugMode) { 1.1182 + rv = jsds->ActivateDebugger(rt); 1.1183 + } 1.1184 + 1.1185 + gDebugMode = gDesiredDebugMode; 1.1186 + return; 1.1187 + 1.1188 +fail: 1.1189 + if (jsds) 1.1190 + jsds->DeactivateDebugger(); 1.1191 + 1.1192 + /* 1.1193 + * If an attempt to turn debug mode on fails, cancel the request. It's 1.1194 + * always safe to turn debug mode off, since DeactivateDebugger prevents 1.1195 + * debugger callbacks from having any effect. 1.1196 + */ 1.1197 + if (gDesiredDebugMode) 1.1198 + JS_SetRuntimeDebugMode(rt, false); 1.1199 + gDesiredDebugMode = gDebugMode = false; 1.1200 +} 1.1201 +#else //MOZ_JSDEBUGGER not defined 1.1202 +void 1.1203 +nsXPConnect::CheckForDebugMode(JSRuntime *rt) 1.1204 +{ 1.1205 + gDesiredDebugMode = gDebugMode = false; 1.1206 +} 1.1207 +#endif //#ifdef MOZ_JSDEBUGGER 1.1208 + 1.1209 + 1.1210 +void 1.1211 +xpc_ActivateDebugMode() 1.1212 +{ 1.1213 + XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); 1.1214 + nsXPConnect::XPConnect()->SetDebugModeWhenPossible(true, true); 1.1215 + nsXPConnect::CheckForDebugMode(rt->Runtime()); 1.1216 +} 1.1217 + 1.1218 +/* virtual */ 1.1219 +JSContext* 1.1220 +nsXPConnect::GetCurrentJSContext() 1.1221 +{ 1.1222 + return GetRuntime()->GetJSContextStack()->Peek(); 1.1223 +} 1.1224 + 1.1225 +/* virtual */ 1.1226 +JSContext* 1.1227 +nsXPConnect::InitSafeJSContext() 1.1228 +{ 1.1229 + return GetRuntime()->GetJSContextStack()->InitSafeJSContext(); 1.1230 +} 1.1231 + 1.1232 +/* virtual */ 1.1233 +JSContext* 1.1234 +nsXPConnect::GetSafeJSContext() 1.1235 +{ 1.1236 + return GetRuntime()->GetJSContextStack()->GetSafeJSContext(); 1.1237 +} 1.1238 + 1.1239 +namespace xpc { 1.1240 + 1.1241 +bool 1.1242 +PushJSContextNoScriptContext(JSContext *aCx) 1.1243 +{ 1.1244 + MOZ_ASSERT_IF(aCx, !GetScriptContextFromJSContext(aCx)); 1.1245 + return XPCJSRuntime::Get()->GetJSContextStack()->Push(aCx); 1.1246 +} 1.1247 + 1.1248 +void 1.1249 +PopJSContextNoScriptContext() 1.1250 +{ 1.1251 + XPCJSRuntime::Get()->GetJSContextStack()->Pop(); 1.1252 +} 1.1253 + 1.1254 +} // namespace xpc 1.1255 + 1.1256 +nsIPrincipal* 1.1257 +nsXPConnect::GetPrincipal(JSObject* obj, bool allowShortCircuit) const 1.1258 +{ 1.1259 + MOZ_ASSERT(IS_WN_REFLECTOR(obj), "What kind of wrapper is this?"); 1.1260 + 1.1261 + XPCWrappedNative *xpcWrapper = XPCWrappedNative::Get(obj); 1.1262 + if (xpcWrapper) { 1.1263 + if (allowShortCircuit) { 1.1264 + nsIPrincipal *result = xpcWrapper->GetObjectPrincipal(); 1.1265 + if (result) { 1.1266 + return result; 1.1267 + } 1.1268 + } 1.1269 + 1.1270 + // If not, check if it points to an nsIScriptObjectPrincipal 1.1271 + nsCOMPtr<nsIScriptObjectPrincipal> objPrin = 1.1272 + do_QueryInterface(xpcWrapper->Native()); 1.1273 + if (objPrin) { 1.1274 + nsIPrincipal *result = objPrin->GetPrincipal(); 1.1275 + if (result) { 1.1276 + return result; 1.1277 + } 1.1278 + } 1.1279 + } 1.1280 + 1.1281 + return nullptr; 1.1282 +} 1.1283 + 1.1284 +NS_IMETHODIMP 1.1285 +nsXPConnect::HoldObject(JSContext *aJSContext, JSObject *aObjectArg, 1.1286 + nsIXPConnectJSObjectHolder **aHolder) 1.1287 +{ 1.1288 + RootedObject aObject(aJSContext, aObjectArg); 1.1289 + XPCJSObjectHolder* objHolder = XPCJSObjectHolder::newHolder(aObject); 1.1290 + if (!objHolder) 1.1291 + return NS_ERROR_OUT_OF_MEMORY; 1.1292 + 1.1293 + NS_ADDREF(*aHolder = objHolder); 1.1294 + return NS_OK; 1.1295 +} 1.1296 + 1.1297 +namespace xpc { 1.1298 + 1.1299 +bool 1.1300 +Base64Encode(JSContext *cx, HandleValue val, MutableHandleValue out) 1.1301 +{ 1.1302 + MOZ_ASSERT(cx); 1.1303 + 1.1304 + JS::RootedValue root(cx, val); 1.1305 + xpc_qsACString encodedString(cx, root, &root, false, 1.1306 + xpc_qsACString::eStringify, 1.1307 + xpc_qsACString::eStringify); 1.1308 + if (!encodedString.IsValid()) 1.1309 + return false; 1.1310 + 1.1311 + nsAutoCString result; 1.1312 + if (NS_FAILED(mozilla::Base64Encode(encodedString, result))) { 1.1313 + JS_ReportError(cx, "Failed to encode base64 data!"); 1.1314 + return false; 1.1315 + } 1.1316 + 1.1317 + JSString *str = JS_NewStringCopyN(cx, result.get(), result.Length()); 1.1318 + if (!str) 1.1319 + return false; 1.1320 + 1.1321 + out.setString(str); 1.1322 + return true; 1.1323 +} 1.1324 + 1.1325 +bool 1.1326 +Base64Decode(JSContext *cx, HandleValue val, MutableHandleValue out) 1.1327 +{ 1.1328 + MOZ_ASSERT(cx); 1.1329 + 1.1330 + JS::RootedValue root(cx, val); 1.1331 + xpc_qsACString encodedString(cx, root, &root, false, 1.1332 + xpc_qsACString::eStringify, 1.1333 + xpc_qsACString::eStringify); 1.1334 + if (!encodedString.IsValid()) 1.1335 + return false; 1.1336 + 1.1337 + nsAutoCString result; 1.1338 + if (NS_FAILED(mozilla::Base64Decode(encodedString, result))) { 1.1339 + JS_ReportError(cx, "Failed to decode base64 string!"); 1.1340 + return false; 1.1341 + } 1.1342 + 1.1343 + JSString *str = JS_NewStringCopyN(cx, result.get(), result.Length()); 1.1344 + if (!str) 1.1345 + return false; 1.1346 + 1.1347 + out.setString(str); 1.1348 + return true; 1.1349 +} 1.1350 + 1.1351 +void 1.1352 +SetLocationForGlobal(JSObject *global, const nsACString& location) 1.1353 +{ 1.1354 + MOZ_ASSERT(global); 1.1355 + EnsureCompartmentPrivate(global)->SetLocation(location); 1.1356 +} 1.1357 + 1.1358 +void 1.1359 +SetLocationForGlobal(JSObject *global, nsIURI *locationURI) 1.1360 +{ 1.1361 + MOZ_ASSERT(global); 1.1362 + EnsureCompartmentPrivate(global)->SetLocationURI(locationURI); 1.1363 +} 1.1364 + 1.1365 +} // namespace xpc 1.1366 + 1.1367 +NS_IMETHODIMP 1.1368 +nsXPConnect::SetDebugModeWhenPossible(bool mode, bool allowSyncDisable) 1.1369 +{ 1.1370 + gDesiredDebugMode = mode; 1.1371 + if (!mode && allowSyncDisable) 1.1372 + CheckForDebugMode(mRuntime->Runtime()); 1.1373 + return NS_OK; 1.1374 +} 1.1375 + 1.1376 +NS_IMETHODIMP 1.1377 +nsXPConnect::NotifyDidPaint() 1.1378 +{ 1.1379 + JS::NotifyDidPaint(GetRuntime()->Runtime()); 1.1380 + return NS_OK; 1.1381 +} 1.1382 + 1.1383 +// Note - We used to have HAS_PRINCIPALS_FLAG = 1 here, so reusing that flag 1.1384 +// will require bumping the XDR version number. 1.1385 +static const uint8_t HAS_ORIGIN_PRINCIPALS_FLAG = 2; 1.1386 + 1.1387 +static nsresult 1.1388 +WriteScriptOrFunction(nsIObjectOutputStream *stream, JSContext *cx, 1.1389 + JSScript *scriptArg, HandleObject functionObj) 1.1390 +{ 1.1391 + // Exactly one of script or functionObj must be given 1.1392 + MOZ_ASSERT(!scriptArg != !functionObj); 1.1393 + 1.1394 + RootedScript script(cx, scriptArg); 1.1395 + if (!script) { 1.1396 + RootedFunction fun(cx, JS_GetObjectFunction(functionObj)); 1.1397 + script.set(JS_GetFunctionScript(cx, fun)); 1.1398 + } 1.1399 + 1.1400 + nsIPrincipal *principal = 1.1401 + nsJSPrincipals::get(JS_GetScriptPrincipals(script)); 1.1402 + nsIPrincipal *originPrincipal = 1.1403 + nsJSPrincipals::get(JS_GetScriptOriginPrincipals(script)); 1.1404 + 1.1405 + uint8_t flags = 0; 1.1406 + 1.1407 + // Optimize for the common case when originPrincipals == principals. As 1.1408 + // originPrincipals is set to principals when the former is null we can 1.1409 + // simply skip the originPrincipals when they are the same as principals. 1.1410 + if (originPrincipal && originPrincipal != principal) 1.1411 + flags |= HAS_ORIGIN_PRINCIPALS_FLAG; 1.1412 + 1.1413 + nsresult rv = stream->Write8(flags); 1.1414 + if (NS_FAILED(rv)) 1.1415 + return rv; 1.1416 + 1.1417 + if (flags & HAS_ORIGIN_PRINCIPALS_FLAG) { 1.1418 + rv = stream->WriteObject(originPrincipal, true); 1.1419 + if (NS_FAILED(rv)) 1.1420 + return rv; 1.1421 + } 1.1422 + 1.1423 + uint32_t size; 1.1424 + void* data; 1.1425 + { 1.1426 + if (functionObj) 1.1427 + data = JS_EncodeInterpretedFunction(cx, functionObj, &size); 1.1428 + else 1.1429 + data = JS_EncodeScript(cx, script, &size); 1.1430 + } 1.1431 + 1.1432 + if (!data) 1.1433 + return NS_ERROR_OUT_OF_MEMORY; 1.1434 + MOZ_ASSERT(size); 1.1435 + rv = stream->Write32(size); 1.1436 + if (NS_SUCCEEDED(rv)) 1.1437 + rv = stream->WriteBytes(static_cast<char *>(data), size); 1.1438 + js_free(data); 1.1439 + 1.1440 + return rv; 1.1441 +} 1.1442 + 1.1443 +static nsresult 1.1444 +ReadScriptOrFunction(nsIObjectInputStream *stream, JSContext *cx, 1.1445 + JSScript **scriptp, JSObject **functionObjp) 1.1446 +{ 1.1447 + // Exactly one of script or functionObj must be given 1.1448 + MOZ_ASSERT(!scriptp != !functionObjp); 1.1449 + 1.1450 + uint8_t flags; 1.1451 + nsresult rv = stream->Read8(&flags); 1.1452 + if (NS_FAILED(rv)) 1.1453 + return rv; 1.1454 + 1.1455 + nsJSPrincipals* originPrincipal = nullptr; 1.1456 + nsCOMPtr<nsIPrincipal> readOriginPrincipal; 1.1457 + if (flags & HAS_ORIGIN_PRINCIPALS_FLAG) { 1.1458 + nsCOMPtr<nsISupports> supports; 1.1459 + rv = stream->ReadObject(true, getter_AddRefs(supports)); 1.1460 + if (NS_FAILED(rv)) 1.1461 + return rv; 1.1462 + readOriginPrincipal = do_QueryInterface(supports); 1.1463 + originPrincipal = nsJSPrincipals::get(readOriginPrincipal); 1.1464 + } 1.1465 + 1.1466 + uint32_t size; 1.1467 + rv = stream->Read32(&size); 1.1468 + if (NS_FAILED(rv)) 1.1469 + return rv; 1.1470 + 1.1471 + char* data; 1.1472 + rv = stream->ReadBytes(size, &data); 1.1473 + if (NS_FAILED(rv)) 1.1474 + return rv; 1.1475 + 1.1476 + { 1.1477 + if (scriptp) { 1.1478 + JSScript *script = JS_DecodeScript(cx, data, size, originPrincipal); 1.1479 + if (!script) 1.1480 + rv = NS_ERROR_OUT_OF_MEMORY; 1.1481 + else 1.1482 + *scriptp = script; 1.1483 + } else { 1.1484 + JSObject *funobj = JS_DecodeInterpretedFunction(cx, data, size, 1.1485 + originPrincipal); 1.1486 + if (!funobj) 1.1487 + rv = NS_ERROR_OUT_OF_MEMORY; 1.1488 + else 1.1489 + *functionObjp = funobj; 1.1490 + } 1.1491 + } 1.1492 + 1.1493 + nsMemory::Free(data); 1.1494 + return rv; 1.1495 +} 1.1496 + 1.1497 +NS_IMETHODIMP 1.1498 +nsXPConnect::WriteScript(nsIObjectOutputStream *stream, JSContext *cx, JSScript *script) 1.1499 +{ 1.1500 + return WriteScriptOrFunction(stream, cx, script, NullPtr()); 1.1501 +} 1.1502 + 1.1503 +NS_IMETHODIMP 1.1504 +nsXPConnect::ReadScript(nsIObjectInputStream *stream, JSContext *cx, JSScript **scriptp) 1.1505 +{ 1.1506 + return ReadScriptOrFunction(stream, cx, scriptp, nullptr); 1.1507 +} 1.1508 + 1.1509 +NS_IMETHODIMP 1.1510 +nsXPConnect::WriteFunction(nsIObjectOutputStream *stream, JSContext *cx, JSObject *functionObjArg) 1.1511 +{ 1.1512 + RootedObject functionObj(cx, functionObjArg); 1.1513 + return WriteScriptOrFunction(stream, cx, nullptr, functionObj); 1.1514 +} 1.1515 + 1.1516 +NS_IMETHODIMP 1.1517 +nsXPConnect::ReadFunction(nsIObjectInputStream *stream, JSContext *cx, JSObject **functionObjp) 1.1518 +{ 1.1519 + return ReadScriptOrFunction(stream, cx, nullptr, functionObjp); 1.1520 +} 1.1521 + 1.1522 +NS_IMETHODIMP 1.1523 +nsXPConnect::MarkErrorUnreported(JSContext *cx) 1.1524 +{ 1.1525 + XPCContext *xpcc = XPCContext::GetXPCContext(cx); 1.1526 + xpcc->MarkErrorUnreported(); 1.1527 + return NS_OK; 1.1528 +} 1.1529 + 1.1530 +/* These are here to be callable from a debugger */ 1.1531 +extern "C" { 1.1532 +JS_EXPORT_API(void) DumpJSStack() 1.1533 +{ 1.1534 + nsresult rv; 1.1535 + nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); 1.1536 + if (NS_SUCCEEDED(rv) && xpc) 1.1537 + xpc->DebugDumpJSStack(true, true, false); 1.1538 + else 1.1539 + printf("failed to get XPConnect service!\n"); 1.1540 +} 1.1541 + 1.1542 +JS_EXPORT_API(char*) PrintJSStack() 1.1543 +{ 1.1544 + nsresult rv; 1.1545 + nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); 1.1546 + return (NS_SUCCEEDED(rv) && xpc) ? 1.1547 + xpc->DebugPrintJSStack(true, true, false) : 1.1548 + nullptr; 1.1549 +} 1.1550 + 1.1551 +JS_EXPORT_API(void) DumpJSEval(uint32_t frameno, const char* text) 1.1552 +{ 1.1553 + nsresult rv; 1.1554 + nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); 1.1555 + if (NS_SUCCEEDED(rv) && xpc) 1.1556 + xpc->DebugDumpEvalInJSStackFrame(frameno, text); 1.1557 + else 1.1558 + printf("failed to get XPConnect service!\n"); 1.1559 +} 1.1560 + 1.1561 +JS_EXPORT_API(void) DumpCompleteHeap() 1.1562 +{ 1.1563 + nsCOMPtr<nsICycleCollectorListener> listener = 1.1564 + do_CreateInstance("@mozilla.org/cycle-collector-logger;1"); 1.1565 + if (!listener) { 1.1566 + NS_WARNING("Failed to create CC logger"); 1.1567 + return; 1.1568 + } 1.1569 + 1.1570 + nsCOMPtr<nsICycleCollectorListener> alltracesListener; 1.1571 + listener->AllTraces(getter_AddRefs(alltracesListener)); 1.1572 + if (!alltracesListener) { 1.1573 + NS_WARNING("Failed to get all traces logger"); 1.1574 + return; 1.1575 + } 1.1576 + 1.1577 + nsJSContext::CycleCollectNow(alltracesListener); 1.1578 +} 1.1579 + 1.1580 +} // extern "C" 1.1581 + 1.1582 +namespace xpc { 1.1583 + 1.1584 +bool 1.1585 +Atob(JSContext *cx, unsigned argc, Value *vp) 1.1586 +{ 1.1587 + CallArgs args = CallArgsFromVp(argc, vp); 1.1588 + if (!args.length()) 1.1589 + return true; 1.1590 + 1.1591 + return xpc::Base64Decode(cx, args[0], args.rval()); 1.1592 +} 1.1593 + 1.1594 +bool 1.1595 +Btoa(JSContext *cx, unsigned argc, Value *vp) 1.1596 +{ 1.1597 + CallArgs args = CallArgsFromVp(argc, vp); 1.1598 + if (!args.length()) 1.1599 + return true; 1.1600 + 1.1601 + return xpc::Base64Encode(cx, args[0], args.rval()); 1.1602 +} 1.1603 + 1.1604 +bool 1.1605 +IsXrayWrapper(JSObject *obj) 1.1606 +{ 1.1607 + return WrapperFactory::IsXrayWrapper(obj); 1.1608 +} 1.1609 + 1.1610 +} // namespace xpc 1.1611 + 1.1612 +namespace mozilla { 1.1613 +namespace dom { 1.1614 + 1.1615 +bool 1.1616 +IsChromeOrXBL(JSContext* cx, JSObject* /* unused */) 1.1617 +{ 1.1618 + MOZ_ASSERT(NS_IsMainThread()); 1.1619 + JSCompartment* c = js::GetContextCompartment(cx); 1.1620 + 1.1621 + // For remote XUL, we run XBL in the XUL scope. Given that we care about 1.1622 + // compat and not security for remote XUL, we just always claim to be XBL. 1.1623 + // 1.1624 + // Note that, for performance, we don't check AllowXULXBLForPrincipal here, 1.1625 + // and instead rely on the fact that AllowXBLScope() only returns false in 1.1626 + // remote XUL situations. 1.1627 + return AccessCheck::isChrome(c) || IsXBLScope(c) || !AllowXBLScope(c); 1.1628 +} 1.1629 + 1.1630 +} // namespace dom 1.1631 +} // namespace mozilla