Bug 624110 - Properly traverse the scope chain over strict eval frames in the tracer. r=brendan

This commit is contained in:
Jeff Walden 2011-01-10 13:09:07 -06:00
parent 882117c5e3
commit 50cccbcec6
2 changed files with 13 additions and 7 deletions

View File

@ -0,0 +1,3 @@
var COUNT = RUNLOOP;
eval("'use strict'; for (let j = 0; j < COUNT; j++); try { x; throw new Error(); } catch (e) { if (!(e instanceof ReferenceError)) throw e; }");
assertEq(typeof j, "undefined");

View File

@ -14978,6 +14978,13 @@ TraceRecorder::record_JSOP_POPN()
return ARECORD_CONTINUE; return ARECORD_CONTINUE;
} }
static inline bool
IsFindableCallObj(JSObject *obj)
{
return obj->isCall() &&
(obj->callIsForEval() || obj->getCallObjCalleeFunction()->isHeavyweight());
}
/* /*
* Generate LIR to reach |obj2| from |obj| by traversing the scope chain. The * Generate LIR to reach |obj2| from |obj| by traversing the scope chain. The
* generated code also ensures that any call objects found have not changed shape. * generated code also ensures that any call objects found have not changed shape.
@ -15019,13 +15026,10 @@ TraceRecorder::traverseScopeChain(JSObject *obj, LIns *obj_ins, JSObject *target
for (;;) { for (;;) {
if (searchObj != globalObj) { if (searchObj != globalObj) {
Class* clasp = searchObj->getClass(); if (searchObj->isBlock())
if (clasp == &js_BlockClass) {
foundBlockObj = true; foundBlockObj = true;
} else if (clasp == &js_CallClass && else if (IsFindableCallObj(searchObj))
searchObj->getCallObjCalleeFunction()->isHeavyweight()) {
foundCallObj = true; foundCallObj = true;
}
} }
if (searchObj == targetObj) if (searchObj == targetObj)
@ -15054,8 +15058,7 @@ TraceRecorder::traverseScopeChain(JSObject *obj, LIns *obj_ins, JSObject *target
// We must guard on the shape of all call objects for heavyweight functions // We must guard on the shape of all call objects for heavyweight functions
// that we traverse on the scope chain: if the shape changes, a variable with // that we traverse on the scope chain: if the shape changes, a variable with
// the same name may have been inserted in the scope chain. // the same name may have been inserted in the scope chain.
if (obj->isCall() && if (IsFindableCallObj(obj)) {
obj->getCallObjCalleeFunction()->isHeavyweight()) {
if (!exit) if (!exit)
exit = snapshot(BRANCH_EXIT); exit = snapshot(BRANCH_EXIT);
guard(true, guard(true,