зеркало из https://github.com/mozilla/gecko-dev.git
Bug 556315 part 2 - JSObject::getGlobal() and JSStackFrame::getThisObject(). r=gal.
--HG-- extra : rebase_source : 103e73537d3c2f537a914b69a620136451a664ba
This commit is contained in:
Родитель
80b07733e2
Коммит
54b9b7f300
|
@ -1685,9 +1685,7 @@ JS_GetScopeChain(JSContext *cx)
|
|||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetGlobalForObject(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
while (JSObject *parent = obj->getParent())
|
||||
obj = parent;
|
||||
return obj;
|
||||
return obj->getGlobal();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(jsval)
|
||||
|
|
|
@ -1227,10 +1227,7 @@ JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
|
|||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFrameThis(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
if (!(fp->flags & JSFRAME_COMPUTED_THIS) && fp->argv)
|
||||
fp->thisv = OBJECT_TO_JSVAL(js_ComputeThis(cx, fp->argv));
|
||||
|
||||
return JSVAL_TO_OBJECT(fp->thisv);
|
||||
return fp->getThisObject(cx);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
|
|
|
@ -407,7 +407,7 @@ js_ComputeGlobalThis(JSContext *cx, jsval *argv)
|
|||
!JSVAL_TO_OBJECT(argv[-2])->getParent()) {
|
||||
thisp = cx->globalObject;
|
||||
} else {
|
||||
thisp = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(argv[-2]));
|
||||
thisp = JSVAL_TO_OBJECT(argv[-2])->getGlobal();
|
||||
}
|
||||
|
||||
return CallThisObjectHook(cx, thisp, argv);
|
||||
|
|
|
@ -167,6 +167,8 @@ struct JSStackFrame {
|
|||
|
||||
/* Short for: varobj(cx->activeCallStack()). */
|
||||
JSObject *varobj(JSContext *cx);
|
||||
|
||||
inline JSObject *getThisObject(JSContext *cx);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -274,21 +276,6 @@ extern const uint16 js_PrimitiveTestFlags[];
|
|||
JSFUN_THISP_TEST(JSFUN_THISP_FLAGS((fun)->flags), \
|
||||
js_PrimitiveTestFlags[JSVAL_TAG(thisv) - 1]))
|
||||
|
||||
#ifdef __cplusplus /* Aargh, libgjs, bug 492720. */
|
||||
static JS_INLINE JSObject *
|
||||
js_ComputeThisForFrame(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
if (fp->flags & JSFRAME_COMPUTED_THIS)
|
||||
return JSVAL_TO_OBJECT(fp->thisv); /* JSVAL_COMPUTED_THIS invariant */
|
||||
JSObject* obj = js_ComputeThis(cx, fp->argv);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
fp->thisv = OBJECT_TO_JSVAL(obj);
|
||||
fp->flags |= JSFRAME_COMPUTED_THIS;
|
||||
return obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NB: js_Invoke requires that cx is currently running JS (i.e., that cx->fp
|
||||
* is non-null), and that vp points to the callee, |this| parameter, and
|
||||
|
@ -472,4 +459,17 @@ js_MeterSlotOpcode(JSOp op, uint32 slot);
|
|||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
inline JSObject *
|
||||
JSStackFrame::getThisObject(JSContext *cx)
|
||||
{
|
||||
if (flags & JSFRAME_COMPUTED_THIS)
|
||||
return JSVAL_TO_OBJECT(thisv); /* JSVAL_COMPUTED_THIS invariant */
|
||||
JSObject* obj = js_ComputeThis(cx, argv);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
thisv = OBJECT_TO_JSVAL(obj);
|
||||
flags |= JSFRAME_COMPUTED_THIS;
|
||||
return obj;
|
||||
}
|
||||
|
||||
#endif /* jsinterp_h___ */
|
||||
|
|
|
@ -1352,7 +1352,7 @@ obj_eval(JSContext *cx, uintN argc, jsval *vp)
|
|||
* with object to maintain invariants in the engine (see bug 520164).
|
||||
*/
|
||||
if (scopeobj->getParent()) {
|
||||
JSObject *global = JS_GetGlobalForObject(cx, scopeobj);
|
||||
JSObject *global = scopeobj->getGlobal();
|
||||
withGuard.obj = js_NewWithObject(cx, scopeobj, global, 0);
|
||||
if (!withGuard.obj)
|
||||
return JS_FALSE;
|
||||
|
@ -6746,6 +6746,15 @@ js_GetWrappedObject(JSContext *cx, JSObject *obj)
|
|||
return obj;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
JSObject::getGlobal()
|
||||
{
|
||||
JSObject *obj = this;
|
||||
while (JSObject *parent = obj->getParent())
|
||||
obj = parent;
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
JSObject::isCallable()
|
||||
{
|
||||
|
|
|
@ -356,6 +356,8 @@ struct JSObject {
|
|||
JS_CALL_OBJECT_TRACER(trc, parent, "__parent__");
|
||||
}
|
||||
|
||||
JSObject *getGlobal();
|
||||
|
||||
void *getPrivate() const {
|
||||
JS_ASSERT(getClass()->flags & JSCLASS_HAS_PRIVATE);
|
||||
jsval v = fslots[JSSLOT_PRIVATE];
|
||||
|
|
|
@ -1420,7 +1420,7 @@ BEGIN_CASE(JSOP_GVARINC)
|
|||
|
||||
#define COMPUTE_THIS(cx, fp, obj) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (!(obj = js_ComputeThisForFrame(cx, fp))) \
|
||||
if (!(obj = (fp)->getThisObject(cx))) \
|
||||
goto error; \
|
||||
JS_END_MACRO
|
||||
|
||||
|
|
|
@ -1112,7 +1112,7 @@ GlobalSlotHash(JSContext* cx, unsigned slot)
|
|||
fp = fp->down;
|
||||
|
||||
HashAccum(h, uintptr_t(fp->script), ORACLE_MASK);
|
||||
HashAccum(h, uintptr_t(OBJ_SHAPE(JS_GetGlobalForObject(cx, fp->scopeChain))), ORACLE_MASK);
|
||||
HashAccum(h, uintptr_t(OBJ_SHAPE(fp->scopeChain->getGlobal())), ORACLE_MASK);
|
||||
HashAccum(h, uintptr_t(slot), ORACLE_MASK);
|
||||
return int(h);
|
||||
}
|
||||
|
@ -1812,7 +1812,7 @@ template <typename Visitor>
|
|||
static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
||||
VisitGlobalSlots(Visitor &visitor, JSContext *cx, SlotList &gslots)
|
||||
{
|
||||
VisitGlobalSlots(visitor, cx, JS_GetGlobalForObject(cx, cx->fp->scopeChain),
|
||||
VisitGlobalSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
||||
gslots.length(), gslots.data());
|
||||
}
|
||||
|
||||
|
@ -1831,7 +1831,7 @@ static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
|||
VisitSlots(Visitor& visitor, JSContext* cx, unsigned callDepth,
|
||||
unsigned ngslots, uint16* gslots)
|
||||
{
|
||||
VisitSlots(visitor, cx, JS_GetGlobalForObject(cx, cx->fp->scopeChain),
|
||||
VisitSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
||||
callDepth, ngslots, gslots);
|
||||
}
|
||||
|
||||
|
@ -1849,7 +1849,7 @@ static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
|||
VisitSlots(Visitor &visitor, JSContext *cx, unsigned callDepth,
|
||||
const SlotList& slots)
|
||||
{
|
||||
VisitSlots(visitor, cx, JS_GetGlobalForObject(cx, cx->fp->scopeChain),
|
||||
VisitSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
||||
callDepth, slots.length(), slots.data());
|
||||
}
|
||||
|
||||
|
@ -2166,7 +2166,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
|
|||
generatedSpecializedNative(),
|
||||
tempTypeMap(cx)
|
||||
{
|
||||
JS_ASSERT(globalObj == JS_GetGlobalForObject(cx, cx->fp->scopeChain));
|
||||
JS_ASSERT(globalObj == cx->fp->scopeChain->getGlobal());
|
||||
JS_ASSERT(cx->fp->regs->pc == (jsbytecode*)fragment->ip);
|
||||
|
||||
fragment->lirbuf = lirbuf;
|
||||
|
@ -5908,7 +5908,7 @@ JS_REQUIRES_STACK bool
|
|||
TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCallCount)
|
||||
{
|
||||
#ifdef JS_THREADSAFE
|
||||
if (OBJ_SCOPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain))->title.ownercx != cx) {
|
||||
if (OBJ_SCOPE(cx->fp->scopeChain->getGlobal())->title.ownercx != cx) {
|
||||
AbortRecording(cx, "Global object not owned by this context");
|
||||
return false; /* we stay away from shared global objects */
|
||||
}
|
||||
|
@ -5931,7 +5931,7 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall
|
|||
* Make sure the shape of the global object still matches (this might flush
|
||||
* the JIT cache).
|
||||
*/
|
||||
JSObject* globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain);
|
||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
||||
uint32 globalShape = -1;
|
||||
SlotList* globalSlots = NULL;
|
||||
if (!CheckGlobalObjectShape(cx, tm, globalObj, &globalShape, &globalSlots)) {
|
||||
|
@ -6399,7 +6399,7 @@ ExecuteTrace(JSContext* cx, Fragment* f, InterpState& state)
|
|||
static JS_REQUIRES_STACK JS_ALWAYS_INLINE bool
|
||||
ScopeChainCheck(JSContext* cx, TreeFragment* f)
|
||||
{
|
||||
JS_ASSERT(f->globalObj == JS_GetGlobalForObject(cx, cx->fp->scopeChain));
|
||||
JS_ASSERT(f->globalObj == cx->fp->scopeChain->getGlobal());
|
||||
|
||||
/*
|
||||
* The JIT records and expects to execute with two scope-chain
|
||||
|
@ -6896,7 +6896,7 @@ MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount, RecordReason reason)
|
|||
* Make sure the shape of the global object still matches (this might flush
|
||||
* the JIT cache).
|
||||
*/
|
||||
JSObject* globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain);
|
||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
||||
uint32 globalShape = -1;
|
||||
SlotList* globalSlots = NULL;
|
||||
|
||||
|
@ -9423,7 +9423,7 @@ JS_REQUIRES_STACK RecordingStatus
|
|||
TraceRecorder::getThis(LIns*& this_ins)
|
||||
{
|
||||
/*
|
||||
* js_ComputeThisForFrame updates cx->fp->argv[-1], so sample it into 'original' first.
|
||||
* JSStackFrame::getThisObject updates cx->fp->argv[-1], so sample it into 'original' first.
|
||||
*/
|
||||
jsval original = JSVAL_NULL;
|
||||
if (cx->fp->argv) {
|
||||
|
@ -9435,9 +9435,9 @@ TraceRecorder::getThis(LIns*& this_ins)
|
|||
}
|
||||
}
|
||||
|
||||
JSObject* thisObj = js_ComputeThisForFrame(cx, cx->fp);
|
||||
JSObject* thisObj = cx->fp->getThisObject(cx);
|
||||
if (!thisObj)
|
||||
RETURN_ERROR("js_ComputeThisForFrame failed");
|
||||
RETURN_ERROR("fp->getThisObject failed");
|
||||
|
||||
/* In global code, bake in the global object as 'this' object. */
|
||||
if (!cx->fp->callee()) {
|
||||
|
@ -9459,7 +9459,7 @@ TraceRecorder::getThis(LIns*& this_ins)
|
|||
* a null value in argv[-1], this trace will only match if we see null at
|
||||
* runtime as well. Bake in the global object as 'this' object, updating
|
||||
* the tracker as well. We can only detect this condition prior to calling
|
||||
* js_ComputeThisForFrame, since it updates the interpreter's copy of
|
||||
* JSStackFrame::getThisObject, since it updates the interpreter's copy of
|
||||
* argv[-1].
|
||||
*/
|
||||
JSClass* clasp = NULL;;
|
||||
|
@ -9811,7 +9811,7 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||
* Make sure the shape of the global object still matches (this might
|
||||
* flush the JIT cache).
|
||||
*/
|
||||
JSObject* globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain);
|
||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
||||
uint32 globalShape = -1;
|
||||
SlotList* globalSlots = NULL;
|
||||
if (!CheckGlobalObjectShape(cx, traceMonitor, globalObj, &globalShape, &globalSlots))
|
||||
|
@ -12425,7 +12425,7 @@ TraceRecorder::interpretedFunctionCall(jsval& fval, JSFunction* fun, uintN argc,
|
|||
return RECORD_CONTINUE;
|
||||
}
|
||||
|
||||
if (JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(fval)) != globalObj)
|
||||
if (JSVAL_TO_OBJECT(fval)->getGlobal() != globalObj)
|
||||
RETURN_STOP("JSOP_CALL or JSOP_NEW crosses global scopes");
|
||||
|
||||
JSStackFrame* fp = cx->fp;
|
||||
|
|
Загрузка…
Ссылка в новой задаче