summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xext/spl/php_spl.c10
-rwxr-xr-xext/spl/spl_engine.c46
-rwxr-xr-xext/spl/spl_engine.h2
-rwxr-xr-xext/spl/spl_foreach.c10
4 files changed, 49 insertions, 19 deletions
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index b97c44f32c..84f86fa931 100755
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -134,29 +134,29 @@ PHP_MINIT_FUNCTION(spl)
REGISTER_SPL_INTERFACE(spl, sequence);
REGISTER_SPL_INTF_FUNC(spl, sequence, rewind);
- REGISTER_SPL_PARENT_CE(spl, sequence, forward);
+ REGISTER_SPL_IMPLEMENT(spl, sequence, forward);
REGISTER_SPL_INTERFACE(spl, assoc);
REGISTER_SPL_INTF_FUNC(spl, assoc, key);
REGISTER_SPL_INTERFACE(spl, forward_assoc);
- REGISTER_SPL_PARENT_CE(spl, forward_assoc, forward);
REGISTER_SPL_IMPLEMENT(spl, forward_assoc, assoc);
+ REGISTER_SPL_IMPLEMENT(spl, forward_assoc, forward);
REGISTER_SPL_INTERFACE(spl, sequence_assoc);
- REGISTER_SPL_PARENT_CE(spl, sequence_assoc, sequence);
REGISTER_SPL_IMPLEMENT(spl, sequence_assoc, forward_assoc);
+ REGISTER_SPL_IMPLEMENT(spl, sequence_assoc, sequence);
REGISTER_SPL_INTERFACE(spl, array_read);
REGISTER_SPL_INTF_FUNC(spl, array_read, get);
REGISTER_SPL_INTF_FUNC(spl, array_read, exists);
REGISTER_SPL_INTERFACE(spl, array_access);
- REGISTER_SPL_PARENT_CE(spl, array_access, array_read);
+ REGISTER_SPL_IMPLEMENT(spl, array_access, array_read);
REGISTER_SPL_INTF_FUNC(spl, array_access, set);
REGISTER_SPL_INTERFACE(spl, array_access_ex);
- REGISTER_SPL_PARENT_CE(spl, array_access_ex, array_access);
+ REGISTER_SPL_IMPLEMENT(spl, array_access_ex, array_access);
REGISTER_SPL_INTF_FUNC(spl, array_access_ex, new_writer);
REGISTER_SPL_INTERFACE(spl, array_writer);
diff --git a/ext/spl/spl_engine.c b/ext/spl/spl_engine.c
index 84e5d8aca3..04dbd75d78 100755
--- a/ext/spl/spl_engine.c
+++ b/ext/spl/spl_engine.c
@@ -193,23 +193,53 @@ zval * spl_get_zval_ptr(znode *node, temp_variable *Ts, zval **should_free TSRML
}
/* }}} */
+/* {{{ */
+inline zend_class_entry *spl_get_class_entry(zval *obj TSRMLS_DC)
+{
+ if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_class_entry) {
+ return Z_OBJ_HT_P(obj)->get_class_entry(obj TSRMLS_CC);
+ } else {
+ return NULL;
+ }
+}
+/* }}} */
+
/* {{{ spl_is_instance_of */
int spl_is_instance_of(zval **obj, zend_class_entry *ce TSRMLS_DC)
{
/* Ensure everything needed is available before checking for the type.
- * HAS_CLASS_ENTRY is neededto ensure Z_OBJCE_PP will not throw an error.
*/
- if (!obj || !*obj || Z_TYPE_PP(obj) != IS_OBJECT || !HAS_CLASS_ENTRY(**obj)) {
- return 0;
- } else {
- zend_class_entry *instance_ce = Z_OBJCE_PP(obj);
-
+ zend_class_entry *instance_ce;
+
+ if (obj && (instance_ce = spl_get_class_entry(*obj TSRMLS_CC)) != NULL) {
if (instanceof_function(instance_ce, ce TSRMLS_CC)) {
return 1;
- } else {
- return 0;
}
}
+ return 0;
+}
+/* }}} */
+
+/* {{{ spl_implements */
+int spl_implements(zval **obj, zend_class_entry *ce TSRMLS_DC)
+{
+ /* Ensure everything needed is available before checking for the type.
+ */
+ zend_class_entry *instance_ce;
+
+ if (obj && (instance_ce = spl_get_class_entry(*obj TSRMLS_CC)) != NULL) {
+ int i;
+
+ while (instance_ce) {
+ for (i = 0; i < instance_ce->num_interfaces; i++) {
+ if (instance_ce->interfaces[i] == ce) {
+ return 1;
+ }
+ }
+ instance_ce = instance_ce->parent;
+ }
+ }
+ return spl_is_instance_of(obj, ce TSRMLS_CC);
}
/* }}} */
diff --git a/ext/spl/spl_engine.h b/ext/spl/spl_engine.h
index ded59f4412..db61a1982d 100755
--- a/ext/spl/spl_engine.h
+++ b/ext/spl/spl_engine.h
@@ -49,7 +49,7 @@ void spl_unlock_zval_ptr_ptr(znode *node, temp_variable *Ts TSRMLS_DC);
zval * spl_get_zval_ptr(znode *node, temp_variable *Ts, zval **should_free TSRMLS_DC);
int spl_is_instance_of(zval **obj, zend_class_entry *ce TSRMLS_DC);
-
+int spl_implements(zval **obj, zend_class_entry *ce TSRMLS_DC);
#endif /* SPL_ENGINE_H */
diff --git a/ext/spl/spl_foreach.c b/ext/spl/spl_foreach.c
index 850b8bb3dd..cbe7dfd1e2 100755
--- a/ext/spl/spl_foreach.c
+++ b/ext/spl/spl_foreach.c
@@ -38,7 +38,7 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET)
if (EX(opline)->extended_value) {
obj = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
- if (spl_is_instance_of(obj, spl_ce_iterator TSRMLS_CC)) {
+ if (spl_implements(obj, spl_ce_iterator TSRMLS_CC)) {
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
MAKE_STD_ZVAL(retval);
spl_begin_method_call_this(obj, "new_iterator", retval TSRMLS_CC);
@@ -49,7 +49,7 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET)
PZVAL_LOCK(retval);
NEXT_OPCODE();
- } else if (spl_is_instance_of(obj, spl_ce_forward TSRMLS_CC)) {
+ } else if (spl_implements(obj, spl_ce_forward TSRMLS_CC)) {
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
EX_T(EX(opline)->result.u.var).var.ptr = *obj;
@@ -72,7 +72,7 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH)
zval **obj = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
zval more, tmp, *value, *key, *result;
- if (spl_is_instance_of(obj, spl_ce_forward TSRMLS_CC)) {
+ if (spl_implements(obj, spl_ce_forward TSRMLS_CC)) {
zend_uint index = EX(opline)->op2.u.EA.type++;
spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC);
@@ -80,7 +80,7 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH)
if (index) {
spl_begin_method_call_this(obj, "next", &more TSRMLS_CC);
- } else if (spl_is_instance_of(obj, spl_ce_sequence TSRMLS_CC)) {
+ } else if (spl_implements(obj, spl_ce_sequence TSRMLS_CC)) {
spl_begin_method_call_this(obj, "rewind", &more TSRMLS_CC);
}
@@ -94,7 +94,7 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH)
zend_hash_index_update(result->value.ht, 0, &value, sizeof(zval *), NULL);
- if (spl_is_instance_of(obj, spl_ce_assoc TSRMLS_CC)) {
+ if (spl_implements(obj, spl_ce_assoc TSRMLS_CC)) {
ALLOC_ZVAL(key);
spl_begin_method_call_this(obj, "key", key TSRMLS_CC);
} else {