diff --git a/hphp/runtime/base/array/array_data.cpp b/hphp/runtime/base/array/array_data.cpp index 08b20b584..f3299b065 100644 --- a/hphp/runtime/base/array/array_data.cpp +++ b/hphp/runtime/base/array/array_data.cpp @@ -194,9 +194,12 @@ bool ArrayData::equal(const ArrayData *v2, bool strict) const { return true; } -ArrayData *ArrayData::lvalPtr(StringData* k, Variant *&ret, bool copy, - bool create) { - throw FatalErrorException("Unimplemented ArrayData::lvalPtr"); +ArrayData *ArrayData::createLvalPtr(StringData* k, Variant *&ret, bool copy) { + throw FatalErrorException("Unimplemented ArrayData::createLvalPtr"); +} + +ArrayData *ArrayData::getLvalPtr(StringData* k, Variant *&ret, bool copy) { + throw FatalErrorException("Unimplemented ArrayData::getLvalPtr"); } ArrayData *ArrayData::add(int64_t k, CVarRef v, bool copy) { diff --git a/hphp/runtime/base/array/array_data.h b/hphp/runtime/base/array/array_data.h index b5450298c..788340efd 100644 --- a/hphp/runtime/base/array/array_data.h +++ b/hphp/runtime/base/array/array_data.h @@ -250,8 +250,8 @@ public: * the dynamic property array in ObjectData or the local cache array * in ShardMap. */ - virtual ArrayData *lvalPtr(StringData* k, Variant *&ret, bool copy, - bool create); + virtual ArrayData *createLvalPtr(StringData* k, Variant *&ret, bool copy); + virtual ArrayData *getLvalPtr(StringData* k, Variant *&ret, bool copy); /** * Setting a value at specified key. If "copy" is true, make a copy first @@ -297,7 +297,8 @@ public: CVarRef get(CVarRef k, bool error = false) const; ArrayData *lval(CStrRef k, Variant *&ret, bool copy, bool checkExist=false); ArrayData *lval(CVarRef k, Variant *&ret, bool copy, bool checkExist=false); - ArrayData *lvalPtr(CStrRef k, Variant *&ret, bool copy, bool create); + ArrayData *createLvalPtr(CStrRef k, Variant *&ret, bool copy); + ArrayData *getLvalPtr(CStrRef k, Variant *&ret, bool copy); ArrayData *set(CStrRef k, CVarRef v, bool copy); ArrayData *set(CVarRef k, CVarRef v, bool copy); ArrayData *setRef(CStrRef k, CVarRef v, bool copy); diff --git a/hphp/runtime/base/array/array_inline.h b/hphp/runtime/base/array/array_inline.h index 2e5ef7b2a..4e15965b5 100644 --- a/hphp/runtime/base/array/array_inline.h +++ b/hphp/runtime/base/array/array_inline.h @@ -77,10 +77,15 @@ inline ArrayData* ArrayData::lval(CVarRef k, Variant *&ret, bool copy, : lval(getStringKey(cell), ret, copy, checkExist); } -inline ArrayData *ArrayData::lvalPtr(CStrRef k, Variant *&ret, bool copy, - bool create) { +inline +ArrayData *ArrayData::createLvalPtr(CStrRef k, Variant *&ret, bool copy) { assert(IsValidKey(k)); - return lvalPtr(k.get(), ret, copy, create); + return createLvalPtr(k.get(), ret, copy); +} + +inline ArrayData *ArrayData::getLvalPtr(CStrRef k, Variant *&ret, bool copy) { + assert(IsValidKey(k)); + return getLvalPtr(k.get(), ret, copy); } inline ArrayData* ArrayData::set(CStrRef k, CVarRef v, bool copy) { diff --git a/hphp/runtime/base/array/hphp_array.cpp b/hphp/runtime/base/array/hphp_array.cpp index 1238e5b4e..55d020ed9 100644 --- a/hphp/runtime/base/array/hphp_array.cpp +++ b/hphp/runtime/base/array/hphp_array.cpp @@ -1103,12 +1103,14 @@ ArrayData* HphpArray::lval(StringData* key, Variant*& ret, bool copy, return copyImpl()->addLvalImpl(key, prehash, &ret); } -ArrayData *HphpArray::lvalPtr(StringData* key, Variant*& ret, bool copy, - bool create) { - strhash_t prehash = key->hash(); +ArrayData *HphpArray::createLvalPtr(StringData* key, Variant*& ret, bool copy) { HphpArray* a = !copy ? this : copyImpl(); - if (create) return a->addLvalImpl(key, prehash, &ret); - auto pos = a->find(key, prehash); + return a->addLvalImpl(key, key->hash(), &ret); +} + +ArrayData *HphpArray::getLvalPtr(StringData* key, Variant*& ret, bool copy) { + HphpArray* a = !copy ? this : copyImpl(); + auto pos = a->find(key, key->hash()); if (pos != (ssize_t)ElmIndEmpty) { Elm* e = &a->m_data[pos]; ret = &tvAsVariant(&e->data); diff --git a/hphp/runtime/base/array/hphp_array.h b/hphp/runtime/base/array/hphp_array.h index cf6a17eda..6aab5729c 100644 --- a/hphp/runtime/base/array/hphp_array.h +++ b/hphp/runtime/base/array/hphp_array.h @@ -83,7 +83,8 @@ public: using ArrayData::get; using ArrayData::lval; using ArrayData::lvalNew; - using ArrayData::lvalPtr; + using ArrayData::createLvalPtr; + using ArrayData::getLvalPtr; using ArrayData::set; using ArrayData::setRef; using ArrayData::add; @@ -128,8 +129,8 @@ public: ArrayData* lvalNew(Variant*& ret, bool copy); // overrides ArrayData - ArrayData* lvalPtr(StringData* k, Variant*& ret, bool copy, - bool create); + ArrayData* createLvalPtr(StringData* k, Variant*& ret, bool copy); + ArrayData* getLvalPtr(StringData* k, Variant*& ret, bool copy); // implements ArrayData ArrayData* set(int64_t k, CVarRef v, bool copy); diff --git a/hphp/runtime/base/array/policy_array.cpp b/hphp/runtime/base/array/policy_array.cpp index 5c9fca0ed..e286c2ca5 100644 --- a/hphp/runtime/base/array/policy_array.cpp +++ b/hphp/runtime/base/array/policy_array.cpp @@ -419,8 +419,11 @@ ArrayData *ArrayShell::lvalNew(Variant *&ret, bool copy) { return this; } -ArrayData *ArrayShell::lvalPtr(StringData* k, Variant *&ret, bool copy, - bool create) { +ArrayData *ArrayShell::createLvalPtr(StringData* k, Variant *&ret, bool copy) { + NOT_IMPLEMENTED(); +} + +ArrayData *ArrayShell::getLvalPtr(StringData* k, Variant *&ret, bool copy) { NOT_IMPLEMENTED(); } diff --git a/hphp/runtime/base/array/policy_array.h b/hphp/runtime/base/array/policy_array.h index 7043ae390..926e565c4 100644 --- a/hphp/runtime/base/array/policy_array.h +++ b/hphp/runtime/base/array/policy_array.h @@ -489,9 +489,10 @@ public: * the dynamic property array in ObjectData or the local cache array * in ShardMap. */ - virtual ArrayData *lvalPtr(StringData* k, Variant *&ret, - bool copy, - bool create) FOLLY_OVERRIDE; + virtual ArrayData *createLvalPtr(StringData* k, Variant *&ret, bool copy) + FOLLY_OVERRIDE; + virtual ArrayData *getLvalPtr(StringData* k, Variant *&ret, bool copy) + FOLLY_OVERRIDE; /** * Setting a value at specified key. If "copy" is true, make a copy first diff --git a/hphp/runtime/base/object_data.cpp b/hphp/runtime/base/object_data.cpp index 6bef9b4e7..39b2209bf 100644 --- a/hphp/runtime/base/object_data.cpp +++ b/hphp/runtime/base/object_data.cpp @@ -217,8 +217,7 @@ Variant* ObjectData::o_realProp(CStrRef propName, int flags, if (!o_properties.get()) { thiz->initDynProps(); } - o_properties.get()->lvalPtr(propName, - *(Variant**)(&ret), false, true); + o_properties.get()->createLvalPtr(propName, *(Variant**)(&ret), false); return (Variant*)ret; } diff --git a/hphp/runtime/base/shared/shared_map.h b/hphp/runtime/base/shared/shared_map.h index 15ea12988..7e7775b4c 100644 --- a/hphp/runtime/base/shared/shared_map.h +++ b/hphp/runtime/base/shared/shared_map.h @@ -49,7 +49,6 @@ public: using ArrayData::get; using ArrayData::lval; using ArrayData::lvalNew; - using ArrayData::lvalPtr; using ArrayData::set; using ArrayData::setRef; using ArrayData::add; diff --git a/hphp/runtime/base/type_array.cpp b/hphp/runtime/base/type_array.cpp index 926659647..0c893bb42 100644 --- a/hphp/runtime/base/type_array.cpp +++ b/hphp/runtime/base/type_array.cpp @@ -486,16 +486,16 @@ Variant Array::rvalAt(CVarRef key, ACCESSPARAMS_IMPL) const { return Array::rvalAtRef(key, flags); } -Variant *Array::lvalPtr(CStrRef key, bool forWrite, bool create) { - if (create) { - if (!m_px) ArrayBase::operator=(ArrayData::Create()); - return &lvalAt(key, AccessFlags::Key); - } +Variant *Array::createLvalPtr(CStrRef key, bool forWrite) { + if (!m_px) ArrayBase::operator=(ArrayData::Create()); + return &lvalAt(key, AccessFlags::Key); +} + +Variant *Array::getLvalPtr(CStrRef key, bool forWrite) { Variant *ret = nullptr; if (m_px) { - ArrayData *escalated = m_px->lvalPtr(key, ret, - forWrite && m_px->getCount() > 1, - false); + ArrayData *escalated = m_px->getLvalPtr(key, ret, + forWrite && m_px->getCount() > 1); if (escalated != m_px) ArrayBase::operator=(escalated); } return ret; diff --git a/hphp/runtime/base/type_array.h b/hphp/runtime/base/type_array.h index 49931db8e..6bee2d2fc 100644 --- a/hphp/runtime/base/type_array.h +++ b/hphp/runtime/base/type_array.h @@ -297,7 +297,8 @@ class Array : protected SmartPtr { return *ret; } - Variant *lvalPtr(CStrRef key, bool forWrite, bool create); + Variant *createLvalPtr(CStrRef key, bool forWrite); + Variant *getLvalPtr(CStrRef key, bool forWrite); Variant &lvalAt(); diff --git a/hphp/runtime/base/type_variant.cpp b/hphp/runtime/base/type_variant.cpp index c859b32b2..b6e8a7797 100644 --- a/hphp/runtime/base/type_variant.cpp +++ b/hphp/runtime/base/type_variant.cpp @@ -1985,10 +1985,18 @@ Variant &Variant::lvalRef(CVarRef k, Variant& tmp, ACCESSPARAMS_IMPL) { return Variant::LvalAtImpl0(this, k, &tmp, false, flags); } -Variant *Variant::lvalPtr(CStrRef key, bool forWrite, bool create) { +Variant *Variant::createLvalPtr(CStrRef key, bool forWrite) { Variant *t = m_type == KindOfRef ? m_data.pref->var() : this; if (t->m_type == KindOfArray) { - return t->asArrRef().lvalPtr(key, forWrite, create); + return t->asArrRef().createLvalPtr(key, forWrite); + } + return nullptr; +} + +Variant *Variant::getLvalPtr(CStrRef key, bool forWrite) { + Variant *t = m_type == KindOfRef ? m_data.pref->var() : this; + if (t->m_type == KindOfArray) { + return t->asArrRef().getLvalPtr(key, forWrite); } return nullptr; } diff --git a/hphp/runtime/base/type_variant.h b/hphp/runtime/base/type_variant.h index ee9aedf68..2e46d9d25 100644 --- a/hphp/runtime/base/type_variant.h +++ b/hphp/runtime/base/type_variant.h @@ -807,7 +807,8 @@ class Variant : private TypedValue { return *ret; } - Variant *lvalPtr(CStrRef key, bool forWrite, bool create); + Variant *createLvalPtr(CStrRef key, bool forWrite); + Variant *getLvalPtr(CStrRef key, bool forWrite); Variant &lvalAt(); diff --git a/hphp/runtime/ext/ext_fb.cpp b/hphp/runtime/ext/ext_fb.cpp index f266c7cef..00be2d92f 100644 --- a/hphp/runtime/ext/ext_fb.cpp +++ b/hphp/runtime/ext/ext_fb.cpp @@ -1650,7 +1650,7 @@ static Array const_data; Variant f_fb_const_fetch(CVarRef key) { String k = key.toString(); - Variant *ret = const_data.lvalPtr(k, false, false); + Variant *ret = const_data.getLvalPtr(k, false); if (ret) return *ret; return false; } diff --git a/hphp/runtime/vm/instance.cpp b/hphp/runtime/vm/instance.cpp index 779f804c9..345e02abd 100644 --- a/hphp/runtime/vm/instance.cpp +++ b/hphp/runtime/vm/instance.cpp @@ -267,8 +267,8 @@ void Instance::propImpl(TypedValue*& retval, TypedValue& tvRef, if (o_properties.get() == nullptr) { initDynProps(); } - o_properties.get()->lvalPtr(*(const String*)&key, - *(Variant**)(&retval), false, true); + o_properties.get()->createLvalPtr(*(const String*)&key, + *(Variant**)(&retval), false); } else { retval = (TypedValue*)&init_null_variant; } @@ -433,8 +433,8 @@ TypedValue* Instance::setOpProp(TypedValue& tvRef, Class* ctx, if (o_properties.get() == nullptr) { initDynProps(); } - o_properties.get()->lvalPtr(*(const String*)&key, - *(Variant**)(&propVal), false, true); + o_properties.get()->createLvalPtr(*(const String*)&key, + *(Variant**)(&propVal), false); // don't write propVal->_count because it holds data // owned by the HphpArray propVal->m_type = KindOfNull; @@ -448,8 +448,8 @@ TypedValue* Instance::setOpProp(TypedValue& tvRef, Class* ctx, if (o_properties.get() == nullptr) { initDynProps(); } - o_properties.get()->lvalPtr(*(const String*)&key, *(Variant**)(&propVal), - false, true); + o_properties.get()->createLvalPtr(*(const String*)&key, + *(Variant**)(&propVal), false); // don't write propVal->_count because it holds data // owned by the HphpArray propVal->m_data.num = tvResult.m_data.num; @@ -506,8 +506,8 @@ void Instance::incDecPropImpl(TypedValue& tvRef, Class* ctx, if (o_properties.get() == nullptr) { initDynProps(); } - o_properties.get()->lvalPtr(*(const String*)&key, - *(Variant**)(&propVal), false, true); + o_properties.get()->createLvalPtr(*(const String*)&key, + *(Variant**)(&propVal), false); // don't write propVal->_count because it holds data // owned by the HphpArray propVal->m_type = KindOfNull; @@ -521,8 +521,8 @@ void Instance::incDecPropImpl(TypedValue& tvRef, Class* ctx, if (o_properties.get() == nullptr) { initDynProps(); } - o_properties.get()->lvalPtr(*(const String*)&key, *(Variant**)(&propVal), - false, true); + o_properties.get()->createLvalPtr(*(const String*)&key, + *(Variant**)(&propVal), false); // don't write propVal->_count because it holds data // owned by the HphpArray propVal->m_data.num = tvResult.m_data.num; @@ -792,7 +792,7 @@ void Instance::cloneSet(ObjectData* clone) { TypedValue *val = props->nvGet(strKey); TypedValue *retval; auto cloneProps = iclone->o_properties.get(); - cloneProps->lvalPtr(strKey, *(Variant**)&retval, false, true); + cloneProps->createLvalPtr(strKey, *(Variant**)&retval, false); tvDupFlattenVars(val, retval, cloneProps); iter = o_properties.get()->iter_advance(iter); decRefStr(strKey); diff --git a/hphp/runtime/vm/name_value_table_wrapper.h b/hphp/runtime/vm/name_value_table_wrapper.h index bc97c1dd0..718439201 100644 --- a/hphp/runtime/vm/name_value_table_wrapper.h +++ b/hphp/runtime/vm/name_value_table_wrapper.h @@ -67,7 +67,6 @@ public: // ArrayData implementation using ArrayData::get; using ArrayData::lval; using ArrayData::lvalNew; - using ArrayData::lvalPtr; using ArrayData::set; using ArrayData::setRef; using ArrayData::add;