Bug 1249469 - Allow any script to execute when resolving constructors. (r=jimb)
authorShu-yu Guo <shu@rfrn.org>
Wed, 24 Feb 2016 18:15:23 -0800
changeset 321830 ff53b1ae1a195e266e9f84b179b26edfeef06844
parent 321829 fb50d4d434bfbb237390f7f78261123a17fafa2a
child 321831 074ce0a4911166fe948857cdca75eecf5e2ead38
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs1249469
milestone47.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 1249469 - Allow any script to execute when resolving constructors. (r=jimb)
js/src/vm/Debugger.h
js/src/vm/GlobalObject.cpp
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -180,16 +180,40 @@ class DebuggerWeakMap : private WeakMap<
         --p->value();
         if (p->value() == 0)
             zoneCounts.remove(zone);
     }
 };
 
 class LeaveDebuggeeNoExecute;
 
+// Suppresses all debuggee NX checks, i.e., allow all execution. Used to allow
+// certain whitelisted operations to execute code.
+//
+// WARNING
+// WARNING Do not use this unless you know what you are doing!
+// WARNING
+class AutoSuppressDebuggeeNoExecuteChecks
+{
+    EnterDebuggeeNoExecute** stack_;
+    EnterDebuggeeNoExecute* prev_;
+
+  public:
+    explicit AutoSuppressDebuggeeNoExecuteChecks(JSContext* cx) {
+        stack_ = &cx->runtime()->noExecuteDebuggerTop;
+        prev_ = *stack_;
+        *stack_ = nullptr;
+    }
+
+    ~AutoSuppressDebuggeeNoExecuteChecks() {
+        MOZ_ASSERT(!*stack_);
+        *stack_ = prev_;
+    }
+};
+
 /*
  * Env is the type of what ES5 calls "lexical environments" (runtime
  * activations of lexical scopes). This is currently just JSObject, and is
  * implemented by Call, Block, With, and DeclEnv objects, among others--but
  * environments and objects are really two different concepts.
  */
 typedef JSObject Env;
 
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -121,16 +121,21 @@ GlobalObject::resolveConstructor(JSConte
     MOZ_ASSERT(!global->isStandardClassResolved(key));
 
     // Prohibit collection of allocation metadata. Metadata builders shouldn't
     // need to observe lazily-constructed prototype objects coming into
     // existence. And assertions start to fail when the builder itself attempts
     // an allocation that re-entrantly tries to create the same prototype.
     AutoSuppressObjectMetadataCallback suppressMetadata(cx);
 
+    // Constructor resolution may execute self-hosted scripts. These
+    // self-hosted scripts do not call out to user code by construction. Allow
+    // all scripts to execute, even in debuggee compartments that are paused.
+    AutoSuppressDebuggeeNoExecuteChecks suppressNX(cx);
+
     // There are two different kinds of initialization hooks. One of them is
     // the class js::InitFoo hook, defined in a JSProtoKey-keyed table at the
     // top of this file. The other lives in the ClassSpec for classes that
     // define it. Classes may use one or the other, but not both.
     ClassInitializerOp init = protoTable[key].init;
     if (init == InitViaClassSpec)
         init = nullptr;