Bug 1394490 - Use global lexical this to initialize NSVO lexical draft
authorTed Campbell <tcampbell@mozilla.com>
Thu, 31 Aug 2017 15:54:23 -0400
changeset 657507 2c68222aaa722ef973bceefd676e213fe42a07d4
parent 657506 f73a1f41a0aada6f3252c590b5396a45216adf9d
child 657508 b2619f543a38779b87494bc46812418ae15ef74b
push id77543
push userbmo:tcampbell@mozilla.com
push dateFri, 01 Sep 2017 15:47:07 +0000
bugs1394490
milestone57.0a1
Bug 1394490 - Use global lexical this to initialize NSVO lexical This is already current behavior, but make it explicit to allow cleanup of NSVOs handling. MozReview-Commit-ID: LeWjzwxstEB
js/src/builtin/Eval.cpp
js/src/jscompartment.cpp
js/src/vm/EnvironmentObject.cpp
js/src/vm/EnvironmentObject.h
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -464,17 +464,19 @@ js::ExecuteInGlobalAndReturnScope(JSCont
     }
 
     Rooted<EnvironmentObject*> env(cx, NonSyntacticVariablesObject::create(cx));
     if (!env)
         return false;
 
     // Unlike the non-syntactic scope chain API used by the subscript loader,
     // this API creates a fresh block scope each time.
-    env = LexicalEnvironmentObject::createNonSyntactic(cx, env);
+    //
+    // NOTE: Gecko FrameScripts expect lexical |this| to be the global.
+    env = LexicalEnvironmentObject::createNonSyntactic(cx, env, global);
     if (!env)
         return false;
 
     RootedValue rval(cx);
     if (!ExecuteKernel(cx, script, *env, UndefinedValue(),
                        NullFramePtr() /* evalInFrame */, rval.address()))
     {
         return false;
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -577,17 +577,17 @@ JSCompartment::getOrCreateNonSyntacticLe
     RootedObject key(cx, enclosing);
     if (enclosing->is<WithEnvironmentObject>()) {
         MOZ_ASSERT(!enclosing->as<WithEnvironmentObject>().isSyntactic());
         key = &enclosing->as<WithEnvironmentObject>().object();
     }
     RootedObject lexicalEnv(cx, nonSyntacticLexicalEnvironments_->lookup(key));
 
     if (!lexicalEnv) {
-        lexicalEnv = LexicalEnvironmentObject::createNonSyntactic(cx, enclosing);
+        lexicalEnv = LexicalEnvironmentObject::createNonSyntactic(cx, enclosing, enclosing);
         if (!lexicalEnv)
             return nullptr;
         if (!nonSyntacticLexicalEnvironments_->add(cx, key, lexicalEnv))
             return nullptr;
     }
 
     return &lexicalEnv->as<LexicalEnvironmentObject>();
 }
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -972,31 +972,33 @@ LexicalEnvironmentObject::createGlobal(J
     if (!JSObject::setSingleton(cx, env))
         return nullptr;
 
     env->initThisValue(global);
     return env;
 }
 
 /* static */ LexicalEnvironmentObject*
-LexicalEnvironmentObject::createNonSyntactic(JSContext* cx, HandleObject enclosing)
+LexicalEnvironmentObject::createNonSyntactic(JSContext* cx, HandleObject enclosing,
+                                             HandleObject thisv)
 {
     MOZ_ASSERT(enclosing);
     MOZ_ASSERT(!IsSyntacticEnvironment(enclosing));
 
     RootedShape shape(cx, LexicalScope::getEmptyExtensibleEnvironmentShape(cx));
     if (!shape)
         return nullptr;
 
     LexicalEnvironmentObject* env =
         LexicalEnvironmentObject::createTemplateObject(cx, shape, enclosing, gc::TenuredHeap);
     if (!env)
         return nullptr;
 
-    env->initThisValue(enclosing);
+    env->initThisValue(thisv);
+
     return env;
 }
 
 /* static */ LexicalEnvironmentObject*
 LexicalEnvironmentObject::createHollowForDebug(JSContext* cx, Handle<LexicalScope*> scope)
 {
     MOZ_ASSERT(!scope->hasEnvironment());
 
--- a/js/src/vm/EnvironmentObject.h
+++ b/js/src/vm/EnvironmentObject.h
@@ -505,17 +505,18 @@ class LexicalEnvironmentObject : public 
     }
 
   public:
     static LexicalEnvironmentObject* create(JSContext* cx, Handle<LexicalScope*> scope,
                                             HandleObject enclosing, gc::InitialHeap heap);
     static LexicalEnvironmentObject* create(JSContext* cx, Handle<LexicalScope*> scope,
                                             AbstractFramePtr frame);
     static LexicalEnvironmentObject* createGlobal(JSContext* cx, Handle<GlobalObject*> global);
-    static LexicalEnvironmentObject* createNonSyntactic(JSContext* cx, HandleObject enclosing);
+    static LexicalEnvironmentObject* createNonSyntactic(JSContext* cx, HandleObject enclosing,
+                                                        HandleObject thisv);
     static LexicalEnvironmentObject* createHollowForDebug(JSContext* cx,
                                                           Handle<LexicalScope*> scope);
 
     // Create a new LexicalEnvironmentObject with the same enclosing env and
     // variable values as this.
     static LexicalEnvironmentObject* clone(JSContext* cx, Handle<LexicalEnvironmentObject*> env);
 
     // Create a new LexicalEnvironmentObject with the same enclosing env as