cvs: spl / php_spl.c php_spl.h spl_foreach.c spl_foreach.h
| From: | Marcus Boerger | 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 */