diff options
-rwxr-xr-x | ext/spl/php_spl.c | 10 | ||||
-rwxr-xr-x | ext/spl/spl_engine.c | 46 | ||||
-rwxr-xr-x | ext/spl/spl_engine.h | 2 | ||||
-rwxr-xr-x | ext/spl/spl_foreach.c | 10 |
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 { |