mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 980059 - Do some simple renaming and minor cleanups in prepration (r=jandem)
--HG-- extra : rebase_source : 1fbb7dd0bde99abef7a6d504e08fd18163cee3ee
This commit is contained in:
parent
b3506a6c7a
commit
f176ca2fd6
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 ®s);
|
||||
js_NewGenerator(JSContext *cx, const js::InterpreterRegs ®s);
|
||||
|
||||
extern JSObject *
|
||||
js_InitIteratorClasses(JSContext *cx, js::HandleObject obj);
|
||||
|
@ -72,7 +72,7 @@ static MOZ_NEVER_INLINE bool
|
||||
#else
|
||||
static bool
|
||||
#endif
|
||||
ToBooleanOp(const FrameRegs ®s)
|
||||
ToBooleanOp(const InterpreterRegs ®s)
|
||||
{
|
||||
return ToBoolean(regs.stackHandleAt(-1));
|
||||
}
|
||||
@ -83,7 +83,7 @@ static MOZ_NEVER_INLINE bool
|
||||
#else
|
||||
static bool
|
||||
#endif
|
||||
LooseEqualityOp(JSContext *cx, FrameRegs ®s)
|
||||
LooseEqualityOp(JSContext *cx, InterpreterRegs ®s)
|
||||
{
|
||||
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 ®s)
|
||||
ForcedReturn(JSContext *cx, ScopeIter &si, InterpreterRegs ®s)
|
||||
{
|
||||
UnwindScope(cx, si, regs.fp()->script()->main());
|
||||
regs.setToEndOfScript();
|
||||
}
|
||||
|
||||
static void
|
||||
ForcedReturn(JSContext *cx, FrameRegs ®s)
|
||||
ForcedReturn(JSContext *cx, InterpreterRegs ®s)
|
||||
{
|
||||
ScopeIter si(regs.fp(), regs.pc, cx);
|
||||
ForcedReturn(cx, si, regs);
|
||||
}
|
||||
|
||||
void
|
||||
js::UnwindForUncatchableException(JSContext *cx, const FrameRegs ®s)
|
||||
js::UnwindForUncatchableException(JSContext *cx, const InterpreterRegs ®s)
|
||||
{
|
||||
/* 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 ®s)
|
||||
}
|
||||
}
|
||||
|
||||
TryNoteIter::TryNoteIter(JSContext *cx, const FrameRegs ®s)
|
||||
TryNoteIter::TryNoteIter(JSContext *cx, const InterpreterRegs ®s)
|
||||
: regs(regs),
|
||||
script(cx, regs.fp()->script()),
|
||||
pcOffset(regs.pc - script->main())
|
||||
@ -988,7 +988,7 @@ enum HandleErrorContinuation
|
||||
};
|
||||
|
||||
static HandleErrorContinuation
|
||||
HandleError(JSContext *cx, FrameRegs ®s)
|
||||
HandleError(JSContext *cx, InterpreterRegs ®s)
|
||||
{
|
||||
JS_ASSERT(regs.fp()->script()->containsPC(regs.pc));
|
||||
|
||||
|
@ -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 ®s);
|
||||
UnwindForUncatchableException(JSContext *cx, const InterpreterRegs ®s);
|
||||
|
||||
extern bool
|
||||
OnUnknownMethod(JSContext *cx, HandleObject obj, Value idval, MutableHandleValue vp);
|
||||
|
||||
class TryNoteIter
|
||||
{
|
||||
const FrameRegs ®s;
|
||||
const InterpreterRegs ®s;
|
||||
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 ®s);
|
||||
explicit TryNoteIter(JSContext *cx, const InterpreterRegs ®s);
|
||||
bool done() const;
|
||||
void operator++();
|
||||
JSTryNote *operator*() const { return tn; }
|
||||
|
@ -283,7 +283,7 @@ InterpreterStack::getCallFrame(JSContext *cx, const CallArgs &args, HandleScript
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
InterpreterStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &args,
|
||||
InterpreterStack::pushInlineFrame(JSContext *cx, InterpreterRegs ®s, const CallArgs &args,
|
||||
HandleScript script, InitialFrameFlags initial)
|
||||
{
|
||||
RootedFunction callee(cx, &args.callee().as<JSFunction>());
|
||||
@ -315,7 +315,7 @@ InterpreterStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void
|
||||
InterpreterStack::popInlineFrame(FrameRegs ®s)
|
||||
InterpreterStack::popInlineFrame(InterpreterRegs ®s)
|
||||
{
|
||||
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:
|
||||
|
@ -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 *
|
||||
|
@ -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 ®s, const CallArgs &args,
|
||||
bool pushInlineFrame(JSContext *cx, InterpreterRegs ®s, const CallArgs &args,
|
||||
HandleScript script, InitialFrameFlags initial);
|
||||
|
||||
void popInlineFrame(FrameRegs ®s);
|
||||
void popInlineFrame(InterpreterRegs ®s);
|
||||
|
||||
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 ®s() {
|
||||
InterpreterRegs ®s() {
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user