зеркало из https://github.com/mozilla/pjs.git
Bug 589318 - guard that eval-in-function frames don't access args (r=brendan)
This commit is contained in:
Родитель
ec2daad82d
Коммит
53bd429318
|
@ -293,7 +293,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
|||
stackDepth = 0;
|
||||
valueCount = 0;
|
||||
for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) {
|
||||
if (fp->hasFunction() && fp->argv) {
|
||||
if (fp->hasFunction() && fp->argv && !fp->isEvalFrame()) {
|
||||
Value v = NullValue();
|
||||
if (checkAccess &&
|
||||
!checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) {
|
||||
|
@ -334,7 +334,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
|||
values = GetStackTraceValueBuffer(priv);
|
||||
elem = priv->stackElems;
|
||||
for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->down) {
|
||||
if (!fp->hasFunction()) {
|
||||
if (!fp->hasFunction() || fp->isEvalFrame()) {
|
||||
elem->funName = NULL;
|
||||
elem->argc = 0;
|
||||
} else {
|
||||
|
|
|
@ -813,12 +813,13 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
JSObject *initialVarObj;
|
||||
if (down) {
|
||||
/* Propagate arg state for eval and the debugger API. */
|
||||
JS_ASSERT_IF(down->hasFunction(), down->hasCallObj());
|
||||
fp->setCallObj(down->maybeCallObj());
|
||||
fp->setArgsObj(NULL);
|
||||
fp->setFunction((script->staticLevel > 0) ? down->maybeFunction() : NULL);
|
||||
fp->setThisValue(down->getThisValue());
|
||||
fp->flags = flags | (down->flags & JSFRAME_COMPUTED_THIS);
|
||||
fp->setNumActualArgs(down->numActualArgs());
|
||||
fp->setNumActualArgs(0);
|
||||
fp->argv = down->argv;
|
||||
fp->setAnnotation(down->maybeAnnotation());
|
||||
fp->setScopeChain(chain);
|
||||
|
|
|
@ -160,6 +160,7 @@ struct JSStackFrame
|
|||
|
||||
JSObject* getArgsObj() const {
|
||||
JS_ASSERT(hasArgsObj());
|
||||
JS_ASSERT(!isEvalFrame());
|
||||
return argsobj;
|
||||
}
|
||||
|
||||
|
@ -384,6 +385,7 @@ struct JSStackFrame
|
|||
}
|
||||
|
||||
size_t numFormalArgs() const {
|
||||
JS_ASSERT(!isEvalFrame());
|
||||
return getFunction()->nargs;
|
||||
}
|
||||
|
||||
|
@ -426,6 +428,7 @@ struct JSStackFrame
|
|||
/* Argument count accessors */
|
||||
|
||||
size_t numActualArgs() const {
|
||||
JS_ASSERT(!isEvalFrame());
|
||||
return argc;
|
||||
}
|
||||
|
||||
|
@ -499,6 +502,7 @@ struct JSStackFrame
|
|||
}
|
||||
|
||||
bool isDummyFrame() const { return !!(flags & JSFRAME_DUMMY); }
|
||||
bool isEvalFrame() const { return !!(flags & JSFRAME_EVAL); }
|
||||
|
||||
/* Contains static assertions for member alignment, don't call. */
|
||||
inline void staticAsserts();
|
||||
|
|
|
@ -1092,7 +1092,13 @@ Tracker::set(const void* v, LIns* i)
|
|||
static inline jsuint
|
||||
argSlots(JSStackFrame* fp)
|
||||
{
|
||||
return JS_MAX(fp->numActualArgs(), fp->numFormalArgs());
|
||||
return fp->isEvalFrame() ? 0 : JS_MAX(fp->numActualArgs(), fp->numFormalArgs());
|
||||
}
|
||||
|
||||
static inline jsuint
|
||||
numEntryFrameArgs(JSStackFrame* fp)
|
||||
{
|
||||
return fp->isEvalFrame() ? 0 : fp->numActualArgs();
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -6102,7 +6108,7 @@ AttemptToExtendTree(JSContext* cx, VMSideExit* anchor, VMSideExit* exitedFrom, j
|
|||
}
|
||||
JS_ASSERT(ngslots >= anchor->numGlobalSlots);
|
||||
bool rv = TraceRecorder::startRecorder(cx, anchor, c, stackSlots, ngslots, typeMap,
|
||||
exitedFrom, outer, cx->fp->numActualArgs(),
|
||||
exitedFrom, outer, numEntryFrameArgs(cx->fp),
|
||||
Record_Branch, hits < maxHits);
|
||||
#ifdef MOZ_TRACEVIS
|
||||
if (!rv && tvso)
|
||||
|
@ -6151,7 +6157,7 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall
|
|||
JS_ASSERT(r->fragment && !r->fragment->lastIns);
|
||||
TreeFragment* root = r->fragment->root;
|
||||
TreeFragment* first = LookupOrAddLoop(tm, cx->regs->pc, root->globalObj,
|
||||
root->globalShape, cx->fp->numActualArgs());
|
||||
root->globalShape, numEntryFrameArgs(cx->fp));
|
||||
|
||||
/*
|
||||
* Make sure the shape of the global object still matches (this might flush
|
||||
|
@ -6179,7 +6185,7 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall
|
|||
TreeFragment* outerFragment = root;
|
||||
jsbytecode* outer = (jsbytecode*) outerFragment->ip;
|
||||
uint32 outerArgc = outerFragment->argc;
|
||||
JS_ASSERT(cx->fp->numActualArgs() == first->argc);
|
||||
JS_ASSERT(numEntryFrameArgs(cx->fp) == first->argc);
|
||||
AbortRecording(cx, "No compatible inner tree");
|
||||
|
||||
return RecordingIfTrue(RecordTree(cx, first, outer, outerArgc, globalSlots, Record_Branch));
|
||||
|
@ -7191,7 +7197,7 @@ MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount, RecordReason reason)
|
|||
}
|
||||
|
||||
jsbytecode* pc = cx->regs->pc;
|
||||
uint32 argc = cx->fp->numActualArgs();
|
||||
uint32 argc = numEntryFrameArgs(cx->fp);
|
||||
|
||||
TreeFragment* f = LookupOrAddLoop(tm, pc, globalObj, globalShape, argc);
|
||||
|
||||
|
@ -8230,19 +8236,16 @@ TraceRecorder::callProp(JSObject* obj, JSProperty* prop, jsid id, Value*& vp,
|
|||
uintN slot = uint16(sprop->shortid);
|
||||
|
||||
vp = NULL;
|
||||
uintN upvar_slot = SPROP_INVALID_SLOT;
|
||||
JSStackFrame* cfp = (JSStackFrame*) obj->getPrivate();
|
||||
if (cfp) {
|
||||
if (sprop->getterOp() == js_GetCallArg) {
|
||||
JS_ASSERT(slot < cfp->numFormalArgs());
|
||||
vp = &cfp->argv[slot];
|
||||
upvar_slot = slot;
|
||||
nr.v = *vp;
|
||||
} else if (sprop->getterOp() == js_GetCallVar ||
|
||||
sprop->getterOp() == js_GetCallVarChecked) {
|
||||
JS_ASSERT(slot < cfp->getSlotCount());
|
||||
vp = &cfp->slots()[slot];
|
||||
upvar_slot = cx->fp->numFormalArgs() + slot;
|
||||
nr.v = *vp;
|
||||
} else {
|
||||
RETURN_STOP("dynamic property of Call object");
|
||||
|
|
Загрузка…
Ссылка в новой задаче