mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 797977 - Rename StackIter::fp() to StackIter::interpFrame(). r=luke
This commit is contained in:
parent
58c21513e0
commit
be98caba91
@ -184,6 +184,7 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, StackFrame *c
|
||||
unsigned staticLevel;
|
||||
RootedValue thisv(cx);
|
||||
if (evalType == DIRECT_EVAL) {
|
||||
JS_ASSERT(!caller->runningInIon());
|
||||
staticLevel = caller->script()->staticLevel + 1;
|
||||
|
||||
// Direct calls to eval are supposed to see the caller's |this|. If we
|
||||
|
@ -609,8 +609,7 @@ ion::ThunkToInterpreter(Value *vp)
|
||||
StackFrame *fp = NULL;
|
||||
Rooted<JSScript*> script(cx, NULL);
|
||||
do {
|
||||
JS_ASSERT(!iter.isIon());
|
||||
fp = iter.fp();
|
||||
fp = iter.interpFrame();
|
||||
script = iter.script();
|
||||
if (script->needsArgsObj()) {
|
||||
// Currently IonMonkey does not compile if the script needs an
|
||||
|
@ -302,6 +302,7 @@ class InlineFrameIterator
|
||||
}
|
||||
bool isFunctionFrame() const;
|
||||
bool isConstructing() const;
|
||||
JSObject *scopeChain() const;
|
||||
JSObject *thisObject() const;
|
||||
InlineFrameIterator operator++();
|
||||
|
||||
|
@ -1030,6 +1030,17 @@ IonFrameIterator::isConstructing() const
|
||||
return activation_->entryfp()->isConstructing();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
InlineFrameIterator::scopeChain() const
|
||||
{
|
||||
SnapshotIterator s(si_);
|
||||
|
||||
// scopeChain
|
||||
Value v = s.read();
|
||||
JS_ASSERT(v.isObject());
|
||||
return &v.toObject();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
InlineFrameIterator::thisObject() const
|
||||
{
|
||||
|
@ -7317,6 +7317,6 @@ JS_GetScriptedGlobal(JSContext *cx)
|
||||
ScriptFrameIter i(cx);
|
||||
if (i.done())
|
||||
return cx->global();
|
||||
return &i.fp()->global();
|
||||
return &i.scopeChain()->global();
|
||||
}
|
||||
|
||||
|
@ -1972,12 +1972,6 @@ namespace mjit {
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/* How much expansion of inlined frames to do when inspecting the stack. */
|
||||
enum FrameExpandKind {
|
||||
FRAME_EXPAND_NONE = 0,
|
||||
FRAME_EXPAND_ALL = 1
|
||||
};
|
||||
|
||||
namespace js {
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -585,16 +585,4 @@ JSContext::setDefaultCompartmentObjectIfUnset(JSObject *obj)
|
||||
setDefaultCompartmentObject(obj);
|
||||
}
|
||||
|
||||
/* Get the current frame, first lazily instantiating stack frames if needed. */
|
||||
static inline js::StackFrame *
|
||||
js_GetTopStackFrame(JSContext *cx, FrameExpandKind expand)
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
if (expand)
|
||||
js::mjit::ExpandInlineFrames(cx->compartment);
|
||||
#endif
|
||||
|
||||
return cx->maybefp();
|
||||
}
|
||||
|
||||
#endif /* jscntxtinlines_h___ */
|
||||
|
@ -682,10 +682,21 @@ JSCompartment::onTooMuchMalloc()
|
||||
bool
|
||||
JSCompartment::hasScriptsOnStack()
|
||||
{
|
||||
for (AllFramesIter i(rt->stackSpace); !i.done(); ++i) {
|
||||
if (i.fp()->script()->compartment() == this)
|
||||
for (AllFramesIter afi(rt->stackSpace); !afi.done(); ++afi) {
|
||||
#ifdef JS_ION
|
||||
// If this is an Ion frame, check the IonActivation instead
|
||||
if (afi.isIon())
|
||||
continue;
|
||||
#endif
|
||||
if (afi.interpFrame()->script()->compartment() == this)
|
||||
return true;
|
||||
}
|
||||
#ifdef JS_ION
|
||||
for (ion::IonActivationIterator iai(rt); iai.more(); ++iai) {
|
||||
if (iai.activation()->compartment() == this)
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -477,7 +477,21 @@ JS_PUBLIC_API(JSStackFrame *)
|
||||
JS_BrokenFrameIterator(JSContext *cx, JSStackFrame **iteratorp)
|
||||
{
|
||||
StackFrame *fp = Valueify(*iteratorp);
|
||||
*iteratorp = Jsvalify((fp == NULL) ? js_GetTopStackFrame(cx, FRAME_EXPAND_ALL) : fp->prev());
|
||||
if (!fp) {
|
||||
#ifdef JS_METHODJIT
|
||||
js::mjit::ExpandInlineFrames(cx->compartment);
|
||||
#endif
|
||||
fp = cx->maybefp();
|
||||
} else {
|
||||
fp = fp->prev();
|
||||
}
|
||||
|
||||
// settle on the next non-ion frame as it is not considered safe to inspect
|
||||
// Ion's activation StackFrame.
|
||||
while (fp && fp->runningInIon())
|
||||
fp = fp->prev();
|
||||
|
||||
*iteratorp = Jsvalify(fp);
|
||||
return *iteratorp;
|
||||
}
|
||||
|
||||
@ -1188,7 +1202,7 @@ JS::DescribeStack(JSContext *cx, unsigned maxFrames)
|
||||
FrameDescription desc;
|
||||
desc.script = i.script();
|
||||
desc.lineno = PCToLineNumber(i.script(), i.pc());
|
||||
desc.fun = i.fp()->maybeFun();
|
||||
desc.fun = i.maybeCallee();
|
||||
if (!frames.append(desc))
|
||||
return NULL;
|
||||
if (frames.length() == maxFrames)
|
||||
@ -1261,11 +1275,12 @@ FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
JSScript* script = iter.script();
|
||||
jsbytecode* pc = iter.pc();
|
||||
|
||||
JSAutoCompartment ac(cx, iter.fp()->scopeChain());
|
||||
RootedObject scopeChain(cx, iter.scopeChain());
|
||||
JSAutoCompartment ac(cx, scopeChain);
|
||||
|
||||
const char *filename = script->filename;
|
||||
unsigned lineno = PCToLineNumber(script, pc);
|
||||
JSFunction *fun = iter.fp()->maybeFun();
|
||||
JSFunction *fun = iter.maybeCallee();
|
||||
JSString *funname = NULL;
|
||||
if (fun)
|
||||
funname = fun->atom();
|
||||
@ -1273,16 +1288,16 @@ FormatFrame(JSContext *cx, const ScriptFrameIter &iter, char *buf, int num,
|
||||
JSObject *callObj = NULL;
|
||||
AutoPropertyDescArray callProps(cx);
|
||||
|
||||
if (showArgs || showLocals) {
|
||||
callObj = JS_GetFrameCallObject(cx, Jsvalify(iter.fp()));
|
||||
if (!iter.isIon() && (showArgs || showLocals)) {
|
||||
callObj = JS_GetFrameCallObject(cx, Jsvalify(iter.interpFrame()));
|
||||
if (callObj)
|
||||
callProps.fetch(callObj);
|
||||
}
|
||||
|
||||
Value thisVal = UndefinedValue();
|
||||
AutoPropertyDescArray thisProps(cx);
|
||||
if (ComputeThis(cx, iter.fp())) {
|
||||
thisVal = iter.fp()->thisValue();
|
||||
if (iter.computeThis()) {
|
||||
thisVal = iter.thisv();
|
||||
if (showThisProps && !thisVal.isPrimitive())
|
||||
thisProps.fetch(&thisVal.toObject());
|
||||
}
|
||||
|
@ -138,9 +138,9 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
StackFrame *fp = iter.fp();
|
||||
if (iter.isScript() && iter.isIon())
|
||||
fp = NULL;
|
||||
StackFrame *fp = NULL;
|
||||
if (iter.isScript() && !iter.isIon())
|
||||
fp = iter.interpFrame();
|
||||
|
||||
if (JSID_IS_ATOM(id, cx->names().caller) && fp && fp->prev()) {
|
||||
/*
|
||||
|
@ -80,6 +80,7 @@ ComputeImplicitThis(JSContext *cx, HandleObject obj, Value *vp)
|
||||
inline bool
|
||||
ComputeThis(JSContext *cx, StackFrame *fp)
|
||||
{
|
||||
JS_ASSERT(!fp->runningInIon());
|
||||
Value &thisv = fp->thisValue();
|
||||
if (thisv.isObject())
|
||||
return true;
|
||||
|
@ -4449,12 +4449,12 @@ js::GetMethod(JSContext *cx, HandleObject obj, HandleId id, unsigned getHow, Mut
|
||||
JS_FRIEND_API(bool)
|
||||
js::CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname)
|
||||
{
|
||||
StackFrame *const fp = js_GetTopStackFrame(cx, FRAME_EXPAND_ALL);
|
||||
if (!fp)
|
||||
JSScript *script = cx->stack.currentScript(NULL, ContextStack::ALLOW_CROSS_COMPARTMENT);
|
||||
if (!script)
|
||||
return true;
|
||||
|
||||
/* If neither cx nor the code is strict, then no check is needed. */
|
||||
if (!fp->script()->strictModeCode && !cx->hasStrictOption())
|
||||
if (!script->strictModeCode && !cx->hasStrictOption())
|
||||
return true;
|
||||
|
||||
JSAutoByteString bytes(cx, propname);
|
||||
@ -5468,7 +5468,7 @@ js_DumpStackFrame(JSContext *cx, StackFrame *start)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
while (!i.done() && i.fp() != start)
|
||||
while (!i.done() && !i.isIon() && i.interpFrame() != start)
|
||||
++i;
|
||||
|
||||
if (i.done()) {
|
||||
@ -5479,44 +5479,49 @@ js_DumpStackFrame(JSContext *cx, StackFrame *start)
|
||||
}
|
||||
|
||||
for (; !i.done(); ++i) {
|
||||
StackFrame *const fp = i.fp();
|
||||
if (i.isIon())
|
||||
fprintf(stderr, "IonFrame\n");
|
||||
else
|
||||
fprintf(stderr, "StackFrame at %p\n", (void *) i.interpFrame());
|
||||
|
||||
fprintf(stderr, "StackFrame at %p\n", (void *) fp);
|
||||
if (fp->isFunctionFrame()) {
|
||||
if (i.isFunctionFrame()) {
|
||||
fprintf(stderr, "callee fun: ");
|
||||
dumpValue(ObjectValue(fp->callee()));
|
||||
dumpValue(i.calleev());
|
||||
} else {
|
||||
fprintf(stderr, "global frame, no callee");
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
|
||||
fprintf(stderr, "file %s line %u\n",
|
||||
fp->script()->filename, (unsigned) fp->script()->lineno);
|
||||
i.script()->filename, (unsigned) i.script()->lineno);
|
||||
|
||||
if (jsbytecode *pc = i.pc()) {
|
||||
fprintf(stderr, " pc = %p\n", pc);
|
||||
fprintf(stderr, " current op: %s\n", js_CodeName[*pc]);
|
||||
}
|
||||
MaybeDumpObject("blockChain", fp->maybeBlockChain());
|
||||
MaybeDumpValue("this", fp->thisValue());
|
||||
if (!i.isIon())
|
||||
MaybeDumpObject("blockChain", i.interpFrame()->maybeBlockChain());
|
||||
MaybeDumpValue("this", i.thisv());
|
||||
if (!i.isIon()) {
|
||||
fprintf(stderr, " rval: ");
|
||||
dumpValue(fp->returnValue());
|
||||
dumpValue(i.interpFrame()->returnValue());
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
fprintf(stderr, " flags:");
|
||||
if (fp->isConstructing())
|
||||
if (i.isConstructing())
|
||||
fprintf(stderr, " constructing");
|
||||
if (fp->isDebuggerFrame())
|
||||
if (!i.isIon() && i.interpFrame()->isDebuggerFrame())
|
||||
fprintf(stderr, " debugger");
|
||||
if (fp->isEvalFrame())
|
||||
if (i.isEvalFrame())
|
||||
fprintf(stderr, " eval");
|
||||
if (fp->isYielding())
|
||||
if (!i.isIon() && i.interpFrame()->isYielding())
|
||||
fprintf(stderr, " yielding");
|
||||
if (fp->isGeneratorFrame())
|
||||
if (!i.isIon() && i.interpFrame()->isGeneratorFrame())
|
||||
fprintf(stderr, " generator");
|
||||
fputc('\n', stderr);
|
||||
|
||||
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) fp->scopeChain());
|
||||
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) i.scopeChain());
|
||||
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
@ -5535,7 +5540,8 @@ js_DumpBacktrace(JSContext *cx)
|
||||
const char *filename = JS_GetScriptFilename(cx, i.script());
|
||||
unsigned line = JS_PCToLineNumber(cx, i.script(), i.pc());
|
||||
sprinter.printf("#%d %14p %s:%d (%p @ %d)\n",
|
||||
depth, (i.isIon() ? 0 : i.fp()), filename, line,
|
||||
depth, (i.isIon() ? 0 : i.interpFrame()),
|
||||
filename, line,
|
||||
i.script(), i.pc() - i.script()->code);
|
||||
} else {
|
||||
sprinter.printf("#%d ???\n", depth);
|
||||
|
@ -2572,8 +2572,19 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
|
||||
* - type inference data for the script assuming script->needsArgsObj; and
|
||||
*/
|
||||
for (AllFramesIter i(cx->stack.space()); !i.done(); ++i) {
|
||||
StackFrame *fp = i.fp();
|
||||
if (fp->isFunctionFrame() && !fp->runningInIon() && fp->script() == script) {
|
||||
/*
|
||||
* We cannot reliably create an arguments object for Ion activations of
|
||||
* this script. To maintain the invariant that "script->needsArgsObj
|
||||
* implies fp->hasArgsObj", the Ion bail mechanism will create an
|
||||
* arguments object right after restoring the StackFrame and before
|
||||
* entering the interpreter (in ion::ThunkToInterpreter). This delay is
|
||||
* safe since the engine avoids any observation of a StackFrame when it
|
||||
* beginsIonActivation (see StackIter::interpFrame comment).
|
||||
*/
|
||||
if (i.isIon())
|
||||
continue;
|
||||
StackFrame *fp = i.interpFrame();
|
||||
if (fp->isFunctionFrame() && fp->script() == script) {
|
||||
ArgumentsObject *argsobj = ArgumentsObject::createExpected(cx, fp);
|
||||
if (!argsobj) {
|
||||
/*
|
||||
|
@ -1382,7 +1382,8 @@ TrapHandler(JSContext *cx, JSScript *, jsbytecode *pc, jsval *rval,
|
||||
ScriptFrameIter iter(cx);
|
||||
JS_ASSERT(!iter.done());
|
||||
|
||||
JSStackFrame *caller = Jsvalify(iter.fp());
|
||||
/* Debug-mode currently disables Ion compilation. */
|
||||
JSStackFrame *caller = Jsvalify(iter.interpFrame());
|
||||
JSScript *script = iter.script();
|
||||
|
||||
size_t length;
|
||||
@ -2504,9 +2505,10 @@ EvalInFrame(JSContext *cx, unsigned argc, jsval *vp)
|
||||
|
||||
JS_ASSERT(cx->hasfp());
|
||||
|
||||
/* Debug-mode currently disables Ion compilation. */
|
||||
ScriptFrameIter fi(cx);
|
||||
for (uint32_t i = 0; i < upCount; ++i, ++fi) {
|
||||
if (!fi.fp()->prev())
|
||||
if (!fi.interpFrame()->prev())
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2519,7 +2521,7 @@ EvalInFrame(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (!chars)
|
||||
return false;
|
||||
|
||||
StackFrame *fp = fi.fp();
|
||||
StackFrame *fp = fi.interpFrame();
|
||||
bool ok = !!JS_EvaluateUCInStackFrame(cx, Jsvalify(fp), chars, length,
|
||||
fp->script()->filename,
|
||||
JS_PCToLineNumber(cx, fp->script(),
|
||||
|
@ -25,7 +25,7 @@ using namespace js::gc;
|
||||
static void
|
||||
CopyStackFrameArguments(const StackFrame *fp, HeapValue *dst)
|
||||
{
|
||||
JS_ASSERT(!fp->beginsIonActivation());
|
||||
JS_ASSERT(!fp->runningInIon());
|
||||
|
||||
unsigned numActuals = fp->numActualArgs();
|
||||
unsigned numFormals = fp->callee().nargs;
|
||||
@ -87,7 +87,7 @@ struct CopyStackIterArgs
|
||||
|
||||
void copyArgs(HeapValue *dstBase) const {
|
||||
if (!iter_.isIon()) {
|
||||
CopyStackFrameArguments(iter_.fp(), dstBase);
|
||||
CopyStackFrameArguments(iter_.interpFrame(), dstBase);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ struct CopyStackIterArgs
|
||||
*/
|
||||
void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) {
|
||||
if (!iter_.isIon())
|
||||
ArgumentsObject::MaybeForwardToCallObject(iter_.fp(), obj, data);
|
||||
ArgumentsObject::MaybeForwardToCallObject(iter_.interpFrame(), obj, data);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1762,8 +1762,14 @@ Debugger::getNewestFrame(JSContext *cx, unsigned argc, Value *vp)
|
||||
* Since there may be multiple contexts, use AllFramesIter instead.
|
||||
*/
|
||||
for (AllFramesIter i(cx->stack.space()); !i.done(); ++i) {
|
||||
if (dbg->observesFrame(i.fp()))
|
||||
return dbg->getScriptFrame(cx, i.fp(), vp);
|
||||
/*
|
||||
* Debug-mode currently disables Ion compilation in the compartment of
|
||||
* the debuggee.
|
||||
*/
|
||||
if (i.isIon())
|
||||
continue;
|
||||
if (dbg->observesFrame(i.interpFrame()))
|
||||
return dbg->getScriptFrame(cx, i.interpFrame(), vp);
|
||||
}
|
||||
args.rval().setNull();
|
||||
return true;
|
||||
@ -2113,7 +2119,7 @@ class Debugger::ScriptQuery {
|
||||
*/
|
||||
JS_ASSERT(script->isForEval());
|
||||
|
||||
GlobalObject *global = &fri.fp()->global();
|
||||
GlobalObject *global = &fri.interpFrame()->global();
|
||||
if (!consider(script, global, vector))
|
||||
return false;
|
||||
}
|
||||
|
@ -1834,7 +1834,14 @@ DebugScopes::updateLiveScopes(JSContext *cx)
|
||||
* the flag for us, at exactly the time when execution resumes fp->prev().
|
||||
*/
|
||||
for (AllFramesIter i(cx->runtime->stackSpace); !i.done(); ++i) {
|
||||
StackFrame *fp = i.fp();
|
||||
/*
|
||||
* Debug-mode currently disables Ion compilation in the compartment of
|
||||
* the debuggee.
|
||||
*/
|
||||
if (i.isIon())
|
||||
continue;
|
||||
|
||||
StackFrame *fp = i.interpFrame();
|
||||
if (fp->scopeChain()->compartment() != cx->compartment)
|
||||
continue;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
|
||||
#include "jsopcode.h"
|
||||
|
||||
@ -823,7 +824,13 @@ bool
|
||||
StackSpace::containsSlow(StackFrame *fp)
|
||||
{
|
||||
for (AllFramesIter i(*this); !i.done(); ++i) {
|
||||
if (i.fp() == fp)
|
||||
/*
|
||||
* Debug-mode currently disables Ion compilation in the compartment of
|
||||
* the debuggee.
|
||||
*/
|
||||
if (i.isIon())
|
||||
continue;
|
||||
if (i.interpFrame() == fp)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -863,16 +870,6 @@ ContextStack::onTop() const
|
||||
return seg_ && seg_ == space().seg_;
|
||||
}
|
||||
|
||||
bool
|
||||
ContextStack::containsSlow(const StackFrame *target) const
|
||||
{
|
||||
for (StackSegment *s = seg_; s; s = s->prevInContext()) {
|
||||
if (s->contains(target))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This helper function brings the ContextStack to the top of the thread stack
|
||||
* (so that it can be extended to push a frame and/or arguments) by potentially
|
||||
@ -1055,8 +1052,13 @@ ContextStack::pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thi
|
||||
/* Though the prev-frame is given, need to search for prev-call. */
|
||||
StackSegment &seg = cx->stack.space().containingSegment(evalInFrame);
|
||||
StackIter iter(cx->runtime, seg);
|
||||
while (!iter.isScript() || iter.fp() != evalInFrame)
|
||||
/* Debug-mode currently disables Ion compilation. */
|
||||
JS_ASSERT(!evalInFrame->runningInIon());
|
||||
JS_ASSERT_IF(evalInFrame->compartment() == iter.compartment(), !iter.isIon());
|
||||
while (!iter.isScript() || iter.isIon() || iter.interpFrame() != evalInFrame) {
|
||||
++iter;
|
||||
JS_ASSERT_IF(evalInFrame->compartment() == iter.compartment(), !iter.isIon());
|
||||
}
|
||||
evalInFrameCalls = iter.calls_;
|
||||
extend = CANT_EXTEND;
|
||||
} else {
|
||||
@ -1330,9 +1332,9 @@ StackIter::settleOnNewState()
|
||||
/* Avoid duplicating logic; seg_ contains fp_, so no iloop. */
|
||||
StackIter tmp = *this;
|
||||
tmp.startOnSegment(seg_);
|
||||
while (!tmp.isScript() || tmp.fp() != fp_)
|
||||
while (!tmp.isScript() || tmp.fp_ != fp_)
|
||||
++tmp;
|
||||
JS_ASSERT(tmp.state_ == SCRIPTED && tmp.seg_ == seg_ && tmp.fp_ == fp_);
|
||||
JS_ASSERT(tmp.isScript() && tmp.seg_ == seg_ && tmp.fp_ == fp_);
|
||||
*this = tmp;
|
||||
return;
|
||||
}
|
||||
@ -1521,10 +1523,31 @@ StackIter::operator==(const StackIter &rhs) const
|
||||
return done() == rhs.done() &&
|
||||
(done() ||
|
||||
(isScript() == rhs.isScript() &&
|
||||
((isScript() && fp() == rhs.fp()) ||
|
||||
((isScript() && fp_ == rhs.fp_) ||
|
||||
(!isScript() && nativeArgs().base() == rhs.nativeArgs().base()))));
|
||||
}
|
||||
|
||||
JSCompartment *
|
||||
StackIter::compartment() const
|
||||
{
|
||||
switch (state_) {
|
||||
case DONE:
|
||||
break;
|
||||
case SCRIPTED:
|
||||
return fp_->compartment();
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
return ionActivations_.activation()->compartment();
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case NATIVE:
|
||||
return calls_->callee().compartment();
|
||||
}
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
StackIter::isFunctionFrame() const
|
||||
{
|
||||
@ -1532,7 +1555,7 @@ StackIter::isFunctionFrame() const
|
||||
case DONE:
|
||||
break;
|
||||
case SCRIPTED:
|
||||
return fp()->isFunctionFrame();
|
||||
return interpFrame()->isFunctionFrame();
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
return ionInlineFrames_.isFunctionFrame();
|
||||
@ -1553,7 +1576,7 @@ StackIter::isEvalFrame() const
|
||||
case DONE:
|
||||
break;
|
||||
case SCRIPTED:
|
||||
return fp()->isEvalFrame();
|
||||
return interpFrame()->isEvalFrame();
|
||||
case ION:
|
||||
case NATIVE:
|
||||
return false;
|
||||
@ -1570,7 +1593,7 @@ StackIter::isNonEvalFunctionFrame() const
|
||||
case DONE:
|
||||
break;
|
||||
case SCRIPTED:
|
||||
return fp()->isNonEvalFunctionFrame();
|
||||
return interpFrame()->isNonEvalFunctionFrame();
|
||||
case ION:
|
||||
case NATIVE:
|
||||
return !isEvalFrame() && isFunctionFrame();
|
||||
@ -1584,19 +1607,18 @@ StackIter::isConstructing() const
|
||||
{
|
||||
switch (state_) {
|
||||
case DONE:
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return false;
|
||||
break;
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
return ionInlineFrames_.isConstructing();
|
||||
#else
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return false;
|
||||
break;
|
||||
#endif
|
||||
case SCRIPTED:
|
||||
case NATIVE:
|
||||
return fp()->isConstructing();
|
||||
return fp_->isConstructing();
|
||||
}
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1608,7 +1630,7 @@ StackIter::callee() const
|
||||
break;
|
||||
case SCRIPTED:
|
||||
JS_ASSERT(isFunctionFrame());
|
||||
return &fp()->callee();
|
||||
return &interpFrame()->callee();
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
if (ionFrames_.isScripted())
|
||||
@ -1633,7 +1655,7 @@ StackIter::calleev() const
|
||||
break;
|
||||
case SCRIPTED:
|
||||
JS_ASSERT(isFunctionFrame());
|
||||
return fp()->calleev();
|
||||
return interpFrame()->calleev();
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
return ObjectValue(*callee());
|
||||
@ -1655,7 +1677,7 @@ StackIter::numActualArgs() const
|
||||
break;
|
||||
case SCRIPTED:
|
||||
JS_ASSERT(isFunctionFrame());
|
||||
return fp()->numActualArgs();
|
||||
return interpFrame()->numActualArgs();
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
return ionInlineFrames_.numActualArgs();
|
||||
@ -1669,6 +1691,37 @@ StackIter::numActualArgs() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
StackIter::scopeChain() const
|
||||
{
|
||||
switch (state_) {
|
||||
case DONE:
|
||||
break;
|
||||
case ION:
|
||||
#ifdef JS_ION
|
||||
return ionInlineFrames_.scopeChain();
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case SCRIPTED:
|
||||
return interpFrame()->scopeChain();
|
||||
case NATIVE:
|
||||
break;
|
||||
}
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
StackIter::computeThis() const
|
||||
{
|
||||
if (isScript() && !isIon()) {
|
||||
JS_ASSERT(maybecx_);
|
||||
return ComputeThis(maybecx_, interpFrame());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Value
|
||||
StackIter::thisv() const
|
||||
{
|
||||
@ -1683,7 +1736,7 @@ StackIter::thisv() const
|
||||
#endif
|
||||
case SCRIPTED:
|
||||
case NATIVE:
|
||||
return fp()->thisValue();
|
||||
return fp_->thisValue();
|
||||
}
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return NullValue();
|
||||
@ -1704,8 +1757,8 @@ StackIter::numFrameSlots() const
|
||||
#endif
|
||||
case SCRIPTED:
|
||||
JS_ASSERT(maybecx_);
|
||||
JS_ASSERT(maybecx_->regs().spForStackDepth(0) == fp()->base());
|
||||
return maybecx_->regs().sp - fp()->base();
|
||||
JS_ASSERT(maybecx_->regs().spForStackDepth(0) == interpFrame()->base());
|
||||
return maybecx_->regs().sp - interpFrame()->base();
|
||||
}
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return 0;
|
||||
@ -1729,7 +1782,7 @@ StackIter::frameSlotValue(size_t index) const
|
||||
break;
|
||||
#endif
|
||||
case SCRIPTED:
|
||||
return fp()->base()[index];
|
||||
return interpFrame()->base()[index];
|
||||
}
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return NullValue();
|
||||
|
@ -1443,6 +1443,7 @@ class StackSpace
|
||||
JS_FRIEND_API(size_t) sizeOfCommitted();
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Only used in assertion of debuggers API. */
|
||||
bool containsSlow(StackFrame *fp);
|
||||
#endif
|
||||
};
|
||||
@ -1533,9 +1534,6 @@ class ContextStack
|
||||
/* The StackSpace currently hosting this ContextStack. */
|
||||
StackSpace &space() const { return *space_; }
|
||||
|
||||
/* Return whether the given frame is in this context's stack. */
|
||||
bool containsSlow(const StackFrame *target) const;
|
||||
|
||||
/*** Stack manipulation ***/
|
||||
|
||||
/*
|
||||
@ -1750,6 +1748,8 @@ class StackIter
|
||||
bool operator==(const StackIter &rhs) const;
|
||||
bool operator!=(const StackIter &rhs) const { return !(*this == rhs); }
|
||||
|
||||
JSCompartment *compartment() const;
|
||||
|
||||
bool isScript() const {
|
||||
JS_ASSERT(!done());
|
||||
#ifdef JS_ION
|
||||
@ -1776,15 +1776,30 @@ class StackIter
|
||||
bool isNonEvalFunctionFrame() const;
|
||||
bool isConstructing() const;
|
||||
|
||||
// :TODO: Add && !isIon() in JS_ASSERT of fp() and sp().
|
||||
StackFrame *fp() const { JS_ASSERT(isScript()); return fp_; }
|
||||
/*
|
||||
* 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(isScript() && !isIon()); return fp_; }
|
||||
|
||||
jsbytecode *pc() const { JS_ASSERT(isScript()); return pc_; }
|
||||
JSScript *script() const { JS_ASSERT(isScript()); return script_; }
|
||||
JSFunction *callee() const;
|
||||
Value calleev() const;
|
||||
unsigned numActualArgs() const;
|
||||
|
||||
JSObject *scopeChain() const;
|
||||
|
||||
// Ensure that thisv is correct, see ComputeThis.
|
||||
bool computeThis() const;
|
||||
Value thisv() const;
|
||||
|
||||
JSFunction *maybeCallee() const {
|
||||
return isFunctionFrame() ? callee() : NULL;
|
||||
}
|
||||
|
||||
// These are only valid for the top frame.
|
||||
size_t numFrameSlots() const;
|
||||
Value frameSlotValue(size_t index) const;
|
||||
@ -1839,7 +1854,8 @@ class AllFramesIter
|
||||
bool done() const { return fp_ == NULL; }
|
||||
AllFramesIter& operator++();
|
||||
|
||||
StackFrame *fp() const { return fp_; }
|
||||
bool isIon() const { return fp_->runningInIon(); }
|
||||
StackFrame *interpFrame() const { return fp_; }
|
||||
|
||||
private:
|
||||
void settle();
|
||||
|
Loading…
Reference in New Issue
Block a user