Bug 820816 - Refactor call object creation to not require a StackFrame. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 13 Dec 2012 13:19:32 +0100
changeset 115897 36a3cac9e3d99c1ee651bbe67dd7c712c90bccdf
parent 115896 1be998d2000717545f3a8757f6a7c08981f0b037
child 115898 e543e17b98243a806c5447df4fd281c31670b069
push id24028
push useremorley@mozilla.com
push dateThu, 13 Dec 2012 15:56:02 +0000
treeherdermozilla-central@9db79b97abbb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs820816
milestone20.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 820816 - Refactor call object creation to not require a StackFrame. r=luke
js/src/vm/ScopeObject.cpp
js/src/vm/ScopeObject.h
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -191,42 +191,53 @@ CallObject::create(JSContext *cx, Handle
         return NULL;
 
     callobj->asScope().setEnclosingScope(enclosing);
     callobj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee));
     return callobj;
 }
 
 CallObject *
+CallObject::createForFunction(JSContext *cx, HandleObject enclosing, HandleFunction callee)
+{
+    AssertCanGC();
+
+    RootedObject scopeChain(cx, enclosing);
+    JS_ASSERT(scopeChain);
+
+    /*
+     * For a named function expression Call's parent points to an environment
+     * object holding function's name.
+     */
+    if (callee->isNamedLambda()) {
+        scopeChain = DeclEnvObject::create(cx, scopeChain, callee);
+        if (!scopeChain)
+            return NULL;
+    }
+
+    RootedScript script(cx, callee->nonLazyScript());
+    return create(cx, script, scopeChain, callee);
+}
+
+CallObject *
 CallObject::createForFunction(JSContext *cx, StackFrame *fp)
 {
     AssertCanGC();
     JS_ASSERT(fp->isNonEvalFunctionFrame());
     assertSameCompartment(cx, fp);
 
     RootedObject scopeChain(cx, fp->scopeChain());
+    RootedFunction callee(cx, &fp->callee());
 
-    /*
-     * For a named function expression Call's parent points to an environment
-     * object holding function's name.
-     */
-    if (fp->fun()->isNamedLambda()) {
-        scopeChain = DeclEnvObject::create(cx, fp);
-        if (!scopeChain)
-            return NULL;
-    }
-
-    RootedScript script(cx, fp->script());
-    RootedFunction callee(cx, &fp->callee());
-    CallObject *callobj = create(cx, script, scopeChain, callee);
+    CallObject *callobj = createForFunction(cx, scopeChain, callee);
     if (!callobj)
         return NULL;
 
     /* Copy in the closed-over formal arguments. */
-    for (AliasedFormalIter i(script); i; i++)
+    for (AliasedFormalIter i(fp->script()); i; i++)
         callobj->setAliasedVar(i, fp->unaliasedFormal(i.frameIndex(), DONT_CHECK_ALIASING));
 
     return callobj;
 }
 
 CallObject *
 CallObject::createForStrictEval(JSContext *cx, StackFrame *fp)
 {
@@ -298,27 +309,24 @@ DeclEnvObject::createTemplateObject(JSCo
         return NULL;
     }
 
     JS_ASSERT(!obj->hasDynamicSlots());
     return &obj->asDeclEnv();
 }
 
 DeclEnvObject *
-DeclEnvObject::create(JSContext *cx, StackFrame *fp)
+DeclEnvObject::create(JSContext *cx, HandleObject enclosing, HandleFunction callee)
 {
-    assertSameCompartment(cx, fp);
-
-    RootedFunction fun(cx, fp->fun());
-    RootedObject obj(cx, createTemplateObject(cx, fun));
+    RootedObject obj(cx, createTemplateObject(cx, callee));
     if (!obj)
         return NULL;
 
-    obj->asScope().setEnclosingScope(fp->scopeChain());
-    obj->setFixedSlot(lambdaSlot(), ObjectValue(fp->callee()));
+    obj->asScope().setEnclosingScope(enclosing);
+    obj->setFixedSlot(lambdaSlot(), ObjectValue(*callee));
     return &obj->asDeclEnv();
 }
 
 WithObject *
 WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, uint32_t depth)
 {
     RootedTypeObject type(cx, proto->getNewType(cx));
     if (!type)
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -188,16 +188,18 @@ class CallObject : public ScopeObject
     static CallObject *
     create(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots);
 
     static CallObject *
     createTemplateObject(JSContext *cx, JSScript *script);
 
     static const uint32_t RESERVED_SLOTS = 2;
 
+    static CallObject *createForFunction(JSContext *cx, HandleObject enclosing, HandleFunction callee);
+
     static CallObject *createForFunction(JSContext *cx, StackFrame *fp);
     static CallObject *createForStrictEval(JSContext *cx, StackFrame *fp);
 
     /* True if this is for a strict mode eval frame. */
     inline bool isForEval() const;
 
     /*
      * Returns the function for which this CallObject was created. (This may
@@ -223,17 +225,17 @@ class DeclEnvObject : public ScopeObject
 
   public:
     static const uint32_t RESERVED_SLOTS = 2;
     static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2;
 
     static DeclEnvObject *
     createTemplateObject(JSContext *cx, HandleFunction fun);
 
-    static DeclEnvObject *create(JSContext *cx, StackFrame *fp);
+    static DeclEnvObject *create(JSContext *cx, HandleObject enclosing, HandleFunction callee);
 
     static inline size_t lambdaSlot() {
         return LAMBDA_SLOT;
     }
 };
 
 class NestedScopeObject : public ScopeObject
 {