Bug 980059 - Do some simple renaming and minor cleanups in prepration (r=jandem)

--HG--
extra : rebase_source : 1fbb7dd0bde99abef7a6d504e08fd18163cee3ee
This commit is contained in:
Luke Wagner 2014-03-05 17:15:32 -06:00
parent b3506a6c7a
commit f176ca2fd6
8 changed files with 187 additions and 179 deletions

View File

@ -519,7 +519,7 @@ struct JSContext : public js::ExclusiveContext,
js::StackFrame *interpreterFrame() const {
return mainThread().activation()->asInterpreter()->current();
}
js::FrameRegs &interpreterRegs() const {
js::InterpreterRegs &interpreterRegs() const {
return mainThread().activation()->asInterpreter()->regs();
}

View File

@ -1642,7 +1642,7 @@ const Class StarGeneratorObject::class_ = {
* if they are non-null.
*/
JSObject *
js_NewGenerator(JSContext *cx, const FrameRegs &stackRegs)
js_NewGenerator(JSContext *cx, const InterpreterRegs &stackRegs)
{
JS_ASSERT(stackRegs.stackDepth() == 0);
StackFrame *stackfp = stackRegs.fp();

View File

@ -243,14 +243,14 @@ struct JSGenerator
{
js::HeapPtrObject obj;
JSGeneratorState state;
js::FrameRegs regs;
js::InterpreterRegs regs;
JSGenerator *prevGenerator;
js::StackFrame *fp;
js::HeapValue stackSnapshot[1];
};
extern JSObject *
js_NewGenerator(JSContext *cx, const js::FrameRegs &regs);
js_NewGenerator(JSContext *cx, const js::InterpreterRegs &regs);
extern JSObject *
js_InitIteratorClasses(JSContext *cx, js::HandleObject obj);

View File

@ -72,7 +72,7 @@ static MOZ_NEVER_INLINE bool
#else
static bool
#endif
ToBooleanOp(const FrameRegs &regs)
ToBooleanOp(const InterpreterRegs &regs)
{
return ToBoolean(regs.stackHandleAt(-1));
}
@ -83,7 +83,7 @@ static MOZ_NEVER_INLINE bool
#else
static bool
#endif
LooseEqualityOp(JSContext *cx, FrameRegs &regs)
LooseEqualityOp(JSContext *cx, InterpreterRegs &regs)
{
HandleValue rval = regs.stackHandleAt(-1);
HandleValue lval = regs.stackHandleAt(-2);
@ -894,21 +894,21 @@ js::UnwindScope(JSContext *cx, ScopeIter &si, jsbytecode *pc)
}
static void
ForcedReturn(JSContext *cx, ScopeIter &si, FrameRegs &regs)
ForcedReturn(JSContext *cx, ScopeIter &si, InterpreterRegs &regs)
{
UnwindScope(cx, si, regs.fp()->script()->main());
regs.setToEndOfScript();
}
static void
ForcedReturn(JSContext *cx, FrameRegs &regs)
ForcedReturn(JSContext *cx, InterpreterRegs &regs)
{
ScopeIter si(regs.fp(), regs.pc, cx);
ForcedReturn(cx, si, regs);
}
void
js::UnwindForUncatchableException(JSContext *cx, const FrameRegs &regs)
js::UnwindForUncatchableException(JSContext *cx, const InterpreterRegs &regs)
{
/* c.f. the regular (catchable) TryNoteIter loop in HandleError. */
for (TryNoteIter tni(cx, regs); !tni.done(); ++tni) {
@ -920,7 +920,7 @@ js::UnwindForUncatchableException(JSContext *cx, const FrameRegs &regs)
}
}
TryNoteIter::TryNoteIter(JSContext *cx, const FrameRegs &regs)
TryNoteIter::TryNoteIter(JSContext *cx, const InterpreterRegs &regs)
: regs(regs),
script(cx, regs.fp()->script()),
pcOffset(regs.pc - script->main())
@ -988,7 +988,7 @@ enum HandleErrorContinuation
};
static HandleErrorContinuation
HandleError(JSContext *cx, FrameRegs &regs)
HandleError(JSContext *cx, InterpreterRegs &regs)
{
JS_ASSERT(regs.fp()->script()->containsPC(regs.pc));

View File

@ -328,14 +328,14 @@ UnwindScope(JSContext *cx, ScopeIter &si, jsbytecode *pc);
* just preserving the basic engine stack invariants.
*/
extern void
UnwindForUncatchableException(JSContext *cx, const FrameRegs &regs);
UnwindForUncatchableException(JSContext *cx, const InterpreterRegs &regs);
extern bool
OnUnknownMethod(JSContext *cx, HandleObject obj, Value idval, MutableHandleValue vp);
class TryNoteIter
{
const FrameRegs &regs;
const InterpreterRegs &regs;
RootedScript script; /* TryNotIter is always stack allocated. */
uint32_t pcOffset;
JSTryNote *tn, *tnEnd;
@ -343,7 +343,7 @@ class TryNoteIter
void settle();
public:
explicit TryNoteIter(JSContext *cx, const FrameRegs &regs);
explicit TryNoteIter(JSContext *cx, const InterpreterRegs &regs);
bool done() const;
void operator++();
JSTryNote *operator*() const { return tn; }

View File

@ -283,7 +283,7 @@ InterpreterStack::getCallFrame(JSContext *cx, const CallArgs &args, HandleScript
}
MOZ_ALWAYS_INLINE bool
InterpreterStack::pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
InterpreterStack::pushInlineFrame(JSContext *cx, InterpreterRegs &regs, const CallArgs &args,
HandleScript script, InitialFrameFlags initial)
{
RootedFunction callee(cx, &args.callee().as<JSFunction>());
@ -315,7 +315,7 @@ InterpreterStack::pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs
}
MOZ_ALWAYS_INLINE void
InterpreterStack::popInlineFrame(FrameRegs &regs)
InterpreterStack::popInlineFrame(InterpreterRegs &regs)
{
StackFrame *fp = regs.fp();
regs.popInlineFrame();
@ -331,7 +331,7 @@ ScriptFrameIter::unaliasedForEachActual(JSContext *cx, Op op)
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
interpFrame()->unaliasedForEachActual(op);
return;
case JIT:

View File

@ -375,11 +375,11 @@ StackFrame::mark(JSTracer *trc)
gc::MarkValueUnbarriered(trc, returnValue().address(), "rval");
}
static void
MarkLocals(StackFrame *frame, JSTracer *trc, unsigned start, unsigned end)
void
StackFrame::markValues(JSTracer *trc, unsigned start, unsigned end)
{
if (start < end)
gc::MarkValueRootRange(trc, end - start, frame->slots() + start, "vm_stack");
gc::MarkValueRootRange(trc, end - start, slots() + start, "vm_stack");
}
void
@ -405,17 +405,17 @@ StackFrame::markValues(JSTracer *trc, Value *sp, jsbytecode *pc)
if (nfixed == nlivefixed) {
// All locals are live.
MarkLocals(this, trc, 0, sp - slots());
markValues(trc, 0, sp - slots());
} else {
// Mark operand stack.
MarkLocals(this, trc, nfixed, sp - slots());
markValues(trc, nfixed, sp - slots());
// Clear dead locals.
while (nfixed > nlivefixed)
unaliasedLocal(--nfixed, DONT_CHECK_ALIASING).setUndefined();
// Mark live locals.
MarkLocals(this, trc, 0, nlivefixed);
markValues(trc, 0, nlivefixed);
}
if (hasArgs()) {
@ -454,7 +454,7 @@ js::MarkInterpreterActivations(JSRuntime *rt, JSTracer *trc)
// Unlike the other methods of this calss, this method is defined here so that
// we don't have to #include jsautooplen.h in vm/Stack.h.
void
FrameRegs::setToEndOfScript()
InterpreterRegs::setToEndOfScript()
{
JSScript *script = fp()->script();
sp = fp()->base();
@ -520,7 +520,7 @@ ScriptFrameIter::popActivation()
void
ScriptFrameIter::popInterpreterFrame()
{
JS_ASSERT(data_.state_ == SCRIPTED);
JS_ASSERT(data_.state_ == INTERP);
++data_.interpFrames_;
@ -612,7 +612,7 @@ ScriptFrameIter::settleOnActivation()
JS_ASSERT(!data_.interpFrames_.frame()->runningInJit());
data_.pc_ = data_.interpFrames_.pc();
data_.state_ = SCRIPTED;
data_.state_ = INTERP;
return;
}
}
@ -729,7 +729,7 @@ ScriptFrameIter::operator++()
switch (data_.state_) {
case DONE:
MOZ_ASSUME_UNREACHABLE("Unexpected state");
case SCRIPTED:
case INTERP:
if (interpFrame()->isDebuggerFrame() && interpFrame()->evalInFramePrev()) {
AbstractFramePtr eifPrev = interpFrame()->evalInFramePrev();
@ -800,7 +800,7 @@ ScriptFrameIter::compartment() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
case JIT:
return data_.activations_.activation()->compartment();
}
@ -813,7 +813,7 @@ ScriptFrameIter::isFunctionFrame() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
return interpFrame()->isFunctionFrame();
case JIT:
#ifdef JS_ION
@ -834,7 +834,7 @@ ScriptFrameIter::isGlobalFrame() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
return interpFrame()->isGlobalFrame();
case JIT:
#ifdef JS_ION
@ -855,7 +855,7 @@ ScriptFrameIter::isEvalFrame() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
return interpFrame()->isEvalFrame();
case JIT:
#ifdef JS_ION
@ -877,7 +877,7 @@ ScriptFrameIter::isNonEvalFunctionFrame() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
return interpFrame()->isNonEvalFunctionFrame();
case JIT:
return !isEvalFrame() && isFunctionFrame();
@ -891,7 +891,7 @@ ScriptFrameIter::isGeneratorFrame() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
return interpFrame()->isGeneratorFrame();
case JIT:
return false;
@ -914,7 +914,7 @@ ScriptFrameIter::isConstructing() const
#else
break;
#endif
case SCRIPTED:
case INTERP:
return interpFrame()->isConstructing();
}
MOZ_ASSUME_UNREACHABLE("Unexpected state");
@ -932,7 +932,7 @@ ScriptFrameIter::abstractFramePtr() const
return data_.ionFrames_.baselineFrame();
#endif
break;
case SCRIPTED:
case INTERP:
JS_ASSERT(interpFrame());
return AbstractFramePtr(interpFrame());
}
@ -945,7 +945,7 @@ ScriptFrameIter::updatePcQuadratic()
switch (data_.state_) {
case DONE:
break;
case SCRIPTED: {
case INTERP: {
StackFrame *frame = interpFrame();
InterpreterActivation *activation = data_.activations_.activation()->asInterpreter();
@ -993,7 +993,7 @@ ScriptFrameIter::callee() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
JS_ASSERT(isFunctionFrame());
return &interpFrame()->callee();
case JIT:
@ -1015,7 +1015,7 @@ ScriptFrameIter::calleev() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
JS_ASSERT(isFunctionFrame());
return interpFrame()->calleev();
case JIT:
@ -1034,7 +1034,7 @@ ScriptFrameIter::numActualArgs() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
JS_ASSERT(isFunctionFrame());
return interpFrame()->numActualArgs();
case JIT:
@ -1051,13 +1051,19 @@ ScriptFrameIter::numActualArgs() const
MOZ_ASSUME_UNREACHABLE("Unexpected state");
}
unsigned
ScriptFrameIter::numFormalArgs() const
{
return script()->functionNonDelazifying()->nargs();
}
Value
ScriptFrameIter::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing) const
{
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
return interpFrame()->unaliasedActual(i, checkAliasing);
case JIT:
#ifdef JS_ION
@ -1084,7 +1090,7 @@ ScriptFrameIter::scopeChain() const
#else
break;
#endif
case SCRIPTED:
case INTERP:
return interpFrame()->scopeChain();
}
MOZ_ASSUME_UNREACHABLE("Unexpected state");
@ -1107,7 +1113,7 @@ ScriptFrameIter::hasArgsObj() const
switch (data_.state_) {
case DONE:
break;
case SCRIPTED:
case INTERP:
return interpFrame()->hasArgsObj();
case JIT:
#ifdef JS_ION
@ -1135,7 +1141,7 @@ ScriptFrameIter::argsObj() const
#else
break;
#endif
case SCRIPTED:
case INTERP:
return interpFrame()->argsObj();
}
MOZ_ASSUME_UNREACHABLE("Unexpected state");
@ -1166,7 +1172,7 @@ ScriptFrameIter::thisv() const
#else
break;
#endif
case SCRIPTED:
case INTERP:
return interpFrame()->thisValue();
}
MOZ_ASSUME_UNREACHABLE("Unexpected state");
@ -1184,7 +1190,7 @@ ScriptFrameIter::returnValue() const
return data_.ionFrames_.baselineFrame()->returnValue();
#endif
break;
case SCRIPTED:
case INTERP:
return interpFrame()->returnValue();
}
MOZ_ASSUME_UNREACHABLE("Unexpected state");
@ -1204,7 +1210,7 @@ ScriptFrameIter::setReturnValue(const Value &v)
}
#endif
break;
case SCRIPTED:
case INTERP:
interpFrame()->setReturnValue(v);
return;
}
@ -1229,7 +1235,7 @@ ScriptFrameIter::numFrameSlots() const
break;
#endif
}
case SCRIPTED:
case INTERP:
JS_ASSERT(data_.interpFrames_.sp() >= interpFrame()->base());
return data_.interpFrames_.sp() - interpFrame()->base();
}
@ -1255,7 +1261,7 @@ ScriptFrameIter::frameSlotValue(size_t index) const
#else
break;
#endif
case SCRIPTED:
case INTERP:
return interpFrame()->base()[index];
}
MOZ_ASSUME_UNREACHABLE("Unexpected state");
@ -1280,6 +1286,15 @@ js::SelfHostedFramesVisible()
}
#endif
void
NonBuiltinScriptFrameIter::settle()
{
if (!SelfHostedFramesVisible()) {
while (!done() && script()->selfHosted())
ScriptFrameIter::operator++();
}
}
/*****************************************************************************/
JSObject *

