Trace reading undefined properties (478512, r=brendan).

This commit is contained in:
Andreas Gal 2009-02-19 19:41:03 -08:00
parent 6b0cb834e9
commit 8910526fc2

View File

@ -5632,7 +5632,7 @@ TraceRecorder::test_property_cache(JSObject* obj, LIns* obj_ins, JSObject*& obj2
// Use PCVAL_NULL to return "no such property" to our caller.
pcval = PCVAL_NULL;
ABORT_TRACE("failed to find property");
return true;
}
OBJ_DROP_PROPERTY(cx, obj2, prop);
@ -7334,11 +7334,13 @@ TraceRecorder::record_JSOP_CALLNAME()
LIns* obj_ins = scopeChain();
JSObject* obj2;
jsuword pcval;
if (!test_property_cache(obj, obj_ins, obj2, pcval))
return false;
if (PCVAL_IS_NULL(pcval) || !PCVAL_IS_OBJECT(pcval))
ABORT_TRACE("callee is not an object");
JS_ASSERT(HAS_FUNCTION_CLASS(PCVAL_TO_OBJECT(pcval)));
stack(0, INS_CONSTPTR(PCVAL_TO_OBJECT(pcval)));
@ -7617,7 +7619,7 @@ TraceRecorder::name(jsval*& vp)
return false;
if (slot == SPROP_INVALID_SLOT)
ABORT_TRACE("name op can't find named property");
ABORT_TRACE("named property not found");
if (!lazilyImportGlobalSlot(slot))
ABORT_TRACE("lazy import of global slot failed");
@ -7649,6 +7651,25 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32& slot, LIns*& v_ins)
/* Check for non-existent property reference, which results in undefined. */
const JSCodeSpec& cs = js_CodeSpec[*cx->fp->regs->pc];
if (PCVAL_IS_NULL(pcval)) {
/*
* This trace will be valid as long as neither the object nor any object
* on its prototype chain change shape.
*/
while ((obj2 = JSVAL_TO_OBJECT(obj->fslots[JSSLOT_PROTO])) = NULL) {
LIns* obj2_ins = stobj_get_fslot(obj_ins, JSSLOT_PROTO);
LIns* map_ins = lir->insLoad(LIR_ldp, obj2_ins, (int)offsetof(JSObject, map));
LIns* ops_ins;
if (!map_is_native(obj2->map, map_ins, ops_ins))
ABORT_TRACE("non-native object along prototype chain");
LIns* shape_ins = addName(lir->insLoad(LIR_ld, map_ins, offsetof(JSScope, shape)),
"shape");
guard(true,
addName(lir->ins2i(LIR_eq, shape_ins, OBJ_SHAPE(obj2)), "guard(shape)"),
BRANCH_EXIT);
obj = obj2;
obj_ins = obj2_ins;
}
v_ins = INS_CONST(JSVAL_TO_PSEUDO_BOOLEAN(JSVAL_VOID));
JS_ASSERT(cs.ndefs == 1);
stack(-cs.nuses, v_ins);
@ -8187,6 +8208,10 @@ TraceRecorder::record_JSOP_BINDNAME()
jsuword pcval;
if (!test_property_cache(obj, obj_ins, obj2, pcval))
return false;
if (PCVAL_IS_NULL(pcval))
ABORT_TRACE("JSOP_BINDNAME is trying to add a new property");
if (obj2 != obj)
ABORT_TRACE("JSOP_BINDNAME found a non-direct property on the global object");