Bug 1520189 - Remove the ToWindowProxyIfWindow call in LexicalEnvironmentObject::thisValue; handle this in js::SetWindowProxy instead. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 15 Jan 2019 20:33:13 +0000
changeset 514051 070316635c495a75684a55168d734a1f7df5edca
parent 514050 6ec84030fb70b4156b028e2c28136fa55c95272d
child 514052 1e7c60e83b86e18d1c7918d2e4b2fd5d4d79fde2
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1520189
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1520189 - Remove the ToWindowProxyIfWindow call in LexicalEnvironmentObject::thisValue; handle this in js::SetWindowProxy instead. r=luke This simplifies LexicalEnvironmentObject::thisValue so it's easier to inline in JIT code. Differential Revision: https://phabricator.services.mozilla.com/D16586
js/src/jsfriendapi.cpp
js/src/vm/EnvironmentObject.cpp
js/src/vm/EnvironmentObject.h
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -1323,19 +1323,21 @@ JS_FRIEND_API void js::SetWindowProxyCla
 }
 
 JS_FRIEND_API void js::SetWindowProxy(JSContext* cx, HandleObject global,
                                       HandleObject windowProxy) {
   AssertHeapIsIdle();
   CHECK_THREAD(cx);
 
   cx->check(global, windowProxy);
+  MOZ_ASSERT(IsWindowProxy(windowProxy));
 
-  MOZ_ASSERT(IsWindowProxy(windowProxy));
-  global->as<GlobalObject>().setWindowProxy(windowProxy);
+  GlobalObject& globalObj = global->as<GlobalObject>();
+  globalObj.setWindowProxy(windowProxy);
+  globalObj.lexicalEnvironment().setWindowProxyThisValue(windowProxy);
 }
 
 JS_FRIEND_API JSObject* js::ToWindowIfWindowProxy(JSObject* obj) {
   if (IsWindowProxy(obj)) {
     return &obj->nonCCWGlobal();
   }
   return obj;
 }
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -1128,27 +1128,30 @@ LexicalEnvironmentObject::createHollowFo
 
 bool LexicalEnvironmentObject::isExtensible() const {
   return NativeObject::isExtensible();
 }
 
 Value LexicalEnvironmentObject::thisValue() const {
   MOZ_ASSERT(isExtensible());
   Value v = getReservedSlot(THIS_VALUE_OR_SCOPE_SLOT);
-  if (v.isObject()) {
-    // A WindowProxy may have been attached after this environment was
-    // created so check ToWindowProxyIfWindow again. For example,
-    // GlobalObject::createInternal will construct its lexical environment
-    // before SetWindowProxy can be called.
-    // See also: js::GetThisValue / js::GetThisValueOfLexical
-    return ObjectValue(*ToWindowProxyIfWindow(&v.toObject()));
-  }
+
+  // Windows must never be exposed to script. setWindowProxyThisValue should
+  // have set this to the WindowProxy.
+  MOZ_ASSERT_IF(v.isObject(), !IsWindow(&v.toObject()));
+
   return v;
 }
 
+void LexicalEnvironmentObject::setWindowProxyThisValue(JSObject* obj) {
+  MOZ_ASSERT(isGlobal());
+  MOZ_ASSERT(IsWindowProxy(obj));
+  setReservedSlot(THIS_VALUE_OR_SCOPE_SLOT, ObjectValue(*obj));
+}
+
 const Class LexicalEnvironmentObject::class_ = {
     "LexicalEnvironment",
     JSCLASS_HAS_RESERVED_SLOTS(LexicalEnvironmentObject::RESERVED_SLOTS) |
         JSCLASS_IS_ANONYMOUS,
     JS_NULL_CLASS_OPS,
     JS_NULL_CLASS_SPEC,
     JS_NULL_CLASS_EXT,
     JS_NULL_OBJECT_OPS};
--- a/js/src/vm/EnvironmentObject.h
+++ b/js/src/vm/EnvironmentObject.h
@@ -562,16 +562,18 @@ class LexicalEnvironmentObject : public 
 
   // Is this the global lexical scope?
   bool isGlobal() const { return enclosingEnvironment().is<GlobalObject>(); }
 
   GlobalObject& global() const {
     return enclosingEnvironment().as<GlobalObject>();
   }
 
+  void setWindowProxyThisValue(JSObject* obj);
+
   // Global and non-syntactic lexical scopes are extensible. All other
   // lexical scopes are not.
   bool isExtensible() const;
 
   // Is this a syntactic (i.e. corresponds to a source text) lexical
   // environment?
   bool isSyntactic() const { return !isExtensible() || isGlobal(); }