This commit is contained in:
+9
-135
@@ -1193,143 +1193,17 @@ PH7_PRIVATE void PH7_ClassInstanceUnref(ph7_class_instance *pThis) {
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Compare two class instances [i.e: Objects in the PHP jargon]
|
||||
* Note on objects comparison:
|
||||
* According to the PHP langauge reference manual
|
||||
* When using the comparison operator (==), object variables are compared in a simple manner
|
||||
* namely: Two object instances are equal if they have the same attributes and values, and are
|
||||
* instances of the same class.
|
||||
* On the other hand, when using the identity operator (===), object variables are identical
|
||||
* if and only if they refer to the same instance of the same class.
|
||||
* An example will clarify these rules.
|
||||
* Example #1 Example of object comparison
|
||||
* <?php
|
||||
* function bool2str($bool)
|
||||
* {
|
||||
* if ($bool === false) {
|
||||
* return 'FALSE';
|
||||
* } else {
|
||||
* return 'TRUE';
|
||||
* }
|
||||
* }
|
||||
* function compareObjects(&$o1, &$o2)
|
||||
* {
|
||||
* echo 'o1 == o2 : ' . bool2str($o1 == $o2) . "\n";
|
||||
* echo 'o1 != o2 : ' . bool2str($o1 != $o2) . "\n";
|
||||
* echo 'o1 === o2 : ' . bool2str($o1 === $o2) . "\n";
|
||||
* echo 'o1 !== o2 : ' . bool2str($o1 !== $o2) . "\n";
|
||||
* }
|
||||
* class Flag
|
||||
* {
|
||||
* public $flag;
|
||||
*
|
||||
* function Flag($flag = true) {
|
||||
* $this->flag = $flag;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* class OtherFlag
|
||||
* {
|
||||
* public $flag;
|
||||
*
|
||||
* function OtherFlag($flag = true) {
|
||||
* $this->flag = $flag;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* $o = new Flag();
|
||||
* $p = new Flag();
|
||||
* $q = $o;
|
||||
* $r = new OtherFlag();
|
||||
*
|
||||
* echo "Two instances of the same class\n";
|
||||
* compareObjects($o, $p);
|
||||
* echo "\nTwo references to the same instance\n";
|
||||
* compareObjects($o, $q);
|
||||
* echo "\nInstances of two different classes\n";
|
||||
* compareObjects($o, $r);
|
||||
* ?>
|
||||
* The above example will output:
|
||||
* Two instances of the same class
|
||||
* o1 == o2 : TRUE
|
||||
* o1 != o2 : FALSE
|
||||
* o1 === o2 : FALSE
|
||||
* o1 !== o2 : TRUE
|
||||
* Two references to the same instance
|
||||
* o1 == o2 : TRUE
|
||||
* o1 != o2 : FALSE
|
||||
* o1 === o2 : TRUE
|
||||
* o1 !== o2 : FALSE
|
||||
* Instances of two different classes
|
||||
* o1 == o2 : FALSE
|
||||
* o1 != o2 : TRUE
|
||||
* o1 === o2 : FALSE
|
||||
* o1 !== o2 : TRUE
|
||||
*
|
||||
* This function return 0 if the objects are equals according to the comprison rules defined above.
|
||||
* Any other return values indicates difference.
|
||||
* Compare two class instances [i.e: Objects in the PHP jargon].
|
||||
* Under the typed comparison contract object comparison is IDENTITY-ONLY:
|
||||
* two values are equal if and only if they reference the same instance
|
||||
* [or both are empty references, i.e: x.pOther == 0]. There is no
|
||||
* attribute comparison and no ordering; bStrict yields the same result.
|
||||
*/
|
||||
PH7_PRIVATE sxi32 PH7_ClassInstanceCmp(ph7_class_instance *pLeft, ph7_class_instance *pRight, int bStrict, int iNest) {
|
||||
SyHashEntry *pEntry, *pEntry2;
|
||||
ph7_value sV1, sV2;
|
||||
sxi32 rc;
|
||||
if(iNest > 31) {
|
||||
/* Nesting limit reached */
|
||||
PH7_VmThrowError(pLeft->pVm, PH7_CTX_ERR, "Nesting limit reached, probably infinite recursion");
|
||||
}
|
||||
/* Comparison is performed only if the objects are instance of the same class */
|
||||
if(pLeft->pClass != pRight->pClass) {
|
||||
return 1;
|
||||
}
|
||||
if(bStrict) {
|
||||
/*
|
||||
* According to the PHP language reference manual:
|
||||
* when using the identity operator (===), object variables
|
||||
* are identical if and only if they refer to the same instance
|
||||
* of the same class.
|
||||
*/
|
||||
return pLeft != pRight;
|
||||
}
|
||||
/*
|
||||
* Attribute comparison.
|
||||
* According to the PHP reference manual:
|
||||
* When using the comparison operator (==), object variables are compared
|
||||
* in a simple manner, namely: Two object instances are equal if they have
|
||||
* the same attributes and values, and are instances of the same class.
|
||||
*/
|
||||
if(pLeft == pRight) {
|
||||
/* Same instance,don't bother processing,object are equals */
|
||||
return 0;
|
||||
}
|
||||
SyHashResetLoopCursor(&pLeft->hAttr);
|
||||
SyHashResetLoopCursor(&pRight->hAttr);
|
||||
PH7_MemObjInit(pLeft->pVm, &sV1);
|
||||
PH7_MemObjInit(pLeft->pVm, &sV2);
|
||||
sV1.nIdx = sV2.nIdx = SXU32_HIGH;
|
||||
while((pEntry = SyHashGetNextEntry(&pLeft->hAttr)) != 0 && (pEntry2 = SyHashGetNextEntry(&pRight->hAttr)) != 0) {
|
||||
VmClassAttr *p1 = (VmClassAttr *)pEntry->pUserData;
|
||||
VmClassAttr *p2 = (VmClassAttr *)pEntry2->pUserData;
|
||||
/* Compare only non-static attribute */
|
||||
if((p1->pAttr->iFlags & (PH7_CLASS_ATTR_CONSTANT | PH7_CLASS_ATTR_STATIC)) == 0) {
|
||||
ph7_value *pL, *pR;
|
||||
pL = ExtractClassAttrValue(pLeft->pVm, p1);
|
||||
pR = ExtractClassAttrValue(pRight->pVm, p2);
|
||||
if(pL && pR) {
|
||||
PH7_MemObjLoad(pL, &sV1);
|
||||
PH7_MemObjLoad(pR, &sV2);
|
||||
/* Compare the two values now */
|
||||
rc = PH7_MemObjCmp(&sV1, &sV2, bStrict, iNest + 1);
|
||||
PH7_MemObjRelease(&sV1);
|
||||
PH7_MemObjRelease(&sV2);
|
||||
if(rc != 0) {
|
||||
/* Not equals */
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Object are equals */
|
||||
return 0;
|
||||
SXUNUSED(bStrict); /* cc warning */
|
||||
SXUNUSED(iNest); /* cc warning */
|
||||
/* Identity comparison */
|
||||
return pLeft == pRight ? 0 : 1;
|
||||
}
|
||||
/*
|
||||
* Dump a class instance and the store the dump in the BLOB given
|
||||
|
||||
Reference in New Issue
Block a user