From 09a74c38af6910bfca5b50c241eb0d3b03725dc6 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Fri, 29 Sep 2017 12:24:22 -0700 Subject: [PATCH] Return member_lval from Array::lval{,Ref}() Reviewed By: alexeyt Differential Revision: D5872547 fbshipit-source-id: 9e173339539dc4ee34dd98b7cbdb1743f1e3cdd0 --- hphp/runtime/base/member-val-inl.h | 10 ++-------- hphp/runtime/base/member-val.h | 6 ++---- hphp/runtime/base/program-functions.cpp | 7 ++++--- hphp/runtime/base/type-array.cpp | 12 ++++++------ hphp/runtime/base/type-array.h | 4 ++-- hphp/runtime/ext/xml/ext_xml.cpp | 7 ++++--- hphp/runtime/test/array.cpp | 4 +++- hphp/runtime/vm/member-operations.h | 14 +++++++------- 8 files changed, 30 insertions(+), 34 deletions(-) diff --git a/hphp/runtime/base/member-val-inl.h b/hphp/runtime/base/member-val-inl.h index bbd6bfee8ca..0417a4466b2 100644 --- a/hphp/runtime/base/member-val-inl.h +++ b/hphp/runtime/base/member-val-inl.h @@ -53,17 +53,11 @@ inline bool member_lval::has_ref() const { return !!m_ptr; } -inline const Value& member_lval::val() const { - return *m_ptr.val; -} -inline Value& member_lval::val() { +inline Value& member_lval::val() const { return *m_ptr.val; } -inline const DataType& member_lval::type() const { - return m_ptr.tv->m_type; -} -inline DataType& member_lval::type() { +inline DataType& member_lval::type() const { return m_ptr.tv->m_type; } diff --git a/hphp/runtime/base/member-val.h b/hphp/runtime/base/member-val.h index d1fde868ded..0e8925964fe 100644 --- a/hphp/runtime/base/member-val.h +++ b/hphp/runtime/base/member-val.h @@ -83,10 +83,8 @@ struct member_lval { * * @requires: has_val() */ - const Value& val() const; - Value& val(); - const DataType& type() const; - DataType& type(); + Value& val() const; + DataType& type() const; /* * Get a pointer to the referenced TypedValue. diff --git a/hphp/runtime/base/program-functions.cpp b/hphp/runtime/base/program-functions.cpp index bf632a70f35..4f5d5bcf344 100644 --- a/hphp/runtime/base/program-functions.cpp +++ b/hphp/runtime/base/program-functions.cpp @@ -326,10 +326,11 @@ void register_variable(Array& variables, char *name, const Variant& value, } if (!index) { - auto& val = symtable->lvalAt(); - val = Array::Create(); + auto lval = symtable->lvalAt(); + lval.type() = KindOfPersistentArray; + lval.val().parr = staticEmptyArray(); gpc_elements.push_back(uninit_null()); - gpc_elements.back().assignRef(val); + gpc_elements.back().assignRef(tvAsVariant(lval.tv_ptr())); } else { String key(index, index_len, CopyString); auto const v = tvToCell(symtable->rvalAt(key)); diff --git a/hphp/runtime/base/type-array.cpp b/hphp/runtime/base/type-array.cpp index 9dccd9b7e8a..99dbd7035a7 100644 --- a/hphp/runtime/base/type-array.cpp +++ b/hphp/runtime/base/type-array.cpp @@ -918,20 +918,20 @@ FOR_EACH_KEY_TYPE(add) /////////////////////////////////////////////////////////////////////////////// -Variant& Array::lvalAt() { +member_lval Array::lvalAt() { if (!m_arr) m_arr = Ptr::attach(ArrayData::Create()); auto const lval = m_arr->lvalNew(m_arr->cowCheck()); if (lval.arr_base() != m_arr) m_arr = Ptr::attach(lval.arr_base()); - assert(lval.tv_ptr()); - return tvAsVariant(lval.tv_ptr()); + assert(lval); + return lval; } -Variant& Array::lvalAtRef() { +member_lval Array::lvalAtRef() { if (!m_arr) m_arr = Ptr::attach(ArrayData::Create()); auto const lval = m_arr->lvalNewRef(m_arr->cowCheck()); if (lval.arr_base() != m_arr) m_arr = Ptr::attach(lval.arr_base()); - assert(lval.tv_ptr()); - return tvAsVariant(lval.tv_ptr()); + assert(lval); + return lval; } void Array::append(TypedValue v) { diff --git a/hphp/runtime/base/type-array.h b/hphp/runtime/base/type-array.h index 227f01b221e..952a3d304f8 100644 --- a/hphp/runtime/base/type-array.h +++ b/hphp/runtime/base/type-array.h @@ -437,8 +437,8 @@ public: /* * Get an lval to a newly created element. */ - Variant& lvalAt(); - Variant& lvalAtRef(); + member_lval lvalAt(); + member_lval lvalAtRef(); ///////////////////////////////////////////////////////////////////////////// // Element access and mutation. diff --git a/hphp/runtime/ext/xml/ext_xml.cpp b/hphp/runtime/ext/xml/ext_xml.cpp index 1b955c599bd..8a098d12849 100644 --- a/hphp/runtime/ext/xml/ext_xml.cpp +++ b/hphp/runtime/ext/xml/ext_xml.cpp @@ -628,9 +628,10 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch if (atcnt) { tag.set(s_attributes,atr); } - auto& lval = parser->data.toArrRef().lvalAt(); - lval.assign(tag); - parser->ctag.assignRef(lval); + auto lval = parser->data.toArrRef().lvalAt(); + lval.type() = KindOfArray; + lval.val().parr = tag.detach(); + parser->ctag.assignRef(tvAsVariant(lval.tv_ptr())); } else if (parser->level == (XML_MAXLEVEL + 1)) { raise_warning("Maximum depth exceeded - Results truncated"); } diff --git a/hphp/runtime/test/array.cpp b/hphp/runtime/test/array.cpp index 3f5dfafcb0b..7014b2c7a07 100644 --- a/hphp/runtime/test/array.cpp +++ b/hphp/runtime/test/array.cpp @@ -458,7 +458,9 @@ TEST(ARRAY, Membership) { } { Array arr; - arr.lvalAt() = String("test"); + auto const lval = arr.lvalAt(); + lval.type() = KindOfString; + lval.val().pstr = StringData::Make("test", CopyString); EXPECT_TRUE(equal(arr, make_packed_array("test"))); } { diff --git a/hphp/runtime/vm/member-operations.h b/hphp/runtime/vm/member-operations.h index cb99614d1d3..cb29bedc30e 100644 --- a/hphp/runtime/vm/member-operations.h +++ b/hphp/runtime/vm/member-operations.h @@ -1212,7 +1212,7 @@ TypedValue* ElemU(TypedValue& tvRef, TypedValue* base, key_type key) { inline TypedValue* NewElemEmptyish(TypedValue* base) { detail::checkPromotion(base); Array a = Array::Create(); - TypedValue* result = const_cast(a.lvalAt().asTypedValue()); + TypedValue* result = a.lvalAt().tv_ptr(); tvAsVariant(base) = a; return result; } @@ -1255,8 +1255,8 @@ inline TypedValue* NewElemArray(TypedValue* base) { assertx(tvIsArray(base)); assertx(tvIsPlausible(*base)); return reffy ? - tvAsVariant(base).asArrRef().lvalAtRef().asTypedValue() : - tvAsVariant(base).asArrRef().lvalAt().asTypedValue(); + tvAsVariant(base).asArrRef().lvalAtRef().tv_ptr() : + tvAsVariant(base).asArrRef().lvalAt().tv_ptr(); } /** @@ -2062,7 +2062,7 @@ inline TypedValue* SetOpNewElemEmptyish(SetOpOp op, TypedValue* base, Cell* rhs) { detail::checkPromotion(base); Array a = Array::Create(); - TypedValue* result = (TypedValue*)&a.lvalAt(); + TypedValue* result = a.lvalAt().tv_ptr(); tvAsVariant(base) = a; setopBody(tvToCell(result), op, rhs); return result; @@ -2114,7 +2114,7 @@ inline TypedValue* SetOpNewElem(TypedValue& tvRef, case KindOfPersistentArray: case KindOfArray: { TypedValue* result; - result = (TypedValue*)&tvAsVariant(base).asArrRef().lvalAt(); + result = tvAsVariant(base).asArrRef().lvalAt().tv_ptr(); setopBody(tvToCell(result), op, rhs); return result; } @@ -2312,7 +2312,7 @@ inline Cell IncDecNewElemEmptyish( ) { detail::checkPromotion(base); auto a = Array::Create(); - auto result = (TypedValue*)&a.lvalAt(); + auto result = a.lvalAt().tv_ptr(); tvAsVariant(base) = a; assert(result->m_type == KindOfNull); return IncDecBody(op, result); @@ -2366,7 +2366,7 @@ inline Cell IncDecNewElem( case KindOfPersistentArray: case KindOfArray: { - TypedValue* result = (TypedValue*)&tvAsVariant(base).asArrRef().lvalAt(); + TypedValue* result = tvAsVariant(base).asArrRef().lvalAt().tv_ptr(); assert(result->m_type == KindOfNull); return IncDecBody(op, tvToCell(result)); } -- 2.11.4.GIT