static void EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, ObjOperandId objId) { Maybe<ObjOperandId> expandoId; TestMatchingReceiver(writer, obj, shape, objId, &expandoId); ObjOperandId holderId; if (obj != holder) { GeneratePrototypeGuards(writer, obj, holder, objId); if (holder) { // Guard on the holder's shape. holderId = writer.loadObject(holder); writer.guardShape(holderId, holder->as<NativeObject>().lastProperty()); } else { // The property does not exist. Guard on everything in the prototype // chain. This is guaranteed to see only Native objects because of // CanAttachNativeGetProp(). JSObject* proto = obj->taggedProto().toObjectOrNull(); ObjOperandId lastObjId = objId; while (proto) { ObjOperandId protoId = writer.loadProto(lastObjId); writer.guardShape(protoId, proto->as<NativeObject>().lastProperty()); proto = proto->staticPrototype(); lastObjId = protoId; } } } else if (obj->is<UnboxedPlainObject>()) { holder = obj->as<UnboxedPlainObject>().maybeExpando(); holderId = *expandoId; } else { holderId = objId; } // Slot access. if (holder) { MOZ_ASSERT(holderId.valid()); EmitLoadSlotResult(writer, holderId, &holder->as<NativeObject>(), shape); } else { MOZ_ASSERT(!holderId.valid()); writer.loadUndefinedResult(); } }
static void TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId) { if (obj->is<UnboxedPlainObject>()) { writer.guardGroup(objId, obj->group()); if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando()) { ObjOperandId expandoId = writer.guardAndLoadUnboxedExpando(objId); writer.guardShape(expandoId, expando->lastProperty()); } else { writer.guardNoUnboxedExpando(objId); } } else if (obj->is<UnboxedArrayObject>() || obj->is<TypedObject>()) { writer.guardGroup(objId, obj->group()); } else { Shape* shape = obj->maybeShape(); MOZ_ASSERT(shape); writer.guardShape(objId, shape); } }
static void EmitCallGetterResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, ObjOperandId objId) { Maybe<ObjOperandId> expandoId; TestMatchingReceiver(writer, obj, shape, objId, &expandoId); if (obj != holder) { GeneratePrototypeGuards(writer, obj, holder, objId); // Guard on the holder's shape. ObjOperandId holderId = writer.loadObject(holder); writer.guardShape(holderId, holder->as<NativeObject>().lastProperty()); } EmitCallGetterResultNoGuards(writer, obj, holder, shape, objId); }