From 8cf23858faccebf33bbc7cb53738fa9400ed2b3b Mon Sep 17 00:00:00 2001 From: Till Schneidereit Date: Thu, 11 Oct 2012 11:53:02 +0200 Subject: [PATCH] Bug 784400 - Enable cloning of object literals within functions. r=luke --- js/src/jsinterpinlines.h | 3 +-- js/src/jsobj.cpp | 8 ++++++++ js/src/jsobj.h | 3 +++ js/src/jsscript.cpp | 10 +++++++++- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/js/src/jsinterpinlines.h b/js/src/jsinterpinlines.h index abac258dcaf..b25cd1a842d 100644 --- a/js/src/jsinterpinlines.h +++ b/js/src/jsinterpinlines.h @@ -400,8 +400,7 @@ inline bool IntrinsicNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, MutableHandleValue vp) { JSOp op = JSOp(*pc); - RootedPropertyName name(cx); - name = GetNameFromBytecode(cx, script, pc, op); + RootedPropertyName name(cx, GetNameFromBytecode(cx, script, pc, op)); cx->global()->getIntrinsicValue(cx, name, vp); return true; } diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index d150843f709..e7367eb13f9 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2652,6 +2652,14 @@ js::CloneObject(JSContext *cx, HandleObject obj, Handle proto, return clone; } +JSObject * +js::CloneObjectLiteral(JSContext *cx, HandleObject parent, HandleObject srcObj) +{ + Rooted typeObj(cx, cx->global()->getOrCreateObjectPrototype(cx)->getNewType(cx)); + RootedShape shape(cx, srcObj->lastProperty()); + return NewReshapedObject(cx, typeObj, parent, srcObj->getAllocKind(), shape); +} + struct JSObject::TradeGutsReserved { Vector avals; Vector bvals; diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 7ea2309b1a3..b1618a3e17e 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -1390,6 +1390,9 @@ ToObjectFromStack(JSContext *cx, HandleValue vp) return ToObjectSlow(cx, vp, true); } +extern JSObject * +CloneObjectLiteral(JSContext *cx, HandleObject parent, HandleObject srcObj); + } /* namespace js */ extern void diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 0599c272fa7..c38eabbe5d2 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -2128,7 +2128,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, enclosingScope = fun; clone = CloneStaticBlockObject(cx, enclosingScope, innerBlock); - } else { + } else if (obj->isFunction()) { RootedFunction innerFun(cx, obj->toFunction()); StaticScopeIter ssi(innerFun->script()->enclosingStaticScope()); @@ -2139,6 +2139,14 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, enclosingScope = fun; clone = CloneInterpretedFunction(cx, enclosingScope, innerFun); + } else { + /* + * Clone object literals emitted for the JSOP_NEWOBJECT opcode. We only emit that + * instead of the less-optimized JSOP_NEWINIT for self-hosted code or code compiled + * with JSOPTION_COMPILE_N_GO set. As we don't clone the latter type of code, this + * case should only ever be hit when cloning objects from self-hosted code. + */ + clone = CloneObjectLiteral(cx, cx->global(), obj); } if (!clone || !objects.append(clone)) return NULL;