[INFER] Don't set script->isCachedEval until it is on the compartment's scriptsToGC, bug 642422.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 17 Mar 2011 12:22:57 -0700
changeset 74802 7085463508eeede7eaa016f28f27e2f584c5112b
parent 74801 e65266e60e1f9d7cdd8efb1296391b36a7074249
child 74803 5f46e05ceecb252bb8967e855ba650b1bcd103ac
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs642422
milestone2.0b13pre
[INFER] Don't set script->isCachedEval until it is on the compartment's scriptsToGC, bug 642422.
js/src/jit-test/tests/basic/bug642422.js
js/src/jsobj.cpp
js/src/jsparse.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug642422.js
@@ -0,0 +1,4 @@
+gczeal(2);
+var x;
+var foo = "for (var z = 0; z < 2; ++z) { new Object(new String(this), x)}";
+eval(foo);
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1279,32 +1279,32 @@ EvalKernel(JSContext *cx, uintN argc, Va
 
         uint32 tcflags = TCF_COMPILE_N_GO | TCF_NEED_MUTABLE_SCRIPT | TCF_COMPILE_FOR_EVAL;
         script = Compiler::compileScript(cx, scopeobj, callerFrame,
                                          principals, tcflags, chars, length,
                                          filename, lineno, cx->findVersion(),
                                          linearStr, staticLevel);
         if (!script)
             return false;
-        script->isCachedEval = true;
     }
 
     assertSameCompartment(cx, scopeobj, script);
 
     /*
      * Belt-and-braces: check that the lesser of eval's principals and the
      * caller's principals has access to scopeobj.
      */
     JSBool ok = js_CheckPrincipalsAccess(cx, scopeobj, principals,
                                          cx->runtime->atomState.evalAtom) &&
                 Execute(cx, scopeobj, script, callerFrame, JSFRAME_EVAL, vp);
 
     MUST_FLOW_LABEL(destroy);
     js_CallDestroyScriptHook(cx, script);
 
+    script->isCachedEval = true;
     script->u.nextToGC = *bucket;
     *bucket = script;
 #ifdef CHECK_SCRIPT_OWNER
     script->owner = NULL;
 #endif
 
     return ok;
 }
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -1120,18 +1120,16 @@ Compiler::compileScript(JSContext *cx, J
     JS_DumpArenaStats(stdout);
 #endif
 
     JS_ASSERT(cg.version() == version);
 
     script = JSScript::NewScriptFromCG(cx, &cg);
     if (script && funbox)
         script->savedCallerFun = true;
-    if (script && cg.compilingForEval())
-        script->isCachedEval = true;
 
 #ifdef JS_SCOPE_DEPTH_METER
     if (script) {
         JSObject *obj = scopeChain;
         uintN depth = 1;
         while ((obj = obj->getParent()) != NULL)
             ++depth;
         JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);