View File

@ -23,18 +23,11 @@ struct JSGenerator;
namespace js {
class StackFrame;
class FrameRegs;
class InvokeFrameGuard;
class ExecuteFrameGuard;
class GeneratorFrameGuard;
class ScriptFrameIter;
class AllFramesIter;
class ArgumentsObject;
class InterpreterRegs;
class ScopeObject;
class ScriptFrameIter;
class StackFrame;
class StaticBlockObject;
struct ScopeCoordinate;
@ -66,8 +59,8 @@ struct ScopeCoordinate;
// The top of an activation's current frame's expression stack is pointed to by the
// activation's "current regs", which contains the stack pointer 'sp'. In the
// interpreter, sp is adjusted as individual values are pushed and popped from
// the stack and the FrameRegs struct (pointed to by the InterpreterActivation)
// is a local var of js::Interpret.
// the stack and the InterpreterRegs struct (pointed to by the
// InterpreterActivation) is a local var of js::Interpret.
enum MaybeCheckAliasing { CHECK_ALIASING = true, DONT_CHECK_ALIASING = false };
@ -367,24 +360,18 @@ class StackFrame
void writeBarrierPost();
/*
* These utilities provide raw access to the values associated with a
* StackFrame (see "VM stack layout" comment). The utilities are private
* since they are not able to assert that only unaliased vars/formals are
* accessed. Normal code should prefer the StackFrame::unaliased* members
* (or FrameRegs::stackDepth for the usual "depth is at least" assertions).
* The utilities are private since they are not able to assert that only
* unaliased vars/formals are accessed. Normal code should prefer the
* StackFrame::unaliased* members (or InterpreterRegs::stackDepth for the
* usual "depth is at least" assertions).
*/
public:
Value *slots() const { return (Value *)(this + 1); }
Value *base() const { return slots() + script()->nfixed(); }
Value *argv() const { return argv_; }
private:
friend class FrameRegs;
friend class InterpreterRegs;
friend class InterpreterStack;
friend class ScriptFrameIter;
friend class CallObject;
friend class ClonedBlockObject;
friend class ArgumentsObject;
friend class jit::BaselineFrame;
/*
* Frame initialization, called by InterpreterStack operations after acquiring
@ -538,6 +525,9 @@ class StackFrame
unsigned numFormalArgs() const { JS_ASSERT(hasArgs()); return fun()->nargs(); }
unsigned numActualArgs() const { JS_ASSERT(hasArgs()); return u.nactual; }
/* Watch out, this exposes a pointer to the unaliased formal arg array. */
Value *argv() const { return argv_; }
/*
* Arguments object
*
@ -935,6 +925,7 @@ class StackFrame
public:
void mark(JSTracer *trc);
void markValues(JSTracer *trc, unsigned start, unsigned end);
void markValues(JSTracer *trc, Value *sp, jsbytecode *pc);
// Entered Baseline/Ion from the interpreter.
@ -971,7 +962,7 @@ InitialFrameFlagsAreConstructing(InitialFrameFlags initial)
/*****************************************************************************/
class FrameRegs
class InterpreterRegs
{
public:
Value *sp;
@ -992,7 +983,7 @@ class FrameRegs
}
/* For generators. */
void rebaseFromTo(const FrameRegs &from, StackFrame &to) {
void rebaseFromTo(const InterpreterRegs &from, StackFrame &to) {
fp_ = &to;
sp = to.slots() + (from.sp - from.fp_->slots());
pc = from.pc;
@ -1067,10 +1058,10 @@ class InterpreterStack
// The interpreter can push light-weight, "inline" frames without entering a
// new InterpreterActivation or recursively calling Interpret.
bool pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
bool pushInlineFrame(JSContext *cx, InterpreterRegs &regs, const CallArgs &args,
HandleScript script, InitialFrameFlags initial);
void popInlineFrame(FrameRegs &regs);
void popInlineFrame(InterpreterRegs &regs);
inline void purge(JSRuntime *rt);
@ -1225,7 +1216,7 @@ class InterpreterActivation : public Activation
friend class js::InterpreterFrameIterator;
RunState &state_;
FrameRegs regs_;
InterpreterRegs regs_;
StackFrame *entryFrame_;
size_t opMask_; // For debugger interrupts, see js::Interpret.
@ -1244,7 +1235,7 @@ class InterpreterActivation : public Activation
StackFrame *current() const {
return regs_.fp();
}
FrameRegs &regs() {
InterpreterRegs &regs() {
return regs_;
}
StackFrame *entryFrame() const {
@ -1414,35 +1405,15 @@ class InterpreterFrameIterator
}
};
/*
* Iterate through the callstack (following fp->prev) of the given context.
* Each element of said callstack can either be the execution of a script
* (scripted function call, global code, eval code, debugger code) or the
* invocation of a (C++) native. Example usage:
*
* for (Stackiter i(cx); !i.done(); ++i) {
* if (i.isScript()) {
* ... i.fp() ... i.sp() ... i.pc()
* } else {
* JS_ASSERT(i.isNativeCall());
* ... i.args();
* }
* }
*
* The SavedOption parameter additionally lets the iterator continue through
* breaks in the callstack (from JS_SaveFrameChain). The default is to stop.
*/
class ScriptFrameIter
{
public:
enum SavedOption { STOP_AT_SAVED, GO_THROUGH_SAVED };
enum ContextOption { CURRENT_CONTEXT, ALL_CONTEXTS };
enum State { DONE, SCRIPTED, JIT };
enum State { DONE, INTERP, JIT };
/*
* Unlike ScriptFrameIter itself, ScriptFrameIter::Data can be allocated on
* the heap, so this structure should not contain any GC things.
*/
// Unlike ScriptFrameIter itself, ScriptFrameIter::Data can be allocated on
// the heap, so this structure should not contain any GC things.
struct Data
{
PerThreadData * perThread_;
@ -1467,22 +1438,6 @@ class ScriptFrameIter
Data(const Data &other);
};
friend class ::JSBrokenFrameIterator;
private:
Data data_;
#ifdef JS_ION
jit::InlineFrameIterator ionInlineFrames_;
#endif
void popActivation();
void popInterpreterFrame();
#ifdef JS_ION
void nextJitFrame();
void popJitFrame();
#endif
void settleOnActivation();
public:
ScriptFrameIter(JSContext *cx, SavedOption = STOP_AT_SAVED);
ScriptFrameIter(JSContext *cx, ContextOption, SavedOption, JSPrincipals* = nullptr);
ScriptFrameIter(const ScriptFrameIter &iter);
@ -1490,46 +1445,20 @@ class ScriptFrameIter
ScriptFrameIter(AbstractFramePtr frame);
bool done() const { return data_.state_ == DONE; }
// -------------------------------------------------------
// The following functions can only be called when !done()
// -------------------------------------------------------
ScriptFrameIter &operator++();
Data *copyData() const;
AbstractFramePtr copyDataAsAbstractFramePtr() const;
JSCompartment *compartment() const;
Activation *activation() const { return data_.activations_.activation(); }
JSScript *script() const {
JS_ASSERT(!done());
if (data_.state_ == SCRIPTED)
return interpFrame()->script();
#ifdef JS_ION
JS_ASSERT(data_.state_ == JIT);
if (data_.ionFrames_.isOptimizedJS())
return ionInlineFrames_.script();
return data_.ionFrames_.script();
#else
return nullptr;
#endif
}
bool isJit() const {
JS_ASSERT(!done());
return data_.state_ == JIT;
}
bool isIon() const {
#ifdef JS_ION
return isJit() && data_.ionFrames_.isOptimizedJS();
#else
return false;
#endif
}
bool isBaseline() const {
#ifdef JS_ION
return isJit() && data_.ionFrames_.isBaselineJS();
#else
return false;
#endif
}
bool isInterp() const { JS_ASSERT(!done()); return data_.state_ == INTERP; }
bool isJit() const { JS_ASSERT(!done()); return data_.state_ == JIT; }
inline bool isIon() const;
inline bool isBaseline() const;
bool isFunctionFrame() const;
bool isGlobalFrame() const;
@ -1537,30 +1466,16 @@ class ScriptFrameIter
bool isNonEvalFunctionFrame() const;
bool isGeneratorFrame() const;
bool isConstructing() const;
bool hasArgs() const { return isNonEvalFunctionFrame(); }
AbstractFramePtr abstractFramePtr() const;
/*
* When entering IonMonkey, the top interpreter frame (pushed by the caller)
* is kept on the stack as bookkeeping (with runningInIon() set). The
* contents of the frame are ignored by Ion code (and GC) and thus
* immediately become garbage and must not be touched directly.
*/
StackFrame *interpFrame() const {
JS_ASSERT(data_.state_ == SCRIPTED);
return data_.interpFrames_.frame();
}
Activation *activation() const { return data_.activations_.activation(); }
inline JSScript *script() const;
jsbytecode *pc() const { JS_ASSERT(!done()); return data_.pc_; }
void updatePcQuadratic();
JSFunction *callee() const;
Value calleev() const;
unsigned numActualArgs() const;
unsigned numFormalArgs() const { return script()->functionNonDelazifying()->nargs(); }
unsigned numFormalArgs() const;
Value unaliasedActual(unsigned i, MaybeCheckAliasing = CHECK_ALIASING) const;
template <class Op> inline void unaliasedForEachActual(JSContext *cx, Op op);
@ -1584,6 +1499,33 @@ class ScriptFrameIter
// These are only valid for the top frame.
size_t numFrameSlots() const;
Value frameSlotValue(size_t index) const;
// --------------------------------------------------------------------------
// The following functions can only be called when isInterp() or isBaseline()
// --------------------------------------------------------------------------
AbstractFramePtr abstractFramePtr() const;
AbstractFramePtr copyDataAsAbstractFramePtr() const;
Data *copyData() const;
// This can only be called when isInterp():
inline StackFrame *interpFrame() const;
private:
Data data_;
#ifdef JS_ION
jit::InlineFrameIterator ionInlineFrames_;
#endif
void popActivation();
void popInterpreterFrame();
#ifdef JS_ION
void nextJitFrame();
void popJitFrame();
#endif
void settleOnActivation();
friend class ::JSBrokenFrameIterator;
};
#ifdef DEBUG
@ -1599,28 +1541,34 @@ SelfHostedFramesVisible()
/* A filtering of the ScriptFrameIter to only stop at non-self-hosted scripts. */
class NonBuiltinScriptFrameIter : public ScriptFrameIter
{
void settle() {
if (!SelfHostedFramesVisible()) {
while (!done() && script()->selfHosted())
ScriptFrameIter::operator++();
}
}
void settle();
public:
NonBuiltinScriptFrameIter(JSContext *cx, ScriptFrameIter::SavedOption opt = ScriptFrameIter::STOP_AT_SAVED)
: ScriptFrameIter(cx, opt) { settle(); }
NonBuiltinScriptFrameIter(JSContext *cx,
ScriptFrameIter::SavedOption opt = ScriptFrameIter::STOP_AT_SAVED)
: ScriptFrameIter(cx, opt)
{
settle();
}
NonBuiltinScriptFrameIter(JSContext *cx,
ScriptFrameIter::ContextOption contextOption,
ScriptFrameIter::SavedOption savedOption,
JSPrincipals *principals = nullptr)
: ScriptFrameIter(cx, contextOption, savedOption, principals) { settle(); }
: ScriptFrameIter(cx, contextOption, savedOption, principals)
{
settle();
}
NonBuiltinScriptFrameIter(const ScriptFrameIter::Data &data)
: ScriptFrameIter(data)
{}
NonBuiltinScriptFrameIter &operator++() { ScriptFrameIter::operator++(); settle(); return *this; }
NonBuiltinScriptFrameIter &operator++() {
ScriptFrameIter::operator++();
settle();
return *this;
}
};
/*
@ -1635,5 +1583,50 @@ class AllFramesIter : public ScriptFrameIter
{}
};
/* Popular inline definitions. */
inline JSScript *
ScriptFrameIter::script() const
{
JS_ASSERT(!done());
if (data_.state_ == INTERP)
return interpFrame()->script();
#ifdef JS_ION
JS_ASSERT(data_.state_ == JIT);
if (data_.ionFrames_.isOptimizedJS())
return ionInlineFrames_.script();
return data_.ionFrames_.script();
#else
return nullptr;
#endif
}
inline bool
ScriptFrameIter::isIon() const
{
#ifdef JS_ION
return isJit() && data_.ionFrames_.isOptimizedJS();
#else
return false;
#endif
}
inline bool
ScriptFrameIter::isBaseline() const
{
#ifdef JS_ION
return isJit() && data_.ionFrames_.isBaselineJS();
#else
return false;
#endif
}
inline StackFrame *
ScriptFrameIter::interpFrame() const
{
JS_ASSERT(data_.state_ == INTERP);
return data_.interpFrames_.frame();
}
} /* namespace js */
#endif /* vm_Stack_h */