Bug 1186409 - Change patch to use new NSVO API. WIP draft
authorAndrew McCreight <continuation@gmail.com>
Fri, 01 Sep 2017 14:01:49 -0700
changeset 657794 2712db7009bd83cb7cfb3eae0f3a764cf7642a53
parent 657793 90353b27c3ea82749063a545997211e5877afcb1
child 729516 953943b465d23c43f5d67c4b97e5b83198692644
push id77618
push userbmo:continuation@gmail.com
push dateFri, 01 Sep 2017 23:15:17 +0000
bugs1186409
milestone57.0a1
Bug 1186409 - Change patch to use new NSVO API. WIP use new non syntactic running API MozReview-Commit-ID: KAxiib4hPrx
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSComponentLoader.h
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -425,25 +425,34 @@ mozJSComponentLoader::LoadModule(FileLoc
     mModules.Put(spec, entry);
 
     // The hash owns the ModuleEntry now, forget about it
     return entry.forget();
 }
 
 void
 mozJSComponentLoader::FindTargetObject(JSContext* aCx,
+                                       MutableHandleObject aTargetObject,
+                                       MutableHandleObject aLexEnv)
+{
+    bool ok = js::GetNonSyntacticGlobalOfScriptedCaller(aCx, aTargetObject, aLexEnv);
+    if (!ok || !aTargetObject) {
+        // The above could fail if the scripted caller is not a
+        // component/JSM (it could be a DOM scope, for instance).
+        aTargetObject.set(CurrentGlobalOrNull(aCx));
+        aLexEnv.set(nullptr);
+    }
+}
+
+void
+mozJSComponentLoader::FindTargetObject(JSContext* aCx,
                                        MutableHandleObject aTargetObject)
 {
-    aTargetObject.set(js::GetVariablesObjectOfScriptedCaller(aCx));
-
-    // The above could fail if the scripted caller is not a
-    // component/JSM (it could be a DOM scope, for instance).
-    if (!aTargetObject) {
-        aTargetObject.set(CurrentGlobalOrNull(aCx));
-    }
+    RootedObject lexEnv(aCx);
+    FindTargetObject(aCx, aTargetObject, &lexEnv);
 }
 
 // This requires that the keys be strings and the values be pointers.
 template <class Key, class Data, class UserData>
 static size_t
 SizeOfTableExcludingThis(const nsBaseHashtable<Key, Data, UserData>& aTable,
                          MallocSizeOf aMallocSizeOf)
 {
@@ -550,17 +559,18 @@ mozJSComponentLoader::ReuseGlobal(bool a
     return true;
 }
 
 JSObject*
 mozJSComponentLoader::PrepareObjectForLocation(JSContext* aCx,
                                                nsIFile* aComponentFile,
                                                nsIURI* aURI,
                                                bool* aReuseGlobal,
-                                               bool* aRealFile)
+                                               bool* aRealFile,
+                                               MutableHandleObject aLexEnv)
 {
     nsAutoCString nativePath;
     NS_ENSURE_SUCCESS(aURI->GetSpec(nativePath), nullptr);
 
     JSAddonId* addonId = MapURIToAddonID(aURI);
     bool reuseGlobal = ReuseGlobal(!!addonId, aURI);
 
     *aReuseGlobal = reuseGlobal;
@@ -591,18 +601,19 @@ mozJSComponentLoader::PrepareObjectForLo
 
     // |thisObj| is the object we set properties on for a particular .jsm.
     RootedObject thisObj(aCx, globalObj);
     NS_ENSURE_TRUE(thisObj, nullptr);
 
     JSAutoCompartment ac(aCx, thisObj);
 
     if (reuseGlobal) {
-        thisObj = js::CreateNonSyntacticVariablesObject(aCx);
+        NS_ENSURE_TRUE(js::CreateNonSyntacticGlobal(aCx, &thisObj, aLexEnv), nullptr);
         NS_ENSURE_TRUE(thisObj, nullptr);
+        NS_ENSURE_TRUE(aLexEnv, nullptr);
     }
 
     *aRealFile = false;
 
     // need to be extra careful checking for URIs pointing to files
     // EnsureFile may not always get called, especially on resource URIs
     // so we need to call GetFile to make sure this is a valid file
     nsresult rv = NS_OK;
@@ -662,18 +673,20 @@ mozJSComponentLoader::ObjectForLocation(
     dom::AutoJSAPI jsapi;
     jsapi.Init();
     JSContext* cx = jsapi.cx();
 
     bool realFile = false;
     nsresult rv = aInfo.EnsureURI();
     NS_ENSURE_SUCCESS(rv, rv);
     bool reuseGlobal = false;
+    RootedObject lexEnv(cx);
     RootedObject obj(cx, PrepareObjectForLocation(cx, aComponentFile, aInfo.URI(),
-                                                  &reuseGlobal, &realFile));
+                                                  &reuseGlobal, &realFile,
+                                                  &lexEnv));
     NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
     MOZ_ASSERT(JS_IsGlobalObject(obj) == !reuseGlobal);
 
     JSAutoCompartment ac(cx, obj);
 
     RootedScript script(cx);
 
     nsAutoCString nativePath;
