зеркало из https://github.com/mozilla/gecko-dev.git
Restore frame pointer at exception block entry before invoking any trap, bug 658491. r=jorendorff.
This commit is contained in:
Родитель
44cd5a6f2c
Коммит
8f4171c010
|
@ -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 "tests.h"
|
||||||
#include "jsdbgapi.h"
|
#include "jsdbgapi.h"
|
||||||
|
#include "jscntxt.h"
|
||||||
|
|
||||||
static int callCount[2] = {0, 0};
|
static int callCount[2] = {0, 0};
|
||||||
|
|
||||||
|
@ -252,3 +253,42 @@ bool testIndirectEval(JSObject *scope, JSObject *g, const char *code, int expect
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
END_TEST(testDebugger_newScriptHook)
|
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();
|
SPEW_OPCODE();
|
||||||
JS_ASSERT(frame.stackDepth() == opinfo->stackDepth);
|
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) {
|
if (trap) {
|
||||||
prepareStubCall(Uses(0));
|
prepareStubCall(Uses(0));
|
||||||
masm.move(Imm32(trap), Registers::ArgReg1);
|
masm.move(Imm32(trap), Registers::ArgReg1);
|
||||||
|
@ -4831,17 +4842,6 @@ mjit::Compiler::jumpAndTrace(Jump j, jsbytecode *target, Jump *slow)
|
||||||
void
|
void
|
||||||
mjit::Compiler::enterBlock(JSObject *obj)
|
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();
|
uint32 oldFrameDepth = frame.localSlots();
|
||||||
|
|
||||||
/* For now, don't bother doing anything for this opcode. */
|
/* For now, don't bother doing anything for this opcode. */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче