static void GeneratePrototypeGuards(CacheIRWriter& writer, JSObject* obj, JSObject* holder, ObjOperandId objId) { // The guards here protect against the effects of JSObject::swap(). If the // prototype chain is directly altered, then TI will toss the jitcode, so we // don't have to worry about it, and any other change to the holder, or // adding a shadowing property will result in reshaping the holder, and thus // the failure of the shape guard. MOZ_ASSERT(obj != holder); if (obj->hasUncacheableProto()) { // If the shape does not imply the proto, emit an explicit proto guard. writer.guardProto(objId, obj->getProto()); } JSObject* pobj = IsCacheableDOMProxy(obj) ? obj->getTaggedProto().toObjectOrNull() : obj->getProto(); if (!pobj) return; while (pobj != holder) { if (pobj->hasUncacheableProto()) { ObjOperandId protoId = writer.loadObject(pobj); if (pobj->isSingleton()) { // Singletons can have their group's |proto| mutated directly. writer.guardProto(protoId, pobj->getProto()); } else { writer.guardGroup(protoId, pobj->group()); } } pobj = pobj->getProto(); } }
JSObject* js::CloneRegExpObject(JSContext* cx, JSObject* obj_) { RegExpObjectBuilder builder(cx); Rooted<RegExpObject*> regex(cx, &obj_->as<RegExpObject>()); JSObject* res = builder.clone(regex); MOZ_ASSERT_IF(res, res->group() == regex->group()); return res; }
bool js::intrinsic_IsPackedArray(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 1); MOZ_ASSERT(args[0].isObject()); JSObject *obj = &args[0].toObject(); bool isPacked = obj->is<ArrayObject>() && !obj->hasLazyGroup() && !obj->group()->hasAllFlags(OBJECT_FLAG_NON_PACKED) && obj->as<ArrayObject>().getDenseInitializedLength() == obj->as<ArrayObject>().length(); args.rval().setBoolean(isPacked); return true; }
bool GetPropIRGenerator::tryAttachDenseElementHole(HandleObject obj, ObjOperandId objId, ValOperandId indexId) { MOZ_ASSERT(idVal_.isInt32()); if (idVal_.toInt32() < 0) return false; if (!obj->isNative() || !CanAttachDenseElementHole(obj)) return false; // Guard on the shape, to prevent non-dense elements from appearing. writer.guardShape(objId, obj->as<NativeObject>().lastProperty()); if (obj->hasUncacheableProto()) { // If the shape does not imply the proto, emit an explicit proto guard. writer.guardProto(objId, obj->staticPrototype()); } JSObject* pobj = obj->staticPrototype(); while (pobj) { ObjOperandId protoId = writer.loadObject(pobj); // Non-singletons with uncacheable protos can change their proto // without a shape change, so also guard on the group (which determines // the proto) in this case. if (pobj->hasUncacheableProto() && !pobj->isSingleton()) writer.guardGroup(protoId, pobj->group()); // Make sure the shape matches, to avoid non-dense elements or anything // else that is being checked by CanAttachDenseElementHole. writer.guardShape(protoId, pobj->as<NativeObject>().lastProperty()); // Also make sure there are no dense elements. writer.guardNoDenseElements(protoId); pobj = pobj->staticPrototype(); } Int32OperandId int32IndexId = writer.guardIsInt32(indexId); writer.loadDenseElementHoleResult(objId, int32IndexId); writer.typeMonitorResult(); return true; }