Remove Variant::GetTypedAccessor

This stuff almost is an abstraction layer, but it's in a
strange place.  Also, the layout of TypedValue isn't something we've
been using through an abstraction layer, and if we want to later I
think we won't want to do so using this one.
Esse commit está contido em:
Jordan DeLong
2013-06-09 15:41:08 -07:00
commit de sgolemon
commit 9e56c78038
16 arquivos alterados com 176 adições e 291 exclusões
+1 -1
Ver Arquivo
@@ -1699,7 +1699,7 @@ void EmitterVisitor::visit(FileScopePtr file) {
} else {
assert(!IS_REFCOUNTED_TYPE(v.getType()));
}
mainReturn = *v.getTypedAccessor();
mainReturn = *v.asCell();
m_ue.returnSeen();
}
break;
@@ -233,7 +233,7 @@ bool UnaryOpExpression::preCompute(CVarRef value, Variant &result) {
case '-':
result = value.negate(); break;
case '~':
result = ~value; break;
result = value.bitNot(); break;
case '@':
result = value; break;
case T_INT_CAST:
+32 -32
Ver Arquivo
@@ -24,18 +24,18 @@ namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
namespace {
typedef Variant::TypedValueAccessor TypedValueAccessor;
inline bool isIntKey(TypedValueAccessor tva) {
return Variant::GetAccessorType(tva) <= KindOfInt64;
inline bool isIntKey(const Cell* cell) {
return IS_INT_KEY_TYPE(cell->m_type);
}
inline int64_t getIntKey(TypedValueAccessor tva) {
return Variant::GetInt64(tva);
inline int64_t getIntKey(const Cell* cell) {
assert(cell->m_type == KindOfInt64);
return cell->m_data.num;
}
inline StringData *getStringKey(TypedValueAccessor tva) {
return Variant::GetStringData(tva);
inline StringData* getStringKey(const Cell* cell) {
assert(IS_STRING_TYPE(cell->m_type));
return cell->m_data.pstr;
}
}
@@ -46,9 +46,9 @@ inline bool ArrayData::exists(CStrRef k) const {
inline bool ArrayData::exists(CVarRef k) const {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? exists(getIntKey(tvk)) :
exists(getStringKey(tvk));
auto const cell = k.asCell();
return isIntKey(cell) ? exists(getIntKey(cell))
: exists(getStringKey(cell));
}
inline CVarRef ArrayData::get(CStrRef k, bool error) const {
@@ -58,9 +58,9 @@ inline CVarRef ArrayData::get(CStrRef k, bool error) const {
inline CVarRef ArrayData::get(CVarRef k, bool error) const {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? get(getIntKey(tvk), error) :
get(getStringKey(tvk), error);
auto const cell = k.asCell();
return isIntKey(cell) ? get(getIntKey(cell), error)
: get(getStringKey(cell), error);
}
inline ArrayData* ArrayData::lval(CStrRef k, Variant *&ret, bool copy,
@@ -72,9 +72,9 @@ inline ArrayData* ArrayData::lval(CStrRef k, Variant *&ret, bool copy,
inline ArrayData* ArrayData::lval(CVarRef k, Variant *&ret, bool copy,
bool checkExist) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? lval(getIntKey(tvk), ret, copy, checkExist) :
lval(getStringKey(tvk), ret, copy, checkExist);
auto const cell = k.asCell();
return isIntKey(cell) ? lval(getIntKey(cell), ret, copy, checkExist)
: lval(getStringKey(cell), ret, copy, checkExist);
}
inline ArrayData *ArrayData::lvalPtr(CStrRef k, Variant *&ret, bool copy,
@@ -90,9 +90,9 @@ inline ArrayData* ArrayData::set(CStrRef k, CVarRef v, bool copy) {
inline ArrayData* ArrayData::set(CVarRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? set(getIntKey(tvk), v, copy) :
set(getStringKey(tvk), v, copy);
auto const cell = k.asCell();
return isIntKey(cell) ? set(getIntKey(cell), v, copy)
: set(getStringKey(cell), v, copy);
}
inline ArrayData* ArrayData::setRef(CStrRef k, CVarRef v, bool copy) {
@@ -102,9 +102,9 @@ inline ArrayData* ArrayData::setRef(CStrRef k, CVarRef v, bool copy) {
inline ArrayData* ArrayData::setRef(CVarRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? setRef(getIntKey(tvk), v, copy) :
setRef(getStringKey(tvk), v, copy);
auto const cell = k.asCell();
return isIntKey(cell) ? setRef(getIntKey(cell), v, copy)
: setRef(getStringKey(cell), v, copy);
}
inline ArrayData* ArrayData::add(CStrRef k, CVarRef v, bool copy) {
@@ -114,9 +114,9 @@ inline ArrayData* ArrayData::add(CStrRef k, CVarRef v, bool copy) {
inline ArrayData* ArrayData::add(CVarRef k, CVarRef v, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? add(getIntKey(tvk), v, copy) :
add(getStringKey(tvk), v, copy);
auto const cell = k.asCell();
return isIntKey(cell) ? add(getIntKey(cell), v, copy)
: add(getStringKey(cell), v, copy);
}
inline ArrayData* ArrayData::addLval(CStrRef k, Variant *&ret, bool copy) {
@@ -126,9 +126,9 @@ inline ArrayData* ArrayData::addLval(CStrRef k, Variant *&ret, bool copy) {
inline ArrayData* ArrayData::addLval(CVarRef k, Variant *&ret, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? addLval(getIntKey(tvk), ret, copy) :
addLval(getStringKey(tvk), ret, copy);
auto const cell = k.asCell();
return isIntKey(cell) ? addLval(getIntKey(cell), ret, copy)
: addLval(getStringKey(cell), ret, copy);
}
inline ArrayData* ArrayData::remove(CStrRef k, bool copy) {
@@ -138,9 +138,9 @@ inline ArrayData* ArrayData::remove(CStrRef k, bool copy) {
inline ArrayData* ArrayData::remove(CVarRef k, bool copy) {
assert(IsValidKey(k));
TypedValueAccessor tvk = k.getTypedAccessor();
return isIntKey(tvk) ? remove(getIntKey(tvk), copy) :
remove(getStringKey(tvk), copy);
auto const cell = k.asCell();
return isIntKey(cell) ? remove(getIntKey(cell), copy)
: remove(getStringKey(cell), copy);
}
///////////////////////////////////////////////////////////////////////////////
+6 -6
Ver Arquivo
@@ -1056,10 +1056,10 @@ AutoloadHandler::Result AutoloadHandler::loadFromMap(CStrRef name,
assert(!m_map.isNull());
while (true) {
CVarRef &type_map = m_map.get()->get(kind);
Variant::TypedValueAccessor tva = type_map.getTypedAccessor();
if (Variant::GetAccessorType(tva) != KindOfArray) return Failure;
auto const typeMapCell = type_map.asCell();
if (typeMapCell->m_type != KindOfArray) return Failure;
String canonicalName = toLower ? StringUtil::ToLower(name) : name;
CVarRef &file = Variant::GetArrayData(tva)->get(canonicalName);
CVarRef &file = typeMapCell->m_data.parr->get(canonicalName);
bool ok = false;
if (file.isString()) {
String fName = file.toCStrRef().get();
@@ -1095,9 +1095,9 @@ AutoloadHandler::Result AutoloadHandler::loadFromMap(CStrRef name,
// - false means we should stop applying autoloaders (only affects classes)
// - anything else means keep going
Variant action = vm_call_user_func(func, CREATE_VECTOR2(kind, name));
tva = action.getTypedAccessor();
if (Variant::GetAccessorType(tva) == KindOfBoolean) {
if (Variant::GetBoolean(tva)) continue;
auto const actionCell = action.asCell();
if (actionCell->m_type == KindOfBoolean) {
if (actionCell->m_data.num) continue;
return StopAutoloading;
}
return ContinueAutoloading;
+3 -3
Ver Arquivo
@@ -28,10 +28,10 @@ bool same(CVarRef v1, bool v2) {
}
bool same(CVarRef v1, int64_t v2) {
auto const acc = v1.getTypedAccessor();
switch (acc->m_type) {
auto const cell = v1.asCell();
switch (cell->m_type) {
case KindOfInt64:
return v2 == acc->m_data.num;
return v2 == cell->m_data.num;
default:
break;
}
+4
Ver Arquivo
@@ -227,6 +227,10 @@ BOOST_STATIC_ASSERT(KindOfString == 0x14);
#define IS_REAL_TYPE(t) \
(((t) >= KindOfUninit && (t) < MaxNumDataTypes) || (t) == KindOfClass)
inline bool IS_INT_KEY_TYPE(DataType t) {
return t <= KindOfInt64;
}
// typeReentersOnRelease --
// Returns whether the release helper for a given type can
// reenter.
+4 -4
Ver Arquivo
@@ -227,14 +227,14 @@ TypedValue* SharedMap::nvGetValueRef(ssize_t pos) {
TypedValue* SharedMap::nvGetCell(int64_t k) const {
int index = getIndex(k);
return index != -1 ? getValueRef(index).getTypedAccessor() :
nvGetNotFound(k);
return index != -1 ? const_cast<Cell*>(getValueRef(index).asCell())
: nvGetNotFound(k);
}
TypedValue* SharedMap::nvGetCell(const StringData* key) const {
int index = getIndex(key);
return index != -1 ? getValueRef(index).getTypedAccessor() :
nvGetNotFound(key);
return index != -1 ? const_cast<Cell*>(getValueRef(index).asCell())
: nvGetNotFound(key);
}
ArrayData* SharedMap::escalateForSort() {
+30 -114
Ver Arquivo
@@ -435,9 +435,9 @@ bool Variant::isScalar() const {
}
bool Variant::isResource() const {
TypedValueAccessor acc = getTypedAccessor();
if (GetAccessorType(acc) == KindOfObject) {
return GetObjectData(acc)->isResource();
auto const cell = asCell();
if (cell->m_type == KindOfObject) {
return cell->m_data.pobj->isResource();
}
return false;
}
@@ -1199,16 +1199,16 @@ Variant &Variant::operator%=(double n) {
///////////////////////////////////////////////////////////////////////////////
// bitwise
Variant Variant::operator~() const {
TypedValueAccessor tva = getTypedAccessor();
switch (GetAccessorType(tva)) {
Variant Variant::bitNot() const {
auto const cell = asCell();
switch (cell->m_type) {
case KindOfInt64:
return ~GetInt64(tva);
return ~cell->m_data.num;
case KindOfDouble:
return ~toInt64(GetDouble(tva));
return ~toInt64(cell->m_data.dbl);
case KindOfStaticString:
case KindOfString:
return ~GetAsString(tva);
return ~String(cell->m_data.pstr);
default:
break;
}
@@ -1377,9 +1377,9 @@ MutableArrayIter Variant::begin(Variant *key, Variant &val,
}
void Variant::escalate() {
TypedValueAccessor tva = getTypedAccessor();
if (GetAccessorType(tva) == KindOfArray) {
ArrayData *arr = GetArrayData(tva);
auto const cell = asCell();
if (cell->m_type == KindOfArray) {
ArrayData *arr = cell->m_data.parr;
ArrayData *esc = arr->escalate();
if (arr != esc) set(esc);
}
@@ -1545,109 +1545,25 @@ Variant::operator Object() const {
///////////////////////////////////////////////////////////////////////////////
#define UNWRAP(reverse) \
TypedValueAccessor acc = getTypedAccessor(); \
switch (GetAccessorType(acc)) { \
case KindOfUninit: \
case KindOfNull: return HPHP::reverse(v2, false); \
case KindOfBoolean: return HPHP::reverse(v2, GetBoolean(acc)); \
case KindOfInt64: return HPHP::reverse(v2, GetInt64(acc)); \
case KindOfDouble: return HPHP::reverse(v2, GetDouble(acc)); \
case KindOfStaticString: \
case KindOfString: return HPHP::reverse(v2, GetStringData(acc)); \
case KindOfArray: return HPHP::reverse(v2, Array(GetArrayData(acc))); \
case KindOfObject: return HPHP::reverse(v2, Object(GetObjectData(acc)));\
default: \
assert(false); \
break; \
} \
return false; \
// "null" needs to convert to "" before comparing with a string
#define UNWRAP_STR(reverse) \
TypedValueAccessor acc = getTypedAccessor(); \
switch (GetAccessorType(acc)) { \
case KindOfUninit: \
case KindOfNull: return HPHP::reverse(v2, empty_string); \
case KindOfBoolean: return HPHP::reverse(v2, GetBoolean(acc)); \
case KindOfInt64: return HPHP::reverse(v2, GetInt64(acc)); \
case KindOfDouble: return HPHP::reverse(v2, GetDouble(acc)); \
case KindOfStaticString: \
case KindOfString: return HPHP::reverse(v2, GetStringData(acc)); \
case KindOfArray: return HPHP::reverse(v2, Array(GetArrayData(acc))); \
case KindOfObject: return HPHP::reverse(v2, Object(GetObjectData(acc)));\
default: \
assert(false); \
break; \
} \
return false; \
// Array needs to convert to "Array" and Object to String
#define UNWRAP_STRING(reverse) \
TypedValueAccessor acc = getTypedAccessor(); \
switch (GetAccessorType(acc)) { \
case KindOfUninit: \
case KindOfNull: return HPHP::reverse(v2, empty_string); \
case KindOfBoolean: return HPHP::reverse(v2, GetBoolean(acc)); \
case KindOfInt64: return HPHP::reverse(v2, GetInt64(acc)); \
case KindOfDouble: return HPHP::reverse(v2, GetDouble(acc)); \
case KindOfStaticString: \
case KindOfString: return HPHP::reverse(v2, GetStringData(acc)); \
case KindOfArray: return HPHP::reverse(v2, s_array); \
case KindOfObject: \
return HPHP::reverse(v2, Object(GetObjectData(acc)).toString()); \
default: \
assert(false); \
break; \
} \
return false; \
// "null" needs to convert to "" before comparing with a string
#define UNWRAP_VAR(forward, reverse) \
TypedValueAccessor acc = getTypedAccessor(); \
switch (GetAccessorType(acc)) { \
case KindOfUninit: \
case KindOfNull: \
if (v2.isString()) { \
return HPHP::reverse(v2.getStringData(), empty_string); \
} \
return HPHP::reverse(v2, false); \
case KindOfBoolean: return HPHP::reverse(v2, GetBoolean(acc)); \
case KindOfInt64: return HPHP::reverse(v2, GetInt64(acc)); \
case KindOfDouble: return HPHP::reverse(v2, GetDouble(acc)); \
case KindOfStaticString: \
case KindOfString: return HPHP::reverse(v2, GetStringData(acc)); \
case KindOfArray: \
if (v2.isArray()) { \
return Array(GetArrayData(acc)).forward(Array(v2.getArrayData())); \
} \
return HPHP::reverse(v2, Array(GetArrayData(acc))); \
case KindOfObject: return HPHP::reverse(v2, Object(GetObjectData(acc)));\
default: \
assert(false); \
break; \
} \
return false; \
// array comparison is directional when they are uncomparable
// also, ">" is implemented as "!<=" in Zend
#define UNWRAP_ARR(forward, reverse) \
TypedValueAccessor acc = getTypedAccessor(); \
switch (GetAccessorType(acc)) { \
case KindOfUninit: \
case KindOfNull: return HPHP::reverse(v2, false); \
case KindOfBoolean: return HPHP::reverse(v2, GetBoolean(acc)); \
case KindOfInt64: return HPHP::reverse(v2, GetInt64(acc)); \
case KindOfDouble: return HPHP::reverse(v2, GetDouble(acc)); \
case KindOfStaticString: \
case KindOfString: return HPHP::reverse(v2, GetStringData(acc)); \
case KindOfArray: return Array(GetArrayData(acc)).forward(v2); \
case KindOfObject: return HPHP::reverse(v2, Object(GetObjectData(acc)));\
default: \
assert(false); \
break; \
} \
return false; \
#define UNWRAP_STRING(reverse) \
auto const cell = asCell(); \
switch (cell->m_type) { \
case KindOfUninit: \
case KindOfNull: return HPHP::reverse(v2, empty_string); \
case KindOfBoolean: return HPHP::reverse(v2, !!cell->m_data.num); \
case KindOfInt64: return HPHP::reverse(v2, cell->m_data.num); \
case KindOfDouble: return HPHP::reverse(v2, cell->m_data.dbl); \
case KindOfStaticString: \
case KindOfString: return HPHP::reverse(v2, cell->m_data.pstr); \
case KindOfArray: return HPHP::reverse(v2, s_array); \
case KindOfObject: \
return HPHP::reverse(v2, Object(cell->m_data.pobj).toString()); \
default: \
assert(false); \
break; \
} \
return false;
bool Variant::equalAsStr(bool v2) const { UNWRAP_STRING(equalAsStr);}
bool Variant::equalAsStr(int v2) const { UNWRAP_STRING(equalAsStr);}
+7 -64
Ver Arquivo
@@ -585,7 +585,6 @@ class Variant : private TypedValue {
Variant &operator %= (int64_t n);
Variant &operator %= (double n);
Variant operator ~ () const;
Variant operator | (CVarRef v) const;
Variant &operator |= (CVarRef v);
Variant operator & (CVarRef v) const;
@@ -600,6 +599,10 @@ class Variant : private TypedValue {
Variant &operator -- ();
Variant operator -- (int);
// Return the result of applying the php bitwise not operator to
// this value.
Variant bitNot() const;
/**
* Iterator functions. See array_iterator.h for end() and next().
*/
@@ -987,65 +990,6 @@ class Variant : private TypedValue {
const Cell* asCell() const { return tvToCell(asTypedValue()); }
Cell* asCell() { return tvToCell(asTypedValue()); }
/**
* Based on the order in complex_types.h, TypedValue is defined before.
* TypedValue is binary compatible with Variant
*/
typedef struct TypedValue* TypedValueAccessor;
TypedValueAccessor getTypedAccessor() const {
const Variant *value = m_type == KindOfRef ? m_data.pref->var() : this;
return (TypedValueAccessor)value;
}
static DataType GetAccessorType(TypedValueAccessor acc) {
assert(acc);
return acc->m_type;
}
static bool GetBoolean(TypedValueAccessor acc) {
assert(acc && acc->m_type == KindOfBoolean);
return acc->m_data.num;
}
static int64_t GetInt64(TypedValueAccessor acc) {
assert(acc);
assert(acc->m_type == KindOfInt64);
return acc->m_data.num;
}
static double GetDouble(TypedValueAccessor acc) {
assert(acc && acc->m_type == KindOfDouble);
return acc->m_data.dbl;
}
static bool IsString(TypedValueAccessor acc) {
return IS_STRING_TYPE(acc->m_type);
}
static StringData *GetStringData(TypedValueAccessor acc) {
assert(acc && IS_STRING_TYPE(acc->m_type));
return acc->m_data.pstr;
}
static ArrayData *GetArrayData(TypedValueAccessor acc) {
assert(acc && acc->m_type == KindOfArray);
return acc->m_data.parr;
}
static ObjectData *GetObjectData(TypedValueAccessor acc) {
assert(acc && acc->m_type == KindOfObject);
return acc->m_data.pobj;
}
static ObjectData *GetArrayAccess(TypedValueAccessor acc) {
assert(acc && acc->m_type == KindOfObject);
ObjectData *obj = acc->m_data.pobj;
if (!obj->instanceof(SystemLib::s_ArrayAccessClass)) {
throw InvalidOperandException("not ArrayAccess objects");
}
return obj;
}
static Array& GetAsArray(TypedValueAccessor acc) {
assert(acc && acc->m_type == KindOfArray);
return *reinterpret_cast<Array*>(&acc->m_data.parr);
}
static String& GetAsString(TypedValueAccessor acc) {
assert(IsString(acc));
return *reinterpret_cast<String*>(&acc->m_data.pstr);
}
private:
bool isPrimitive() const { return !IS_REFCOUNTED_TYPE(m_type); }
bool isObjectConvertable() {
@@ -1270,9 +1214,11 @@ public:
return *const_cast<VRefParamValue*>(this);
}
operator Variant&() const { return m_var; }
Variant *operator&() const { return &m_var; }
Variant *operator&() const { return &m_var; } // FIXME
Variant *operator->() const { return &m_var; }
Variant& wrapped() const { return m_var; }
explicit operator bool () const { return m_var.toBoolean();}
operator int () const { return m_var.toInt32();}
operator int64_t () const { return m_var.toInt64();}
@@ -1316,9 +1262,6 @@ public:
Variant array_iter_key() const { return m_var.array_iter_key(); }
Variant array_iter_each() const { return m_var.array_iter_each(); }
Variant::TypedValueAccessor getTypedAccessor() const {
return m_var.getTypedAccessor();
}
private:
mutable Variant m_var;
};
+10 -6
Ver Arquivo
@@ -177,12 +177,16 @@ void StringBuffer::append(int64_t n) {
}
void StringBuffer::append(CVarRef v) {
Variant::TypedValueAccessor tva = v.getTypedAccessor();
if (Variant::IsString(tva)) {
append(Variant::GetAsString(tva));
} else if (IS_INT_TYPE(Variant::GetAccessorType(tva))) {
append(Variant::GetInt64(tva));
} else {
auto const cell = v.asCell();
switch (cell->m_type) {
case KindOfStaticString:
case KindOfString:
append(cell->m_data.pstr);
break;
case KindOfInt64:
append(cell->m_data.num);
break;
default:
append(v.toString());
}
}
+18 -11
Ver Arquivo
@@ -670,54 +670,60 @@ void VariableSerializer::writePropertyKey(CStrRef prop) {
/* key MUST be a non-reference string or int */
void VariableSerializer::writeArrayKey(Variant key) {
Variant::TypedValueAccessor tva = key.getTypedAccessor();
bool skey = Variant::IsString(tva);
auto const keyCell = key.asCell();
bool const skey = IS_STRING_TYPE(keyCell->m_type);
if (skey && m_type == APCSerialize) {
write(Variant::GetAsString(tva));
write(StrNR(keyCell->m_data.pstr).asString());
return;
}
ArrayInfo &info = m_arrayInfos.back();
switch (m_type) {
case DebuggerDump:
case PrintR: {
indent();
m_buf->append('[');
if (info.is_object && skey) {
writePropertyKey(Variant::GetAsString(tva));
writePropertyKey(keyCell->m_data.pstr);
} else {
m_buf->append(key);
}
m_buf->append("] => ");
break;
}
case VarExport:
case PHPOutput:
indent();
write(key, true);
m_buf->append(" => ");
break;
case VarDump:
case DebugDump:
indent();
m_buf->append('[');
if (!skey) {
m_buf->append(Variant::GetInt64(tva));
m_buf->append(keyCell->m_data.num);
} else {
m_buf->append('"');
if (info.is_object) {
writePropertyKey(Variant::GetAsString(tva));
writePropertyKey(keyCell->m_data.pstr);
} else {
m_buf->append(Variant::GetAsString(tva));
m_buf->append(keyCell->m_data.pstr);
m_buf->append('"');
}
}
m_buf->append("]=>\n");
break;
case APCSerialize:
case Serialize:
case DebuggerSerialize:
write(key);
break;
case JSON:
if (!info.first_element) {
m_buf->append(',');
@@ -728,9 +734,9 @@ void VariableSerializer::writeArrayKey(Variant key) {
}
if (!info.is_vector) {
if (skey) {
CStrRef s = Variant::GetAsString(tva);
const char *k = s.data();
int len = s.size();
auto const sdata = keyCell->m_data.pstr;
const char *k = sdata->data();
int len = sdata->size();
if (info.is_object && !*k && len) {
while (*++k) len--;
k++;
@@ -739,7 +745,7 @@ void VariableSerializer::writeArrayKey(Variant key) {
write(k, len);
} else {
m_buf->append('"');
m_buf->append(Variant::GetInt64(tva));
m_buf->append(keyCell->m_data.num);
m_buf->append('"');
}
m_buf->append(':');
@@ -748,6 +754,7 @@ void VariableSerializer::writeArrayKey(Variant key) {
}
}
break;
default:
assert(false);
break;
+40 -29
Ver Arquivo
@@ -65,16 +65,15 @@ const int64_t k_UCOL_NUMERIC_COLLATION = UCOL_NUMERIC_COLLATION;
using HPHP::Transl::CallerFrame;
using HPHP::Transl::EagerCallerFrame;
#define getCheckedArrayRetType(input, fail, type) \
Variant::TypedValueAccessor tva_##input = input.getTypedAccessor(); \
if (UNLIKELY(Variant::GetAccessorType(tva_##input) != KindOfArray)) { \
throw_bad_array_exception(); \
return fail; \
} \
type arr_##input = Variant::GetAsArray(tva_##input);
#define getCheckedArrayRet(input, fail) \
auto const cell_##input = static_cast<CVarRef>(input).asCell(); \
if (UNLIKELY(cell_##input->m_type != KindOfArray)) { \
throw_bad_array_exception(); \
return fail; \
} \
ArrNR arrNR_##input(cell_##input->m_data.parr); \
CArrRef arr_##input = arrNR_##input.asArray();
#define getCheckedArrayRet(input, fail) \
getCheckedArrayRetType(input, fail, CArrRef)
#define getCheckedArray(input) getCheckedArrayRet(input, uninit_null())
Variant f_array_change_key_case(CVarRef input, bool upper /* = false */) {
@@ -191,12 +190,12 @@ Variant f_array_flip(CVarRef trans) {
HOT_FUNC
bool f_array_key_exists(CVarRef key, CVarRef search) {
const ArrayData *ad;
Variant::TypedValueAccessor sacc = search.getTypedAccessor();
DataType saccType = Variant::GetAccessorType(sacc);
if (LIKELY(saccType == KindOfArray)) {
ad = Variant::GetArrayData(sacc);
} else if (saccType == KindOfObject) {
ObjectData* obj = Variant::GetObjectData(sacc);
auto const searchCell = search.asCell();
if (LIKELY(searchCell->m_type == KindOfArray)) {
ad = searchCell->m_data.parr;
} else if (searchCell->m_type == KindOfObject) {
ObjectData* obj = searchCell->m_data.pobj;
if (obj->isCollection()) {
return collectionOffsetContains(obj, key);
}
@@ -206,19 +205,20 @@ bool f_array_key_exists(CVarRef key, CVarRef search) {
"false returned.");
return false;
}
Variant::TypedValueAccessor kacc = key.getTypedAccessor();
switch (Variant::GetAccessorType(kacc)) {
auto const cell = key.asCell();
switch (cell->m_type) {
case KindOfString:
case KindOfStaticString: {
int64_t n = 0;
StringData *sd = Variant::GetStringData(kacc);
StringData *sd = cell->m_data.pstr;
if (sd->isStrictlyInteger(n)) {
return ad->exists(n);
}
return ad->exists(StrNR(sd));
}
case KindOfInt64:
return ad->exists(Variant::GetInt64(kacc));
return ad->exists(cell->m_data.num);
case KindOfUninit:
case KindOfNull:
return ad->exists(empty_string);
@@ -445,7 +445,18 @@ Variant f_array_product(CVarRef array) {
}
Variant f_array_push(int _argc, VRefParam array, CVarRef var, CArrRef _argv /* = null_array */) {
getCheckedArrayRetType(array, uninit_null(), Array &);
auto const array_cell = array.wrapped().asCell();
if (UNLIKELY(array_cell->m_type != KindOfArray)) {
throw_bad_array_exception();
return uninit_null();
}
/*
* Important note: this *must* cast the parr in the inner cell to
* the Array&---we can't copy it to the stack or anything because we
* might escalate.
*/
Array& arr_array = *reinterpret_cast<Array*>(&array_cell->m_data.parr);
arr_array.append(var);
for (ArrayIter iter(_argv); iter; ++iter) {
arr_array.append(iter.second());
@@ -1086,7 +1097,7 @@ class ArraySortTmp {
static bool
php_sort(VRefParam array, int sort_flags, bool ascending, bool use_collator) {
if (array.isArray()) {
Array& arr_array = Variant::GetAsArray(array.getTypedAccessor());
Array& arr_array = array.wrapped().toArrRef();
if (use_collator && sort_flags != SORT_LOCALE_STRING) {
UCollator *coll = s_collator->getCollator();
if (coll) {
@@ -1114,7 +1125,7 @@ php_sort(VRefParam array, int sort_flags, bool ascending, bool use_collator) {
static bool
php_asort(VRefParam array, int sort_flags, bool ascending, bool use_collator) {
if (array.isArray()) {
Array& arr_array = Variant::GetAsArray(array.getTypedAccessor());
Array& arr_array = array.wrapped().toArrRef();
if (use_collator && sort_flags != SORT_LOCALE_STRING) {
UCollator *coll = s_collator->getCollator();
if (coll) {
@@ -1142,7 +1153,7 @@ php_asort(VRefParam array, int sort_flags, bool ascending, bool use_collator) {
static bool
php_ksort(VRefParam array, int sort_flags, bool ascending) {
if (array.isArray()) {
Array& arr_array = Variant::GetAsArray(array.getTypedAccessor());
Array& arr_array = array.wrapped().toArrRef();
ArraySortTmp ast(arr_array);
ast->ksort(sort_flags, ascending);
return true;
@@ -1201,7 +1212,7 @@ Variant f_natcasesort(VRefParam array) {
bool f_usort(VRefParam array, CVarRef cmp_function) {
if (array.isArray()) {
Array& arr_array = Variant::GetAsArray(array.getTypedAccessor());
Array& arr_array = array.wrapped().toArrRef();
ArraySortTmp ast(arr_array);
ast->usort(cmp_function);
return true;
@@ -1220,7 +1231,7 @@ bool f_usort(VRefParam array, CVarRef cmp_function) {
bool f_uasort(VRefParam array, CVarRef cmp_function) {
if (array.isArray()) {
Array& arr_array = Variant::GetAsArray(array.getTypedAccessor());
Array& arr_array = array.wrapped().toArrRef();
ArraySortTmp ast(arr_array);
ast->uasort(cmp_function);
return true;
@@ -1239,7 +1250,7 @@ bool f_uasort(VRefParam array, CVarRef cmp_function) {
bool f_uksort(VRefParam array, CVarRef cmp_function) {
if (array.isArray()) {
Array& arr_array = Variant::GetAsArray(array.getTypedAccessor());
Array& arr_array = array.wrapped().toArrRef();
ArraySortTmp ast(arr_array);
ast->uksort(cmp_function);
return true;
@@ -1273,8 +1284,8 @@ bool f_array_multisort(int _argc, VRefParam ar1,
bool ascending = true;
for (int i = 0; i < _argv.size(); i++) {
Variant *v = &((Array&)_argv).lvalAt(i);
Variant::TypedValueAccessor tva = v->getTypedAccessor();
if (Variant::GetAccessorType(tva) == KindOfArray) {
auto const cell = v->asCell();
if (cell->m_type == KindOfArray) {
sd.cmp_func = get_cmp_func(sort_flags, ascending);
data.push_back(sd);
@@ -1282,7 +1293,7 @@ bool f_array_multisort(int _argc, VRefParam ar1,
ascending = true;
sd.original = v;
arrays.push_back(Variant::GetAsArray(tva));
arrays.push_back(Array(cell->m_data.parr));
sd.array = &arrays.back();
} else {
int n = v->toInt32();
+15 -15
Ver Arquivo
@@ -74,14 +74,14 @@ bool f_is_callable(CVarRef v, bool syntax /* = false */,
if (!name.isReferenced()) return ret;
}
Variant::TypedValueAccessor tv_func = v.getTypedAccessor();
if (Variant::IsString(tv_func)) {
if (name.isReferenced()) name = Variant::GetStringData(tv_func);
auto const tv_func = v.asCell();
if (IS_STRING_TYPE(tv_func->m_type)) {
if (name.isReferenced()) name = tv_func->m_data.pstr;
return ret;
}
if (Variant::GetAccessorType(tv_func) == KindOfArray) {
CArrRef arr = Variant::GetAsArray(tv_func);
if (tv_func->m_type == KindOfArray) {
CArrRef arr = tv_func->m_data.parr;
CVarRef clsname = arr.rvalAtRef(int64_t(0));
CVarRef mthname = arr.rvalAtRef(int64_t(1));
if (arr.size() != 2 ||
@@ -91,28 +91,28 @@ bool f_is_callable(CVarRef v, bool syntax /* = false */,
return false;
}
Variant::TypedValueAccessor tv_meth = mthname.getTypedAccessor();
if (!Variant::IsString(tv_meth)) {
auto const tv_meth = mthname.asCell();
if (!IS_STRING_TYPE(tv_meth->m_type)) {
if (name.isReferenced()) name = v.toString();
return false;
}
Variant::TypedValueAccessor tv_cls = clsname.getTypedAccessor();
if (Variant::GetAccessorType(tv_cls) == KindOfObject) {
name = Variant::GetObjectData(tv_cls)->o_getClassName();
} else if (Variant::IsString(tv_cls)) {
name = Variant::GetStringData(tv_cls);
auto const tv_cls = clsname.asCell();
if (tv_cls->m_type == KindOfObject) {
name = tv_cls->m_data.pobj->o_getClassName();
} else if (IS_STRING_TYPE(tv_cls->m_type)) {
name = tv_cls->m_data.pstr;
} else {
name = v.toString();
return false;
}
name = concat3(name, s_colon2, Variant::GetAsString(tv_meth));
name = concat3(name, s_colon2, tv_meth->m_data.pstr);
return ret;
}
if (Variant::GetAccessorType(tv_func) == KindOfObject) {
ObjectData *d = Variant::GetObjectData(tv_func);
if (tv_func->m_type == KindOfObject) {
ObjectData *d = tv_func->m_data.pobj;
const Func* invoke = d->getVMClass()->lookupMethod(s__invoke.get());
if (name.isReferenced()) {
if (d->instanceof(c_Closure::s_cls)) {
+1 -1
Ver Arquivo
@@ -136,7 +136,7 @@ bool f_define(CStrRef name, CVarRef value,
if (case_insensitive) {
raise_warning(Strings::CONSTANTS_CASE_SENSITIVE);
}
return Unit::defCns(name.get(), value.getTypedAccessor());
return Unit::defCns(name.get(), value.asCell());
}
bool f_defined(CStrRef name, bool autoload /* = true */) {
+3 -3
Ver Arquivo
@@ -667,11 +667,11 @@ Variant f_strcspn(CStrRef str1, CStrRef str2, int start /* = 0 */,
}
Variant f_strlen(CVarRef vstr) {
Variant::TypedValueAccessor tva = vstr.getTypedAccessor();
switch (Variant::GetAccessorType(tva)) {
auto const cell = vstr.asCell();
switch (cell->m_type) {
case KindOfString:
case KindOfStaticString:
return Variant(Variant::GetStringData(tva)->size());
return Variant(cell->m_data.pstr->size());
case KindOfArray:
raise_warning("strlen() expects parameter 1 to be string, array given");
return uninit_null();
+1 -1
Ver Arquivo
@@ -4185,7 +4185,7 @@ inline void OPTBLD_INLINE VMExecutionContext::iopBitNot(PC& pc) {
c1->m_type = KindOfInt64;
c1->m_data.num = ~int64_t(c1->m_data.dbl);
} else if (IS_STRING_TYPE(c1->m_type)) {
tvCellAsVariant(c1) = ~tvCellAsVariant(c1);
tvCellAsVariant(c1) = tvCellAsVariant(c1).bitNot();
} else {
raise_error("Unsupported operand type for ~");
}