Restore frame pointer at exception block entry before invoking any trap, bug 658491. r=jorendorff.

This commit is contained in:
Brian Hackett 2011-08-23 14:43:26 -05:00
Родитель 4770acfea4
Коммит a8529294dd
3 изменённых файлов: 59 добавлений и 11 удалений

Просмотреть файл

@ -0,0 +1,8 @@
// |jit-test| debug
// bug 658491
function f7() {
try { y = w; } catch(y) {}
}
trap(f7, 14, '')
f7()

Просмотреть файл

@ -4,6 +4,7 @@
#include "tests.h"
#include "jsdbgapi.h"
#include "jscntxt.h"
static int callCount[2] = {0, 0};
@ -252,3 +253,42 @@ bool testIndirectEval(JSObject *scope, JSObject *g, const char *code, int expect
return true;
}
END_TEST(testDebugger_newScriptHook)
BEGIN_TEST(testDebugger_singleStepThrow)
{
CHECK(JS_SetDebugModeForCompartment(cx, cx->compartment, true));
CHECK(JS_SetInterrupt(rt, onStep, NULL));
uint32 opts = JS_GetOptions(cx);
opts |= JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS;
opts &= ~JSOPTION_JIT;
JS_SetOptions(cx, opts);
CHECK(JS_DefineFunction(cx, global, "setStepMode", setStepMode, 0, 0));
EXEC("var e;\n"
"setStepMode();\n"
"function f() { throw 0; }\n"
"try { f(); }\n"
"catch (x) { e = x; }\n");
return true;
}
static JSBool
setStepMode(JSContext *cx, uintN argc, jsval *vp)
{
JSStackFrame *fp = JS_GetScriptedCaller(cx, NULL);
JS_ASSERT(fp);
JSScript *script = JS_GetFrameScript(cx, fp);
JS_ASSERT(script);
if (!JS_SetSingleStepMode(cx, script, true))
return false;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
}
static JSTrapStatus
onStep(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *closure)
{
return JSTRAP_CONTINUE;
}
END_TEST(testDebugger_singleStepThrow)

Просмотреть файл

@ -942,6 +942,17 @@ mjit::Compiler::generateMethod()
SPEW_OPCODE();
JS_ASSERT(frame.stackDepth() == opinfo->stackDepth);
// If this is an exception entry point, then jsl_InternalThrow has set
// VMFrame::fp to the correct fp for the entry point. We need to copy
// that value here to FpReg so that FpReg also has the correct sp.
// Otherwise, we would simply be using a stale FpReg value.
// Additionally, we check the interrupt flag to allow interrupting
// deeply nested exception handling.
if (op == JSOP_ENTERBLOCK && analysis->getCode(PC).exceptionEntry) {
restoreFrameRegs(masm);
interruptCheckHelper();
}
if (trap) {
prepareStubCall(Uses(0));
masm.move(Imm32(trap), Registers::ArgReg1);
@ -4831,17 +4842,6 @@ mjit::Compiler::jumpAndTrace(Jump j, jsbytecode *target, Jump *slow)
void
mjit::Compiler::enterBlock(JSObject *obj)
{
// If this is an exception entry point, then jsl_InternalThrow has set
// VMFrame::fp to the correct fp for the entry point. We need to copy
// that value here to FpReg so that FpReg also has the correct sp.
// Otherwise, we would simply be using a stale FpReg value.
// Additionally, we check the interrupt flag to allow interrupting
// deeply nested exception handling.
if (analysis->getCode(PC).exceptionEntry) {
restoreFrameRegs(masm);
interruptCheckHelper();
}
uint32 oldFrameDepth = frame.localSlots();
/* For now, don't bother doing anything for this opcode. */