Move bytecode.cpp use of comparisons to tv_comparisons functions

Instead of calling into the comparisons.h stuff, call into
the cell/tv functions.  This meant moving more_or_equal and
less_or_equal to tv_comparisons and moving cellToBool out of its
unnamed namespace.  Also replaces the global tv() function with some
make_tv() and make_value() thing---it looked like it was incorrect for
doubles, and since the correct compile-time type for the unconstrained
template parameter essentially depended on the runtime value of the
first parameter it seemed more reasonable to move that to
compile-time, too.
Esse commit está contido em:
Jordan DeLong
2013-06-23 16:30:17 -07:00
commit de Sara Golemon
commit afc51da4c6
13 arquivos alterados com 287 adições e 190 exclusões
@@ -543,11 +543,11 @@ ExpressionPtr BinaryOpExpression::foldConst(AnalysisResultConstPtr ar) {
case '<':
result = less(v1, v2); break;
case T_IS_SMALLER_OR_EQUAL:
result = less_or_equal(v1, v2); break;
result = cellLessOrEqual(v1.asCell(), v2.asCell()); break;
case '>':
result = more(v1, v2); break;
case T_IS_GREATER_OR_EQUAL:
result = more_or_equal(v1, v2); break;
result = cellGreaterOrEqual(v1.asCell(), v2.asCell()); break;
case '+':
result = plus(v1, v2); break;
case '-':
-32
Ver Arquivo
@@ -85,38 +85,6 @@ bool same(CVarRef v1, CObjRef v2) {
//////////////////////////////////////////////////////////////////////
bool less_or_equal(CVarRef v1, CVarRef v2) {
// To be PHP-compatible, when comparing two arrays or two objects we
// cannot assume that "($x <= $y)" is equivalent to "!($x > $y)".
if (v1.is(KindOfArray) && v2.is(KindOfArray)) {
Array a1 = v1.toArray();
Array a2 = v2.toArray();
return a1.less(a2) || a1.equal(a2);
}
if (v1.is(KindOfObject) && v2.is(KindOfObject)) {
Object o1 = v1.toObject();
Object o2 = v2.toObject();
return o1.less(o2) || o1.equal(o2);
}
return !more(v1, v2);
}
bool more_or_equal(CVarRef v1, CVarRef v2) {
// To be PHP-compatible, when comparing two arrays or two objects we
// cannot assume that "($x >= $y)" is equivalent to "!($x < $y)".
if (v1.is(KindOfArray) && v2.is(KindOfArray)) {
Array a1 = v1.toArray();
Array a2 = v2.toArray();
return a1.more(a2) || a1.equal(a2);
}
if (v1.is(KindOfObject) && v2.is(KindOfObject)) {
Object o1 = v1.toObject();
Object o2 = v2.toObject();
return o1.more(o2) || o1.equal(o2);
}
return !less(v1, v2);
}
bool equal(int v1, const StringData *v2) {
return equal((int64_t)v1, v2);
}
-9
Ver Arquivo
@@ -687,15 +687,6 @@ inline bool more(CObjRef v1, CArrRef v2) { return less(v2, v1);}
inline bool more(CObjRef v1, CObjRef v2) { return v1.more(v2);}
inline bool more(CObjRef v1, CVarRef v2) { return less(v2, v1);}
///////////////////////////////////////////////////////////////////////////////
/**
* Special-casing comparisons between arrays to get the same results from
* comparisons between uncomparable arrays.
*/
bool less_or_equal(CVarRef v1, CVarRef v2);
bool more_or_equal(CVarRef v1, CVarRef v2);
///////////////////////////////////////////////////////////////////////////////
}
+1
Ver Arquivo
@@ -483,6 +483,7 @@ private:
template <unsigned mdepth>
void setHelperPost(unsigned ndiscard, Variant& tvRef,
Variant& tvRef2);
template<class Op> void implCellBinOpBool(PC&, Op op);
bool cellInstanceOf(TypedValue* c, const HPHP::NamedEntity* s);
bool initIterator(PC& pc, PC& origPc, Iter* it,
Offset offset, Cell* c1);
+70 -3
Ver Arquivo
@@ -13,21 +13,22 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_HPHPVALUE_H_
#define incl_HPHP_HPHPVALUE_H_
#ifndef incl_HPHP_INSIDE_HPHP_COMPLEX_TYPES_H_
#error Directly including 'hphp_value.h' is prohibited. \
Include 'complex_types.h' instead.
#endif
#ifndef incl_HPHP_HPHPVALUE_H_
#define incl_HPHP_HPHPVALUE_H_
#include <type_traits>
#include "hphp/runtime/base/types.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
class Class;
class Class;
struct TypedValue;
@@ -138,6 +139,72 @@ private:
typedef TypedValue Cell;
typedef TypedValue Var;
//////////////////////////////////////////////////////////////////////
/*
* make_value and make_tv are helpers for creating TypedValues and
* Values as temporaries, without messing up the conversions.
*/
template<class T>
typename std::enable_if<
std::is_integral<T>::value,
Value
>::type make_value(T t) { Value v; v.num = t; return v; }
template<class T>
typename std::enable_if<
std::is_pointer<T>::value,
Value
>::type make_value(T t) {
Value v;
v.num = reinterpret_cast<int64_t>(t);
return v;
}
inline Value make_value(double d) { Value v; v.dbl = d; return v; }
namespace detail {
template<DataType> struct DataTypeCPPType;
#define X(dt, cpp) \
template<> struct DataTypeCPPType<dt> { typedef cpp type; }
X(KindOfNull, void);
X(KindOfBoolean, bool);
X(KindOfInt64, int64_t);
X(KindOfDouble, double);
X(KindOfArray, ArrayData*);
X(KindOfObject, ObjectData*);
X(KindOfRef, RefData*);
X(KindOfString, StringData*);
X(KindOfStaticString, StringData*);
#undef X
}
template<DataType DType>
typename std::enable_if<
!std::is_same<typename detail::DataTypeCPPType<DType>::type,void>::value,
TypedValue
>::type make_tv(typename detail::DataTypeCPPType<DType>::type val) {
TypedValue ret;
ret.m_data = make_value(val);
ret.m_type = DType;
return ret;
}
template<DataType DType>
typename std::enable_if<
std::is_same<typename detail::DataTypeCPPType<DType>::type,void>::value,
TypedValue
>::type make_tv() {
TypedValue ret;
ret.m_type = DType;
return ret;
}
///////////////////////////////////////////////////////////////////////////////
}
+78 -56
Ver Arquivo
@@ -32,28 +32,6 @@ namespace {
//////////////////////////////////////////////////////////////////////
bool cellToBool(const Cell* cell) {
assert(tvIsPlausible(cell));
assert(cell->m_type != KindOfRef);
switch (cell->m_type) {
case KindOfUninit:
case KindOfNull: return false;
case KindOfInt64: return cell->m_data.num != 0;
case KindOfBoolean: return cell->m_data.num;
case KindOfDouble: return cell->m_data.dbl != 0;
case KindOfStaticString:
case KindOfString: return cell->m_data.pstr->toBoolean();
case KindOfArray: return !cell->m_data.parr->empty();
case KindOfObject: // TODO: should handle o_toBoolean?
return true;
default: break;
}
not_reached();
}
//////////////////////////////////////////////////////////////////////
/*
* Family of relative op functions.
*
@@ -247,31 +225,36 @@ bool cellRelOp(Op op, const Cell* cell, const ObjectData* od) {
}
template<class Op>
bool tvRelOp(Op op, const TypedValue* tv1, const TypedValue* tv2) {
assert(tvIsPlausible(tv1));
assert(tvIsPlausible(tv2));
tv1 = tvToCell(tv1);
tv2 = tvToCell(tv2);
bool cellRelOp(Op op, const Cell* c1, const Cell* c2) {
assert(c1->m_type != KindOfRef);
assert(c2->m_type != KindOfRef);
switch (tv2->m_type) {
switch (c2->m_type) {
case KindOfUninit:
case KindOfNull:
return IS_STRING_TYPE(tv1->m_type)
? op(tv1->m_data.pstr, empty_string.get())
: cellRelOp(op, tv1, false);
case KindOfInt64: return cellRelOp(op, tv1, tv2->m_data.num);
case KindOfBoolean: return cellRelOp(op, tv1, !!tv2->m_data.num);
case KindOfDouble: return cellRelOp(op, tv1, tv2->m_data.dbl);
return IS_STRING_TYPE(c1->m_type)
? op(c1->m_data.pstr, empty_string.get())
: cellRelOp(op, c1, false);
case KindOfInt64: return cellRelOp(op, c1, c2->m_data.num);
case KindOfBoolean: return cellRelOp(op, c1, !!c2->m_data.num);
case KindOfDouble: return cellRelOp(op, c1, c2->m_data.dbl);
case KindOfStaticString:
case KindOfString: return cellRelOp(op, tv1, tv2->m_data.pstr);
case KindOfArray: return cellRelOp(op, tv1, tv2->m_data.parr);
case KindOfObject: return cellRelOp(op, tv1, tv2->m_data.pobj);
case KindOfString: return cellRelOp(op, c1, c2->m_data.pstr);
case KindOfArray: return cellRelOp(op, c1, c2->m_data.parr);
case KindOfObject: return cellRelOp(op, c1, c2->m_data.pobj);
default:
break;
}
not_reached();
}
template<class Op>
bool tvRelOp(Op op, const TypedValue* tv1, const TypedValue* tv2) {
assert(tvIsPlausible(tv1));
assert(tvIsPlausible(tv2));
return cellRelOp(op, tvToCell(tv1), tvToCell(tv2));
}
/*
* These relative ops helper function objects define operator() for
* each primitive type, and for the case of a complex type being
@@ -387,39 +370,36 @@ struct Gt {
}
bool tvSame(const TypedValue* tv1, const TypedValue* tv2) {
assert(tvIsPlausible(tv1));
assert(tvIsPlausible(tv2));
bool cellSame(const Cell* c1, const Cell* c2) {
assert(c1->m_type != KindOfRef);
assert(c2->m_type != KindOfRef);
tv1 = tvToCell(tv1);
tv2 = tvToCell(tv2);
bool const null1 = IS_NULL_TYPE(tv1->m_type);
bool const null2 = IS_NULL_TYPE(tv2->m_type);
bool const null1 = IS_NULL_TYPE(c1->m_type);
bool const null2 = IS_NULL_TYPE(c2->m_type);
if (null1 && null2) return true;
if (null1 || null2) return false;
switch (tv1->m_type) {
switch (c1->m_type) {
case KindOfInt64:
case KindOfBoolean:
if (tv2->m_type != tv1->m_type) return false;
return tv1->m_data.num == tv2->m_data.num;
if (c2->m_type != c1->m_type) return false;
return c1->m_data.num == c2->m_data.num;
case KindOfDouble:
if (tv2->m_type != tv1->m_type) return false;
return tv1->m_data.dbl == tv2->m_data.dbl;
if (c2->m_type != c1->m_type) return false;
return c1->m_data.dbl == c2->m_data.dbl;
case KindOfStaticString:
case KindOfString:
if (!IS_STRING_TYPE(tv2->m_type)) return false;
return tv1->m_data.pstr->same(tv2->m_data.pstr);
if (!IS_STRING_TYPE(c2->m_type)) return false;
return c1->m_data.pstr->same(c2->m_data.pstr);
case KindOfArray:
if (tv2->m_type != KindOfArray) return false;
return tv1->m_data.parr->equal(tv2->m_data.parr, true);
if (c2->m_type != KindOfArray) return false;
return c1->m_data.parr->equal(c2->m_data.parr, true);
case KindOfObject:
return tv2->m_type == KindOfObject &&
tv1->m_data.pobj == tv2->m_data.pobj;
return c2->m_type == KindOfObject &&
c1->m_data.pobj == c2->m_data.pobj;
default:
break;
@@ -427,6 +407,12 @@ bool tvSame(const TypedValue* tv1, const TypedValue* tv2) {
not_reached();
}
bool tvSame(const TypedValue* tv1, const TypedValue* tv2) {
assert(tvIsPlausible(tv1));
assert(tvIsPlausible(tv2));
return cellSame(tvToCell(tv1), tvToCell(tv2));
}
//////////////////////////////////////////////////////////////////////
/*
@@ -459,6 +445,10 @@ bool cellEqual(const Cell* cell, const ObjectData* val) {
return cellRelOp(Eq(), cell, val);
}
bool cellEqual(const Cell* c1, const Cell* c2) {
return cellRelOp(Eq(), c1, c2);
}
HOT_FUNC
bool tvEqual(const TypedValue* tv1, const TypedValue* tv2) {
return tvRelOp(Eq(), tv1, tv2);
@@ -488,6 +478,10 @@ bool cellLess(const Cell* cell, const ObjectData* val) {
return cellRelOp(Lt(), cell, val);
}
bool cellLess(const Cell* c1, const Cell* c2) {
return cellRelOp(Lt(), c1, c2);
}
HOT_FUNC
bool tvLess(const TypedValue* tv1, const TypedValue* tv2) {
return tvRelOp(Lt(), tv1, tv2);
@@ -518,11 +512,39 @@ bool cellGreater(const Cell* cell, const ObjectData* val) {
return cellRelOp(Gt(), cell, val);
}
bool cellGreater(const Cell* c1, const Cell* c2) {
return cellRelOp(Gt(), c1, c2);
}
bool tvGreater(const TypedValue* tv1, const TypedValue* tv2) {
return tvRelOp(Gt(), tv1, tv2);
}
//////////////////////////////////////////////////////////////////////
bool cellLessOrEqual(const Cell* c1, const Cell* c2) {
assert(c1->m_type != KindOfRef);
assert(c2->m_type != KindOfRef);
if ((c1->m_type == KindOfArray && c2->m_type == KindOfArray) ||
(c1->m_type == KindOfObject && c2->m_type == KindOfObject)) {
return cellLess(c1, c2) || cellEqual(c1, c2);
}
return !cellGreater(c1, c2);
}
bool cellGreaterOrEqual(const Cell* c1, const Cell* c2) {
assert(c1->m_type != KindOfRef);
assert(c2->m_type != KindOfRef);
if ((c1->m_type == KindOfArray && c2->m_type == KindOfArray) ||
(c1->m_type == KindOfObject && c2->m_type == KindOfObject)) {
return cellGreater(c1, c2) || cellEqual(c1, c2);
}
return !cellLess(c1, c2);
}
//////////////////////////////////////////////////////////////////////
}
+37
Ver Arquivo
@@ -23,6 +23,12 @@ namespace HPHP {
//////////////////////////////////////////////////////////////////////
// Php's operator ===
/*
* Returns whether two Cells have the same value, in the sense of
* php's === operator.
*/
bool cellSame(const Cell*, const Cell*);
/*
* Returns whether two TypedValues have the same value, in sense of
* php's === operator.
@@ -44,6 +50,12 @@ bool cellEqual(const Cell*, const StringData*);
bool cellEqual(const Cell*, const ArrayData*);
bool cellEqual(const Cell*, const ObjectData*);
/*
* Returns whether two Cells have the same value, in the same of php's
* == operator.
*/
bool cellEqual(const Cell*, const Cell*);
/*
* Returns whether two TypedValues have the same value, in the sense
* of php's == operator.
@@ -65,6 +77,12 @@ bool cellLess(const Cell*, const StringData*);
bool cellLess(const Cell*, const ArrayData*);
bool cellLess(const Cell*, const ObjectData*);
/*
* Returns whether a Cell is greater than another Cell, in the sense
* of php's < operator.
*/
bool cellLess(const Cell*, const Cell*);
/*
* Returns whether tv1 is less than tv2, as in php's < operator.
*/
@@ -85,6 +103,12 @@ bool cellGreater(const Cell*, const StringData*);
bool cellGreater(const Cell*, const ArrayData*);
bool cellGreater(const Cell*, const ObjectData*);
/*
* Returns whether a Cell is greater than another Cell, in the sense
* of php's > operator.
*/
bool cellGreater(const Cell*, const Cell*);
/*
* Returns whether tv1 is greather than tv2, as in php's > operator.
*/
@@ -92,6 +116,19 @@ bool tvGreater(const TypedValue*, const TypedValue*);
//////////////////////////////////////////////////////////////////////
/*
* Php operator >= and <=
*
* Note that in php $x <= $y is not equivalent to !($x > $y) for
* objects and arrays.
*
* These functions are necessary to handle those cases specially.
*/
bool cellLessOrEqual(const Cell*, const Cell*);
bool cellGreaterOrEqual(const Cell*, const Cell*);
//////////////////////////////////////////////////////////////////////
}
#include "hphp/runtime/base/tv_comparisons-inl.h"
+43
Ver Arquivo
@@ -0,0 +1,43 @@
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
namespace HPHP {
//////////////////////////////////////////////////////////////////////
inline bool cellToBool(const Cell* cell) {
assert(tvIsPlausible(cell));
assert(cell->m_type != KindOfRef);
switch (cell->m_type) {
case KindOfUninit:
case KindOfNull: return false;
case KindOfInt64: return cell->m_data.num != 0;
case KindOfBoolean: return cell->m_data.num;
case KindOfDouble: return cell->m_data.dbl != 0;
case KindOfStaticString:
case KindOfString: return cell->m_data.pstr->toBoolean();
case KindOfArray: return !cell->m_data.parr->empty();
case KindOfObject: // TODO: should handle o_toBoolean?
return true;
default: break;
}
not_reached();
}
//////////////////////////////////////////////////////////////////////
}
+11 -10
Ver Arquivo
@@ -29,16 +29,6 @@ namespace HPHP {
class Variant;
template<typename Data>
inline TypedValue tv(DataType type, Data data) {
static_assert(sizeof(Data) == sizeof(int64_t),
"Data type in tv() not proper size");
TypedValue v;
v.m_data.num = (int64_t)data;
v.m_type = type;
return v;
}
// Assumes 'data' is live
// Assumes 'IS_REFCOUNTED_TYPE(type)'
void tvDecRefHelper(DataType type, uint64_t datum);
@@ -448,6 +438,15 @@ inline bool tvIsString(const TypedValue* tv) {
void tvUnboxIfNeeded(TypedValue* tv);
/*
* Convert a cell to a boolean, without changing the Cell.
*/
bool cellToBool(const Cell*);
/*
* TypedValue conversions that update the tv in place (decrefing and
* old value, if necessary).
*/
void tvCastToBooleanInPlace(TypedValue* tv);
void tvCastToInt64InPlace(TypedValue* tv, int base = 10);
int64_t tvCastToInt64(TypedValue* tv, int base = 10);
@@ -471,4 +470,6 @@ extern const RawDestructor g_destructors[kDestrTableSize];
///////////////////////////////////////////////////////////////////////////////
}
#include "hphp/runtime/base/tv_helpers-inl.h"
#endif // incl_HPHP_TV_HELPERS_H_
-24
Ver Arquivo
@@ -587,14 +587,6 @@ bool String::operator!=(litstr v) const {
return !HPHP::equal(m_px, v);
}
bool String::operator>=(litstr v) const {
return more_or_equal(m_px, v);
}
bool String::operator<=(litstr v) const {
return less_or_equal(m_px, v);
}
bool String::operator>(litstr v) const {
return HPHP::more(m_px, v);
}
@@ -611,14 +603,6 @@ bool String::operator!=(CStrRef v) const {
return !HPHP::equal(m_px, v);
}
bool String::operator>=(CStrRef v) const {
return more_or_equal(m_px, v);
}
bool String::operator<=(CStrRef v) const {
return less_or_equal(m_px, v);
}
bool String::operator>(CStrRef v) const {
return HPHP::more(m_px, v);
}
@@ -635,14 +619,6 @@ bool String::operator!=(CVarRef v) const {
return !HPHP::equal(m_px, v);
}
bool String::operator>=(CVarRef v) const {
return more_or_equal(m_px, v);
}
bool String::operator<=(CVarRef v) const {
return less_or_equal(m_px, v);
}
bool String::operator>(CVarRef v) const {
return HPHP::more(m_px, v);
}
+6 -6
Ver Arquivo
@@ -332,20 +332,20 @@ public:
*/
bool operator == (litstr v) const;
bool operator != (litstr v) const;
bool operator >= (litstr v) const;
bool operator <= (litstr v) const;
bool operator >= (litstr v) const = delete;
bool operator <= (litstr v) const = delete;
bool operator > (litstr v) const;
bool operator < (litstr v) const;
bool operator == (CStrRef v) const;
bool operator != (CStrRef v) const;
bool operator >= (CStrRef v) const;
bool operator <= (CStrRef v) const;
bool operator >= (CStrRef v) const = delete;
bool operator <= (CStrRef v) const = delete;
bool operator > (CStrRef v) const;
bool operator < (CStrRef v) const;
bool operator == (CVarRef v) const;
bool operator != (CVarRef v) const;
bool operator >= (CVarRef v) const;
bool operator <= (CVarRef v) const;
bool operator >= (CVarRef v) const = delete;
bool operator <= (CVarRef v) const = delete;
bool operator > (CVarRef v) const;
bool operator < (CVarRef v) const;
+34 -43
Ver Arquivo
@@ -3780,79 +3780,70 @@ inline void OPTBLD_INLINE VMExecutionContext::iopMod(PC& pc) {
#undef MATHOP_DOUBLE
#undef MATHOP_DIVCHECK
#define LOGICOP(OP) do { \
NEXT(); \
Cell* c1 = m_stack.topC(); \
Cell* c2 = m_stack.indC(1); \
{ \
tvCellAsVariant(c2) = \
bool(tvCellAsVariant(c2).toBoolean() OP tvCellAsVariant(c1).toBoolean()); \
} \
m_stack.popC(); \
} while (0)
inline void OPTBLD_INLINE VMExecutionContext::iopXor(PC& pc) {
LOGICOP(^);
}
#undef LOGICOP
inline void OPTBLD_INLINE VMExecutionContext::iopNot(PC& pc) {
NEXT();
Cell* c1 = m_stack.topC();
tvCellAsVariant(c1) = !tvCellAsVariant(c1).toBoolean();
}
#define CMPOP(OP, VOP) do { \
NEXT(); \
Cell* c1 = m_stack.topC(); \
Cell* c2 = m_stack.indC(1); \
if (c2->m_type == KindOfInt64 && c1->m_type == KindOfInt64) { \
int64_t a = c2->m_data.num; \
int64_t b = c1->m_data.num; \
c2->m_data.num = (a OP b); \
c2->m_type = KindOfBoolean; \
m_stack.popX(); \
} else { \
int64_t result = VOP(tvCellAsVariant(c2), tvCellAsCVarRef(c1)); \
tvRefcountedDecRefCell(c2); \
c2->m_data.num = result; \
c2->m_type = KindOfBoolean; \
m_stack.popC(); \
} \
} while (0)
template<class Op>
void OPTBLD_INLINE VMExecutionContext::implCellBinOpBool(PC& pc, Op op) {
NEXT();
auto const c1 = m_stack.topC();
auto const c2 = m_stack.indC(1);
bool const result = op(c2, c1);
tvRefcountedDecRefCell(c2);
*c2 = make_tv<KindOfBoolean>(result);
m_stack.popC();
}
inline void OPTBLD_INLINE VMExecutionContext::iopXor(PC& pc) {
implCellBinOpBool(pc, [&] (const Cell* c1, const Cell* c2) -> bool {
return cellToBool(c1) ^ cellToBool(c2);
});
}
inline void OPTBLD_INLINE VMExecutionContext::iopSame(PC& pc) {
CMPOP(==, same);
implCellBinOpBool(pc, cellSame);
}
inline void OPTBLD_INLINE VMExecutionContext::iopNSame(PC& pc) {
CMPOP(!=, !same);
implCellBinOpBool(pc, [&] (const Cell* c1, const Cell* c2) {
return !cellSame(c1, c2);
});
}
inline void OPTBLD_INLINE VMExecutionContext::iopEq(PC& pc) {
CMPOP(==, equal);
implCellBinOpBool(pc, [&] (const Cell* c1, const Cell* c2) {
return cellEqual(c1, c2);
});
}
inline void OPTBLD_INLINE VMExecutionContext::iopNeq(PC& pc) {
CMPOP(!=, !equal);
implCellBinOpBool(pc, [&] (const Cell* c1, const Cell* c2) {
return !cellEqual(c1, c2);
});
}
inline void OPTBLD_INLINE VMExecutionContext::iopLt(PC& pc) {
CMPOP(<, less);
implCellBinOpBool(pc, [&] (const Cell* c1, const Cell* c2) {
return cellLess(c1, c2);
});
}
inline void OPTBLD_INLINE VMExecutionContext::iopLte(PC& pc) {
CMPOP(<=, less_or_equal);
implCellBinOpBool(pc, cellLessOrEqual);
}
inline void OPTBLD_INLINE VMExecutionContext::iopGt(PC& pc) {
CMPOP(>, more);
implCellBinOpBool(pc, [&] (const Cell* c1, const Cell* c2) {
return cellGreater(c1, c2);
});
}
inline void OPTBLD_INLINE VMExecutionContext::iopGte(PC& pc) {
CMPOP(>=, more_or_equal);
implCellBinOpBool(pc, cellGreaterOrEqual);
}
#undef CMPOP
#define MATHOP_DOUBLE(OP)
#define MATHOP_DIVCHECK(x)
+5 -5
Ver Arquivo
@@ -31,7 +31,7 @@ class InvalidSetMException : public std::runtime_error {
public:
InvalidSetMException()
: std::runtime_error("Empty InvalidSetMException")
, m_tv(HPHP::tv(KindOfNull, 0LL))
, m_tv(make_tv<KindOfNull>())
{}
explicit InvalidSetMException(const TypedValue& value)
@@ -543,7 +543,7 @@ inline void SetElemNumberish(Cell* value) {
tvRefcountedDecRefCell((TypedValue*)value);
tvWriteNull((TypedValue*)value);
} else {
throw InvalidSetMException(tv(KindOfNull, 0LL));
throw InvalidSetMException(make_tv<KindOfNull>());
}
}
@@ -631,7 +631,7 @@ inline void SetElemArray(TypedValue* base, TypedValue* key,
tvRefcountedDecRef(value);
tvWriteNull(value);
} else {
throw InvalidSetMException(tv(KindOfNull, 0LL));
throw InvalidSetMException(make_tv<KindOfNull>());
}
}
@@ -788,7 +788,7 @@ inline void SetNewElemNumberish(Cell* value) {
tvRefcountedDecRefCell((TypedValue*)value);
tvWriteNull((TypedValue*)value);
} else {
throw InvalidSetMException(tv(KindOfNull, 0LL));
throw InvalidSetMException(make_tv<KindOfNull>());
}
}
template <bool setResult>
@@ -1519,7 +1519,7 @@ inline void SetPropNull(Cell* val) {
tvRefcountedDecRefCell(val);
tvWriteNull(val);
} else {
throw InvalidSetMException(tv(KindOfNull, 0LL));
throw InvalidSetMException(make_tv<KindOfNull>());
}
}
inline void SetPropStdclass(TypedValue* base, TypedValue* key,