mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 937058 - Paper over debug-mode checks of stack depth for unreachable bytecode. r=jandem
This commit is contained in:
parent
e3b27bcf78
commit
89a820f764
5
js/src/jit-test/tests/basic/bug935294.js
Normal file
5
js/src/jit-test/tests/basic/bug935294.js
Normal file
@ -0,0 +1,5 @@
|
||||
// |jit-test| error: ReferenceError
|
||||
for (var c in foo)
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {}
|
@ -795,8 +795,8 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
|
||||
BaselineScript *baselineScript = script->baselineScript();
|
||||
|
||||
#ifdef DEBUG
|
||||
uint32_t expectedDepth = js_ReconstructStackDepth(cx, script,
|
||||
resumeAfter ? GetNextPc(pc) : pc);
|
||||
uint32_t expectedDepth;
|
||||
if (ReconstructStackDepth(cx, script, resumeAfter ? GetNextPc(pc) : pc, &expectedDepth)) {
|
||||
if (op != JSOP_FUNAPPLY || !iter.moreFrames() || resumeAfter) {
|
||||
if (op == JSOP_FUNCALL) {
|
||||
// For fun.call(this, ...); the reconstructStackDepth will
|
||||
@ -821,6 +821,7 @@ InitFromBailout(JSContext *cx, HandleScript caller, jsbytecode *callerPC,
|
||||
JS_ASSERT(exprStackSlots == expectedDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IonSpew(IonSpew_BaselineBailouts, " Resuming %s pc offset %d (op %s) (line %d) of %s:%d",
|
||||
resumeAfter ? "after" : "at", (int) pcOff, js_CodeName[op],
|
||||
|
@ -279,7 +279,8 @@ CodeGeneratorShared::encode(LSnapshot *snapshot)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (GetIonContext()->cx) {
|
||||
uint32_t stackDepth = js_ReconstructStackDepth(GetIonContext()->cx, script, bailPC);
|
||||
uint32_t stackDepth;
|
||||
if (ReconstructStackDepth(GetIonContext()->cx, script, bailPC, &stackDepth)) {
|
||||
if (JSOp(*bailPC) == JSOP_FUNCALL) {
|
||||
// For fun.call(this, ...); the reconstructStackDepth will
|
||||
// include the this. When inlining that is not included.
|
||||
@ -293,13 +294,15 @@ CodeGeneratorShared::encode(LSnapshot *snapshot)
|
||||
// funapply. In that case exprStackSlots, will have the real
|
||||
// arguments in the slots and not be 4.
|
||||
|
||||
// With accessors, we have different stack depths depending on whether or not we
|
||||
// inlined the accessor, as the inlined stack contains a callee function that should
|
||||
// never have been there and we might just be capturing an uneventful property site,
|
||||
// in which case there won't have been any violence.
|
||||
// With accessors, we have different stack depths depending on
|
||||
// whether or not we inlined the accessor, as the inlined stack
|
||||
// contains a callee function that should never have been there
|
||||
// and we might just be capturing an uneventful property site, in
|
||||
// which case there won't have been any violence.
|
||||
JS_ASSERT(exprStack == stackDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TRACK_SNAPSHOTS
|
||||
|
@ -402,12 +402,16 @@ class BytecodeParser
|
||||
|
||||
bool parse();
|
||||
|
||||
#ifdef DEBUG
|
||||
bool isReachable(uint32_t offset) { return maybeCode(offset); }
|
||||
bool isReachable(const jsbytecode *pc) { return maybeCode(pc); }
|
||||
#endif
|
||||
|
||||
uint32_t stackDepthAtPC(uint32_t offset) {
|
||||
// Sometimes the code generator in debug mode asks about the stack depth
|
||||
// of unreachable code (bug 932180 comment 22). Assume that unreachable
|
||||
// code has no operands on the stack.
|
||||
Bytecode *code = maybeCode(offset);
|
||||
return code ? code->stackDepth : 0;
|
||||
return getCode(offset).stackDepth;
|
||||
}
|
||||
uint32_t stackDepthAtPC(const jsbytecode *pc) { return stackDepthAtPC(pc - script_->code); }
|
||||
|
||||
@ -697,6 +701,21 @@ BytecodeParser::parse()
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
bool
|
||||
js::ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc, uint32_t *depth)
|
||||
{
|
||||
BytecodeParser parser(cx, script);
|
||||
if (!parser.parse())
|
||||
return false;
|
||||
|
||||
if (!parser.isReachable(pc))
|
||||
return false;
|
||||
|
||||
*depth = parser.stackDepthAtPC(pc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* If pc != nullptr, include a prefix indicating whether the PC is at the
|
||||
* current line. If showAll is true, include the source note type and the
|
||||
@ -707,10 +726,14 @@ js_DisassembleAtPC(JSContext *cx, JSScript *scriptArg, bool lines,
|
||||
jsbytecode *pc, bool showAll, Sprinter *sp)
|
||||
{
|
||||
RootedScript script(cx, scriptArg);
|
||||
BytecodeParser parser(cx, script);
|
||||
|
||||
jsbytecode *next, *end;
|
||||
unsigned len;
|
||||
|
||||
if (showAll && !parser.parse())
|
||||
return false;
|
||||
|
||||
if (showAll)
|
||||
Sprint(sp, "%s:%u\n", script->filename(), script->lineno);
|
||||
|
||||
@ -757,10 +780,10 @@ js_DisassembleAtPC(JSContext *cx, JSScript *scriptArg, bool lines,
|
||||
}
|
||||
else
|
||||
sp->put(" ");
|
||||
if (script->hasAnalysis() && script->analysis()->maybeCode(next))
|
||||
Sprint(sp, "%05u ", script->analysis()->getCode(next).stackDepth);
|
||||
if (parser.isReachable(next))
|
||||
Sprint(sp, "%05u ", parser.stackDepthAtPC(next));
|
||||
else
|
||||
sp->put(" ");
|
||||
Sprint(sp, " ", parser.stackDepthAtPC(next));
|
||||
}
|
||||
len = js_Disassemble1(cx, script, next, next - script->code, lines, sp);
|
||||
if (!len)
|
||||
@ -1985,16 +2008,6 @@ js::DecompileArgument(JSContext *cx, int formalIndex, HandleValue v)
|
||||
return LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str();
|
||||
}
|
||||
|
||||
unsigned
|
||||
js_ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
BytecodeParser parser(cx, script);
|
||||
if (!parser.parse())
|
||||
return 0;
|
||||
return parser.stackDepthAtPC(pc);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
js::CallResultEscapes(jsbytecode *pc)
|
||||
{
|
||||
|
@ -351,14 +351,17 @@ StackUses(JSScript *script, jsbytecode *pc);
|
||||
extern unsigned
|
||||
StackDefs(JSScript *script, jsbytecode *pc);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Given bytecode address pc in script's main program code, return the operand
|
||||
* stack depth just before (JSOp) *pc executes.
|
||||
* Given bytecode address pc in script's main program code, compute the operand
|
||||
* stack depth just before (JSOp) *pc executes. If *pc is not reachable, return
|
||||
* false.
|
||||
*/
|
||||
extern unsigned
|
||||
js_ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc);
|
||||
extern bool
|
||||
ReconstructStackDepth(JSContext *cx, JSScript *script, jsbytecode *pc, uint32_t *depth);
|
||||
#endif
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
|
Loading…
Reference in New Issue
Block a user