Permalink
Browse files

Delete ObjectData::declPropInd()

Summary:
It will be difficult to support with a different property layout, and
the information it derives was almost available in the callers anyway.

Reviewed By: alexeyt

Differential Revision: D8826010

fbshipit-source-id: 958195f0d3295d02a7a2ae941b07d2f2ada2d253
  • Loading branch information...
swtaarrs authored and hhvm-bot committed Jul 13, 2018
1 parent 48075c5 commit d6dff022236ebfc7fcd5fb9ec70afe0feae9de0c
Showing with 24 additions and 38 deletions.
  1. +21 −35 hphp/runtime/base/object-data.cpp
  2. +3 −3 hphp/runtime/base/object-data.h
@@ -442,7 +442,7 @@ void ObjectData::o_set(const String& propName, const Variant& v,
if (prop && lookup.accessible) {
if (!useSet || type(prop) != KindOfUninit) {
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
tvSet(tvToInitCell(*v.asTypedValue()), prop);
return;
@@ -1095,34 +1095,19 @@ Object ObjectData::FromArray(ArrayData* properties) {
return retval;
}
Slot ObjectData::declPropInd(tv_rval rval) const {
// Do an address range check to determine whether prop physically resides in
// propVec. This will have to change if propVec() ever stops being a
// TypedValue[].
auto const vec = reinterpret_cast<const char*>(&propVec()->m_data);
auto const prop = reinterpret_cast<const char*>(&val(rval));
if (prop >= vec &&
prop < (vec + m_cls->numDeclProperties() * sizeof(TypedValue))) {
return (prop - vec) / sizeof(TypedValue);
}
return kInvalidSlot;
}
NEVER_INLINE
void ObjectData::throwMutateImmutable(tv_rval prop) const {
auto const propIdx = declPropInd(prop);
void ObjectData::throwMutateImmutable(Slot prop) const {
throw_cannot_modify_immutable_prop(
getClassName().data(),
m_cls->declProperties()[propIdx].name->data()
m_cls->declProperties()[prop].name->data()
);
}
NEVER_INLINE
void ObjectData::throwBindImmutable(tv_rval prop) const {
auto const propIdx = declPropInd(prop);
void ObjectData::throwBindImmutable(Slot prop) const {
throw_cannot_bind_immutable_prop(
getClassName().data(),
m_cls->declProperties()[propIdx].name->data()
m_cls->declProperties()[prop].name->data()
);
}
@@ -1149,6 +1134,7 @@ ObjectData::PropLookup ObjectData::getPropImpl(
return {
const_cast<TypedValue*>(prop),
propIdx,
lookup.accessible,
// we always return true in the !forWrite case; this way the compiler
// may optimize away this value, and if a caller intends to write but
@@ -1169,19 +1155,19 @@ ObjectData::PropLookup ObjectData::getPropImpl(
// the property we need to allow the array to escalate.
if (forWrite) {
auto const lval = arr.lvalAt(StrNR(key), AccessFlags::Key);
return { lval, true, false };
return { lval, kInvalidSlot, true, false };
}
return { rval.as_lval(), true, true };
return { rval.as_lval(), kInvalidSlot, true, true };
}
}
return { nullptr, false, forWrite ? false : true };
return { nullptr, kInvalidSlot, false, forWrite ? false : true };
}
tv_lval ObjectData::getPropLval(const Class* ctx, const StringData* key) {
auto const lookup = getPropImpl<true>(ctx, key);
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(lookup.prop);
throwMutateImmutable(lookup.slot);
}
return lookup.prop && lookup.accessible ? lookup.prop : nullptr;
}
@@ -1195,7 +1181,7 @@ tv_rval ObjectData::getProp(const Class* ctx, const StringData* key) const {
tv_lval ObjectData::vGetProp(const Class* ctx, const StringData* key) {
auto const lookup = getPropImpl<true>(ctx, key);
auto prop = lookup.prop;
if (UNLIKELY(lookup.immutable)) throwBindImmutable(prop);
if (UNLIKELY(lookup.immutable)) throwBindImmutable(lookup.slot);
if (lookup.accessible && prop && type(prop) != KindOfUninit) {
tvBoxIfNeeded(prop);
return prop;
@@ -1206,7 +1192,7 @@ tv_lval ObjectData::vGetProp(const Class* ctx, const StringData* key) {
tv_lval ObjectData::vGetPropIgnoreAccessibility(const StringData* key) {
auto const lookup = getPropImpl<true>(nullptr, key);
auto prop = lookup.prop;
if (UNLIKELY(lookup.immutable)) throwBindImmutable(prop);
if (UNLIKELY(lookup.immutable)) throwBindImmutable(lookup.slot);
if (prop && type(prop) != KindOfUninit) {
tvBoxIfNeeded(prop);
return prop;
@@ -1412,11 +1398,11 @@ tv_lval ObjectData::propImpl(TypedValue* tvRef, const Class* ctx,
if (lookup.accessible) {
auto const checkImmutable = [&]() {
if (mode == PropMode::Bind) {
if (UNLIKELY(lookup.immutable)) throwBindImmutable(prop);
if (UNLIKELY(lookup.immutable)) throwBindImmutable(lookup.slot);
}
if (mode == PropMode::DimForWrite) {
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
}
return prop;
@@ -1593,7 +1579,7 @@ void ObjectData::setProp(Class* ctx, const StringData* key, Cell val) {
!m_cls->rtAttribute(Class::UseSet) ||
!invokeSet(key, val)) {
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
tvSet(val, prop);
}
@@ -1647,14 +1633,14 @@ tv_lval ObjectData::setOpProp(TypedValue& tvRef,
tvRef.m_type = KindOfUninit;
}
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
cellDup(tvAssertCell(r.val), prop);
return prop;
}
}
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
prop = tvToCell(prop);
setopBody(prop, op, val);
@@ -1739,15 +1725,15 @@ Cell ObjectData::incDecProp(Class* ctx, IncDecOp op, const StringData* key) {
return dest;
}
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
cellCopy(tvAssertCell(r.val), prop);
tvWriteNull(r.val); // suppress decref
return dest;
}
}
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
if (type(prop) == KindOfUninit) {
tvWriteNull(prop);
@@ -1816,10 +1802,10 @@ void ObjectData::unsetProp(Class* ctx, const StringData* key) {
auto const prop = lookup.prop;
if (prop && lookup.accessible && type(prop) != KindOfUninit) {
if (declPropInd(prop) != kInvalidSlot) {
if (lookup.slot != kInvalidSlot) {
// Declared property.
if (UNLIKELY(lookup.immutable) && !isBeingConstructed()) {
throwMutateImmutable(prop);
throwMutateImmutable(lookup.slot);
}
tvSetIgnoreRef(*uninit_variant.asTypedValue(), prop);
} else {
@@ -451,11 +451,10 @@ struct ObjectData : Countable, type_scan::MarkCollectable<ObjectData> {
*/
Array& reserveProperties(int nProp = 2);
Slot declPropInd(tv_rval prop) const;
[[noreturn]] NEVER_INLINE
void throwMutateImmutable(tv_rval prop) const;
void throwMutateImmutable(Slot prop) const;
[[noreturn]] NEVER_INLINE
void throwBindImmutable(tv_rval prop) const;
void throwBindImmutable(Slot prop) const;
public:
// never box the lval returned from getPropLval; use propB or vGetProp instead
@@ -468,6 +467,7 @@ struct ObjectData : Countable, type_scan::MarkCollectable<ObjectData> {
private:
struct PropLookup {
tv_lval prop;
Slot slot;
bool accessible;
bool immutable;
};

0 comments on commit d6dff02

Please sign in to comment.