@@ -805,30 +818,32 @@ mozJSComponentLoader::ObjectForLocation(
 
     aTableScript.set(script);
 
 
     {   // Scope for AutoEntryScript
 
         // We're going to run script via JS_ExecuteScript, so we need an
         // AutoEntryScript. This is Gecko-specific and not in any spec.
-        dom::AutoEntryScript aes(CurrentGlobalOrNull(cx),
+        JS::RootedObject global(cx, CurrentGlobalOrNull(cx));
+        dom::AutoEntryScript aes(global,
                                  "component loader load module");
         JSContext* aescx = aes.cx();
-        AutoObjectVector scopeChain(cx);
-        if (!JS_IsGlobalObject(obj)) {
-            if (!scopeChain.append(obj))
-                return NS_ERROR_FAILURE;
+
+        bool executeOk = false;
+        if (JS_IsGlobalObject(obj)) {
+            MOZ_ASSERT(!lexEnv);
+            JS::RootedValue rval(cx);
+            executeOk = JS::CloneAndExecuteScript(aescx, script, &rval);
+        } else {
+            executeOk = js::ExecuteInNonSyntacticGlobal(aescx, global,
+                                                        script, &obj, &lexEnv);
         }
-        JS::RootedValue rval(cx);
 
-        if (scopeChain.length() == 0
-            ? !JS::CloneAndExecuteScript(aescx, script, &rval)
-            : !JS::CloneAndExecuteScript(aescx, scopeChain, script, &rval))
-        {
+        if (!executeOk) {
             if (aPropagateExceptions && aes.HasException()) {
                 // Ignore return value because we're returning an error code
                 // anyway.
                 Unused << aes.StealException(aException);
             }
             aObject.set(nullptr);
             aTableScript.set(nullptr);
             return NS_ERROR_FAILURE;
--- a/js/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -43,16 +43,19 @@ class mozJSComponentLoader : public mozi
     NS_DECL_NSIOBSERVER
 
     mozJSComponentLoader();
 
     // ModuleLoader
     const mozilla::Module* LoadModule(mozilla::FileLocation& aFile) override;
 
     void FindTargetObject(JSContext* aCx,
+                          JS::MutableHandleObject aTargetObject,
+                          JS::MutableHandleObject aLexEnv);
+    void FindTargetObject(JSContext* aCx,
                           JS::MutableHandleObject aTargetObject);
 
     static mozJSComponentLoader* Get() { return sSelf; }
 
     nsresult Import(const nsACString& aResourceURI, JS::HandleValue aTargetObj,
                     JSContext* aCx, uint8_t aArgc, JS::MutableHandleValue aRetval);
     nsresult Unload(const nsACString& aResourceURI);
     nsresult IsModuleLoaded(const nsACString& aResourceURI, bool* aRetval);
@@ -76,17 +79,18 @@ class mozJSComponentLoader : public mozi
                             JS::MutableHandleObject aGlobal);
 
     bool ReuseGlobal(bool aIsAddon, nsIURI* aComponent);
 
     JSObject* PrepareObjectForLocation(JSContext* aCx,
                                        nsIFile* aComponentFile,
                                        nsIURI* aComponent,
                                        bool* aReuseGlobal,
-                                       bool* aRealFile);
+                                       bool* aRealFile,
+                                       JS::MutableHandleObject aLexEnv);
 
     nsresult ObjectForLocation(ComponentLoaderInfo& aInfo,
                                nsIFile* aComponentFile,
                                JS::MutableHandleObject aObject,
                                JS::MutableHandleScript aTableScript,
                                char** location,
                                bool aCatchException,
                                JS::MutableHandleValue aException);