Bug 804558 - Make JSScript::loadSource GC-safe. r=terrence
authorBenjamin Peterson <benjamin@python.org>
Wed, 24 Oct 2012 13:51:28 -0700
changeset 111423 0689e804a40e768ca3ce2f365d79883d6f9221a5
parent 111422 94ea624a1d8e0df74c58340f3ff87e9bfbdbbb6e
child 111424 414e2834bbdcab7b67bf13f8b1b2d7d835309da0
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersterrence
bugs804558
milestone19.0a1
Bug 804558 - Make JSScript::loadSource GC-safe. r=terrence
js/src/jsfun.cpp
js/src/jsscript.cpp
js/src/jsscript.h
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -615,18 +615,22 @@ FindBody(JSContext *cx, HandleFunction f
     JS_ASSERT(*bodyStart <= *bodyEnd);
     return true;
 }
 
 JSString *
 js::FunctionToString(JSContext *cx, HandleFunction fun, bool bodyOnly, bool lambdaParen)
 {
     StringBuffer out(cx);
+    RootedScript script(cx);
 
-    if (fun->isInterpreted() && fun->script()->isGeneratorExp) {
+    if (fun->isInterpreted())
+        script = fun->script();
+
+    if (fun->isInterpreted() && script->isGeneratorExp) {
         if ((!bodyOnly && !out.append("function genexp() {")) ||
             !out.append("\n    [generator expression]\n") ||
             (!bodyOnly && !out.append("}"))) {
             return NULL;
         }
         return out.finishString();
     }
     if (!bodyOnly) {
@@ -638,23 +642,22 @@ js::FunctionToString(JSContext *cx, Hand
         if (!out.append("function "))
             return NULL;
         if (fun->atom()) {
             if (!out.append(fun->atom()))
                 return NULL;
         }
     }
     bool haveSource = fun->isInterpreted() && !fun->isSelfHostedBuiltin();
-    if (haveSource && !fun->script()->scriptSource()->hasSourceData() &&
-        !fun->script()->loadSource(cx, &haveSource))
+    if (haveSource && !script->scriptSource()->hasSourceData() &&
+        !JSScript::loadSource(cx, script, &haveSource))
     {
         return NULL;
     }
     if (haveSource) {
-        RootedScript script(cx, fun->script());
         RootedString srcStr(cx, script->sourceData(cx));
         if (!srcStr)
             return NULL;
         Rooted<JSStableString *> src(cx, srcStr->ensureStable(cx));
         if (!src)
             return NULL;
 
         StableCharPtr chars = src->chars();
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1036,30 +1036,30 @@ SourceCompressorThread::abort(SourceComp
 void
 JSScript::setScriptSource(ScriptSource *ss)
 {
     JS_ASSERT(ss);
     ss->incref();
     scriptSource_ = ss;
 }
 
-bool
-JSScript::loadSource(JSContext *cx, bool *worked)
+/* static */ bool
+JSScript::loadSource(JSContext *cx, HandleScript script, bool *worked)
 {
-    JS_ASSERT(!scriptSource_->hasSourceData());
+    JS_ASSERT(!script->scriptSource_->hasSourceData());
     *worked = false;
-    if (!cx->runtime->sourceHook || !scriptSource_->sourceRetrievable())
+    if (!cx->runtime->sourceHook || !script->scriptSource_->sourceRetrievable())
         return true;
     jschar *src = NULL;
     uint32_t length;
-    if (!cx->runtime->sourceHook(cx, this, &src, &length))
+    if (!cx->runtime->sourceHook(cx, script, &src, &length))
         return false;
     if (!src)
         return true;
-    ScriptSource *ss = scriptSource();
+    ScriptSource *ss = script->scriptSource();
     ss->setSource(src, length);
     *worked = true;
     return true;
 }
 
 JSFlatString *
 JSScript::sourceData(JSContext *cx)
 {
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -570,17 +570,17 @@ struct JSScript : public js::gc::Cell
      * Original compiled function for the script, if it has a function.
      * NULL for global and eval scripts.
      */
     JSFunction *function() const { return function_; }
     void setFunction(JSFunction *fun);
 
     JSFlatString *sourceData(JSContext *cx);
 
-    bool loadSource(JSContext *cx, bool *worked);
+    static bool loadSource(JSContext *cx, js::HandleScript scr, bool *worked);
 
     js::ScriptSource *scriptSource() {
         return scriptSource_;
     }
 
     void setScriptSource(js::ScriptSource *ss);
 
   public: