Bug 497119 - Don't assume that we have a cx->fp (or that fp is on cx->fp at all). Set up display as it would have been when fp was active, though. r=brendan

--HG--
extra : transplant_source : %05E%E4%F1/K%60%B9%3B%B6%BFq%B1%22i%2A%BD%A4%BC%EE
This commit is contained in:
Blake Kaplan 2009-06-11 14:12:23 -07:00
parent cf9c877b39
commit 7ffb0fe3f9

View File

@ -1272,12 +1272,36 @@ JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
if (cx->fp != fp) {
memcpy(displayCopy, cx->display, sizeof displayCopy);
/* This API requires an active fp on cx, so fp2 can't go null here. */
for (JSStackFrame *fp2 = cx->fp; fp2 != fp; fp2 = fp2->down) {
if (fp2->displaySave) {
JS_ASSERT(fp2->script->staticLevel < JS_DISPLAY_SIZE);
cx->display[fp2->script->staticLevel] = fp2->displaySave;
}
/*
* Set up cx->display as it would have been when fp was active.
*
* NB: To reconstruct cx->display for fp, we have to follow the frame
* chain from oldest to youngest, in the opposite direction to its
* single linkge. To avoid the obvious recursive reversal algorithm,
* which might use too much stack, we reverse in place and reverse
* again as we reconstruct the display. This is safe because cx is
* thread-local and we can't cause GC until the call to js_Execute
* below.
*/
JSStackFrame *fp2 = fp, *last = NULL;
while (fp2) {
JSStackFrame *next = fp2->down;
fp2->down = last;
last = fp2;
fp2 = next;
}
fp2 = last;
last = NULL;
while (fp2) {
JSStackFrame *next = fp2->down;
fp2->down = last;
last = fp2;
JSScript *script = fp2->script;
if (script && script->staticLevel < JS_DISPLAY_SIZE)
cx->display[script->staticLevel] = fp2;
fp2 = next;
}
}