Move cx->fp to cx->regs->fp, bug 588978. r=lw

--HG--
extra : rebase_source : 14a90a53ceeb1f65d0ab70eafb5371095535e66f
This commit is contained in:
Brian Hackett 2010-08-22 16:00:20 -07:00
parent 7357103c6c
commit 5e3903b1fc
20 changed files with 432 additions and 415 deletions

View File

@ -359,7 +359,7 @@ MozAxAutoPushJSContext::MozAxAutoPushJSContext(JSContext *cx,
// See if there are any scripts on the stack.
// If not, we need to add a dummy frame with a principal.
PRBool hasScript = PR_FALSE;
JSStackFrame* tempFP = cx->fp;
JSStackFrame* tempFP = cx->fp();
while (tempFP)
{
if (tempFP->script)

View File

@ -1822,8 +1822,8 @@ JS_GetGlobalForScopeChain(JSContext *cx)
*/
VOUCH_DOES_NOT_REQUIRE_STACK();
if (cx->fp)
return cx->fp->getScopeChain()->getGlobal();
if (cx->hasfp())
return cx->fp()->getScopeChain()->getGlobal();
JSObject *scope = cx->globalObject;
if (!scope) {
@ -4090,8 +4090,8 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
CHECK_REQUEST(cx);
assertSameCompartment(cx, parent); // XXX no funobj for now
if (!parent) {
if (cx->fp)
parent = js_GetScopeChain(cx, cx->fp);
if (cx->hasfp())
parent = js_GetScopeChain(cx, cx->fp());
if (!parent)
parent = cx->globalObject;
JS_ASSERT(parent);
@ -4298,7 +4298,7 @@ js_generic_native_method_dispatcher(JSContext *cx, JSObject *obj,
if (!ComputeThisFromArgv(cx, argv))
return JS_FALSE;
js_GetTopStackFrame(cx)->setThisValue(argv[-1]);
JS_ASSERT(cx->fp->argv == argv);
JS_ASSERT(cx->fp()->argv == argv);
/* Clear the last parameter in case too few arguments were passed. */
argv[--argc].setUndefined();
@ -4942,9 +4942,9 @@ JS_IsRunning(JSContext *cx)
VOUCH_DOES_NOT_REQUIRE_STACK();
#ifdef JS_TRACER
JS_ASSERT_IF(JS_TRACE_MONITOR(cx).tracecx == cx, cx->fp);
JS_ASSERT_IF(JS_TRACE_MONITOR(cx).tracecx == cx, cx->hasfp());
#endif
JSStackFrame *fp = cx->fp;
JSStackFrame *fp = cx->maybefp();
while (fp && fp->isDummyFrame())
fp = fp->down;
return fp != NULL;
@ -4972,7 +4972,7 @@ JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp)
{
CHECK_REQUEST(cx);
JS_ASSERT_NOT_ON_TRACE(cx);
JS_ASSERT(!cx->fp);
JS_ASSERT(!cx->hasfp());
if (!fp)
return;
cx->restoreSegment();

View File

@ -335,8 +335,8 @@ JS_DEFINE_CALLINFO_4(extern, OBJECT, js_NewNullClosure, CONTEXT, OBJECT, OBJECT,
JS_REQUIRES_STACK JSBool FASTCALL
js_PopInterpFrame(JSContext* cx, TracerState* state)
{
JS_ASSERT(cx->fp && cx->fp->down);
JSStackFrame* const fp = cx->fp;
JS_ASSERT(cx->hasfp() && cx->fp()->down);
JSStackFrame* const fp = cx->fp();
/*
* Mirror frame popping code from inline_return in js_Interpret. There are

View File

@ -110,10 +110,12 @@ StackSegment::contains(const JSStackFrame *fp) const
JSStackFrame *start;
JSStackFrame *stop;
if (isActive()) {
start = cx->fp;
JS_ASSERT(cx->hasfp());
start = cx->fp();
stop = cx->activeSegment()->initialFrame->down;
} else {
start = suspendedFrame;
JS_ASSERT(suspendedRegs && suspendedRegs->fp);
start = suspendedRegs->fp;
stop = initialFrame->down;
}
for (JSStackFrame *f = start; f != stop; f = f->down) {
@ -313,7 +315,9 @@ StackSpace::pushExecuteFrame(JSContext *cx, ExecuteFrameGuard &fg,
StackSegment *seg = fg.seg;
seg->setPreviousInMemory(currentSegment);
currentSegment = seg;
cx->pushSegmentAndFrame(seg, fg.fp, regs);
regs.fp = fg.fp;
cx->pushSegmentAndFrame(seg, regs);
seg->setInitialVarObj(initialVarObj);
fg.cx = cx;
}
@ -333,7 +337,7 @@ ExecuteFrameGuard::~ExecuteFrameGuard()
if (!pushed())
return;
JS_ASSERT(cx->activeSegment() == seg);
JS_ASSERT(cx->fp == fp);
JS_ASSERT(cx->maybefp() == fp);
cx->stack().popExecuteFrame(cx);
}
@ -347,14 +351,13 @@ StackSpace::getSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *&seg, JSS
}
JS_REQUIRES_STACK void
StackSpace::pushSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *seg, JSStackFrame *fp,
JSFrameRegs &regs)
StackSpace::pushSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *seg, JSFrameRegs &regs)
{
JS_ASSERT(!fp->hasScript() && FUN_SLOW_NATIVE(fp->getFunction()));
fp->down = cx->fp;
JS_ASSERT(!regs.fp->hasScript() && FUN_SLOW_NATIVE(regs.fp->getFunction()));
regs.fp->down = cx->maybefp();
seg->setPreviousInMemory(currentSegment);
currentSegment = seg;
cx->pushSegmentAndFrame(seg, fp, regs);
cx->pushSegmentAndFrame(seg, regs);
seg->setInitialVarObj(NULL);
}
@ -363,8 +366,8 @@ StackSpace::popSynthesizedSlowNativeFrame(JSContext *cx)
{
JS_ASSERT(isCurrentAndActive(cx));
JS_ASSERT(cx->hasActiveSegment());
JS_ASSERT(currentSegment->getInitialFrame() == cx->fp);
JS_ASSERT(!cx->fp->hasScript() && FUN_SLOW_NATIVE(cx->fp->getFunction()));
JS_ASSERT(currentSegment->getInitialFrame() == cx->fp());
JS_ASSERT(!cx->fp()->hasScript() && FUN_SLOW_NATIVE(cx->fp()->getFunction()));
cx->popSegmentAndFrame();
currentSegment = currentSegment->getPreviousInMemory();
}
@ -1934,7 +1937,7 @@ js_GetCurrentBytecodePC(JSContext* cx)
pc = cx->regs ? cx->regs->pc : NULL;
if (!pc)
return NULL;
imacpc = cx->fp->maybeIMacroPC();
imacpc = cx->fp()->maybeIMacroPC();
}
/*
@ -1952,7 +1955,7 @@ js_CurrentPCIsInImacro(JSContext *cx)
VOUCH_DOES_NOT_REQUIRE_STACK();
if (JS_ON_TRACE(cx))
return cx->bailExit->imacpc != NULL;
return cx->fp->hasIMacroPC();
return cx->fp()->hasIMacroPC();
#else
return false;
#endif
@ -1997,54 +2000,48 @@ DSTOffsetCache::DSTOffsetCache()
JSContext::JSContext(JSRuntime *rt)
: runtime(rt),
compartment(rt->defaultCompartment),
fp(NULL),
regs(NULL),
regExpStatics(this),
busyArrays(this)
{}
void
JSContext::pushSegmentAndFrame(js::StackSegment *newseg, JSStackFrame *newfp,
JSFrameRegs &newregs)
JSContext::pushSegmentAndFrame(js::StackSegment *newseg, JSFrameRegs &newregs)
{
if (hasActiveSegment()) {
JS_ASSERT(fp->savedPC == JSStackFrame::sInvalidPC);
fp->savedPC = regs->pc;
currentSegment->suspend(fp, regs);
JS_ASSERT(regs->fp->savedPC == JSStackFrame::sInvalidPC);
regs->fp->savedPC = regs->pc;
currentSegment->suspend(regs);
}
newseg->setPreviousInContext(currentSegment);
currentSegment = newseg;
#ifdef DEBUG
newfp->savedPC = JSStackFrame::sInvalidPC;
newregs.fp->savedPC = JSStackFrame::sInvalidPC;
#endif
setCurrentFrame(newfp);
setCurrentRegs(&newregs);
newseg->joinContext(this, newfp);
newseg->joinContext(this, newregs.fp);
}
void
JSContext::popSegmentAndFrame()
{
JS_ASSERT(currentSegment->maybeContext() == this);
JS_ASSERT(currentSegment->getInitialFrame() == fp);
JS_ASSERT(fp->savedPC == JSStackFrame::sInvalidPC);
JS_ASSERT(currentSegment->getInitialFrame() == regs->fp);
JS_ASSERT(regs->fp->savedPC == JSStackFrame::sInvalidPC);
currentSegment->leaveContext();
currentSegment = currentSegment->getPreviousInContext();
if (currentSegment) {
if (currentSegment->isSaved()) {
setCurrentFrame(NULL);
setCurrentRegs(NULL);
} else {
setCurrentFrame(currentSegment->getSuspendedFrame());
setCurrentRegs(currentSegment->getSuspendedRegs());
currentSegment->resume();
#ifdef DEBUG
fp->savedPC = JSStackFrame::sInvalidPC;
regs->fp->savedPC = JSStackFrame::sInvalidPC;
#endif
}
} else {
JS_ASSERT(fp->down == NULL);
setCurrentFrame(NULL);
JS_ASSERT(regs->fp->down == NULL);
setCurrentRegs(NULL);
}
}
@ -2053,10 +2050,9 @@ void
JSContext::saveActiveSegment()
{
JS_ASSERT(hasActiveSegment());
currentSegment->save(fp, regs);
JS_ASSERT(fp->savedPC == JSStackFrame::sInvalidPC);
fp->savedPC = regs->pc;
setCurrentFrame(NULL);
currentSegment->save(regs);
JS_ASSERT(regs->fp->savedPC == JSStackFrame::sInvalidPC);
regs->fp->savedPC = regs->pc;
setCurrentRegs(NULL);
}
@ -2064,11 +2060,10 @@ void
JSContext::restoreSegment()
{
js::StackSegment *ccs = currentSegment;
setCurrentFrame(ccs->getSuspendedFrame());
setCurrentRegs(ccs->getSuspendedRegs());
ccs->restore();
#ifdef DEBUG
fp->savedPC = JSStackFrame::sInvalidPC;
regs->fp->savedPC = JSStackFrame::sInvalidPC;
#endif
}
@ -2099,10 +2094,11 @@ JSContext::containingSegment(const JSStackFrame *target)
if (!seg)
return NULL;
/* The active segments's top frame is cx->fp. */
if (fp) {
/* The active segments's top frame is cx->regs->fp. */
if (regs) {
JS_ASSERT(regs->fp);
JS_ASSERT(activeSegment() == seg);
JSStackFrame *f = fp;
JSStackFrame *f = regs->fp;
JSStackFrame *stop = seg->getInitialFrame()->down;
for (; f != stop; f = f->down) {
if (f == target)

View File

@ -301,16 +301,16 @@ struct GlobalState {
* The frames of a non-empty segment must all be in the same context and thus
* each non-empty segment is referred to as being "in" a context. Segments in a
* context have an additional state of being either "active" or "suspended". A
* suspended segment |ss| has a "suspended frame" which is snapshot of |cx->fp|
* suspended segment |ss| has a "suspended frame" which is snapshot of |cx->regs|
* when the segment was suspended and serves as the current frame of |ss|.
* There is at most one active segment in a given context. Segments in a
* context execute LIFO and are maintained in a stack. The top of this stack
* is the context's "current segment". If a context |cx| has an active segment
* |ss|, then:
* 1. |ss| is |cx|'s current segment,
* 2. |cx->fp != NULL|, and
* 3. |ss|'s current frame is |cx->fp|.
* Moreover, |cx->fp != NULL| iff |cx| has an active segment.
* 2. |cx->regs != NULL|, and
* 3. |ss|'s current frame is |cx->regs->fp|.
* Moreover, |cx->regs != NULL| iff |cx| has an active segment.
*
* An empty segment is not associated with any context. Empty segments are
* created when there is not an active segment for a context at the top of the
@ -341,9 +341,6 @@ class StackSegment
/* The first frame executed in this segment. null iff cx is null */
JSStackFrame *initialFrame;
/* If this segment is suspended, the top of the segment. */
JSStackFrame *suspendedFrame;
/* If this segment is suspended, |cx->regs| when it was suspended. */
JSFrameRegs *suspendedRegs;
@ -353,17 +350,22 @@ class StackSegment
/* Whether this segment was suspended by JS_SaveFrameChain. */
bool saved;
/* Align at 8 bytes on all platforms. */
#if JS_BITS_PER_WORD == 32
void *padding;
#endif
/*
* To make isActive a single null-ness check, this non-null constant is
* assigned to suspendedFrame when !inContext.
* assigned to suspendedRegs when !inContext.
*/
#define NON_NULL_SUSPENDED_FRAME ((JSStackFrame *)0x1)
#define NON_NULL_SUSPENDED_REGS ((JSFrameRegs *)0x1)
public:
StackSegment()
: cx(NULL), previousInContext(NULL), previousInMemory(NULL),
initialFrame(NULL), suspendedFrame(NON_NULL_SUSPENDED_FRAME),
suspendedRegs(NULL), initialVarObj(NULL), saved(false)
initialFrame(NULL), suspendedRegs(NON_NULL_SUSPENDED_REGS),
initialVarObj(NULL), saved(false)
{
JS_ASSERT(!inContext());
}
@ -391,20 +393,20 @@ class StackSegment
bool inContext() const {
JS_ASSERT(!!cx == !!initialFrame);
JS_ASSERT_IF(!cx, suspendedFrame == NON_NULL_SUSPENDED_FRAME && !saved);
JS_ASSERT_IF(!cx, suspendedRegs == NON_NULL_SUSPENDED_REGS && !saved);
return cx;
}
bool isActive() const {
JS_ASSERT_IF(!suspendedFrame, cx && !saved);
JS_ASSERT_IF(!cx, suspendedFrame == NON_NULL_SUSPENDED_FRAME);
return !suspendedFrame;
JS_ASSERT_IF(!suspendedRegs, cx && !saved);
JS_ASSERT_IF(!cx, suspendedRegs == NON_NULL_SUSPENDED_REGS);
return !suspendedRegs;
}
bool isSuspended() const {
JS_ASSERT_IF(!cx || !suspendedFrame, !saved);
JS_ASSERT_IF(!cx, suspendedFrame == NON_NULL_SUSPENDED_FRAME);
return cx && suspendedFrame;
JS_ASSERT_IF(!cx || !suspendedRegs, !saved);
JS_ASSERT_IF(!cx, suspendedRegs == NON_NULL_SUSPENDED_REGS);
return cx && suspendedRegs;
}
/* Substate of suspended, queryable in any state. */
@ -420,7 +422,7 @@ class StackSegment
JS_ASSERT(!inContext());
this->cx = cx;
initialFrame = f;
suspendedFrame = NULL;
suspendedRegs = NULL;
JS_ASSERT(isActive());
}
@ -428,7 +430,7 @@ class StackSegment
JS_ASSERT(isActive());
this->cx = NULL;
initialFrame = NULL;
suspendedFrame = NON_NULL_SUSPENDED_FRAME;
suspendedRegs = NON_NULL_SUSPENDED_REGS;
JS_ASSERT(!inContext());
}
@ -436,29 +438,28 @@ class StackSegment
return cx;
}
#undef NON_NULL_SUSPENDED_FRAME
#undef NON_NULL_SUSPENDED_REGS
/* Transitioning between isActive <--> isSuspended */
void suspend(JSStackFrame *fp, JSFrameRegs *regs) {
void suspend(JSFrameRegs *regs) {
JS_ASSERT(isActive());
JS_ASSERT(fp && contains(fp));
suspendedFrame = fp;
JS_ASSERT(isSuspended());
JS_ASSERT(regs && regs->fp && contains(regs->fp));
suspendedRegs = regs;
JS_ASSERT(isSuspended());
}
void resume() {
JS_ASSERT(isSuspended());
suspendedFrame = NULL;
suspendedRegs = NULL;
JS_ASSERT(isActive());
}
/* When isSuspended, transitioning isSaved <--> !isSaved */
void save(JSStackFrame *fp, JSFrameRegs *regs) {
void save(JSFrameRegs *regs) {
JS_ASSERT(!isSuspended());
suspend(fp, regs);
suspend(regs);
saved = true;
JS_ASSERT(isSaved());
}
@ -477,21 +478,20 @@ class StackSegment
return initialFrame;
}
inline JSStackFrame *getCurrentFrame() const;
inline JSFrameRegs *getCurrentRegs() const;
inline JSStackFrame *getCurrentFrame() const;
/* Data available when isSuspended. */
JSStackFrame *getSuspendedFrame() const {
JS_ASSERT(isSuspended());
return suspendedFrame;
}
JSFrameRegs *getSuspendedRegs() const {
JS_ASSERT(isSuspended());
return suspendedRegs;
}
JSStackFrame *getSuspendedFrame() const {
return suspendedRegs->fp;
}
/* JSContext / js::StackSpace bookkeeping. */
void setPreviousInContext(StackSegment *seg) {
@ -560,14 +560,12 @@ class InvokeFrameGuard
{
friend class StackSpace;
JSContext *cx; /* null implies nothing pushed */
JSStackFrame *fp;
JSFrameRegs regs;
JSFrameRegs *prevRegs;
public:
InvokeFrameGuard() : cx(NULL), fp(NULL) {}
InvokeFrameGuard() : cx(NULL) {}
JS_REQUIRES_STACK ~InvokeFrameGuard();
bool pushed() const { return cx != NULL; }
JSStackFrame *getFrame() { return fp; }
JSFrameRegs &getRegs() { return regs; }
};
@ -817,8 +815,7 @@ class StackSpace
void getSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *&seg, JSStackFrame *&fp);
JS_REQUIRES_STACK
void pushSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *seg, JSStackFrame *fp,
JSFrameRegs &regs);
void pushSynthesizedSlowNativeFrame(JSContext *cx, StackSegment *seg, JSFrameRegs &regs);
JS_REQUIRES_STACK
void popSynthesizedSlowNativeFrame(JSContext *cx);
@ -1976,26 +1973,32 @@ struct JSContext
/* GC heap compartment. */
JSCompartment *compartment;
/* Currently executing frame, set by stack operations. */
JS_REQUIRES_STACK
JSStackFrame *fp;
/*
* Currently executing frame's regs, set by stack operations.
* |fp != NULL| iff |regs != NULL| (although regs->pc can be NULL)
*/
/* Currently executing frame and regs, set by stack operations. */
JS_REQUIRES_STACK
JSFrameRegs *regs;
/* Current frame accessors. */
JSStackFrame* fp() {
JS_ASSERT(regs && regs->fp);
return regs->fp;
}
JSStackFrame* maybefp() {
JS_ASSERT_IF(regs, regs->fp);
return regs ? regs->fp : NULL;
}
bool hasfp() {
JS_ASSERT_IF(regs, regs->fp);
return !!regs;
}
public:
friend class js::StackSpace;
friend bool js::Interpret(JSContext *, JSStackFrame *, uintN);
/* 'fp' and 'regs' must only be changed by calling these functions. */
void setCurrentFrame(JSStackFrame *fp) {
this->fp = fp;
}
/* 'regs' must only be changed by calling this function. */
void setCurrentRegs(JSFrameRegs *regs) {
this->regs = regs;
}
@ -2046,7 +2049,7 @@ struct JSContext
public:
void assertSegmentsInSync() const {
#ifdef DEBUG
if (fp) {
if (regs) {
JS_ASSERT(currentSegment->isActive());
if (js::StackSegment *prev = currentSegment->getPreviousInContext())
JS_ASSERT(!prev->isActive());
@ -2059,7 +2062,7 @@ struct JSContext
/* Return whether this context has an active segment. */
bool hasActiveSegment() const {
assertSegmentsInSync();
return !!fp;
return !!regs;
}
/* Assuming there is an active segment, return it. */
@ -2075,8 +2078,7 @@ struct JSContext
}
/* Add the given segment to the list as the new active segment. */
void pushSegmentAndFrame(js::StackSegment *newseg, JSStackFrame *newfp,
JSFrameRegs &regs);
void pushSegmentAndFrame(js::StackSegment *newseg, JSFrameRegs &regs);
/* Remove the active segment and make the next segment active. */
void popSegmentAndFrame();
@ -2097,7 +2099,7 @@ struct JSContext
* Search the call stack for the nearest frame with static level targetLevel.
*/
JSStackFrame *findFrameAtLevel(uintN targetLevel) {
JSStackFrame *fp = this->fp;
JSStackFrame *fp = this->regs->fp;
while (true) {
JS_ASSERT(fp && fp->hasScript());
if (fp->getScript()->staticLevel == targetLevel)
@ -2356,8 +2358,8 @@ struct JSContext
#ifdef DEBUG
void assertValidStackDepth(uintN depth) {
JS_ASSERT(0 <= regs->sp - fp->base());
JS_ASSERT(depth <= uintptr_t(regs->sp - fp->base()));
JS_ASSERT(0 <= regs->sp - regs->fp->base());
JS_ASSERT(depth <= uintptr_t(regs->sp - regs->fp->base()));
}
#else
void assertValidStackDepth(uintN /*depth*/) {}
@ -2397,8 +2399,8 @@ JSStackFrame::varobj(JSContext *cx) const
JS_ALWAYS_INLINE jsbytecode *
JSStackFrame::pc(JSContext *cx) const
{
JS_ASSERT(cx->containingSegment(this) != NULL);
return (cx->fp == this) ? cx->regs->pc : savedPC;
JS_ASSERT(cx->regs && cx->containingSegment(this) != NULL);
return (cx->regs->fp == this) ? cx->regs->pc : savedPC;
}
#ifdef JS_THREADSAFE
@ -3279,8 +3281,8 @@ SetPendingException(JSContext *cx, const Value &v);
} /* namespace js */
/*
* Get the current cx->fp, first lazily instantiating stack frames if needed.
* (Do not access cx->fp directly except in JS_REQUIRES_STACK code.)
* Get the current frame, first lazily instantiating stack frames if needed.
* (Do not access cx->fp() directly except in JS_REQUIRES_STACK code.)
*
* Defined in jstracer.cpp if JS_TRACER is defined.
*/
@ -3288,7 +3290,7 @@ static JS_FORCES_STACK JS_INLINE JSStackFrame *
js_GetTopStackFrame(JSContext *cx)
{
js::LeaveTrace(cx);
return cx->fp;
return cx->maybefp();
}
static JS_INLINE JSBool

View File

@ -57,13 +57,6 @@ JSContext::ensureGeneratorStackSpace()
namespace js {
JS_REQUIRES_STACK JS_ALWAYS_INLINE JSStackFrame *
StackSegment::getCurrentFrame() const
{
JS_ASSERT(inContext());
return isActive() ? cx->fp : getSuspendedFrame();
}
JS_REQUIRES_STACK JS_ALWAYS_INLINE JSFrameRegs *
StackSegment::getCurrentRegs() const
{
@ -71,6 +64,12 @@ StackSegment::getCurrentRegs() const
return isActive() ? cx->regs : getSuspendedRegs();
}
JS_REQUIRES_STACK JS_ALWAYS_INLINE JSStackFrame *
StackSegment::getCurrentFrame() const
{
return getCurrentRegs()->fp;
}
JS_REQUIRES_STACK inline Value *
StackSpace::firstUnused() const
{
@ -83,7 +82,8 @@ StackSpace::firstUnused() const
Value *sp = seg->getCurrentRegs()->sp;
if (invokeArgEnd > sp) {
JS_ASSERT(invokeSegment == currentSegment);
JS_ASSERT_IF(seg->maybeContext()->fp, invokeFrame == seg->maybeContext()->fp);
JS_ASSERT_IF(seg->maybeContext()->hasfp(),
invokeFrame == seg->maybeContext()->fp());
return invokeArgEnd;
}
return sp;
@ -219,7 +219,7 @@ StackSpace::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard &ag)
ag.prevInvokeSegment = invokeSegment;
invokeSegment = currentSegment;
ag.prevInvokeFrame = invokeFrame;
invokeFrame = cx->fp;
invokeFrame = cx->maybefp();
#endif
ag.cx = cx;
@ -238,7 +238,7 @@ StackSpace::popInvokeArgs(const InvokeArgsGuard &ag)
JS_ASSERT(isCurrentAndActive(ag.cx));
JS_ASSERT(invokeSegment == currentSegment);
JS_ASSERT(invokeFrame == ag.cx->fp);
JS_ASSERT(invokeFrame == ag.cx->maybefp());
JS_ASSERT(invokeArgEnd == ag.argv() + ag.argc());
#ifdef DEBUG
@ -267,7 +267,7 @@ StackSpace::getInvokeFrame(JSContext *cx, const CallArgs &args,
ptrdiff_t nvals = nmissing + VALUES_PER_STACK_FRAME + nfixed;
if (!ensureSpace(cx, start, nvals))
return false;
fg.fp = reinterpret_cast<JSStackFrame *>(start + nmissing);
fg.regs.fp = reinterpret_cast<JSStackFrame *>(start + nmissing);
return true;
}
@ -277,18 +277,17 @@ StackSpace::pushInvokeFrame(JSContext *cx, const CallArgs &args,
{
JS_ASSERT(firstUnused() == args.argv() + args.argc());
JSStackFrame *fp = fg.fp;
JSStackFrame *down = cx->fp;
JSStackFrame *fp = fg.regs.fp;
JSStackFrame *down = cx->maybefp();
fp->down = down;
if (JS_UNLIKELY(!currentSegment->inContext())) {
cx->pushSegmentAndFrame(currentSegment, fp, fg.regs);
cx->pushSegmentAndFrame(currentSegment, fg.regs);
} else {
#ifdef DEBUG
fp->savedPC = JSStackFrame::sInvalidPC;
JS_ASSERT(down->savedPC == JSStackFrame::sInvalidPC);
#endif
down->savedPC = cx->regs->pc;
cx->setCurrentFrame(fp);
fg.prevRegs = cx->regs;
cx->setCurrentRegs(&fg.regs);
}
@ -301,18 +300,17 @@ JS_REQUIRES_STACK JS_ALWAYS_INLINE void
StackSpace::popInvokeFrame(const InvokeFrameGuard &fg)
{
JSContext *cx = fg.cx;
JSStackFrame *fp = fg.fp;
JSStackFrame *fp = fg.regs.fp;
JS_ASSERT(isCurrentAndActive(cx));
if (JS_UNLIKELY(currentSegment->getInitialFrame() == fp)) {
cx->popSegmentAndFrame();
} else {
JS_ASSERT(fp == cx->fp);
JS_ASSERT(&fg.regs == cx->regs);
cx->setCurrentFrame(fp->down);
JS_ASSERT(fp->down == fg.prevRegs->fp);
cx->setCurrentRegs(fg.prevRegs);
#ifdef DEBUG
cx->fp->savedPC = JSStackFrame::sInvalidPC;
cx->fp()->savedPC = JSStackFrame::sInvalidPC;
#endif
}
}
@ -353,14 +351,13 @@ StackSpace::pushInlineFrame(JSContext *cx, JSStackFrame *fp, jsbytecode *pc,
JSStackFrame *newfp)
{
JS_ASSERT(isCurrentAndActive(cx));
JS_ASSERT(cx->fp == fp && cx->regs->pc == pc);
JS_ASSERT(cx->regs->fp == fp && cx->regs->pc == pc);
fp->savedPC = pc;
newfp->down = fp;
#ifdef DEBUG
newfp->savedPC = JSStackFrame::sInvalidPC;
#endif
cx->setCurrentFrame(newfp);
}
JS_REQUIRES_STACK JS_ALWAYS_INLINE void
@ -368,16 +365,16 @@ StackSpace::popInlineFrame(JSContext *cx, JSStackFrame *up, JSStackFrame *down)
{
JS_ASSERT(isCurrentAndActive(cx));
JS_ASSERT(cx->hasActiveSegment());
JS_ASSERT(cx->fp == up && up->down == down);
JS_ASSERT(cx->regs->fp == up && up->down == down);
JS_ASSERT(up->savedPC == JSStackFrame::sInvalidPC);
JS_ASSERT(!up->hasIMacroPC());
JSFrameRegs *regs = cx->regs;
regs->fp = down;
regs->pc = down->savedPC;
#ifdef DEBUG
down->savedPC = JSStackFrame::sInvalidPC;
#endif
cx->setCurrentFrame(down);
}
JS_REQUIRES_STACK inline
@ -388,8 +385,8 @@ FrameRegsIter::FrameRegsIter(JSContext *cx)
initSlow();
return;
}
JS_ASSERT(cx->fp);
curfp = cx->fp;
JS_ASSERT(cx->regs->fp);
curfp = cx->regs->fp;
cursp = cx->regs->sp;
curpc = cx->regs->pc;
return;
@ -467,7 +464,7 @@ class CompartmentChecker
public:
explicit CompartmentChecker(JSContext *cx) : context(cx), compartment(cx->compartment) {
check(cx->fp ? JS_GetGlobalForScopeChain(cx) : cx->globalObject);
check(cx->hasfp() ? JS_GetGlobalForScopeChain(cx) : cx->globalObject);
VOUCH_DOES_NOT_REQUIRE_STACK();
}

View File

@ -2830,7 +2830,7 @@ js_NewFlatClosure(JSContext *cx, JSFunction *fun)
* Flat closures can be partial, they may need to search enclosing scope
* objects via JSOP_NAME, etc.
*/
JSObject *scopeChain = js_GetScopeChain(cx, cx->fp);
JSObject *scopeChain = js_GetScopeChain(cx, cx->fp());
if (!scopeChain)
return NULL;
@ -2851,11 +2851,11 @@ js_NewFlatClosure(JSContext *cx, JSFunction *fun)
JSObject *
js_NewDebuggableFlatClosure(JSContext *cx, JSFunction *fun)
{
JS_ASSERT(cx->fp->getFunction()->flags & JSFUN_HEAVYWEIGHT);
JS_ASSERT(!cx->fp->getFunction()->optimizedClosure());
JS_ASSERT(cx->fp()->getFunction()->flags & JSFUN_HEAVYWEIGHT);
JS_ASSERT(!cx->fp()->getFunction()->optimizedClosure());
JS_ASSERT(FUN_FLAT_CLOSURE(fun));
return WrapEscapingClosure(cx, cx->fp, fun);
return WrapEscapingClosure(cx, cx->fp(), fun);
}
JSFunction *

View File

@ -527,7 +527,7 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
InvokeFrameGuard frame;
if (!cx->stack().getInvokeFrame(cx, args, nmissing, nfixed, frame))
return false;
JSStackFrame *fp = frame.getFrame();
JSStackFrame *fp = frame.getRegs().fp;
/* Initialize missing missing arguments and new local variables. */
Value *missing = args.argv() + args.argc();
@ -627,7 +627,7 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
ok = callJSNative(cx, native, thisp, fp->numActualArgs(), fp->argv,
fp->addressReturnValue());
JS_ASSERT(cx->fp == fp);
JS_ASSERT(cx->fp() == fp);
JS_RUNTIME_METER(cx->runtime, nativeCalls);
#ifdef DEBUG_NOT_THROWING
if (ok && !alreadyThrowing)
@ -667,7 +667,7 @@ DoConstruct(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval)
static JSBool
DoSlowCall(JSContext *cx, uintN argc, Value *vp)
{
JSStackFrame *fp = cx->fp;
JSStackFrame *fp = cx->fp();
JSObject *obj = fp->getThisObject(cx);
if (!obj)
return false;
@ -887,12 +887,12 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
/*
* We want to call |down->varobj()|, but this requires knowing the
* CallStackSegment of |down|. If |down == cx->fp|, the callstack is
* CallStackSegment of |down|. If |down == cx->fp()|, the callstack is
* simply the context's active callstack, so we can use
* |down->varobj(cx)|. When |down != cx->fp|, we need to do a slow
* |down->varobj(cx)|. When |down != cx->fp()|, we need to do a slow
* linear search. Luckily, this only happens with EvaluateInFrame.
*/
initialVarObj = (down == cx->fp)
initialVarObj = (down == cx->maybefp())
? down->varobj(cx)
: down->varobj(cx->containingSegment(down));
} else {
@ -1278,7 +1278,7 @@ ValueToId(JSContext *cx, const Value &v, jsid *idp)
JS_STATIC_INTERPRET JS_REQUIRES_STACK JSBool
js_EnterWith(JSContext *cx, jsint stackIndex)
{
JSStackFrame *fp = cx->fp;
JSStackFrame *fp = cx->fp();
Value *sp = cx->regs->sp;
JS_ASSERT(stackIndex < 0);
JS_ASSERT(fp->base() <= sp + stackIndex);
@ -1315,11 +1315,11 @@ js_LeaveWith(JSContext *cx)
{
JSObject *withobj;
withobj = cx->fp->getScopeChain();
withobj = cx->fp()->getScopeChain();
JS_ASSERT(withobj->getClass() == &js_WithClass);
JS_ASSERT(withobj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
JS_ASSERT(withobj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()));
JS_ASSERT(OBJ_BLOCK_DEPTH(cx, withobj) >= 0);
cx->fp->setScopeChain(withobj->getParent());
cx->fp()->setScopeChain(withobj->getParent());
withobj->setPrivate(NULL);
}
@ -1330,7 +1330,7 @@ js_IsActiveWithOrBlock(JSContext *cx, JSObject *obj, int stackDepth)
clasp = obj->getClass();
if ((clasp == &js_WithClass || clasp == &js_BlockClass) &&
obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp) &&
obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()) &&
OBJ_BLOCK_DEPTH(cx, obj) >= stackDepth) {
return clasp;
}
@ -1348,9 +1348,9 @@ js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
Class *clasp;
JS_ASSERT(stackDepth >= 0);
JS_ASSERT(cx->fp->base() + stackDepth <= cx->regs->sp);
JS_ASSERT(cx->fp()->base() + stackDepth <= cx->regs->sp);
JSStackFrame *fp = cx->fp;
JSStackFrame *fp = cx->fp();
for (obj = fp->maybeBlockChain(); obj; obj = obj->getParent()) {
JS_ASSERT(obj->getClass() == &js_BlockClass);
if (OBJ_BLOCK_DEPTH(cx, obj) < stackDepth)
@ -1438,7 +1438,7 @@ js_TraceOpcode(JSContext *cx)
tracefp = (FILE *) cx->tracefp;
JS_ASSERT(tracefp);
fp = cx->fp;
fp = cx->fp();
regs = cx->regs;
/*
@ -2249,7 +2249,7 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount)
JSRuntime *const rt = cx->runtime;
/* Set registerized frame pointer and derived script pointer. */
JSStackFrame *fp = cx->fp;
JSStackFrame *fp = cx->fp();
JSScript *script = fp->getScript();
JS_ASSERT(!script->isEmpty());
JS_ASSERT(script->length > 1);
@ -2316,7 +2316,7 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount)
#define RESTORE_INTERP_VARS() \
JS_BEGIN_MACRO \
fp = cx->fp; \
fp = cx->fp(); \
script = fp->getScript(); \
atoms = FrameAtomBase(cx, fp); \
currentVersion = (JSVersion) script->version; \
@ -2792,7 +2792,7 @@ BEGIN_CASE(JSOP_STOP)
regs.sp[-1] = fp->getReturnValue();
/* Sync interpreter registers. */
fp = cx->fp;
fp = cx->fp();
script = fp->getScript();
atoms = FrameAtomBase(cx, fp);
@ -4752,11 +4752,12 @@ BEGIN_CASE(JSOP_APPLY)
stack.pushInlineFrame(cx, fp, regs.pc, newfp);
/* Initializer regs after pushInlineFrame snapshots pc. */
regs.fp = newfp;
regs.pc = newscript->code;
regs.sp = newsp;
/* Import into locals. */
JS_ASSERT(newfp == cx->fp);
JS_ASSERT(newfp == cx->fp());
fp = newfp;
script = newscript;
atoms = script->atomMap.vector;

View File

@ -53,6 +53,7 @@
typedef struct JSFrameRegs {
js::Value *sp; /* stack pointer */
jsbytecode *pc; /* program counter */
JSStackFrame *fp; /* active frame */
} JSFrameRegs;
/* JS stack frame flags. */

View File

@ -1140,7 +1140,7 @@ js_NewGenerator(JSContext *cx)
return NULL;
/* Load and compute stack slot counts. */
JSStackFrame *fp = cx->fp;
JSStackFrame *fp = cx->fp();
uintN argc = fp->numActualArgs();
uintN nargs = JS_MAX(argc, fp->numFormalArgs());
uintN vplen = 2 + nargs;
@ -1276,7 +1276,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
* the code before pushExecuteFrame must not reenter the interpreter.
*/
ExecuteFrameGuard frame;
if (!cx->stack().getExecuteFrame(cx, cx->fp, vplen, nfixed, frame)) {
if (!cx->stack().getExecuteFrame(cx, cx->maybefp(), vplen, nfixed, frame)) {
gen->state = JSGEN_CLOSED;
return JS_FALSE;
}

View File

@ -2693,10 +2693,10 @@ Detecting(JSContext *cx, jsbytecode *pc)
JSOp op;
JSAtom *atom;
script = cx->fp->getScript();
script = cx->fp()->getScript();
endpc = script->code + script->length;
for (;; pc += js_CodeSpec[op].length) {
JS_ASSERT_IF(!cx->fp->hasIMacroPC(), script->code <= pc && pc < endpc);
JS_ASSERT_IF(!cx->fp()->hasIMacroPC(), script->code <= pc && pc < endpc);
/* General case: a branch or equality op follows the access. */
op = js_GetOpcode(cx, script, pc);
@ -2776,7 +2776,8 @@ js_InferFlags(JSContext *cx, uintN defaultFlags)
flags |= JSRESOLVE_ASSIGNING;
} else if (cs->length >= 0) {
pc += cs->length;
if (pc < cx->fp->getScript()->code + cx->fp->getScript()->length && Detecting(cx, pc))
JSScript *script = cx->fp()->getScript();
if (pc < script->code + script->length && Detecting(cx, pc))
flags |= JSRESOLVE_DETECTING;
}
if (format & JOF_DECLARING)
@ -2893,7 +2894,7 @@ js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth)
if (!obj)
return NULL;
obj->init(&js_WithClass, proto, parent,
PrivateValue(js_FloatingFrameIfGenerator(cx, cx->fp)));
PrivateValue(js_FloatingFrameIfGenerator(cx, cx->fp())));
OBJ_SET_BLOCK_DEPTH(cx, obj, depth);
obj->map = cx->runtime->emptyWithScope->hold();
@ -2952,10 +2953,10 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
/* Blocks have one fixed slot available for the first local.*/
JS_STATIC_ASSERT(JS_INITIAL_NSLOTS == JSSLOT_BLOCK_DEPTH + 2);
JSStackFrame *const fp = cx->fp;
JSStackFrame *const fp = cx->fp();
JSObject *obj = fp->getScopeChain();
JS_ASSERT(obj->getClass() == &js_BlockClass);
JS_ASSERT(obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
JS_ASSERT(obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp()));
JS_ASSERT(OBJ_IS_CLONED_BLOCK(obj));
/*
@ -3730,12 +3731,12 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
JSScopeProperty *sprop;
/*
* Find the global object. Use cx->fp directly to avoid falling off
* Find the global object. Use cx->fp() directly to avoid falling off
* trace; all JIT-elided stack frames have the same global object as
* cx->fp.
* cx->fp().
*/
VOUCH_DOES_NOT_REQUIRE_STACK();
if (!start && (fp = cx->fp) != NULL)
if (!start && (fp = cx->maybefp()) != NULL)
start = fp->maybeScopeChain();
if (start) {
@ -4776,7 +4777,7 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN getHow,
op = (JSOp) *pc;
if (op == JSOP_TRAP) {
JS_ASSERT_NOT_ON_TRACE(cx);
op = JS_GetTrapOpcode(cx, cx->fp->getScript(), pc);
op = JS_GetTrapOpcode(cx, cx->fp()->getScript(), pc);
}
if (op == JSOP_GETXPROP) {
flags = JSREPORT_ERROR;
@ -5263,7 +5264,7 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval)
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
if (fun != funobj) {
for (JSStackFrame *fp = cx->fp; fp; fp = fp->down) {
for (JSStackFrame *fp = cx->maybefp(); fp; fp = fp->down) {
if (fp->callee() == fun &&
fp->getThisValue().isObject() &&
&fp->getThisValue().toObject() == obj) {
@ -5560,8 +5561,8 @@ js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey,
if (protoKey != JSProto_Null) {
if (!scope) {
if (cx->fp)
scope = cx->fp->maybeScopeChain();
if (cx->hasfp())
scope = cx->fp()->maybeScopeChain();
if (!scope) {
scope = cx->globalObject;
if (!scope) {
@ -6351,7 +6352,7 @@ js_DumpStackFrame(JSContext *cx, JSStackFrame *start)
VOUCH_DOES_NOT_REQUIRE_STACK();
if (!start)
start = cx->fp;
start = cx->maybefp();
FrameRegsIter i(cx);
while (!i.done() && i.fp() != start)
++i;

View File

@ -547,7 +547,7 @@ NewNativeClassInstance(JSContext *cx, Class *clasp, JSObject *proto, JSObject *p
JS_ASSERT(proto->isNative());
JS_ASSERT(parent);
DTrace::ObjectCreationScope objectCreationScope(cx, cx->fp, clasp);
DTrace::ObjectCreationScope objectCreationScope(cx, cx->maybefp(), clasp);
/*
* Allocate an object from the GC heap and initialize all its fields before
@ -599,13 +599,13 @@ NewBuiltinClassInstance(JSContext *cx, Class *clasp)
/* NB: inline-expanded and specialized version of js_GetClassPrototype. */
JSObject *global;
if (!cx->fp) {
if (!cx->hasfp()) {
global = cx->globalObject;
OBJ_TO_INNER_OBJECT(cx, global);
if (!global)
return NULL;
} else {
global = cx->fp->getScopeChain()->getGlobal();
global = cx->fp()->getScopeChain()->getGlobal();
}
JS_ASSERT(global->getClass()->flags & JSCLASS_IS_GLOBAL);
@ -682,7 +682,7 @@ NewObject(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
}
DTrace::ObjectCreationScope objectCreationScope(cx, cx->fp, clasp);
DTrace::ObjectCreationScope objectCreationScope(cx, cx->maybefp(), clasp);
/*
* Allocate an object from the GC heap and initialize all its fields before

View File

@ -279,7 +279,7 @@ js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp)
JS_FRIEND_API(JSBool)
js_DumpPC(JSContext *cx)
{
return js_DisassembleAtPC(cx, cx->fp->getScript(), true, stdout, cx->regs->pc);
return js_DisassembleAtPC(cx, cx->fp()->getScript(), true, stdout, cx->regs->pc);
}
JSBool
@ -5190,7 +5190,8 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v_in,
jsbytecode* savepc = i.pc();
jsbytecode* savedIMacroPC = fp->maybeIMacroPC();
if (savedIMacroPC) {
if (fp == cx->fp)
JS_ASSERT(cx->hasfp());
if (fp == cx->fp())
cx->regs->pc = savedIMacroPC;
else
fp->savedPC = savedIMacroPC;
@ -5208,7 +5209,8 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v_in,
name = DecompileExpression(cx, script, fp->maybeFunction(), pc);
if (savedIMacroPC) {
if (fp == cx->fp)
JS_ASSERT(cx->hasfp());
if (fp == cx->fp())
cx->regs->pc = savedIMacroPC;
else
fp->savedPC = savepc;

View File

@ -62,7 +62,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
JS_ASSERT(!cx->runtime->gcRunning);
/* FIXME bug 489098: consider enabling the property cache for eval. */
if (js_IsPropertyCacheDisabled(cx) || (cx->fp->flags & JSFRAME_EVAL)) {
if (js_IsPropertyCacheDisabled(cx) || (cx->fp()->flags & JSFRAME_EVAL)) {
PCMETER(disfills++);
return JS_NO_PROP_CACHE_FILL;
}
@ -128,7 +128,7 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
* opcode format flags.
*/
pc = cx->regs->pc;
op = js_GetOpcode(cx, cx->fp->getScript(), pc);
op = js_GetOpcode(cx, cx->fp()->getScript(), pc);
cs = &js_CodeSpec[op];
kshape = 0;
@ -322,7 +322,7 @@ GetAtomFromBytecode(JSContext *cx, jsbytecode *pc, JSOp op, const JSCodeSpec &cs
ptrdiff_t pcoff = (JOF_TYPE(cs.format) == JOF_SLOTATOM) ? SLOTNO_LEN : 0;
JSAtom *atom;
GET_ATOM_FROM_BYTECODE(cx->fp->getScript(), pc, pcoff, atom);
GET_ATOM_FROM_BYTECODE(cx->fp()->getScript(), pc, pcoff, atom);
return atom;
}
@ -333,12 +333,13 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject
JSObject *obj, *pobj, *tmp;
uint32 vcap;
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
JS_ASSERT(
uintN((cx->fp->hasIMacroPC() ? cx->fp->getIMacroPC() : pc) - cx->fp->getScript()->code)
< cx->fp->getScript()->length);
JSStackFrame *fp = cx->fp();
JSOp op = js_GetOpcode(cx, cx->fp->getScript(), pc);
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
JS_ASSERT(uintN((fp->hasIMacroPC() ? fp->getIMacroPC() : pc) - fp->getScript()->code)
< fp->getScript()->length);
JSOp op = js_GetOpcode(cx, fp->getScript(), pc);
const JSCodeSpec &cs = js_CodeSpec[op];
obj = *objp;

View File

@ -183,10 +183,10 @@ TraceRecorder::downSnapshot(FrameInfo* downFrame)
JS_ASSERT(unsigned(exit->calldepth) == callDepth);
exit->numGlobalSlots = ngslots;
exit->numStackSlots = downPostSlots + 1;
exit->numStackSlotsBelowCurrentFrame = cx->fp->down->argv ?
nativeStackOffset(&cx->fp->argv[-2]) / sizeof(double) : 0;
exit->numStackSlotsBelowCurrentFrame = cx->fp()->down->argv ?
nativeStackOffset(&cx->fp()->argv[-2]) / sizeof(double) : 0;
exit->exitType = UNSTABLE_LOOP_EXIT;
exit->block = cx->fp->down->maybeBlockChain();
exit->block = cx->fp()->down->maybeBlockChain();
exit->pc = downFrame->pc + JSOP_CALL_LENGTH;
exit->imacpc = NULL;
exit->sp_adj = ((downPostSlots + 1) * sizeof(double)) - tree->nativeStackBase;
@ -205,16 +205,16 @@ DownFrameSP(JSContext *cx)
{
FrameRegsIter i(cx);
++i;
JS_ASSERT(i.fp() == cx->fp->down);
JS_ASSERT(i.fp() == cx->fp()->down);
return i.sp();
}
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::upRecursion()
{
JS_ASSERT((JSOp)*cx->fp->down->savedPC == JSOP_CALL);
JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, cx->fp->down->getScript(),
cx->fp->down->savedPC)].length == JSOP_CALL_LENGTH);
JS_ASSERT((JSOp)*cx->fp()->down->savedPC == JSOP_CALL);
JS_ASSERT(js_CodeSpec[js_GetOpcode(cx, cx->fp()->down->getScript(),
cx->fp()->down->savedPC)].length == JSOP_CALL_LENGTH);
JS_ASSERT(callDepth == 0);
@ -226,10 +226,10 @@ TraceRecorder::upRecursion()
if (anchor && (anchor->exitType == RECURSIVE_EMPTY_RP_EXIT ||
anchor->exitType == RECURSIVE_SLURP_MISMATCH_EXIT ||
anchor->exitType == RECURSIVE_SLURP_FAIL_EXIT)) {
return slurpDownFrames(cx->fp->down->savedPC);
return slurpDownFrames(cx->fp()->down->savedPC);
}
jsbytecode* return_pc = cx->fp->down->savedPC;
jsbytecode* return_pc = cx->fp()->down->savedPC;
jsbytecode* recursive_pc = return_pc + JSOP_CALL_LENGTH;
/*
@ -256,11 +256,11 @@ TraceRecorder::upRecursion()
* Need to compute this from the down frame, since the stack could have
* moved on this one.
*/
fi->spdist = DownFrameSP(cx) - cx->fp->down->slots();
JS_ASSERT(cx->fp->numActualArgs() == cx->fp->down->numActualArgs());
fi->set_argc(uint16(cx->fp->numActualArgs()), false);
fi->spdist = DownFrameSP(cx) - cx->fp()->down->slots();
JS_ASSERT(cx->fp()->numActualArgs() == cx->fp()->down->numActualArgs());
fi->set_argc(uint16(cx->fp()->numActualArgs()), false);
fi->callerHeight = downPostSlots;
fi->callerArgc = cx->fp->down->numActualArgs();
fi->callerArgc = cx->fp()->down->numActualArgs();
if (anchor && anchor->exitType == RECURSIVE_MISMATCH_EXIT) {
/*
@ -390,7 +390,7 @@ JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
{
/* Missing - no go */
if (cx->fp->numActualArgs() != cx->fp->numFormalArgs())
if (cx->fp()->numActualArgs() != cx->fp()->numFormalArgs())
RETURN_STOP_A("argc != nargs");
LIns* argv_ins;
@ -398,8 +398,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
unsigned downPostSlots;
FrameRegsIter i(cx);
LIns* fp_ins =
addName(lir->insLoad(LIR_ldp, cx_ins, offsetof(JSContext, fp), ACCSET_OTHER), "fp");
LIns* fp_ins = addName(entryFrameIns(), "fp");
/*
* When first emitting slurp code, do so against the down frame. After
@ -434,7 +433,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
addName(lir->insLoad(LIR_ldp, fp_ins,
JSStackFrame::offsetScript(), ACCSET_OTHER),
"script"),
INS_CONSTPTR(cx->fp->down->getScript())),
INS_CONSTPTR(cx->fp()->down->getScript())),
RECURSIVE_LOOP_EXIT);
}
@ -453,7 +452,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
addName(lir->insLoad(LIR_ldi, fp_ins, JSStackFrame::offsetNumActualArgs(),
ACCSET_OTHER),
"argc"),
INS_CONST(cx->fp->numActualArgs())),
INS_CONST(cx->fp()->numActualArgs())),
MISMATCH_EXIT);
/* Pop the interpreter frame. */
@ -672,7 +671,7 @@ public:
JS_REQUIRES_STACK AbortableRecordingStatus
TraceRecorder::downRecursion()
{
JSStackFrame* fp = cx->fp;
JSStackFrame* fp = cx->fp();
JSScript *script = fp->getScript();
if ((jsbytecode*)fragment->ip < script->code ||
(jsbytecode*)fragment->ip >= script->code + script->length) {

View File

@ -2340,7 +2340,7 @@ ASTSerializer::literal(JSParseNode *pn, Value *dst)
LOCAL_ASSERT(re1 && re1->isRegExp());
JSObject *proto;
if (!js_GetClassPrototype(cx, cx->fp->getScopeChain(), JSProto_RegExp, &proto))
if (!js_GetClassPrototype(cx, cx->fp()->getScopeChain(), JSProto_RegExp, &proto))
return false;
JSObject *re2 = js_CloneRegExpObject(cx, re1, proto);

File diff suppressed because it is too large Load Diff

View File

@ -1144,6 +1144,7 @@ class TraceRecorder
JS_REQUIRES_STACK nanojit::LIns* scopeChain();
JS_REQUIRES_STACK nanojit::LIns* entryScopeChain() const;
JS_REQUIRES_STACK nanojit::LIns* entryFrameIns() const;
JS_REQUIRES_STACK JSStackFrame* frameIfInRange(JSObject* obj, unsigned* depthp = NULL) const;
JS_REQUIRES_STACK RecordingStatus traverseScopeChain(JSObject *obj, nanojit::LIns *obj_ins, JSObject *obj2, nanojit::LIns *&obj2_ins);
JS_REQUIRES_STACK AbortableRecordingStatus scopeChainProp(JSObject* obj, Value*& vp, nanojit::LIns*& ins, NameResult& nr);

View File

@ -387,7 +387,8 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
* we parent all wrappers to the global object in their home compartment.
* This loses us some transparency, and is generally very cheesy.
*/
JSObject *global = cx->fp ? cx->fp->getScopeChain()->getGlobal() : cx->globalObject;
JSObject *global =
cx->hasfp() ? cx->fp()->getScopeChain()->getGlobal() : cx->globalObject;
wrapper->setParent(global);
return true;
}

View File

@ -3195,7 +3195,7 @@ EvalInFrame(JSContext *cx, uintN argc, jsval *vp)
? !!(JSVAL_TO_BOOLEAN(argv[2]))
: false;
JS_ASSERT(cx->fp);
JS_ASSERT(cx->hasfp());
FrameRegsIter fi(cx);
for (uint32 i = 0; i < upCount; ++i, ++fi) {