Pass scope chain explicitly to FindProperty, bug 717494. r=dvander

This commit is contained in:
Brian Hackett 2012-01-18 17:15:00 -08:00
parent 92dea45444
commit 68e8fc5429
6 changed files with 29 additions and 37 deletions

View File

@ -1277,13 +1277,10 @@ js::AssertValidPropertyCacheHit(JSContext *cx,
JSProperty *prop;
JSBool ok;
if (JOF_OPMODE(*pc) == JOF_NAME) {
bool global = js_CodeSpec[*pc].format & JOF_GNAME;
ok = FindProperty(cx, name, global, &obj, &pobj, &prop);
} else {
obj = start;
ok = LookupProperty(cx, obj, name, &pobj, &prop);
}
if (JOF_OPMODE(*pc) == JOF_NAME)
ok = FindProperty(cx, name, start, &obj, &pobj, &prop);
else
ok = LookupProperty(cx, start, name, &pobj, &prop);
JS_ASSERT(ok);
if (cx->runtime->gcNumber != sample)
@ -2613,7 +2610,7 @@ BEGIN_CASE(JSOP_DELNAME)
LOAD_NAME(0, name);
JSObject *obj, *obj2;
JSProperty *prop;
if (!FindProperty(cx, name, false, &obj, &obj2, &prop))
if (!FindProperty(cx, name, cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
goto error;
/* Strict mode code should never contain JSOP_DELNAME opcodes. */
@ -3092,7 +3089,7 @@ BEGIN_CASE(JSOP_IMPLICITTHIS)
JSObject *obj, *obj2;
JSProperty *prop;
if (!FindPropertyHelper(cx, name, false, false, &obj, &obj2, &prop))
if (!FindPropertyHelper(cx, name, false, cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
goto error;
Value v;

View File

@ -383,8 +383,16 @@ NameOperation(JSContext *cx, jsbytecode *pc, Value *vp)
{
JSObject *obj = cx->stack.currentScriptedScopeChain();
bool global = js_CodeSpec[*pc].format & JOF_GNAME;
if (global)
/*
* Skip along the scope chain to the enclosing global object. This is
* used for GNAME opcodes where the bytecode emitter has determined a
* name access must be on the global. It also insulates us from bugs
* in the emitter: type inference will assume that GNAME opcodes are
* accessing the global object, and the inferred behavior should match
* the actual behavior even if the id could be found on the scope chain
* before the global object.
*/
if (js_CodeSpec[*pc].format & JOF_GNAME)
obj = &obj->global();
PropertyCacheEntry *entry;
@ -401,7 +409,7 @@ NameOperation(JSContext *cx, jsbytecode *pc, Value *vp)
jsid id = ATOM_TO_JSID(name);
JSProperty *prop;
if (!FindPropertyHelper(cx, name, true, global, &obj, &obj2, &prop))
if (!FindPropertyHelper(cx, name, true, obj, &obj, &obj2, &prop))
return false;
if (!prop) {
/* Kludge to allow (typeof foo == "undefined") tests. */

View File

@ -5096,29 +5096,14 @@ js::LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
}
bool
js::FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, bool global,
js::FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, JSObject *scopeChain,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
{
jsid id = ATOM_TO_JSID(name);
JSObject *scopeChain, *obj, *parent, *pobj;
JSObject *obj, *parent, *pobj;
int scopeIndex;
JSProperty *prop;
scopeChain = cx->stack.currentScriptedScopeChain();
if (global) {
/*
* Skip along the scope chain to the enclosing global object. This is
* used for GNAME opcodes where the bytecode emitter has determined a
* name access must be on the global. It also insulates us from bugs
* in the emitter: type inference will assume that GNAME opcodes are
* accessing the global object, and the inferred behavior should match
* the actual behavior even if the id could be found on the scope chain
* before the global object.
*/
scopeChain = &scopeChain->global();
}
/* Scan entries on the scope chain that we can cache across. */
obj = scopeChain;
parent = obj->enclosingScope();
@ -5203,10 +5188,10 @@ js::FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, bool
* Otherwise, its type and meaning depends on the host object's implementation.
*/
bool
js::FindProperty(JSContext *cx, PropertyName *name, bool global,
js::FindProperty(JSContext *cx, PropertyName *name, JSObject *scopeChain,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
{
return !!FindPropertyHelper(cx, name, false, global, objp, pobjp, propp);
return !!FindPropertyHelper(cx, name, false, scopeChain, objp, pobjp, propp);
}
JSObject *

View File

@ -1829,7 +1829,7 @@ static const uintN RESOLVE_INFER = 0xffff;
* If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success.
*/
extern bool
FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, bool global,
FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, JSObject *scopeChain,
JSObject **objp, JSObject **pobjp, JSProperty **propp);
/*
@ -1837,7 +1837,7 @@ FindPropertyHelper(JSContext *cx, PropertyName *name, bool cacheResult, bool glo
* global object, per the global parameter.
*/
extern bool
FindProperty(JSContext *cx, PropertyName *name, bool global,
FindProperty(JSContext *cx, PropertyName *name, JSObject *scopeChain,
JSObject **objp, JSObject **pobjp, JSProperty **propp);
extern JSObject *

View File

@ -743,8 +743,10 @@ struct GetPropHelper {
public:
LookupStatus bind() {
RecompilationMonitor monitor(cx);
bool global = (js_CodeSpec[*f.pc()].format & JOF_GNAME);
if (!FindProperty(cx, name, global, &obj, &holder, &prop))
JSObject *scopeChain = cx->stack.currentScriptedScopeChain();
if (js_CodeSpec[*f.pc()].format & JOF_GNAME)
scopeChain = &scopeChain->global();
if (!FindProperty(cx, name, scopeChain, &obj, &holder, &prop))
return ic.error(cx);
if (monitor.recompiled())
return Lookup_Uncacheable;

View File

@ -297,7 +297,7 @@ stubs::ImplicitThis(VMFrame &f, PropertyName *name)
{
JSObject *obj, *obj2;
JSProperty *prop;
if (!FindPropertyHelper(f.cx, name, false, false, &obj, &obj2, &prop))
if (!FindPropertyHelper(f.cx, name, false, f.cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
THROW();
if (!ComputeImplicitThis(f.cx, obj, &f.regs.sp[0]))
@ -1626,7 +1626,7 @@ stubs::DelName(VMFrame &f, PropertyName *name)
{
JSObject *obj, *obj2;
JSProperty *prop;
if (!FindProperty(f.cx, name, false, &obj, &obj2, &prop))
if (!FindProperty(f.cx, name, f.cx->stack.currentScriptedScopeChain(), &obj, &obj2, &prop))
THROW();
/* Strict mode code should never contain JSOP_DELNAME opcodes. */