Bug 637385 - Don't try to trace through a bindname in strict mode eval code. r=dvander, a=dmandelin

This commit is contained in:
Jeff Walden 2011-03-01 09:59:37 -08:00
parent 37cc2cd994
commit ed564f147e
2 changed files with 22 additions and 11 deletions

View File

@ -0,0 +1,3 @@
'use strict';
eval("var i = 0; var end = RUNLOOP; for(var j = 0; j < end; i++, j++) { i = 0; }");
print("done");

View File

@ -15269,8 +15269,10 @@ TraceRecorder::record_JSOP_BINDNAME()
JSStackFrame *fp2 = fp; JSStackFrame *fp2 = fp;
#endif #endif
// In global code, fp->scopeChain can only contain blocks whose values /*
// are still on the stack. We never use BINDNAME to refer to these. * In global code, fp->scopeChain can only contain blocks whose values
* are still on the stack. We never use BINDNAME to refer to these.
*/
while (obj->isBlock()) { while (obj->isBlock()) {
// The block's values are still on the stack. // The block's values are still on the stack.
#ifdef DEBUG #ifdef DEBUG
@ -15287,17 +15289,23 @@ TraceRecorder::record_JSOP_BINDNAME()
JS_ASSERT(obj); JS_ASSERT(obj);
} }
// If anything other than Block, Call, DeclEnv, and the global object /*
// is on the scope chain, we shouldn't be recording. Of those, only * If this is a strict mode eval frame, we will have a Call object for
// Block and global can be present in global code. * it. For now just don't trace this case.
JS_ASSERT(obj == globalObj); */
if (obj != globalObj) {
JS_ASSERT(obj->isCall());
JS_ASSERT(obj->callIsForEval());
RETURN_STOP_A("BINDNAME within strict eval code");
}
/* /*
* The trace is specialized to this global object. Furthermore, we know it * The trace is specialized to this global object. Furthermore, we know
* is the sole 'global' object on the scope chain: we set globalObj to the * it is the sole 'global' object on the scope chain: we set globalObj
* scope chain element with no parent, and we reached it starting from the * to the scope chain element with no parent, and we reached it
* function closure or the current scopeChain, so there is nothing inner to * starting from the function closure or the current scopeChain, so
* it. Therefore this must be the right base object. * there is nothing inner to it. Therefore this must be the right base
* object.
*/ */
stack(0, w.immpObjGC(obj)); stack(0, w.immpObjGC(obj));
return ARECORD_CONTINUE; return ARECORD_CONTINUE;