cvs: spl / php_spl.c php_spl.h spl_foreach.c spl_foreach.h

From: Date: Sun, 25 May 2003 19:10:45 +0000
Subject: cvs: spl / php_spl.c php_spl.h spl_foreach.c spl_foreach.h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-21255@lists.php.net to get a copy of this message
helly Sun May 25 15:10:45 2003 EDT Modified files: /spl php_spl.c php_spl.h spl_foreach.c spl_foreach.h Log: Make foreach on spl'ed objects work with break, too Index: spl/php_spl.c diff -u spl/php_spl.c:1.3 spl/php_spl.c:1.4 --- spl/php_spl.c:1.3 Sun May 25 08:10:48 2003 +++ spl/php_spl.c Sun May 25 15:10:44 2003 @@ -102,6 +102,7 @@ #ifdef SPL_FOREACH ZEND_EXECUTE_HOOK(ZEND_FE_RESET); ZEND_EXECUTE_HOOK(ZEND_FE_FETCH); + ZEND_EXECUTE_HOOK(ZEND_SWITCH_FREE); #endif #if defined(SPL_ARRAY_READ) | defined(SPL_ARRAY_WRITE) @@ -195,6 +196,7 @@ #ifdef SPL_FOREACH ZEND_EXECUTE_HOOK_RESTORE(ZEND_FE_RESET); ZEND_EXECUTE_HOOK_RESTORE(ZEND_FE_FETCH); + ZEND_EXECUTE_HOOK_RESTORE(ZEND_SWITCH_FREE); #endif #if defined(SPL_ARRAY_READ) | defined(SPL_ARRAY_WRITE) Index: spl/php_spl.h diff -u spl/php_spl.h:1.1.1.1 spl/php_spl.h:1.2 --- spl/php_spl.h:1.1.1.1 Thu May 1 19:28:28 2003 +++ spl/php_spl.h Sun May 25 15:10:44 2003 @@ -63,6 +63,7 @@ #ifdef SPL_FOREACH ZEND_EXECUTE_HOOK_PTR(ZEND_FE_RESET); ZEND_EXECUTE_HOOK_PTR(ZEND_FE_FETCH); + ZEND_EXECUTE_HOOK_PTR(ZEND_SWITCH_FREE); #endif #if defined(SPL_ARRAY_READ) | defined(SPL_ARRAY_WRITE) ZEND_EXECUTE_HOOK_PTR(ZEND_FETCH_DIM_R); Index: spl/spl_foreach.c diff -u spl/spl_foreach.c:1.6 spl/spl_foreach.c:1.7 --- spl/spl_foreach.c:1.6 Sat May 24 21:36:50 2003 +++ spl/spl_foreach.c Sun May 25 15:10:44 2003 @@ -37,8 +37,9 @@ memset(emalloc(size), 0, size) typedef struct { - zend_uint index; + zval *obj; zend_class_entry *obj_ce; + zend_uint index; zend_uint is_ce_assoc; zend_function *f_next; zend_function *f_rewind; @@ -51,33 +52,41 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET) { zval **obj, *retval; + spl_foreach_proxy proxy; - if (EX(opline)->extended_value) { - obj = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); - if (spl_implements(obj, spl_ce_iterator TSRMLS_CC)) { - spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); - spl_begin_method_call_ex(obj, NULL, NULL, "new_iterator", sizeof("new_iterator")-1, &retval TSRMLS_CC); - EX_T(EX(opline)->result.u.var).var.ptr = retval; - EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr; - /* EX(opline)->result.u.EA.type = 0; */ - - PZVAL_LOCK(retval); - - NEXT_OPCODE(); - } 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; - EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr; - /* EX(opline)->result.u.EA.type = 0; */ - - (*obj)->refcount++; - PZVAL_LOCK(*obj); - - NEXT_OPCODE(); + obj = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); + if (spl_implements(obj, spl_ce_iterator TSRMLS_CC)) { + spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); + spl_begin_method_call_ex(obj, NULL, NULL, "new_iterator", sizeof("new_iterator")-1, &retval TSRMLS_CC); + if (!spl_implements(&retval, spl_ce_forward TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Objects created by new_iterator() must implement spl::forward"); + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_RESET); } + PZVAL_LOCK(retval); + } else if (spl_implements(obj, spl_ce_forward TSRMLS_CC)) { + spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); + (*obj)->refcount += 2; /* lock two times */ + retval = *obj; + } else { + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_RESET); } - ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_RESET); + + /* create the proxy */ + memset(&proxy, 0, sizeof(spl_foreach_proxy)); + proxy.obj = retval; + proxy.obj_ce = spl_get_class_entry(retval TSRMLS_CC); + proxy.is_ce_assoc = spl_implements(&retval, spl_ce_assoc TSRMLS_CC); + /* And pack it into a zval. Since it is nowhere accessible using a + * zval of type STRING is the fastest approach of storing the proxy. + */ + ALLOC_INIT_ZVAL(retval); + ZVAL_STRINGL(retval, (char*)&proxy, sizeof(spl_foreach_proxy), 1); + retval->refcount += 2; /* lock two times */ + /* return the created proxy container */ + EX_T(EX(opline)->result.u.var).var.ptr = retval; + EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr; + + NEXT_OPCODE(); } /* }}} */ @@ -109,24 +118,22 @@ znode *op1 = &EX(opline)->op1; zval **obj = spl_get_zval_ptr_ptr(op1, EX(Ts) TSRMLS_CC); zval more, tmp, *value, *key, *result; - spl_foreach_proxy *proxy = (spl_foreach_proxy*)op1->u.EA.type; + spl_foreach_proxy *proxy; - if (proxy || spl_implements(obj, spl_ce_forward TSRMLS_CC)) { - if (!proxy) { - (spl_foreach_proxy*)op1->u.EA.type = proxy = ezalloc(sizeof(spl_foreach_proxy)); - proxy->obj_ce = spl_get_class_entry(*obj TSRMLS_CC); - } - + if (Z_TYPE_PP(obj) == IS_STRING) { spl_unlock_zval_ptr_ptr(op1, EX(Ts) TSRMLS_CC); PZVAL_LOCK(*obj); + proxy = (spl_foreach_proxy*)Z_STRVAL_PP(obj); + obj = &proxy->obj; /* will be optimized out */ + if (proxy->index++) { spl_begin_method_call_this(obj, proxy->obj_ce, &proxy->f_next, "next", sizeof("next")-1, &tmp TSRMLS_CC); } else { - proxy->is_ce_assoc = spl_implements(obj, spl_ce_assoc TSRMLS_CC); if (spl_implements(obj, spl_ce_sequence TSRMLS_CC)) { spl_begin_method_call_this(obj, proxy->obj_ce, &proxy->f_rewind, "rewind", sizeof("rewind")-1, &tmp TSRMLS_CC); } + op_array->opcodes[EX(opline)->op2.u.opline_num].op2 = *op1; } spl_begin_method_call_this(obj, proxy->obj_ce, &proxy->f_more, "has_more", sizeof("has_more")-1, &more TSRMLS_CC); @@ -195,12 +202,35 @@ #endif NEXT_OPCODE(); } - efree(proxy); - op1->u.EA.type = 0; EX(opline) = op_array->opcodes+EX(opline)->op2.u.opline_num; return 0; } ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_FE_FETCH); +} +/* }}} */ + +/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_SWITCH_FREE) */ +ZEND_EXECUTE_HOOK_FUNCTION(ZEND_SWITCH_FREE) +{ + znode *op1 = &EX(opline)->op1; + znode *op2 = &EX(opline)->op2; + zval *tmp, **obj = spl_get_zval_ptr_ptr(op2, EX(Ts) TSRMLS_CC); + spl_foreach_proxy *proxy; + + if (obj) { + proxy = (spl_foreach_proxy*)Z_STRVAL_PP(obj); + tmp = *obj; + *obj = proxy->obj; /* restore */ + + zval_dtor(tmp); + FREE_ZVAL(tmp); + + spl_unlock_zval_ptr_ptr(op1, EX(Ts) TSRMLS_CC); + PZVAL_LOCK(*obj); + + SET_UNUSED(*op2); + } + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_SWITCH_FREE); } /* }}} */ Index: spl/spl_foreach.h diff -u spl/spl_foreach.h:1.1.1.1 spl/spl_foreach.h:1.2 --- spl/spl_foreach.h:1.1.1.1 Thu May 1 19:28:28 2003 +++ spl/spl_foreach.h Sun May 25 15:10:44 2003 @@ -24,6 +24,7 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET); ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_FETCH); +ZEND_EXECUTE_HOOK_FUNCTION(ZEND_SWITCH_FREE); #endif /* SPL_FOREACH_H */

« previous php.cvs (#21255) next »