Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Bug 666094 - initCallFrameLatePrologue should ensureSlots (r=dvander,…

…a=clegnitto)
  • Loading branch information...
commit cef74a51ea275ef21305636e4bb0fd5ff7dec84a 1 parent 987eec8
Luke Wagner authored
View
2  js/src/methodjit/InvokeHelpers.cpp
@@ -309,7 +309,7 @@ stubs::CompileFunction(VMFrame &f, uint32 nactual)
}
/* Finish frame initialization. */
- fp->initCallFrameLatePrologue();
+ fp->initCallFrameLatePrologue(cx, f.entryfp, &f.stackLimit);
/* These would have been initialized by the prologue. */
f.regs.prepareToRun(fp, script);
View
2  js/src/methodjit/MonoIC.cpp
@@ -656,7 +656,7 @@ class CallCompiler : public BaseCompiler
void *compilePtr = JS_FUNC_TO_DATA_PTR(void *, stubs::CompileFunction);
if (ic.frameSize.isStatic()) {
masm.move(Imm32(ic.frameSize.staticArgc()), Registers::ArgReg1);
- masm.fallibleVMCall(compilePtr, script->code, ic.frameSize.staticLocalSlots());
+ masm.fallibleVMCall(compilePtr, script->code, 0 /* sp not used */);
} else {
masm.load32(FrameAddress(offsetof(VMFrame, u.call.dynamicArgc)), Registers::ArgReg1);
masm.fallibleVMCall(compilePtr, script->code, -1);
View
31 js/src/vm/Stack-inl.h
@@ -379,8 +379,8 @@ StackFrame::initCallFrameCallerHalf(JSContext *cx, uint32 flagsArg,
}
/*
- * The "early prologue" refers to the members that are stored for the benefit
- * of slow paths before initializing the rest of the members.
+ * The "early prologue" refers to either the fast path or arity check path up
+ * to the "late prologue".
*/
inline void
StackFrame::initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual)
@@ -391,13 +391,25 @@ StackFrame::initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual)
}
/*
- * The "late prologue" refers to the members that are stored after having
- * checked for stack overflow and formal/actual arg mismatch.
+ * The "late prologue" (in generatePrologue) extends from the join point of the
+ * fast path and arity check to where the call object is (possibly) created.
*/
-inline void
-StackFrame::initCallFrameLatePrologue()
+inline bool
+StackFrame::initCallFrameLatePrologue(JSContext *cx, StackFrame *fp, Value **limit)
{
+ uintN nvals = script()->nslots + VALUES_PER_STACK_FRAME;
+ Value *required = (Value *)this + nvals;
+ if (required >= *limit) {
+ ContextStack &stack = cx->stack;
+ if (!stack.space().bumpLimit(NULL, fp, slots(), nvals, limit)) {
+ stack.popFrameAfterOverflow();
+ js_ReportOverRecursed(cx);
+ return false;
+ }
+ }
+
SetValueRangeToUndefined(slots(), script()->nfixed);
+ return true;
}
inline void
@@ -928,6 +940,13 @@ ContextStack::popInlineFrame()
regs_->popFrame(newsp);
}
+inline void
+ContextStack::popFrameAfterOverflow()
+{
+ /* Restore the regs to what they were on entry to JSOP_CALL. */
+ regs_->popFrame(regs_->fp()->actualArgsEnd());
+}
+
JS_ALWAYS_INLINE bool
ContextStack::pushInvokeArgs(JSContext *cx, uintN argc, InvokeArgsGuard *argsGuard)
{
View
5 js/src/vm/Stack.h
@@ -305,7 +305,7 @@ class StackFrame
/* Called by method-jit stubs and serve as a specification for jit-code. */
inline void initCallFrameCallerHalf(JSContext *cx, uint32 flags, void *ncode);
inline void initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual);
- inline void initCallFrameLatePrologue();
+ bool initCallFrameLatePrologue(JSContext *cx, StackFrame *fp, Value **limit);
/* Used for eval. */
inline void initEvalFrame(JSContext *cx, JSScript *script, StackFrame *prev,
@@ -1326,6 +1326,9 @@ class ContextStack
inline void pushInlineFrame(JSScript *script, StackFrame *fp, FrameRegs &regs);
inline void popInlineFrame();
+ /* Pop a partially-pushed frame after hitting the limit before throwing. */
+ void popFrameAfterOverflow();
+
/* For jit use: */
static size_t offsetOfRegs() { return offsetof(ContextStack, regs_); }
};
Please sign in to comment.
Something went wrong with that request. Please try again.