Convert a few tvFoo functions to take parameters by reference

Since TypedValue::operator= is dangerous, something like
tvTeleport is usually what you want to use, but it doesn't work with
temporary TypedValues (e.g. return values of things like make_tv or
cellAdd), because it took the arguments by pointer.  This also means
we can change it to take parameters by value later without updating
callsites.  This diff does the tvDup family and changes tvTeleport to
tvCopy.  I'll gradually get the other ones done, but I just need these
for now to work with temporaries for changing SetOp to not use Variant
arithmetic.
Esse commit está contido em:
Jordan DeLong
2013-06-28 13:41:13 -07:00
commit de Sara Golemon
commit 8220a18060
18 arquivos alterados com 166 adições e 139 exclusões
+6 -6
Ver Arquivo
@@ -818,14 +818,14 @@ HOT_FUNC static
void iterValue(ArrayIter* iter, TypedValue* out) {
Variant val = iter->iterValue<Coll>(Style());
assert(val.getRawType() != KindOfRef);
tvDupCell(val.asTypedValue(), out);
cellDup(*val.asTypedValue(), *out);
}
template<class Coll, class Style>
HOT_FUNC static
void iterKey(ArrayIter* iter, TypedValue* out) {
Variant key = iter->iterKey<Coll>(Style());
tvDupCell(key.asTypedValue(), out);
cellDup(*key.asTypedValue(), *out);
}
template<class Coll, class Style>
@@ -909,11 +909,11 @@ static inline void iter_value_cell_local_impl(Iter* iter, TypedValue* out) {
cur = cur->m_data.pref->tv();
}
}
tvDup(cur, out);
tvDup(*cur, *out);
} else {
Variant val = arrIter.second();
assert(val.getRawType() != KindOfRef);
tvDupCell(val.asTypedValue(), out);
cellDup(*val.asTypedValue(), *out);
}
tvRefcountedDecRefHelper(oldType, oldDatum);
}
@@ -931,7 +931,7 @@ static inline void iter_key_cell_local_impl(Iter* iter, TypedValue* out) {
arr.nvFirst(out);
} else {
Variant key = arr.first();
tvDupCell(key.asTypedValue(), out);
cellDup(*key.asTypedValue(), *out);
}
tvRefcountedDecRefHelper(oldType, oldDatum);
}
@@ -978,7 +978,7 @@ void getHphpArrayElm(HphpArray::Elm* elm, TypedValue* valOut,
}
} else {
TypedValue* cur = tvToCell(&elm->data);
tvDupCell(cur, valOut);
cellDup(*cur, *valOut);
if (keyOut) {
HphpArray::getElmKey(elm, keyOut);
}
+1 -1
Ver Arquivo
@@ -838,7 +838,7 @@ void HphpArray::compact(bool renumber /* = false */) {
}
static inline void elemConstruct(const TypedValue* fr, TypedValue* to) {
tvDupCell(tvToCell(fr), to);
cellDup(*tvToCell(fr), *to);
}
bool HphpArray::nextInsert(CVarRef data) {
+4 -4
Ver Arquivo
@@ -243,8 +243,8 @@ struct ElmUCompare {
bool operator()(ElmT left, ElmT right) const {
Variant ret;
TypedValue args[2];
tvDup(acc.getValue(left).asTypedValue(), args+0);
tvDup(acc.getValue(right).asTypedValue(), args+1);
tvDup(*acc.getValue(left).asTypedValue(), args[0]);
tvDup(*acc.getValue(right).asTypedValue(), args[1]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), *ctx,
2, args);
if (ret.isInteger()) {
@@ -274,8 +274,8 @@ struct ElmUCompare {
return false;
}
Variant ret2;
tvDup(acc.getValue(right).asTypedValue(), args+0);
tvDup(acc.getValue(left).asTypedValue(), args+1);
tvDup(*acc.getValue(right).asTypedValue(), args[0]);
tvDup(*acc.getValue(left).asTypedValue(), args[1]);
g_vmContext->invokeFuncFew(ret2.asTypedValue(), *ctx,
2, args);
if (ret2.isBoolean()) {
+13 -13
Ver Arquivo
@@ -526,24 +526,24 @@ Variant ObjectData::o_invoke_few_args(CStrRef s, int count,
switch(count) {
default: not_implemented();
#if INVOKE_FEW_ARGS_COUNT > 6
case 10: tvDup(a9.asTypedValue(), args + 9);
case 9: tvDup(a8.asTypedValue(), args + 8);
case 8: tvDup(a7.asTypedValue(), args + 7);
case 7: tvDup(a6.asTypedValue(), args + 6);
case 10: tvDup(*a9.asTypedValue(), args[9]);
case 9: tvDup(*a8.asTypedValue(), args[8]);
case 8: tvDup(*a7.asTypedValue(), args[7]);
case 7: tvDup(*a6.asTypedValue(), args[6]);
#endif
#if INVOKE_FEW_ARGS_COUNT > 3
case 6: tvDup(a5.asTypedValue(), args + 5);
case 5: tvDup(a4.asTypedValue(), args + 4);
case 4: tvDup(a3.asTypedValue(), args + 3);
case 6: tvDup(*a5.asTypedValue(), args[5]);
case 5: tvDup(*a4.asTypedValue(), args[4]);
case 4: tvDup(*a3.asTypedValue(), args[3]);
#endif
case 3: tvDup(a2.asTypedValue(), args + 2);
case 2: tvDup(a1.asTypedValue(), args + 1);
case 1: tvDup(a0.asTypedValue(), args + 0);
case 3: tvDup(*a2.asTypedValue(), args[2]);
case 2: tvDup(*a1.asTypedValue(), args[1]);
case 1: tvDup(*a0.asTypedValue(), args[0]);
case 0: break;
}
Variant ret;
g_vmContext->invokeFuncFew((TypedValue*)&ret, ctx, count, args);
g_vmContext->invokeFuncFew(ret.asTypedValue(), ctx, count, args);
return ret;
}
@@ -747,8 +747,8 @@ Variant ObjectData::offsetGet(Variant key) {
}
Variant v;
TypedValue args[1];
tvDup(key.asTypedValue(), args + 0);
g_vmContext->invokeFuncFew((TypedValue*)(&v), method,
tvDup(*key.asTypedValue(), args[0]);
g_vmContext->invokeFuncFew(v.asTypedValue(), method,
this, nullptr, 1, args);
return v;
}
+6
Ver Arquivo
@@ -78,6 +78,12 @@ bool tvIsPlausible(const TypedValue* tv) {
return cellIsPlausible(tv);
}
bool varIsPlausible(const Var* var) {
assert(var);
assert(var->m_type == KindOfRef);
return tvIsPlausible(var);
}
inline void tvUnboxIfNeeded(TypedValue *tv) {
if (tv->m_type == KindOfRef) {
tvUnbox(tv);
+59 -43
Ver Arquivo
@@ -35,6 +35,7 @@ class Variant;
*/
bool tvIsPlausible(const TypedValue*);
bool cellIsPlausible(const Cell*);
bool varIsPlausible(const Var*);
// Assumes 'data' is live
// Assumes 'IS_REFCOUNTED_TYPE(type)'
@@ -180,49 +181,63 @@ inline void tvReadCell(const TypedValue* fr, TypedValue* to) {
tvRefcountedIncRef(to);
}
// Assumes 'fr' is live and 'to' is dead
// Assumes 'fr->m_type != KindOfRef'
// NOTE: this helper will not modify to->_count
inline void tvDupCell(const TypedValue* fr, TypedValue* to) {
assert(tvIsPlausible(fr));
assert(fr->m_type != KindOfRef);
to->m_data.num = fr->m_data.num;
to->m_type = fr->m_type;
tvRefcountedIncRef(to);
/*
* Raw copy of a TypedValue from one location to another, without
* doing any reference count manipulation.
*
* Copies the m_data and m_type fields, but not m_aux. (For that you
* need TypedValue::operator=.)
*/
inline void tvCopy(const TypedValue& fr, TypedValue& to) {
assert(tvIsPlausible(&fr));
to.m_data.num = fr.m_data.num;
to.m_type = fr.m_type;
}
// Assumes 'fr' is live and 'to' is dead
// Assumes 'fr->m_type == KindOfRef'
// NOTE: this helper will not modify to->_count
inline void tvDupVar(const TypedValue* fr, TypedValue* to) {
assert(tvIsPlausible(fr));
assert(fr->m_type == KindOfRef);
to->m_data.num = fr->m_data.num;
to->m_type = KindOfRef;
tvIncRefNotShared(to);
/*
* Equivalent of tvCopy for Cells and Vars. These functions have the
* same effects as tvCopy, but have some added assertions.
*/
inline void cellCopy(const Cell& fr, Cell& to) {
assert(cellIsPlausible(&fr));
tvCopy(fr, to);
}
inline void varCopy(const Var& fr, Var& to) {
assert(cellIsPlausible(&fr));
tvCopy(fr, to);
}
// Assumes 'fr' is live and 'to' is dead
inline void tvDupRef(RefData* fr, TypedValue* to) {
assert(tvIsPlausible(fr->tv()));
to->m_data.pref = fr;
to->m_type = KindOfRef;
fr->incRefCount();
/*
* Duplicate a TypedValue to a new location. Copies the m_data and
* m_type fields, and increments reference count. Does not perform a
* decRef on to.
*/
inline void tvDup(const TypedValue& fr, TypedValue& to) {
tvCopy(fr, to);
tvRefcountedIncRef(&to);
}
// Assumes 'fr' is live and 'to' is dead
// After this operation, 'fr' is dead and 'to' live.
inline void tvTeleport(const TypedValue* fr, TypedValue* to) {
assert(tvIsPlausible(fr));
to->m_data.num = fr->m_data.num;
to->m_type = fr->m_type;
/*
* Duplicate a Cell from one location to another. Is equivalent to
* tvDup, with some added assertions.
*/
inline void cellDup(const Cell& fr, Cell& to) {
assert(cellIsPlausible(&fr));
tvDup(fr, to);
}
// Assumes 'fr' is live and 'to' is dead
// NOTE: this helper does not modify to->_count
inline void tvDup(const TypedValue* fr, TypedValue* to) {
tvTeleport(fr, to);
tvRefcountedIncRef(to);
/*
* Duplicate a Var from one location to another.
*
* This has the same effects as tvDup(fr, to), but is slightly more
* efficient because we don't need to check the type tag.
*/
inline void varDup(const Var& fr, Var& to) {
assert(varIsPlausible(&fr));
to.m_data.num = fr.m_data.num;
to.m_type = KindOfRef;
tvIncRefNotShared(&to);
}
// Assumes 'tv' is dead
@@ -260,7 +275,7 @@ inline void tvSetImpl(const TypedValue* fr, TypedValue* to) {
if (respectRef) to = tvToCell(to);
DataType oldType = to->m_type;
uint64_t oldDatum = to->m_data.num;
tvDupCell(fr, to);
cellDup(*fr, *to);
tvRefcountedDecRefHelper(oldType, oldDatum);
}
@@ -325,15 +340,16 @@ inline void tvBind(TypedValue * fr, TypedValue * to) {
assert(fr->m_type == KindOfRef);
DataType oldType = to->m_type;
uint64_t oldDatum = to->m_data.num;
tvDupVar(fr, to);
varDup(*fr, *to);
tvRefcountedDecRefHelper(oldType, oldDatum);
}
// Assumes 'to' and 'fr' are live
inline void tvBindRef(RefData* fr, TypedValue* to) {
DataType oldType = to->m_type;
uint64_t oldDatum = to->m_data.num;
tvDupRef(fr, to);
auto const oldType = to->m_type;
auto const oldDatum = to->m_data.num;
tvCopy(make_tv<KindOfRef>(fr), *to);
fr->incRefCount();
tvRefcountedDecRefHelper(oldType, oldDatum);
}
@@ -427,13 +443,13 @@ inline bool tvIsStronglyBound(const TypedValue* tv) {
inline void tvDupFlattenVars(const TypedValue* fr, TypedValue* to,
const ArrayData* container) {
if (LIKELY(fr->m_type != KindOfRef)) {
tvDupCell(fr, to);
cellDup(*fr, *to);
} else if (fr->m_data.pref->_count <= 1 &&
(!container || fr->m_data.pref->tv()->m_data.parr != container)) {
fr = fr->m_data.pref->tv();
tvDupCell(fr, to);
cellDup(*fr, *to);
} else {
tvDupVar(fr, to);
varDup(*fr, *to);
}
}
+1 -1
Ver Arquivo
@@ -94,7 +94,7 @@ void c_WaitableWaitHandle::setResult(const TypedValue* result) {
assert(result->m_type != KindOfRef);
setState(STATE_SUCCEEDED);
tvDupCell(result, &m_resultOrException);
cellDup(*result, m_resultOrException);
// unref creator
if (m_creator) {
+8 -8
Ver Arquivo
@@ -163,7 +163,7 @@ static bool filter_func(CVarRef value, const void *data) {
CallCtx* ctx = (CallCtx*)data;
Variant ret;
TypedValue args[1];
tvDup(value.asTypedValue(), args + 0);
tvDup(*value.asTypedValue(), args[0]);
g_vmContext->invokeFuncFew((TypedValue*)&ret, *ctx, 1, args);
return ret.toBoolean();
}
@@ -473,9 +473,9 @@ static Variant reduce_func(CVarRef result, CVarRef operand, const void *data) {
CallCtx* ctx = (CallCtx*)data;
Variant ret;
TypedValue args[2];
tvDup(result.asTypedValue(), args + 0);
tvDup(operand.asTypedValue(), args + 1);
g_vmContext->invokeFuncFew((TypedValue*)&ret, *ctx, 2, args);
tvDup(*result.asTypedValue(), args[0]);
tvDup(*operand.asTypedValue(), args[1]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), *ctx, 2, args);
return ret;
}
Variant f_array_reduce(CVarRef input, CVarRef callback,
@@ -581,10 +581,10 @@ static void walk_func(VRefParam value, CVarRef key, CVarRef userdata,
CallCtx* ctx = (CallCtx*)data;
Variant sink;
TypedValue args[3];
tvDup(value->asTypedValue(), args + 0);
tvDup(key.asTypedValue(), args + 1);
tvDup(userdata.asTypedValue(), args + 2);
g_vmContext->invokeFuncFew((TypedValue*)&sink, *ctx, 3, args);
tvDup(*value->asTypedValue(), args[0]);
tvDup(*key.asTypedValue(), args[1]);
tvDup(*userdata.asTypedValue(), args[2]);
g_vmContext->invokeFuncFew(sink.asTypedValue(), *ctx, 3, args);
}
bool f_array_walk_recursive(VRefParam input, CVarRef funcname,
CVarRef userdata /* = null_variant */) {
+18 -18
Ver Arquivo
@@ -159,7 +159,7 @@ void c_Vector::resize(int64_t sz, TypedValue* val) {
} while (m_size > requestedSize);
} else {
for (; m_size < requestedSize; ++m_size) {
tvDup(val, &m_data[m_size]);
tvDup(*val, m_data[m_size]);
}
}
}
@@ -195,7 +195,7 @@ c_Vector* c_Vector::clone() {
target->m_capacity = target->m_size = sz;
target->m_data = data = (TypedValue*)smart_malloc(sz * sizeof(TypedValue));
for (int i = 0; i < sz; ++i) {
tvDup(&m_data[i], &data[i]);
tvDup(m_data[i], data[i]);
}
return target;
}
@@ -537,7 +537,7 @@ Object c_Vector::t_map(CVarRef callback) {
TypedValue* tv = &vec->m_data[i];
int32_t version = m_version;
TypedValue args[1];
tvDup(&m_data[i], args + 0);
tvDup(m_data[i], args[0]);
g_vmContext->invokeFuncFew(tv, ctx, 1, args);
if (UNLIKELY(version != m_version)) {
tvRefcountedDecRef(tv);
@@ -562,7 +562,7 @@ Object c_Vector::t_filter(CVarRef callback) {
Variant ret;
int32_t version = m_version;
TypedValue args[1];
tvDup(&m_data[i], args + 0);
tvDup(m_data[i], args[0]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), ctx, 1, args);
if (UNLIKELY(version != m_version)) {
throw_collection_modified();
@@ -683,7 +683,7 @@ Object c_Vector::ti_fromvector(CVarRef vec) {
target->m_capacity = target->m_size = sz;
target->m_data = data = (TypedValue*)smart_malloc(sz * sizeof(TypedValue));
for (uint i = 0; i < sz; ++i) {
tvDup(&v->m_data[i], &data[i]);
tvDup(v->m_data[i], data[i]);
}
return ret;
}
@@ -752,7 +752,7 @@ Variant c_Vector::ti_slice(CVarRef vec, CVarRef offset,
target->m_data = data =
(TypedValue*)smart_malloc(targetSize * sizeof(TypedValue));
for (uint i = 0; i < targetSize; ++i, ++startPos) {
tvDup(&v->m_data[startPos], &data[i]);
tvDup(v->m_data[startPos], data[i]);
}
return ret;
}
@@ -1480,7 +1480,7 @@ Object c_Map::t_map(CVarRef callback) {
TypedValue* tv = &np.data;
int32_t version = m_version;
TypedValue args[1];
tvDup(&p.data, args + 0);
tvDup(p.data, args[0]);
g_vmContext->invokeFuncFew(tv, ctx, 1, args);
if (UNLIKELY(version != m_version)) {
tvRefcountedDecRef(tv);
@@ -1512,7 +1512,7 @@ Object c_Map::t_filter(CVarRef callback) {
Variant ret;
int32_t version = m_version;
TypedValue args[1];
tvDup(&p.data, args + 0);
tvDup(p.data, args[0]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), ctx, 1, args);
if (UNLIKELY(version != m_version)) {
throw_collection_modified();
@@ -2262,7 +2262,7 @@ c_StableMap* c_StableMap::clone() {
Bucket *last = nullptr;
for (Bucket* p = m_pListHead; p; p = p->pListNext) {
Bucket *np = NEW(Bucket)();
tvDup(&p->data, &np->data);
tvDup(p->data, np->data);
uint nIndex;
if (p->hasIntKey()) {
np->setIntKey(p->ikey);
@@ -2516,7 +2516,7 @@ Object c_StableMap::t_values() {
Bucket* p = m_pListHead;
for (int64_t i = 0; i < sz; ++i) {
assert(p);
tvDup(&p->data, &data[i]);
tvDup(p->data, data[i]);
p = p->pListNext;
}
return ret;
@@ -2648,7 +2648,7 @@ Object c_StableMap::t_map(CVarRef callback) {
Variant ret;
int32_t version = m_version;
TypedValue args[1];
tvDup(&p->data, args + 0);
tvDup(p->data, args[0]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), ctx, 1, args);
if (UNLIKELY(version != m_version)) {
throw_collection_modified();
@@ -2691,7 +2691,7 @@ Object c_StableMap::t_filter(CVarRef callback) {
Variant ret;
int32_t version = m_version;
TypedValue args[1];
tvDup(&p->data, args + 0);
tvDup(p->data, args[0]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), ctx, 1, args);
if (UNLIKELY(version != m_version)) {
throw_collection_modified();
@@ -3636,7 +3636,7 @@ Object c_Set::t_map(CVarRef callback) {
TypedValue* tv = &np.data;
int32_t version = m_version;
TypedValue args[1];
tvDup(&p.data, args + 0);
tvDup(p.data, args[0]);
g_vmContext->invokeFuncFew(tv, ctx, 1, args);
if (UNLIKELY(version != m_version)) {
tvRefcountedDecRef(tv);
@@ -3664,7 +3664,7 @@ Object c_Set::t_filter(CVarRef callback) {
Variant ret;
int32_t version = m_version;
TypedValue args[1];
tvDup(&p.data, args + 0);
tvDup(p.data, args[0]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), ctx, 1, args);
if (UNLIKELY(version != m_version)) {
throw_collection_modified();
@@ -4271,8 +4271,8 @@ c_Pair* c_Pair::clone() {
auto pair = NEWOBJ(c_Pair)();
pair->incRefCount();
pair->m_size = 2;
tvDup(&elm0, &pair->elm0);
tvDup(&elm1, &pair->elm1);
tvDup(elm0, pair->elm0);
tvDup(elm1, pair->elm1);
return pair;
}
@@ -4375,7 +4375,7 @@ Object c_Pair::t_map(CVarRef callback) {
vec->reserve(2);
for (uint64_t i = 0; i < 2; ++i) {
TypedValue args[1];
tvDup(&getElms()[i], args + 0);
tvDup(getElms()[i], args[0]);
g_vmContext->invokeFuncFew(&vec->m_data[i], ctx, 1, args);
++vec->m_size;
}
@@ -4395,7 +4395,7 @@ Object c_Pair::t_filter(CVarRef callback) {
for (uint64_t i = 0; i < 2; ++i) {
Variant ret;
TypedValue args[1];
tvDup(&getElms()[i], args + 0);
tvDup(getElms()[i], args[0]);
g_vmContext->invokeFuncFew(ret.asTypedValue(), ctx, 1, args);
if (ret.toBoolean()) {
vec->add(&getElms()[i]);
+1 -1
Ver Arquivo
@@ -650,7 +650,7 @@ class c_StableMap : public ExtObjectDataFlags<ObjectData::StableMapAttrInit|
}
explicit Bucket(TypedValue* tv) : ikey(0), pListNext(nullptr),
pListLast(nullptr), pNext(nullptr) {
tvDup(tv, &data);
tvDup(*tv, data);
data.hash() = 0;
}
~Bucket();
+17 -17
Ver Arquivo
@@ -1750,7 +1750,7 @@ void VMExecutionContext::invokeFunc(TypedValue* retval,
// (i.e. the last extra arg has the lowest address)
to = extraArgs->getExtraArg(paramId - numParams);
}
tvDup(from, to);
tvDup(*from, *to);
if (LIKELY(!f->byRef(paramId))) {
if (to->m_type == KindOfRef) {
tvUnbox(to);
@@ -1875,7 +1875,7 @@ void VMExecutionContext::invokeContFunc(const Func* f,
ar->setVarEnv(nullptr);
if (param != nullptr) {
tvDup(param, m_stack.allocTV());
tvDup(*param, *m_stack.allocTV());
}
TypedValue retval;
@@ -3029,7 +3029,7 @@ VMExecutionContext::getElem(TypedValue* base, TypedValue* key,
tvWriteUninit(dest);
TypedValue* result = Elem<true>(*dest, *dest, base, key);
if (result != dest) {
tvDup(result, dest);
tvDup(*result, *dest);
}
}
@@ -3272,7 +3272,7 @@ inline bool OPTBLD_INLINE VMExecutionContext::memberHelperPre(
if (base != &tvScratch) {
// Acquire a reference to the result via tvDup(); base points to the
// result but does not own a reference.
tvDup(base, &tvScratch);
tvDup(*base, tvScratch);
}
}
@@ -4291,7 +4291,7 @@ static void raise_undefined_local(ActRec* fp, Id pind) {
static inline void cgetl_inner_body(TypedValue* fr, TypedValue* to) {
assert(fr->m_type != KindOfUninit);
tvDup(fr, to);
tvDup(*fr, *to);
if (to->m_type == KindOfRef) {
tvUnbox(to);
}
@@ -4403,10 +4403,10 @@ inline void OPTBLD_INLINE VMExecutionContext::iopCGetG(PC& pc) {
name->data()); \
} \
if (box) { \
if (val->m_type != KindOfRef) { \
if (val->m_type != KindOfRef) { \
tvBox(val); \
} \
tvDupVar(val, output); \
varDup(*val, *output); \
} else { \
tvReadCell(val, output); \
} \
@@ -4444,7 +4444,7 @@ static inline void vgetl_body(TypedValue* fr, TypedValue* to) {
if (fr->m_type != KindOfRef) {
tvBox(fr);
}
tvDup(fr, to);
tvDup(*fr, *to);
}
inline void OPTBLD_INLINE VMExecutionContext::iopVGetL(PC& pc) {
@@ -4495,7 +4495,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopVGetM(PC& pc) {
if (base->m_type != KindOfRef) {
tvBox(base);
}
tvDupVar(base, tv1);
varDup(*base, *tv1);
} else {
tvWriteNull(tv1);
tvBox(tv1);
@@ -5771,7 +5771,7 @@ void VMExecutionContext::iopFPassM(PC& pc) {
if (base->m_type != KindOfRef) {
tvBox(base);
}
tvDupVar(base, tv1);
varDup(*base, *tv1);
} else {
tvWriteNull(tv1);
tvBox(tv1);
@@ -6007,9 +6007,9 @@ bool VMExecutionContext::prepareArrayArgs(ActRec* ar,
return false;
}
}
tvDup(from, to);
tvDup(*from, *to);
} else {
tvDup(from, to);
tvDup(*from, *to);
if (UNLIKELY(to->m_type == KindOfRef)) {
tvUnbox(to);
}
@@ -6020,7 +6020,7 @@ bool VMExecutionContext::prepareArrayArgs(ActRec* ar,
ExtraArgs* extraArgs = ExtraArgs::allocateUninit(extra);
for (int i = 0; i < extra; ++i) {
TypedValue* to = extraArgs->getExtraArg(i);
tvDup(args->getValueRef(pos).asTypedValue(), to);
tvDup(*args->getValueRef(pos).asTypedValue(), *to);
if (to->m_type == KindOfRef && to->m_data.pref->_count == 2) {
tvUnbox(to);
}
@@ -6535,7 +6535,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopStaticLocInit(PC& pc) {
assert(fr != nullptr);
if (!inited) {
Cell* initVal = m_stack.topC();
tvDup(initVal, fr);
tvDup(*initVal, *fr);
}
if (fr->m_type != KindOfRef) {
assert(!inited);
@@ -6709,7 +6709,7 @@ static inline void setContVar(const Func* genFunc,
if (destId != kInvalidId) {
// Copy the value of the local to the cont object and set the
// local to uninit so that we don't need to change refcounts.
tvTeleport(src, frame_local(cont->actRec(), destId));
tvCopy(*src, *frame_local(cont->actRec(), destId));
tvWriteUninit(src);
} else {
ActRec *contFP = cont->actRec();
@@ -6896,7 +6896,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContSend(PC& pc) {
NEXT();
// prepare value to be sent by ContEnter
tvTeleport(frame_local(m_fp, 0), m_stack.allocTV());
tvCopy(*frame_local(m_fp, 0), *m_stack.allocTV());
tvWriteUninit(frame_local(m_fp, 0));
}
@@ -6907,7 +6907,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopContRaise(PC& pc) {
--cont->m_label;
// prepare exception to be sent by ContEnter
tvTeleport(frame_local(m_fp, 0), m_stack.allocTV());
tvCopy(*frame_local(m_fp, 0), *m_stack.allocTV());
tvWriteUninit(frame_local(m_fp, 0));
}
+3 -3
Ver Arquivo
@@ -628,10 +628,10 @@ public:
assert(m_top != m_base);
assert(m_top != m_elms);
assert(m_top->m_type != KindOfRef);
Cell* fr = (Cell*)m_top;
Cell* fr = m_top;
m_top--;
Cell* to = (Cell*)m_top;
tvDupCell(fr, to);
Cell* to = m_top;
cellDup(*fr, *to);
}
inline void ALWAYS_INLINE box() {
+2 -2
Ver Arquivo
@@ -880,7 +880,7 @@ Class::PropInitVec* Class::initPropsImpl() const {
auto const* value = propArr->nvGet(k);
assert(value);
tvDup(value, &prop);
tvDup(*value, prop);
}
}
}
@@ -2590,7 +2590,7 @@ void Class::PropInitVec::push_back(const TypedValue& v) {
m_data = (TypedValueAux*)realloc(m_data, size * sizeof(*m_data));
assert(m_data);
}
tvDup(&v, &m_data[m_size++]);
tvDup(v, m_data[m_size++]);
}
using Transl::TargetCache::handleToRef;
+1 -1
Ver Arquivo
@@ -163,7 +163,7 @@ bool EventHook::RunInterceptHandler(ActRec* ar) {
frame_free_locals_inl_no_hook<true>(ar, ar->m_func->numLocals());
Stack& stack = g_vmContext->getStack();
stack.top() = (Cell*)(ar + 1);
tvDup(ret.asTypedValue(), stack.allocTV());
tvDup(*ret.asTypedValue(), *stack.allocTV());
g_vmContext->m_fp = outer;
g_vmContext->m_pc = outer ? outer->m_func->unit()->at(pcOff) : nullptr;
+18 -13
Ver Arquivo
@@ -624,7 +624,7 @@ Variant Instance::t___destruct() {
const Func* method = m_cls->lookupMethod(sd__destruct);
if (method) {
Variant v;
g_vmContext->invokeFuncFew((TypedValue*)&v, method, this);
g_vmContext->invokeFuncFew(v.asTypedValue(), method, this);
return v;
} else {
return uninit_null();
@@ -637,9 +637,10 @@ Variant Instance::t___call(Variant v_name, Variant v_arguments) {
if (method) {
Variant v;
TypedValue args[2];
tvDup(v_name.asTypedValue(), args + 0);
tvDup(v_arguments.asTypedValue(), args + 1);
g_vmContext->invokeFuncFew((TypedValue*)&v, method, this, nullptr, 2, args);
tvDup(*v_name.asTypedValue(), args[0]);
tvDup(*v_arguments.asTypedValue(), args[1]);
g_vmContext->invokeFuncFew(v.asTypedValue(), method, this, nullptr, 2,
args);
return v;
} else {
return uninit_null();
@@ -650,7 +651,7 @@ Variant Instance::t___set(Variant v_name, Variant v_value) {
const Func* method = m_cls->lookupMethod(s___set.get());
if (method) {
Variant v;
g_vmContext->invokeFunc((TypedValue*)&v, method,
g_vmContext->invokeFunc(v.asTypedValue(), method,
Array(ArrayInit(2).set(v_name).set(withRefBind(v_value)).create()),
this);
return v;
@@ -664,8 +665,9 @@ Variant Instance::t___get(Variant v_name) {
if (method) {
Variant v;
TypedValue args[1];
tvDup(v_name.asTypedValue(), args + 0);
g_vmContext->invokeFuncFew((TypedValue*)&v, method, this, nullptr, 1, args);
tvDup(*v_name.asTypedValue(), args[0]);
g_vmContext->invokeFuncFew(v.asTypedValue(), method, this, nullptr, 1,
args);
return v;
} else {
return uninit_null();
@@ -677,8 +679,9 @@ bool Instance::t___isset(Variant v_name) {
if (method) {
Variant v;
TypedValue args[1];
tvDup(v_name.asTypedValue(), args + 0);
g_vmContext->invokeFuncFew((TypedValue*)&v, method, this, nullptr, 1, args);
tvDup(*v_name.asTypedValue(), args[0]);
g_vmContext->invokeFuncFew(v.asTypedValue(), method, this, nullptr, 1,
args);
return v.toBoolean();
} else {
return false;
@@ -690,8 +693,9 @@ Variant Instance::t___unset(Variant v_name) {
if (method) {
Variant v;
TypedValue args[1];
tvDup(v_name.asTypedValue(), args + 0);
g_vmContext->invokeFuncFew((TypedValue*)&v, method, this, nullptr, 1, args);
tvDup(*v_name.asTypedValue(), args[0]);
g_vmContext->invokeFuncFew(v.asTypedValue(), method, this, nullptr, 1,
args);
return v;
} else {
return uninit_null();
@@ -729,8 +733,9 @@ Variant Instance::t___set_state(Variant v_properties) {
if (method) {
Variant v;
TypedValue args[1];
tvDup(v_properties.asTypedValue(), args + 0);
g_vmContext->invokeFuncFew((TypedValue*)&v, method, this, nullptr, 1, args);
tvDup(*v_properties.asTypedValue(), args[0]);
g_vmContext->invokeFuncFew(v.asTypedValue(), method, this, nullptr, 1,
args);
return v;
} else {
return false;
+2 -2
Ver Arquivo
@@ -2015,7 +2015,7 @@ void setWithRefElemC(TypedValue* base, TypedValue keyVal, TypedValue* val,
MInstrState* mis) {
base = HPHP::ElemD<false, false>(mis->tvScratch, mis->tvRef, base, &keyVal);
if (base != &mis->tvScratch) {
tvDup(val, base);
tvDup(*val, *base);
} else {
assert(base->m_type == KindOfUninit);
}
@@ -2025,7 +2025,7 @@ void setWithRefNewElem(TypedValue* base, TypedValue* val,
MInstrState* mis) {
base = NewElem(mis->tvScratch, mis->tvRef, base);
if (base != &mis->tvScratch) {
tvDup(val, base);
tvDup(*val, *base);
} else {
assert(base->m_type == KindOfUninit);
}
+5 -5
Ver Arquivo
@@ -1007,13 +1007,13 @@ inline void IncDecBody(unsigned char op, TypedValue* fr,
case PreInc: {
++(fr->m_data.num);
if (setResult) {
tvDupCell(fr, to);
cellDup(*fr, *to);
}
break;
}
case PostInc: {
if (setResult) {
tvDupCell(fr, to);
cellDup(*fr, *to);
}
++(fr->m_data.num);
break;
@@ -1021,13 +1021,13 @@ inline void IncDecBody(unsigned char op, TypedValue* fr,
case PreDec: {
--(fr->m_data.num);
if (setResult) {
tvDupCell(fr, to);
cellDup(*fr, *to);
}
break;
}
case PostDec: {
if (setResult) {
tvDupCell(fr, to);
cellDup(*fr, *to);
}
--(fr->m_data.num);
break;
@@ -1440,7 +1440,7 @@ inline bool IssetEmptyElem(TypedValue& tvScratch, TypedValue& tvRef,
case KindOfString: {
TypedValue tv;
initScratchKey<keyType>(scratch, key);
tvDup(key, &tv);
tvDup(*key, tv);
tvCastToInt64InPlace(&tv);
int64_t x = tv.m_data.num;
if (x < 0 || x >= base->m_data.pstr->size()) {
+1 -1
Ver Arquivo
@@ -484,7 +484,7 @@ int init_closure(ActRec* ar, TypedValue* sp) {
TypedValue* prop = closure->getUseVars();
int n = closure->getNumUseVars();
for (int i=0; i < n; i++) {
tvDup(prop++, --sp);
tvDup(*prop++, *--sp);
}
return n + 1;