Bug 1157963 - Fix LazyScript::hasUncompiledEnclosingScript. (r=jimb)
authorShu-yu Guo <shu@rfrn.org>
Tue, 28 Apr 2015 01:44:22 -0700
changeset 241316 17f588e15c3c2e9e5dac9bf10367d1ef327adc8d
parent 241315 6adf6c6f97944da2d850c0d5c7497cdd753d9ee9
child 241317 bbc6552982960dbf4992ed143fb473953ad94eb4
push id59096
push usershu@rfrn.org
push dateTue, 28 Apr 2015 08:44:27 +0000
treeherdermozilla-inbound@bbc655298296 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimb
bugs1157963
milestone40.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 1157963 - Fix LazyScript::hasUncompiledEnclosingScript. (r=jimb)
js/src/jit-test/tests/debug/bug980585.js
js/src/jsfun.h
js/src/jsscript.cpp
--- a/js/src/jit-test/tests/debug/bug980585.js
+++ b/js/src/jit-test/tests/debug/bug980585.js
@@ -1,10 +1,10 @@
 var g = newGlobal();
 var dbg = new Debugger(g);
 
 try {
-  g.eval("function f() { var array = ['a', 'b']; [1].map(function () {}); return {array}; }");
+  g.eval("function f() { [1].map(function () {}); const x = 42; x = 43; } f();");
 } catch (e) {
   // Ignore the syntax error.
 }
 
 dbg.findScripts();
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -337,19 +337,26 @@ class JSFunction : public js::NativeObje
 
             flags_ &= ~INTERPRETED_LAZY;
             flags_ |= INTERPRETED;
             initScript(script);
         }
         return nonLazyScript();
     }
 
-    JSScript* nonLazyScript() const {
+    // The state of a JSFunction whose script errored out during bytecode
+    // compilation. Such JSFunctions are only reachable via GC iteration and
+    // not from script.
+    bool hasUncompiledScript() const {
         MOZ_ASSERT(hasScript());
-        MOZ_ASSERT(u.i.s.script_);
+        return !u.i.s.script_;
+    }
+
+    JSScript* nonLazyScript() const {
+        MOZ_ASSERT(!hasUncompiledScript());
         return u.i.s.script_;
     }
 
     bool getLength(JSContext* cx, uint16_t* length) {
         JS::RootedFunction self(cx, this);
         if (self->isInterpretedLazy() && !self->getOrCreateScript(cx))
             return false;
 
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -3906,17 +3906,17 @@ LazyScript::hasUncompiledEnclosingScript
     //
     // If the enclosing scope is a function with a null script or has a script
     // without code, it was not successfully compiled.
 
     if (!enclosingScope() || !enclosingScope()->is<JSFunction>())
         return false;
 
     JSFunction& fun = enclosingScope()->as<JSFunction>();
-    return fun.isInterpreted() && (!fun.hasScript() || !fun.nonLazyScript()->code());
+    return !fun.hasScript() || fun.hasUncompiledScript() || !fun.nonLazyScript()->code();
 }
 
 uint32_t
 LazyScript::staticLevel(JSContext* cx) const
 {
     for (StaticScopeIter<NoGC> ssi(enclosingScope()); !ssi.done(); ssi++) {
         if (ssi.type() == StaticScopeIter<NoGC>::Function)
             return ssi.funScript()->staticLevel() + 1;