From 3bb947b0d4e6b93e364ab788ea789047405ac3b7 Mon Sep 17 00:00:00 2001 From: jimb Date: Tue, 21 Apr 2009 22:42:43 -0700 Subject: [PATCH] Bug 469237: Only trace where BINDNAME will choose the global object. --- js/src/jstracer.cpp | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 4f88d03e20..b12d57bbc3 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -8925,23 +8925,46 @@ TraceRecorder::record_JSOP_POPN() JS_REQUIRES_STACK bool TraceRecorder::record_JSOP_BINDNAME() { - JSObject* obj = cx->fp->scopeChain; - if (obj != globalObj) - ABORT_TRACE("JSOP_BINDNAME crosses global scopes"); + JSStackFrame *fp = cx->fp; + JSObject *scope; + + if (fp->fun) { + // We can't trace BINDNAME in functions that contain direct + // calls to eval, as they might add bindings which + // previously-traced references would have to see. + if (JSFUN_HEAVYWEIGHT_TEST(fp->fun->flags)) + ABORT_TRACE("Can't trace JSOP_BINDNAME in heavyweight functions."); + + // In non-heavyweight functions, we can safely skip the call + // object, if any. + scope = OBJ_GET_PARENT(cx, FUN_OBJECT(fp->fun)); + } else { + scope = fp->scopeChain; - LIns* obj_ins = scopeChain(); - JSObject* obj2; - jsuword pcval; - if (!test_property_cache(obj, obj_ins, obj2, pcval)) - return false; + // 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_GET_CLASS(cx, scope) == &js_BlockClass) { + // The block's values are still on the stack. + JS_ASSERT(OBJ_GET_PRIVATE(cx, scope) == fp); - if (PCVAL_IS_NULL(pcval)) - ABORT_TRACE("JSOP_BINDNAME is trying to add a new property"); + scope = OBJ_GET_PARENT(cx, scope); - if (obj2 != obj) - ABORT_TRACE("JSOP_BINDNAME found a non-direct property on the global object"); + // Blocks always have parents. + JS_ASSERT(scope); + } + } + + if (scope != globalObj) + ABORT_TRACE("JSOP_BINDNAME must return global object on trace"); - stack(0, obj_ins); + // The trace is specialized to this global object. Furthermore, + // we know it is the sole 'global' object on the scope chain: we + // set globalObj to the scope chain element with no parent, and we + // reached it starting from the function closure or the current + // scopeChain, so there is nothing inner to it. So this must be + // the right base object. + stack(0, INS_CONSTPTR(globalObj)); return true; } -- 2.11.4.GIT