Bug 810987: When sharing a global, don't import properties onto the global, import them onto the appropriate 'this' object. r=mrbkap

--HG--
extra : rebase_source : c3a92d4197831fa3061bf3f01b7cc610cc89e867
This commit is contained in:
Kyle Huey 2012-11-13 11:13:27 -08:00
Родитель bb4830f48c
Коммит e690de14af
4 изменённых файлов: 73 добавлений и 41 удалений

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

@ -431,6 +431,7 @@ mozJSComponentLoader::ReallyInit()
mModules.Init(32);
mImports.Init(32);
mInProgressImports.Init(32);
mThisObjects.Init(32);
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService(kObserverServiceContractID, &rv);
@ -578,6 +579,52 @@ mozJSComponentLoader::LoadModule(FileLocation &aFile)
return entry.forget();
}
nsresult
mozJSComponentLoader::FindTargetObject(JSContext* aCx,
JSObject** aTargetObject)
{
JSObject* targetObject = nullptr;
*aTargetObject = nullptr;
if (mReuseLoaderGlobal) {
JSScript* script =
js::GetOutermostEnclosingFunctionOfScriptedCaller(aCx);
if (script) {
targetObject = mThisObjects.Get(script);
}
}
// The above could fail, even if mReuseLoaderGlobal, if the scripted
// caller is not a component/JSM (it could be a DOM scope, for
// instance).
if (!targetObject) {
// Our targetObject is the caller's global object. Let's get it.
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc =
do_GetService(kXPConnectServiceContractID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAXPCNativeCallContext *cc = nullptr;
rv = xpc->GetCurrentNativeCallContext(&cc);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIXPConnectWrappedNative> wn;
rv = cc->GetCalleeWrapper(getter_AddRefs(wn));
NS_ENSURE_SUCCESS(rv, rv);
wn->GetJSObject(&targetObject);
if (!targetObject) {
NS_ERROR("null calling object");
return NS_ERROR_FAILURE;
}
targetObject = JS_GetGlobalForObject(aCx, targetObject);
}
*aTargetObject = targetObject;
return NS_OK;
}
// Some stack based classes for cleaning up on early return
#ifdef HAVE_PR_MEMMAP
class FileAutoCloser
@ -977,6 +1024,14 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
// See bug 384168.
*aObject = obj;
JSScript* tableScript = script;
if (!tableScript) {
tableScript = JS_GetFunctionScript(cx, function);
MOZ_ASSERT(tableScript);
}
mThisObjects.Put(tableScript, obj);
uint32_t oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts |
(exception ? JSOPTION_DONT_REPORT_UNCAUGHT : 0));
@ -1040,6 +1095,7 @@ mozJSComponentLoader::UnloadModules()
mInProgressImports.Clear();
mImports.Clear();
mThisObjects.Clear();
mModules.Enumerate(ClearModules, NULL);
@ -1089,28 +1145,8 @@ mozJSComponentLoader::Import(const nsACString& registryLocation,
PromiseFlatCString(registryLocation).get());
}
} else {
// Our targetObject is the caller's global object. Find it by
// walking the calling object's parent chain.
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc =
do_GetService(kXPConnectServiceContractID, &rv);
nsresult rv = FindTargetObject(cx, &targetObject);
NS_ENSURE_SUCCESS(rv, rv);
nsAXPCNativeCallContext *cc = nullptr;
rv = xpc->GetCurrentNativeCallContext(&cc);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIXPConnectWrappedNative> wn;
rv = cc->GetCalleeWrapper(getter_AddRefs(wn));
NS_ENSURE_SUCCESS(rv, rv);
wn->GetJSObject(&targetObject);
if (!targetObject) {
NS_ERROR("null calling object");
return NS_ERROR_FAILURE;
}
targetObject = JS_GetGlobalForObject(cx, targetObject);
}
Maybe<JSAutoCompartment> ac;

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

@ -50,6 +50,10 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
// ModuleLoader
const mozilla::Module* LoadModule(mozilla::FileLocation &aFile);
nsresult FindTargetObject(JSContext* aCx, JSObject** aTargetObject);
static mozJSComponentLoader* Get() { return sSelf; }
protected:
static mozJSComponentLoader* sSelf;
@ -136,6 +140,7 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
nsClassHashtable<nsCStringHashKey, ModuleEntry> mImports;
nsDataHashtable<nsCStringHashKey, ModuleEntry*> mInProgressImports;
nsDataHashtable<nsPtrHashKey<JSScript>, JSObject*> mThisObjects;
bool mInitialized;
bool mReuseLoaderGlobal;

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

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozJSSubScriptLoader.h"
#include "mozJSComponentLoader.h"
#include "mozJSLoaderUtils.h"
#include "nsIServiceManager.h"
@ -53,6 +54,9 @@ mozJSLoaderErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
mozJSSubScriptLoader::mozJSSubScriptLoader() : mSystemPrincipal(nullptr)
{
// Force construction of the JS component loader. We may need it later.
nsCOMPtr<xpcIJSModuleLoader> componentLoader =
do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
}
mozJSSubScriptLoader::~mozJSSubScriptLoader()
@ -179,23 +183,10 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
if (!targetObj) {
// If the user didn't provide an object to eval onto, find the global
// object by walking the parent chain of the calling object.
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
NS_ENSURE_TRUE(xpc, NS_ERROR_FAILURE);
nsAXPCNativeCallContext *cc = nullptr;
rv = xpc->GetCurrentNativeCallContext(&cc);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIXPConnectWrappedNative> wn;
rv = cc->GetCalleeWrapper(getter_AddRefs(wn));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
rv = wn->GetJSObject(&targetObj);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
targetObj = JS_GetGlobalForObject(cx, targetObj);
// If the user didn't provide an object to eval onto, find one.
mozJSComponentLoader* loader = mozJSComponentLoader::Get();
rv = loader->FindTargetObject(cx, &targetObj);
NS_ENSURE_SUCCESS(rv, rv);
}
// Remember an object out of the calling compartment so that we

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

@ -7,17 +7,17 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
var EXPORTED_SYMBOLS = ['ContentPrefInstance'];
this.EXPORTED_SYMBOLS = ['ContentPrefInstance'];
// This is a wrapper for nsIContentPrefService that alleviates the need to pass
// an nsILoadContext argument to every method. Pass the context to the constructor
// instead and continue on your way in blissful ignorance.
function ContentPrefInstance(aContext) {
this.ContentPrefInstance = function ContentPrefInstance(aContext) {
this._contentPrefSvc = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService);
this._context = aContext;
}
};
ContentPrefInstance.prototype = {
getPref: function ContentPrefInstance_init(aName, aGroup, aCallback) {